/*======================================================================* flush *======================================================================*/ PRIVATE void flush(CONSOLE* p_con) { if (is_current_console(p_con)) { set_cursor(p_con->cursor); set_video_start_addr(p_con->current_start_addr); } }
static void tty_do_read(TTY* p_tty) { if (is_current_console(p_tty->p_console)) { keyboard_read(p_tty); } }
/* fresh tty buf to screen */ static void keyboard_write(TTY * tty_p) { int i = 0; u16 print; u32 key = 0; while (!is_tty_buf_empty(tty_p)) { key = keymap[(*(tty_p->tail_p)&0xff)*3]; if (*(tty_p->tail_p) & FLAG_CTRL_L) { if (key == 'p') { scroll(tty_p->console_p, SCROLL_UP, 1); } if (key == 'n') { scroll(tty_p->console_p, SCROLL_DOWN, 1); } if (key == F1) { switch_console(0); current_console_p = &console_table[0]; } if (key == F2) { switch_console(1); current_console_p = &console_table[1]; } if (key == F3) { switch_console(2); current_console_p = &console_table[2]; } goto CLEAR; } int line; if (key & FLAG_EXT) { if (key == ENTER) { line = tty_p->console_p->cursor / (80 * 2); tty_p->console_p->cursor = (line + 1) * (80 * 2); goto ADD_KEY_TO_LINE_CACHE; } if (key == BACKSPACE) { tty_p->console_p->cursor -= 2; xdisp_word_at(0|0x0F00, tty_p->console_p->cursor); del_key_from_line_in_cache(tty_p); goto CLEAR; } } assert(tty_p != NULL); xdisp_word_at(key|0x0f00, tty_p->console_p->cursor); tty_p->console_p->cursor += 2; //write do it ADD_KEY_TO_LINE_CACHE: add_key_to_line_in_cache(*(tty_p->tail_p), tty_p); CLEAR: if (is_current_console(tty_p->console_p)) set_cursor(tty_p->console_p->cursor); tty_p->buf_count--; tty_p->tail_p++; if (tty_p->tail_p == tty_p->read_buf + TTY_BUF_SIZE) tty_p->tail_p = tty_p->read_buf; } }
/* @return 0->read something -1->not */ static int keyboard_read(TTY * tty_p) { u32 key; int has_read_something = -1; /* 对应 当前console 而且 键盘的buf里不是空 */ while (is_current_console(tty_p->console_p) && !is_keyboard_buf_empty()) { key = keyboard_get_key(); if (tty_p->buf_count < TTY_BUF_SIZE) { *(tty_p->head_p) = key; tty_p->head_p ++ ; if (tty_p->head_p == tty_p->read_buf + TTY_BUF_SIZE) tty_p->head_p = tty_p->read_buf; tty_p->buf_count ++ ; } has_read_something = 0; } return has_read_something; }
/** * Set the cursor and starting address of a console by writing the * CRT Controller Registers. * * @param con The console to be set. *****************************************************************************/ PUBLIC void flush(CONSOLE* con) { if (is_current_console(con)) { set_cursor(con->cursor); set_video_start_addr(con->crtc_start); } #ifdef __TTY_DEBUG__ int lineno = 0; for (lineno = 0; lineno < con->con_size / SCR_WIDTH; lineno++) { u8 * pch = (u8*)(V_MEM_BASE + (con->orig + (lineno + 1) * SCR_WIDTH) * 2 - 4); *pch++ = lineno / 10 + '0'; *pch++ = RED_CHAR; *pch++ = lineno % 10 + '0'; *pch++ = RED_CHAR; } #endif }
static void flush_tty_out_cache(TTY * tty_p) { char c; int line; while (tty_p->out_count > 0) { c = *(tty_p->out_tail_p); if (c == '\n') { line = tty_p->console_p->cursor / (80 * 2); tty_p->console_p->cursor = (line + 1) * (80 * 2); } else { xdisp_word_at(c|0x0F00, tty_p->console_p->cursor); tty_p->console_p->cursor += 2; } tty_p->out_tail_p ++ ; tty_p->out_count -- ; if (tty_p->out_tail_p == tty_p->tty_out_cache + TTY_CHAR_CACHE_SIZE) tty_p->out_tail_p = tty_p->tty_out_cache; if (is_current_console(tty_p->console_p)) set_cursor(tty_p->console_p->cursor); } }
/** * Get chars from the keyboard buffer if the TTY::console is the `current' * console. * * @see keyboard_read() * * @param tty Ptr to TTY. *****************************************************************************/ PRIVATE void tty_dev_read(TTY* tty) { if (is_current_console(tty->console)) keyboard_read(tty); }
/** * Yes, it is an ugly function. * * @param tty Which TTY is reading the keyboard input. *****************************************************************************/ PUBLIC void keyboard_read(TTY* tty) { if (!is_current_console((CONSOLE *)tty->tty_dev)) return; u8 scan_code; /** * 1 : make * 0 : break */ int make; /** * We use a integer to record a key press. * For instance, if the key HOME is pressed, key will be evaluated to * `HOME' defined in keyboard.h. */ u32 key = 0; /** * This var points to a row in keymap[]. I don't use two-dimension * array because I don't like it. */ u32* keyrow; while (kb_in.count > 0) { code_with_E0 = 0; scan_code = get_byte_from_kb_buf(); /* parse the scan code below */ if (scan_code == 0xE1) { int i; u8 pausebreak_scan_code[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5}; int is_pausebreak = 1; for (i = 1; i < 6; i++) { if (get_byte_from_kb_buf() != pausebreak_scan_code[i]) { is_pausebreak = 0; break; } } if (is_pausebreak) { key = PAUSEBREAK; } } else if (scan_code == 0xE0) { code_with_E0 = 1; scan_code = get_byte_from_kb_buf(); /* PrintScreen is pressed */ if (scan_code == 0x2A) { code_with_E0 = 0; if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { code_with_E0 = 1; if ((scan_code = get_byte_from_kb_buf()) == 0x37) { key = PRINTSCREEN; make = 1; } } } /* PrintScreen is released */ else if (scan_code == 0xB7) { code_with_E0 = 0; if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { code_with_E0 = 1; if ((scan_code = get_byte_from_kb_buf()) == 0xAA) { key = PRINTSCREEN; make = 0; } } } } if ((key != PAUSEBREAK) && (key != PRINTSCREEN)) { int caps; /* make or break */ make = (scan_code & FLAG_BREAK ? 0 : 1); keyrow = &keymap[(scan_code & 0177) * MAP_COLS]; column = 0; caps = shift_l || shift_r; if (caps_lock && keyrow[0] >= 'a' && keyrow[0] <= 'z') caps = !caps; if (caps) column = 1; if (code_with_E0) column = 2; if (ctrl_l || ctrl_r) column = 3; key = keyrow[column]; switch(key) { case SHIFT_L: shift_l = make; break; case SHIFT_R: shift_r = make; break; case CTRL_L: ctrl_l = make; break; case CTRL_R: ctrl_r = make; break; case ALT_L: alt_l = make; break; case ALT_R: alt_l = make; break; case CAPS_LOCK: if (make) { caps_lock = !caps_lock; set_leds(); } break; case NUM_LOCK: if (make) { num_lock = !num_lock; set_leds(); } break; case SCROLL_LOCK: if (make) { scroll_lock = !scroll_lock; set_leds(); } break; default: break; } } if(make){ /* Break Code is ignored */ int pad = 0; /* deal with the numpad first */ if ((key >= PAD_SLASH) && (key <= PAD_9)) { pad = 1; switch(key) { /* '/', '*', '-', '+', * and 'Enter' in num pad */ case PAD_SLASH: key = '/'; break; case PAD_STAR: key = '*'; break; case PAD_MINUS: key = '-'; break; case PAD_PLUS: key = '+'; break; case PAD_ENTER: key = ENTER; break; default: /* the value of these keys * depends on the Numlock */ if (num_lock) { /* '0' ~ '9' and '.' in num pad */ if (key >= PAD_0 && key <= PAD_9) key = key - PAD_0 + '0'; else if (key == PAD_DOT) key = '.'; } else{ switch(key) { case PAD_HOME: key = HOME; break; case PAD_END: key = END; break; case PAD_PAGEUP: key = PAGEUP; break; case PAD_PAGEDOWN: key = PAGEDOWN; break; case PAD_INS: key = INSERT; break; case PAD_UP: key = UP; break; case PAD_DOWN: key = DOWN; break; case PAD_LEFT: key = LEFT; break; case PAD_RIGHT: key = RIGHT; break; case PAD_DOT: key = DELETE; break; default: break; } } break; } } key |= shift_l ? FLAG_SHIFT_L : 0; key |= shift_r ? FLAG_SHIFT_R : 0; key |= ctrl_l ? FLAG_CTRL_L : 0; key |= ctrl_r ? FLAG_CTRL_R : 0; key |= alt_l ? FLAG_ALT_L : 0; key |= alt_r ? FLAG_ALT_R : 0; key |= pad ? FLAG_PAD : 0; int raw_code = key & MASK_RAW; switch(raw_code) { case UP: if ((key & FLAG_SHIFT_L) || (key & FLAG_SHIFT_R)) { /* Shift + Up */ scroll_screen((CONSOLE *)tty->tty_dev, SCR_DN); } break; case DOWN: if ((key & FLAG_SHIFT_L) || (key & FLAG_SHIFT_R)) { /* Shift + Down */ scroll_screen((CONSOLE *)tty->tty_dev, SCR_UP); } break; case F1: case F2: case F3: case F4: case F5: case F6: case F7: case F8: case F9: case F10: case F11: case F12: if ((key & FLAG_ALT_L) || (key & FLAG_ALT_R)) { /* Alt + F1~F12 */ select_console(raw_code - F1); } break; default: break; } in_process(tty, key); } } }
/*-----tty_do_read-----*/ static void tty_do_read(struct ttybuf *pTty) { if(is_current_console(pTty - ttyTab) == 0) keyboard_read_keybuf(pTty); }