📄 console.c
字号:
if (cons->c_column > scr_width) cons->c_column = scr_width; if (cons->c_row < 0) cons->c_row = 0; if (cons->c_row >= scr_lines) cons->c_row = scr_lines - 1; cur = cons->c_org + cons->c_row * scr_width + cons->c_column; if (cur != cons->c_cur) { if (cons == curcons) set_6845(CURSOR, cur); cons->c_cur = cur; }}/*===========================================================================* * parse_escape * *===========================================================================*/PRIVATE void parse_escape(cons, c)register console_t *cons; /* pointer to console struct */char c; /* next character in escape sequence */{/* The following ANSI escape sequences are currently supported. * If n and/or m are omitted, they default to 1. * ESC [nA moves up n lines * ESC [nB moves down n lines * ESC [nC moves right n spaces * ESC [nD moves left n spaces * ESC [m;nH" moves cursor to (m,n) * ESC [J clears screen from cursor * ESC [K clears line from cursor * ESC [nL inserts n lines ar cursor * ESC [nM deletes n lines at cursor * ESC [nP deletes n chars at cursor * ESC [n@ inserts n chars at cursor * ESC [nm enables rendition n (0=normal, 4=bold, 5=blinking, 7=reverse) * ESC M scrolls the screen backwards if the cursor is on the top line */ switch (cons->c_esc_state) { case 1: /* ESC seen */ cons->c_esc_intro = '\0'; cons->c_esc_parmp = bufend(cons->c_esc_parmv); do { *--cons->c_esc_parmp = 0; } while (cons->c_esc_parmp > cons->c_esc_parmv); switch (c) { case '[': /* Control Sequence Introducer */ cons->c_esc_intro = c; cons->c_esc_state = 2; break; case 'M': /* Reverse Index */ do_escape(cons, c); break; default: cons->c_esc_state = 0; } break; case 2: /* ESC [ seen */ if (c >= '0' && c <= '9') { if (cons->c_esc_parmp < bufend(cons->c_esc_parmv)) *cons->c_esc_parmp = *cons->c_esc_parmp * 10 + (c-'0'); } else if (c == ';') { if (cons->c_esc_parmp < bufend(cons->c_esc_parmv)) cons->c_esc_parmp++; } else { do_escape(cons, c); } break; }}/*===========================================================================* * do_escape * *===========================================================================*/PRIVATE void do_escape(cons, c)register console_t *cons; /* pointer to console struct */char c; /* next character in escape sequence */{ int value, n; unsigned src, dst, count; int *parmp; /* Some of these things hack on screen RAM, so it had better be up to date */ flush(cons); if (cons->c_esc_intro == '\0') { /* Handle a sequence beginning with just ESC */ switch (c) { case 'M': /* Reverse Index */ if (cons->c_row == 0) { scroll_screen(cons, SCROLL_DOWN); } else { cons->c_row--; } flush(cons); break; default: break; } } else if (cons->c_esc_intro == '[') { /* Handle a sequence beginning with ESC [ and parameters */ value = cons->c_esc_parmv[0]; switch (c) { case 'A': /* ESC [nA moves up n lines */ n = (value == 0 ? 1 : value); cons->c_row -= n; flush(cons); break; case 'B': /* ESC [nB moves down n lines */ n = (value == 0 ? 1 : value); cons->c_row += n; flush(cons); break; case 'C': /* ESC [nC moves right n spaces */ n = (value == 0 ? 1 : value); cons->c_column += n; flush(cons); break; case 'D': /* ESC [nD moves left n spaces */ n = (value == 0 ? 1 : value); cons->c_column -= n; flush(cons); break; case 'H': /* ESC [m;nH" moves cursor to (m,n) */ cons->c_row = cons->c_esc_parmv[0] - 1; cons->c_column = cons->c_esc_parmv[1] - 1; flush(cons); break; case 'J': /* ESC [sJ clears in display */ switch (value) { case 0: /* Clear from cursor to end of screen */ count = scr_size - (cons->c_cur - cons->c_org); dst = cons->c_cur; break; case 1: /* Clear from start of screen to cursor */ count = cons->c_cur - cons->c_org; dst = cons->c_org; break; case 2: /* Clear entire screen */ count = scr_size; dst = cons->c_org; break; default: /* Do nothing */ count = 0; dst = cons->c_org; } blank_color = cons->c_blank; mem_vid_copy(BLANK_MEM, dst, count); break; case 'K': /* ESC [sK clears line from cursor */ switch (value) { case 0: /* Clear from cursor to end of line */ count = scr_width - cons->c_column; dst = cons->c_cur; break; case 1: /* Clear from beginning of line to cursor */ count = cons->c_column; dst = cons->c_cur - cons->c_column; break; case 2: /* Clear entire line */ count = scr_width; dst = cons->c_cur - cons->c_column; break; default: /* Do nothing */ count = 0; dst = cons->c_cur; } blank_color = cons->c_blank; mem_vid_copy(BLANK_MEM, dst, count); break; case 'L': /* ESC [nL inserts n lines at cursor */ n = value; if (n < 1) n = 1; if (n > (scr_lines - cons->c_row)) n = scr_lines - cons->c_row; src = cons->c_org + cons->c_row * scr_width; dst = src + n * scr_width; count = (scr_lines - cons->c_row - n) * scr_width; vid_vid_copy(src, dst, count); blank_color = cons->c_blank; mem_vid_copy(BLANK_MEM, src, n * scr_width); break; case 'M': /* ESC [nM deletes n lines at cursor */ n = value; if (n < 1) n = 1; if (n > (scr_lines - cons->c_row)) n = scr_lines - cons->c_row; dst = cons->c_org + cons->c_row * scr_width; src = dst + n * scr_width; count = (scr_lines - cons->c_row - n) * scr_width; vid_vid_copy(src, dst, count); blank_color = cons->c_blank; mem_vid_copy(BLANK_MEM, dst + count, n * scr_width); break; case '@': /* ESC [n@ inserts n chars at cursor */ n = value; if (n < 1) n = 1; if (n > (scr_width - cons->c_column)) n = scr_width - cons->c_column; src = cons->c_cur; dst = src + n; count = scr_width - cons->c_column - n; vid_vid_copy(src, dst, count); blank_color = cons->c_blank; mem_vid_copy(BLANK_MEM, src, n); break; case 'P': /* ESC [nP deletes n chars at cursor */ n = value; if (n < 1) n = 1; if (n > (scr_width - cons->c_column)) n = scr_width - cons->c_column; dst = cons->c_cur; src = dst + n; count = scr_width - cons->c_column - n; vid_vid_copy(src, dst, count); blank_color = cons->c_blank; mem_vid_copy(BLANK_MEM, dst + count, n); break; case 'm': /* ESC [nm enables rendition n */ for (parmp = cons->c_esc_parmv; parmp <= cons->c_esc_parmp && parmp < bufend(cons->c_esc_parmv); parmp++) { if (cons->c_reverse) { /* Unswap fg and bg colors */ cons->c_attr = ((cons->c_attr & 0x7000) >> 4) | ((cons->c_attr & 0x0700) << 4) | ((cons->c_attr & 0x8800)); } switch (n = *parmp) { case 0: /* NORMAL */ cons->c_attr = cons->c_blank = BLANK_COLOR; cons->c_reverse = FALSE; break; case 1: /* BOLD */ /* Set intensity bit */ cons->c_attr |= 0x0800; break; case 4: /* UNDERLINE */ if (color) { /* Change white to cyan, i.e. lose red */ cons->c_attr = (cons->c_attr & 0xBBFF); } else { /* Set underline attribute */ cons->c_attr = (cons->c_attr & 0x99FF); } break; case 5: /* BLINKING */ /* Set the blink bit */ cons->c_attr |= 0x8000; break; case 7: /* REVERSE */ cons->c_reverse = TRUE; break; default: /* COLOR */ if (n == 39) n = 37; /* set default color */ if (n == 49) n = 40; if (!color) { /* Don't mess up a monochrome screen */ } else if (30 <= n && n <= 37) { /* Foreground color */ cons->c_attr = (cons->c_attr & 0xF8FF) | (ansi_colors[(n - 30)] << 8); cons->c_blank = (cons->c_blank & 0xF8FF) | (ansi_colors[(n - 30)] << 8); } else if (40 <= n && n <= 47) { /* Background color */ cons->c_attr = (cons->c_attr & 0x8FFF) | (ansi_colors[(n - 40)] << 12); cons->c_blank = (cons->c_blank & 0x8FFF) | (ansi_colors[(n - 40)] << 12); } } if (cons->c_reverse) { /* Swap fg and bg colors */ cons->c_attr = ((cons->c_attr & 0x7000) >> 4) | ((cons->c_attr & 0x0700) << 4) | ((cons->c_attr & 0x8800)); } } break; } } cons->c_esc_state = 0;}/*===========================================================================* * set_6845 * *===========================================================================*/PRIVATE void set_6845(reg, val)int reg; /* which register pair to set */unsigned val; /* 16-bit value to set it to */{/* Set a register pair inside the 6845. * Registers 12-13 tell the 6845 where in video ram to start * Registers 14-15 tell the 6845 where to put the cursor */ pvb_pair_t char_out[4]; pv_set(char_out[0], vid_port + INDEX, reg); /* set index register */ pv_set(char_out[1], vid_port + DATA, (val>>8) & BYTE); /* high byte */ pv_set(char_out[2], vid_port + INDEX, reg + 1); /* again */ pv_set(char_out[3], vid_port + DATA, val&BYTE); /* low byte */ sys_voutb(char_out, 4); /* do actual output */}/*===========================================================================* * get_6845 * *===========================================================================*/PRIVATE void get_6845(reg, val)int reg; /* which register pair to set */unsigned *val; /* 16-bit value to set it to */{ char v1, v2;/* Get a register pair inside the 6845. */ sys_outb(vid_port + INDEX, reg); sys_inb(vid_port + DATA, &v1); sys_outb(vid_port + INDEX, reg+1); sys_inb(vid_port + DATA, &v2); *val = (v1 << 8) | v2;}/*===========================================================================* * beep * *===========================================================================*/PRIVATE void beep(){/* Making a beeping sound on the speaker (output for CRTL-G). * This routine works by turning on the bits 0 and 1 in port B of the 8255 * chip that drive the speaker. */ static timer_t tmr_stop_beep; pvb_pair_t char_out[3]; clock_t now; int port_b_val, s; /* Fetch current time in advance to prevent beeping delay. */ if ((s=getuptime(&now)) != OK) panic("TTY","Console couldn't get clock's uptime.", s); if (!beeping) { /* Set timer channel 2, square wave, with given frequency. */ pv_set(char_out[0], TIMER_MODE, 0xB6); pv_set(char_out[1], TIMER2, (BEEP_FREQ >> 0) & BYTE); pv_set(char_out[2], TIMER2, (BEEP_FREQ >> 8) & BYTE); if (sys_voutb(char_out, 3)==OK) { if (sys_inb(PORT_B, &port_b_val)==OK && sys_outb(PORT_B, (port_b_val|3))==OK) beeping = TRUE; } } /* Add a timer to the timers list. Possibly reschedule the alarm. */ tmrs_settimer(&tty_timers, &tmr_stop_beep, now+B_TIME, stop_beep, NULL); if (tty_timers->tmr_exp_time != tty_next_timeout) { tty_next_timeout = tty_timers->tmr_exp_time; if ((s=sys_setalarm(tty_next_timeout, 1)) != OK) panic("TTY","Console couldn't set alarm.", s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -