/* * linux/kernel/tty_io.c * * (C) 1991 Linus Torvalds */ /* * 'tty_io.c' gives an orthogonal feeling to tty's, be they consoles * or rs-channels. It also implements echoing, cooked mode etc. * * Kill-line thanks to John T Kohl. */ #include #include #include #define ALRMMASK (1<<(SIGALRM-1)) #define KILLMASK (1<<(SIGKILL-1)) #define INTMASK (1<<(SIGINT-1)) #define QUITMASK (1<<(SIGQUIT-1)) #define TSTPMASK (1<<(SIGTSTP-1)) #include #include #include #include #define _L_FLAG(tty,f) ((tty)->termios.c_lflag & f) #define _I_FLAG(tty,f) ((tty)->termios.c_iflag & f) #define _O_FLAG(tty,f) ((tty)->termios.c_oflag & f) #define L_CANON(tty) _L_FLAG((tty),ICANON) #define L_ISIG(tty) _L_FLAG((tty),ISIG) #define L_ECHO(tty) _L_FLAG((tty),ECHO) #define L_ECHOE(tty) _L_FLAG((tty),ECHOE) #define L_ECHOK(tty) _L_FLAG((tty),ECHOK) #define L_ECHOCTL(tty) _L_FLAG((tty),ECHOCTL) #define L_ECHOKE(tty) _L_FLAG((tty),ECHOKE) #define I_UCLC(tty) _I_FLAG((tty),IUCLC) #define I_NLCR(tty) _I_FLAG((tty),INLCR) #define I_CRNL(tty) _I_FLAG((tty),ICRNL) #define I_NOCR(tty) _I_FLAG((tty),IGNCR) #define O_POST(tty) _O_FLAG((tty),OPOST) #define O_NLCR(tty) _O_FLAG((tty),ONLCR) #define O_CRNL(tty) _O_FLAG((tty),OCRNL) #define O_NLRET(tty) _O_FLAG((tty),ONLRET) #define O_LCUC(tty) _O_FLAG((tty),OLCUC) struct tty_struct tty_table[] = { { {ICRNL, /* change incoming CR to NL */ OPOST|ONLCR, /* change outgoing NL to CRNL */ 0, ISIG | ICANON | ECHO | ECHOCTL | ECHOKE, 0, /* console termio */ INIT_C_CC}, 0, /* initial pgrp */ 0, /* initial stopped */ con_write, {0,0,0,0,""}, /* console read-queue */ {0,0,0,0,""}, /* console write-queue */ {0,0,0,0,""} /* console secondary queue */ },{ {0, /* no translation */ 0, /* no translation */ B2400 | CS8, 0, 0, INIT_C_CC}, 0, 0, rs_write, {0x3f8,0,0,0,""}, /* rs 1 */ {0x3f8,0,0,0,""}, {0,0,0,0,""} },{ {0, /* no translation */ 0, /* no translation */ B2400 | CS8, 0, 0, INIT_C_CC}, 0, 0, rs_write, {0x2f8,0,0,0,""}, /* rs 2 */ {0x2f8,0,0,0,""}, {0,0,0,0,""} } }; /* * these are the tables used by the machine code handlers. * you can implement pseudo-tty's or something by changing * them. Currently not done. */ struct tty_queue * table_list[]={ &tty_table[0].read_q, &tty_table[0].write_q, &tty_table[1].read_q, &tty_table[1].write_q, &tty_table[2].read_q, &tty_table[2].write_q }; void tty_init(void) { rs_init(); con_init(); } void tty_intr(struct tty_struct * tty, int mask) { int i; if (tty->pgrp <= 0) return; for (i=0;ipgrp==tty->pgrp) task[i]->signal |= mask; } static void sleep_if_empty(struct tty_queue * queue) { cli(); while (!current->signal && EMPTY(*queue)) interruptible_sleep_on(&queue->proc_list); sti(); } static void sleep_if_full(struct tty_queue * queue) { if (!FULL(*queue)) return; cli(); while (!current->signal && LEFT(*queue)<128) interruptible_sleep_on(&queue->proc_list); sti(); } void wait_for_keypress(void) { sleep_if_empty(&tty_table[0].secondary); } void copy_to_cooked(struct tty_struct * tty) { signed char c; while (!EMPTY(tty->read_q) && !FULL(tty->secondary)) { GETCH(tty->read_q,c); if (c==13) if (I_CRNL(tty)) c=10; else if (I_NOCR(tty)) continue; else ; else if (c==10 && I_NLCR(tty)) c=13; if (I_UCLC(tty)) c=tolower(c); if (L_CANON(tty)) { if (c==KILL_CHAR(tty)) { /* deal with killing the input line */ while(!(EMPTY(tty->secondary) || (c=LAST(tty->secondary))==10 || c==EOF_CHAR(tty))) { if (L_ECHO(tty)) { if (c<32) PUTCH(127,tty->write_q); PUTCH(127,tty->write_q); tty->write(tty); } DEC(tty->secondary.head); } continue; } if (c==ERASE_CHAR(tty)) { if (EMPTY(tty->secondary) || (c=LAST(tty->secondary))==10 || c==EOF_CHAR(tty)) continue; if (L_ECHO(tty)) { if (c<32) PUTCH(127,tty->write_q); PUTCH(127,tty->write_q); tty->write(tty); } DEC(tty->secondary.head); continue; } if (c==STOP_CHAR(tty)) { tty->stopped=1; continue; } if (c==START_CHAR(tty)) { tty->stopped=0; continue; } } if (L_ISIG(tty)) { if (c==INTR_CHAR(tty)) { tty_intr(tty,INTMASK); continue; } if (c==QUIT_CHAR(tty)) { tty_intr(tty,QUITMASK); continue; } } if (c==10 || c==EOF_CHAR(tty)) tty->secondary.data++; if (L_ECHO(tty)) { if (c==10) { PUTCH(10,tty->write_q); PUTCH(13,tty->write_q); } else if (c<32) { if (L_ECHOCTL(tty)) { PUTCH('^',tty->write_q); PUTCH(c+64,tty->write_q); } } else PUTCH(c,tty->write_q); tty->write(tty); } PUTCH(c,tty->secondary); } wake_up(&tty->secondary.proc_list); } int tty_read(unsigned channel, char * buf, int nr) { struct tty_struct * tty; char c, * b=buf; int minimum,time,flag=0; long oldalarm; if (channel>2 || nr<0) return -1; tty = &tty_table[channel]; oldalarm = current->alarm; time = 10L*tty->termios.c_cc[VTIME]; minimum = tty->termios.c_cc[VMIN]; if (time && !minimum) { minimum=1; if (flag=(!oldalarm || time+jiffiesalarm = time+jiffies; } if (minimum>nr) minimum=nr; while (nr>0) { if (flag && (current->signal & ALRMMASK)) { current->signal &= ~ALRMMASK; break; } if (current->signal) break; if (EMPTY(tty->secondary) || (L_CANON(tty) && !tty->secondary.data && LEFT(tty->secondary)>20)) { sleep_if_empty(&tty->secondary); continue; } do { GETCH(tty->secondary,c); if (c==EOF_CHAR(tty) || c==10) tty->secondary.data--; if (c==EOF_CHAR(tty) && L_CANON(tty)) return (b-buf); else { put_fs_byte(c,b++); if (!--nr) break; } } while (nr>0 && !EMPTY(tty->secondary)); if (time && !L_CANON(tty)) if (flag=(!oldalarm || time+jiffiesalarm = time+jiffies; else current->alarm = oldalarm; if (L_CANON(tty)) { if (b-buf) break; } else if (b-buf >= minimum) break; } current->alarm = oldalarm; if (current->signal && !(b-buf)) return -EINTR; return (b-buf); } int tty_write(unsigned channel, char * buf, int nr) { static cr_flag=0; struct tty_struct * tty; char c, *b=buf; if (channel>2 || nr<0) return -1; tty = channel + tty_table; while (nr>0) { sleep_if_full(&tty->write_q); if (current->signal) break; while (nr>0 && !FULL(tty->write_q)) { c=get_fs_byte(b); if (O_POST(tty)) { if (c=='\r' && O_CRNL(tty)) c='\n'; else if (c=='\n' && O_NLRET(tty)) c='\r'; if (c=='\n' && !cr_flag && O_NLCR(tty)) { cr_flag = 1; PUTCH(13,tty->write_q); continue; } if (O_LCUC(tty)) c=toupper(c); } b++; nr--; cr_flag = 0; PUTCH(c,tty->write_q); } tty->write(tty); if (nr>0) schedule(); } return (b-buf); } /* * Jeh, sometimes I really like the 386. * This routine is called from an interrupt, * and there should be absolutely no problem * with sleeping even in an interrupt (I hope). * Of course, if somebody proves me wrong, I'll * hate intel for all time :-). We'll have to * be careful and see to reinstating the interrupt * chips before calling this, though. * * I don't think we sleep here under normal circumstances * anyway, which is good, as the task sleeping might be * totally innocent. */ void do_tty_interrupt(int tty) { copy_to_cooked(tty_table+tty); } void chr_dev_init(void) { } #include #define MSG_MOUSE_CLICK 1 static unsigned char mouse_input_count = 0; //第几个字节 static unsigned char mouse_left_down; //鼠标左键是否按下 static unsigned char mouse_right_down; //鼠标右键是否按下 static unsigned char mouse_left_move; //鼠标是否向左移动 static unsigned char mouse_down_move;//鼠标是否向下移动 static unsigned char mouse_x_overflow; // x溢出标志位 static unsigned char mouse_y_overflow; // y溢出标志位 static unsigned int mouse_x_position; //记录鼠标的 x 轴位置 static unsigned int mouse_y_position;//记录鼠标的 y 轴位置 void readmouse(int mousecode) { if(mousecode==0xFA || mouse_input_count>=4 ) { mouse_input_count=1; jumpp=100; jumpp++; return ; } switch(mouse_input_count) { case 1: //鼠标左右键是否按下 mouse_left_down=(mousecode &0x01) ==0x01; mouse_right_down=(mousecode &0x02)==0x02; mouse_left_move=(mousecode & 0x10)==0x10; mouse_down_move=(mousecode & 0x20)==0x20; mouse_x_overflow = (mousecode & 0x40) == 0x40; mouse_y_overflow = (mousecode & 0x80) == 0x80; mouse_input_count++; jumpp+=50; if(mouse_left_down==1 && mouse_left_move==0 && mouse_down_move==0) { post_message(MSG_MOUSE_LEFT_DOWN); } if (mouse_right_down==1&& mouse_left_move==0 && mouse_down_move==0) { post_message(MSG_MOUSE_RIGHT_DOWN); } break; case 2: //x if(mouse_left_move) mouse_x_position +=(int)(0xFFFFFF00|mousecode); if(mouse_x_position>100) mouse_x_position=100; if(mouse_x_position<0) mouse_x_position=0; mouse_input_count++; jumpp++; break; case 3: //y if(mouse_down_move) mouse_y_position +=(int)(0xFFFFFF00|mousecode); if(mouse_y_position>100) mouse_y_position=100; if(mouse_y_position<0) mouse_y_position=0; mouse_input_count++; jumpp+=50; break; case 4: //z ++mouse_input_count; jumpp+=50; break; } sys_init_graphics(); }