📄 console.c
字号:
nr=1; while (nr--) delete_line(currcons);}static void save_cur(int currcons){ saved_x=x; saved_y=y;}static void restore_cur(int currcons){ gotoxy(currcons,saved_x, saved_y);}enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey, ESsetterm, ESsetgraph, ESgraph, ESgresc, ESignore };void con_write(struct tty_struct * tty){ int nr; char c; int currcons; wake_up(&tty->write_q->proc_list); currcons = tty - tty_table; if ((currcons>=MAX_CONSOLES) || (currcons<0)) { printk("con_write: illegal tty\n\r"); return; } nr = CHARS(tty->write_q); while (nr--) { if (tty->stopped) break; GETCH(tty->write_q,c); if (c == 24 || c == 26) state = ESnormal; switch(state) { case ESnormal: if (c>31 && c<127) { if (x>=video_num_columns) { x -= video_num_columns; pos -= video_size_row; lf(currcons); } *(char *) pos = translate[c-32]; pos++; *(char *) pos = attr; pos++; x++; } else if (c==27) state = ESesc; else if (c==10 || c==11 || c==12) lf(currcons); else if (c==13) cr(currcons); else if (c==127) del(currcons); else if (c==8) { if (x) { x--; pos -= 2; } } else if (c==9) { c = 8-(x&7); x += c; pos += c<<1; if (x>video_num_columns) { x -= video_num_columns; pos -= video_size_row; lf(currcons); } c=9; } else if (c==7) sysbeep(); else if (c == 14) { checkin = 1; translate = restate; } else if (c == 15) { translate = NORM_TRANS; checkin = 0; } break; case ESesc: state = ESnormal; switch (c) { case '[': state = ESsquare; break; case 'E': gotoxy(currcons,0,y+1); break; case 'M': ri(currcons); break; case 'D': lf(currcons); break; case 'Z': respond(currcons,tty); break; case '7': save_cur(currcons); break; case '8': restore_cur(currcons); break; case '(': case ')': state = ESsetgraph; break; case 'P': state = ESsetterm; break; case '#': state = -1; break; case 'c': tty->termios = DEF_TERMIOS; state = ESnormal; restate = NORM_TRANS; checkin = 0; top = 0; bottom = video_num_lines; translate = NORM_TRANS; case '>': /* Numeric keypad */ kbdapplic = 0; if (currcons == fg_console) kapplic = 0; break; case '=': /* Appl. keypad */ kbdapplic = 1; if (currcons == fg_console) kapplic = 1; break; } break; case ESsquare: for(npar = 0 ; npar < NPAR ; npar++) par[npar]=0; npar = 0; state = ESgetpars; if (c == '[') { /* Function key */ state=ESfunckey; break; } if (ques=(c=='?')) break; case ESgetpars: if (c==';' && npar<NPAR-1) { npar++; break; } else if (c>='0' && c<='9') { par[npar]=10*par[npar]+c-'0'; break; } else state=ESgotpars; case ESgotpars: state = ESnormal; if (ques) { ques = 0; break; } switch(c) { case 'G': case '`': if (par[0]) par[0]--; gotoxy(currcons,par[0],y); break; case 'A': if (!par[0]) par[0]++; gotoxy(currcons,x,y-par[0]); break; case 'B': case 'e': if (!par[0]) par[0]++; gotoxy(currcons,x,y+par[0]); break; case 'C': case 'a': if (!par[0]) par[0]++; gotoxy(currcons,x+par[0],y); break; case 'D': if (!par[0]) par[0]++; gotoxy(currcons,x-par[0],y); break; case 'E': if (!par[0]) par[0]++; gotoxy(currcons,0,y+par[0]); break; case 'F': if (!par[0]) par[0]++; gotoxy(currcons,0,y-par[0]); break; case 'd': if (par[0]) par[0]--; gotoxy(currcons,x,par[0]); break; case 'H': case 'f': if (par[0]) par[0]--; if (par[1]) par[1]--; gotoxy(currcons,par[1],par[0]); break; case 'J': csi_J(currcons,par[0]); break; case 'K': csi_K(currcons,par[0]); break; case 'L': csi_L(currcons,par[0]); break; case 'M': csi_M(currcons,par[0]); break; case 'P': csi_P(currcons,par[0]); break; case '@': csi_at(currcons,par[0]); break; case 'm': csi_m(currcons); break; case 'r': if (par[0]) par[0]--; if (!par[1]) par[1] = video_num_lines; if (par[0] < par[1] && par[1] <= video_num_lines) { top=par[0]; bottom=par[1]; } break; case 's': save_cur(currcons); break; case 'u': restore_cur(currcons); break; case 'l': /* blank interval */ case 'b': /* bold attribute */ if (!((npar >= 2) && ((par[1]-13) == par[0]) && ((par[2]-17) == par[0]))) break; if ((c=='l') && (par[0]<=60)) { blankinterval = HZ*60*par[0]; } if (c=='b') vc_cons[currcons].vc_bold_attr = par[0]; } break; case ESfunckey: state = ESnormal; break; case ESsetterm: /* Setterm functions. */ state = ESnormal; if (c == 'S') { def_attr = attr; video_erase_char = (video_erase_char&0x0ff) | (def_attr<<8); } else if (c == 'L') /*linewrap on*/; else if (c == 'l') /*linewrap off*/; break; case ESsetgraph: if (c == '0') { if (checkin) translate = GRAF_TRANS; restate = GRAF_TRANS; } else if (c == 'B') translate = restate = NORM_TRANS; state = ESnormal; break; default: state = ESnormal; } } set_cursor(currcons); timer_active &= ~(1<<BLANK_TIMER); if (console_blanked) { timer_table[BLANK_TIMER].expires = 0; timer_active |= 1<<BLANK_TIMER; } else if (blankinterval) { timer_table[BLANK_TIMER].expires = jiffies + blankinterval; timer_active |= 1<<BLANK_TIMER; }}void do_keyboard_interrupt(void){ copy_to_cooked(TTY_TABLE(0)); timer_active &= ~(1<<BLANK_TIMER); if (console_blanked) { timer_table[BLANK_TIMER].expires = 0; timer_active |= 1<<BLANK_TIMER; } else if (blankinterval) { timer_table[BLANK_TIMER].expires = jiffies + blankinterval; timer_active |= 1<<BLANK_TIMER; }} void * memsetw(void * s,unsigned short c,int count){__asm__("cld\n\t" "rep\n\t" "stosw" ::"a" (c),"D" (s),"c" (count) :"cx","di");return s;}/* * void con_init(void); * * This routine initalizes console interrupts, and does nothing * else. If you want the screen to clear, call tty_write with * the appropriate escape-sequece. * * Reads the information preserved by setup.s to determine the current display * type and sets everything accordingly. */void con_init(void){ register unsigned char a; char *display_desc = "????"; char *display_ptr; int currcons = 0; long base, term; long video_memory; long saveterm, savebase; video_num_columns = ORIG_VIDEO_COLS; video_size_row = video_num_columns * 2; video_num_lines = ORIG_VIDEO_LINES; video_page = ORIG_VIDEO_PAGE; video_erase_char = 0x0720; timer_table[BLANK_TIMER].fn = blank_screen; timer_table[BLANK_TIMER].expires = 0; if (blankinterval) { timer_table[BLANK_TIMER].expires = jiffies+blankinterval; timer_active |= 1<<BLANK_TIMER; } if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */ { video_mem_base = 0xb0000; video_port_reg = 0x3b4; video_port_val = 0x3b5; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { video_type = VIDEO_TYPE_EGAM; video_mem_term = 0xb8000; display_desc = "EGAm"; } else { video_type = VIDEO_TYPE_MDA; video_mem_term = 0xb2000; display_desc = "*MDA"; } } else /* If not, it is color. */ { can_do_colour = 1; video_mem_base = 0xb8000; video_port_reg = 0x3d4; video_port_val = 0x3d5; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { video_type = VIDEO_TYPE_EGAC; video_mem_term = 0xc0000; display_desc = "EGAc"; } else { video_type = VIDEO_TYPE_CGA; video_mem_term = 0xba000; display_desc = "*CGA"; } } /* Let the user known what kind of display driver we are using */ display_ptr = ((char *)video_mem_base) + video_size_row - 8; while (*display_desc) { *display_ptr++ = *display_desc++; display_ptr++; } savebase = video_mem_base; saveterm = video_mem_term; memsetw(vc_scrmembuf,video_erase_char,MEM_BUFFER_SIZE/2); video_mem_base = (long)vc_scrmembuf; video_mem_term = (long)&(vc_scrmembuf[MEM_BUFFER_SIZE/2]); video_memory = video_mem_term - video_mem_base; screen_size = (video_num_lines * video_size_row); NR_CONSOLES = video_memory / screen_size; if (NR_CONSOLES > MAX_CONSOLES) NR_CONSOLES = MAX_CONSOLES; if (!NR_CONSOLES) NR_CONSOLES = 1; video_memory = screen_size; /* Initialize the variables used for scrolling (mostly EGA/VGA) */ base = origin = video_mem_start = video_mem_base; term = video_mem_end = base + video_memory; scr_end = video_mem_start + screen_size; top = 0; bottom = video_num_lines; attr = 0x07; def_attr = 0x07; restate = NORM_TRANS; state = ESnormal; checkin = 0; ques = 0; iscolor = 0; translate = NORM_TRANS; kbdleds = 2; kbdmode = 0; kbdapplic = 0; vc_cons[0].vc_bold_attr = -1; gotoxy(currcons,ORIG_X,ORIG_Y); for (currcons = 1; currcons<NR_CONSOLES; currcons++) { vc_cons[currcons] = vc_cons[0]; origin = video_mem_start = (base += video_memory); scr_end = origin + video_num_lines * video_size_row; video_mem_end = (term += video_memory); gotoxy(currcons,0,0); } for (currcons = 0; currcons<NR_CONSOLES; currcons++) vc_scrbuf[currcons] = (unsigned short *)origin; currcons = 0; video_mem_base = savebase; video_mem_term = saveterm; video_mem_start = video_mem_base; video_mem_end = video_mem_term; origin = video_mem_start; scr_end = video_mem_start + video_num_lines * video_size_row; top = 0; bottom = video_num_lines; pos=origin + y*video_size_row + (x<<1); update_screen(fg_console); set_trap_gate(0x21,&keyboard_interrupt); outb_p(inb_p(0x21)&0xfd,0x21); a=inb_p(0x61); outb_p(a|0x80,0x61); outb_p(a,0x61);}void kbdsave(int new_console){ int currcons = fg_console; kbdmode = kmode; kbdleds = kleds; kbdapplic = kapplic; currcons = new_console; kmode = (kmode & 0x3F) | (kbdmode & 0xC0); kleds = kbdleds; kapplic = kbdapplic; set_leds();}static void get_scrmem(int currcons){ memcpy((void *)vc_scrbuf[fg_console],(void *)origin, screen_size); video_mem_start = (unsigned long)vc_scrbuf[fg_console]; origin = video_mem_start; scr_end = video_mem_end = video_mem_start+screen_size; top = 0; pos = origin + y*video_size_row + (x<<1); bottom = video_num_lines;}static void set_scrmem(int currcons){ video_mem_start = video_mem_base; video_mem_end = video_mem_term; origin = video_mem_start; scr_end = video_mem_start + screen_size; top = 0; bottom = video_num_lines; pos = origin + y*video_size_row + (x<<1); memcpy((void *)video_mem_base, (void *)vc_scrbuf[fg_console], screen_size);}void blank_screen(void){ timer_table[BLANK_TIMER].fn = unblank_screen; get_scrmem(fg_console); hide_cursor(fg_console); console_blanked = 1; memsetw((void *)video_mem_base, 0x0020, video_mem_term-video_mem_base );}void unblank_screen(void){ timer_table[BLANK_TIMER].fn = blank_screen; if (blankinterval) { timer_table[BLANK_TIMER].expires = jiffies + blankinterval; timer_active |= 1<<BLANK_TIMER; } console_blanked = 0; set_scrmem(fg_console); set_origin(fg_console); set_cursor(fg_console);}void update_screen(int new_console){ static int lock = 0; if (new_console == fg_console || lock) return; lock = 1; kbdsave(new_console); get_scrmem(fg_console); fg_console = new_console; set_scrmem(fg_console); set_origin(fg_console); set_cursor(new_console); lock = 0;}/* from bsd-net-2: */static void sysbeepstop(void){ /* disable counter 2 */ outb(inb_p(0x61)&0xFC, 0x61);}static void sysbeep(void){ /* enable counter 2 */ outb_p(inb_p(0x61)|3, 0x61); /* set command for counter 2, 2 byte write */ outb_p(0xB6, 0x43); /* send 0x637 for 750 HZ */ outb_p(0x37, 0x42); outb(0x06, 0x42); /* 1/8 second */ timer_table[BEEP_TIMER].expires = jiffies + HZ/8; timer_table[BEEP_TIMER].fn = sysbeepstop; timer_active |= 1<<BEEP_TIMER;}int do_screendump(int arg){ char *sptr, *buf = (char *)arg; int currcons, l; verify_area(buf,2+video_num_columns*video_num_lines); currcons = get_fs_byte(buf+1); if ((currcons<0) || (currcons>NR_CONSOLES)) return -EIO; put_fs_byte((char)(video_num_lines),buf++); put_fs_byte((char)(video_num_columns),buf++); currcons = (currcons ? currcons-1 : fg_console); sptr = (char *) origin; for (l=video_num_lines*video_num_columns; l>0 ; l--, sptr++) put_fs_byte(*sptr++,buf++); return(0);}void console_print(const char * b){ int currcons = fg_console; char c; if (currcons<0 || currcons>=NR_CONSOLES) currcons = 0; while (c = *(b++)) { if (c == 10) { cr(currcons); lf(currcons); continue; } if (c == 13) { cr(currcons); continue; } if (x>=video_num_columns) { x -= video_num_columns; pos -= video_size_row; lf(currcons); } *(char *) pos = c; pos++; *(char *) pos = attr; pos++; x++; } set_cursor(currcons);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -