/*======================================================================* keyboard_read *======================================================================*/ PUBLIC void keyboard_read(TTY* p_tty) { t_8 scan_code; t_bool make; /* TRUE : make */ /* FALSE: break */ t_32 key = 0;/* 用一个整型来表示一个键。 */ /* 比如,如果 Home 被按下,则 key 值将为定义在 keyboard.h 中的 'HOME'。*/ t_32* keyrow; /* 指向 keymap[] 的某一行 */ if(kb_in.count > 0){ code_with_E0 = FALSE; scan_code = get_byte_from_kb_buf(); /* 下面开始解析扫描码 */ if (scan_code == 0xE1) { int i; t_8 pausebreak_scan_code[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5}; t_bool is_pausebreak = TRUE; for(i=1;i<6;i++){ if (get_byte_from_kb_buf() != pausebreak_scan_code[i]) { is_pausebreak = FALSE; break; } } if (is_pausebreak) { key = PAUSEBREAK; } } else if (scan_code == 0xE0) { scan_code = get_byte_from_kb_buf(); /* PrintScreen 被按下 */ if (scan_code == 0x2A) { if (get_byte_from_kb_buf() == 0xE0) { if (get_byte_from_kb_buf() == 0x37) { key = PRINTSCREEN; make = TRUE; } } } /* PrintScreen 被释放 */ if (scan_code == 0xB7) { if (get_byte_from_kb_buf() == 0xE0) { if (get_byte_from_kb_buf() == 0xAA) { key = PRINTSCREEN; make = FALSE; } } } /* 不是 PrintScreen。此时 scan_code 为 0xE0 紧跟的那个值。 */ if (key == 0) { code_with_E0 = TRUE; } } if ((key != PAUSEBREAK) && (key != PRINTSCREEN)) { /* 首先判断Make Code 还是 Break Code */ make = (scan_code & FLAG_BREAK ? FALSE : TRUE); /* 先定位到 keymap 中的行 */ keyrow = &keymap[(scan_code & 0x7F) * MAP_COLS]; column = 0; if (shift_l || shift_r) { column = 1; } if (code_with_E0) { column = 2; } 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; default: break; } } if(make){ /* 忽略 Break Code */ 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; in_process(p_tty, key); } } }
/*======================================================================* keyboard_read *======================================================================*/ PUBLIC void keyboard_read(TTY* p_tty) { t_8 scan_code; t_bool make; /* TRUE : make */ /* FALSE: break */ t_32 key = 0;/* 用一个整型来表示一个键。 */ /* 比如,如果 Home 被按下,则 key 值将为定义在 keyboard.h 中的 'HOME'。*/ t_32* keyrow; /* 指向 keymap[] 的某一行 */ if(kb_in.count > 0){ code_with_E0 = FALSE; scan_code = get_byte_from_kb_buf(); /* 下面开始解析扫描码 */ if (scan_code == 0xE1) { int i; t_8 pausebreak_scan_code[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5}; t_bool is_pausebreak = TRUE; for(i=1;i<6;i++){ if (get_byte_from_kb_buf() != pausebreak_scan_code[i]) { is_pausebreak = FALSE; break; } } if (is_pausebreak) { key = PAUSEBREAK; } } else if (scan_code == 0xE0) { code_with_E0 = TRUE; scan_code = get_byte_from_kb_buf(); /* PrintScreen 被按下 */ if (scan_code == 0x2A) { code_with_E0 = FALSE; if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { code_with_E0 = TRUE; if ((scan_code = get_byte_from_kb_buf()) == 0x37) { key = PRINTSCREEN; make = TRUE; } } } /* PrintScreen 被释放 */ else if (scan_code == 0xB7) { code_with_E0 = FALSE; if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { code_with_E0 = TRUE; if ((scan_code = get_byte_from_kb_buf()) == 0xAA) { key = PRINTSCREEN; make = FALSE; } } } } /* 如果不是 PrintScreen。则此时 scan_code 为 0xE0 紧跟的那个值。 */ if ((key != PAUSEBREAK) && (key != PRINTSCREEN)) { /* 首先判断Make Code 还是 Break Code */ make = (scan_code & FLAG_BREAK ? FALSE : TRUE); /* 先定位到 keymap 中的行 */ keyrow = &keymap[(scan_code & 0x7F) * MAP_COLS]; column = 0; t_bool caps = shift_l || shift_r; if (caps_lock) { if ((keyrow[0] >= 'a') && (keyrow[0] <= 'z')){ caps = !caps; } } if (caps) { column = 1; } if (code_with_E0) { column = 2; } 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 */ t_bool pad = FALSE; /* 首先处理小键盘 */ if ((key >= PAD_SLASH) && (key <= PAD_9)) { pad = TRUE; 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: /* keys whose value 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; in_process(p_tty, key); } } }
/** * Yes, it is an ugly function. * * @param tty Which TTY is reading the keyboard input. *****************************************************************************/ PUBLIC void keyboard_read(TTY* tty) { 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 & 0x7F) * 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; 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; in_process(tty, key); } } }
void keyboard_read() { uint8_t scan_code; int make = 0; uint32_t key = 0; uint32_t* keyrow; while (kbdbuf.count > 0) { code_with_E0 = 0; scan_code = get_byte_from_kb_buf(); /* parse the scan code below */ if (scan_code == 0xE1) { int i; uint8_t 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 & 0x7F) * 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; 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; handle_key(key); } } }