From c8a4887d3ccd366dc84bfcb31ffff843e4b2c59f Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sun, 20 Nov 2011 21:10:32 +0800 Subject: [PATCH] Kernel/Keyboard - Changed keyboard API to facilitate the GUI better - Cleaned shift out into the keymap (finally) - Cleaned up the keyboard driver - Added a way for the keyboard to send raw scancodes along with the translated key. --- Kernel/drv/vterm.c | 66 ++++++++++++++----------- Kernel/include/api_drv_keyboard.h | 26 ++++++++-- Modules/Input/PS2KbMouse/kb.c | 74 +++++++++++------------------ Modules/Input/PS2KbMouse/kb_kbdus.h | 60 ++++++++++------------- 4 files changed, 113 insertions(+), 113 deletions(-) diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index 05d8090a..82eac3e1 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -889,35 +889,32 @@ void VT_SetTerminal(int ID) void VT_KBCallBack(Uint32 Codepoint) { tVTerm *term = gpVT_CurTerm; - - // How the hell did we get a codepoint of zero? - if(Codepoint == 0) return; - + // Key Up - if( Codepoint & 0x80000000 ) + switch( Codepoint & KEY_ACTION_MASK ) { - Codepoint &= 0x7FFFFFFF; - switch(Codepoint) + case KEY_ACTION_RELEASE: + switch(Codepoint & KEY_CODEPOINT_MASK) { case KEY_LALT: gbVT_AltDown &= ~1; break; case KEY_RALT: gbVT_AltDown &= ~2; break; case KEY_LCTRL: gbVT_CtrlDown &= ~1; break; case KEY_RCTRL: gbVT_CtrlDown &= ~2; break; } - return; - } - - switch(Codepoint) - { - case KEY_LALT: gbVT_AltDown |= 1; break; - case KEY_RALT: gbVT_AltDown |= 2; break; - case KEY_LCTRL: gbVT_CtrlDown |= 1; break; - case KEY_RCTRL: gbVT_CtrlDown |= 2; break; + break; - default: + case KEY_ACTION_PRESS: + switch(Codepoint & KEY_CODEPOINT_MASK) + { + case KEY_LALT: gbVT_AltDown |= 1; break; + case KEY_RALT: gbVT_AltDown |= 2; break; + case KEY_LCTRL: gbVT_CtrlDown |= 1; break; + case KEY_RCTRL: gbVT_CtrlDown |= 2; break; + } + if(!gbVT_AltDown || !gbVT_CtrlDown) break; - switch(Codepoint) + switch(Codepoint & KEY_CODEPOINT_MASK) { case KEY_F1: VT_SetTerminal(0); return; case KEY_F2: VT_SetTerminal(1); return; @@ -949,6 +946,7 @@ void VT_KBCallBack(Uint32 Codepoint) gpVT_CurTerm->ViewPos = gpVT_CurTerm->Width*gpVT_CurTerm->Height*(giVT_Scrollback); return; } + break; } // Encode key @@ -956,37 +954,49 @@ void VT_KBCallBack(Uint32 Codepoint) { Uint8 buf[6] = {0}; int len = 0; - + + // Ignore anything that isn't a press or refire + if( (Codepoint & KEY_ACTION_MASK) != KEY_ACTION_PRESS + && (Codepoint & KEY_ACTION_MASK) != KEY_ACTION_REFIRE + ) + { + return ; + } + + Codepoint &= KEY_CODEPOINT_MASK; + // Ignore Modifer Keys if(Codepoint > KEY_MODIFIERS) return; // Get UTF-8/ANSI Encoding switch(Codepoint) { + // 0: No translation, don't send to user + case 0: break; case KEY_LEFT: - buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'D'; + buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'D'; len = 3; break; case KEY_RIGHT: - buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'C'; + buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'C'; len = 3; break; case KEY_UP: - buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'A'; + buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'A'; len = 3; break; case KEY_DOWN: - buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'B'; + buf[0] = '\x1B'; buf[1] = '['; buf[2] = 'B'; len = 3; break; case KEY_PGUP: - //buf[0] = '\x1B'; buf[1] = '['; buf[2] = '5'; // Some overline also - //len = 4; // Commented out until I'm sure - len = 0; + buf[0] = '\x1B'; buf[1] = '['; buf[2] = '5'; buf[3] = '~'; + len = 4; break; case KEY_PGDOWN: - len = 0; + buf[0] = '\x1B'; buf[1] = '['; buf[2] = '6'; buf[3] = '~'; + len = 4; break; // Attempt to encode in UTF-8 @@ -1033,7 +1043,7 @@ void VT_KBCallBack(Uint32 Codepoint) } else { - // Encode the raw UTF-32 Key + // Encode the raw key event Uint32 *raw_in = (void*)term->InputBuffer; raw_in[ term->InputWrite ] = Codepoint; term->InputWrite ++; diff --git a/Kernel/include/api_drv_keyboard.h b/Kernel/include/api_drv_keyboard.h index 58eafb9e..2085df66 100644 --- a/Kernel/include/api_drv_keyboard.h +++ b/Kernel/include/api_drv_keyboard.h @@ -53,6 +53,10 @@ enum eTplKeyboard_IOCtl { * Sets the function to be called when a key event occurs (press, release * or repeat). This function pointer must be in kernel mode (although, * kernel->user or kernel->ring3driver abstraction functions can be used) + * + * This function is called when a key is pressed, repeated or released. + * If the raw scancode is to be included with the key event, it should precede + * the event. */ KB_IOCTL_SETCALLBACK }; @@ -64,11 +68,25 @@ enum eTplKeyboard_IOCtl { /** * \brief Callback type for KB_IOCTL_SETCALLBACK - * \param Key Unicode character code for the pressed key (with bit 31 - * set if the key is released) + * \param Key Key symbol (Unicode or eTplKeyboard_KeyCodes) */ typedef void (*tKeybardCallback)(Uint32 Key); +/** + * \name Callback key flags + * \brief Flags for values passed to the callback + * \{ + */ +#define KEY_CODEPOINT_MASK 0x3FFFFFFF +#define KEY_ACTION_MASK 0xC0000000 +#define KEY_ACTION_PRESS 0x00000000 //!< Key pressed +#define KEY_ACTION_RELEASE 0x40000000 //!< Key released +#define KEY_ACTION_REFIRE 0x80000000 //!< Repeated key +#define KEY_ACTION_RAWSYM 0xC0000000 //!< Raw key symbol (comes before a press/repeat/release) +/** + * \} + */ + /** * \brief Symbolic key codes * @@ -80,7 +98,7 @@ typedef void (*tKeybardCallback)(Uint32 Key); enum eTplKeyboard_KeyCodes { KEY_ESC = 0x1B, //!< Escape Character - KEY_NP_MASK = 0x40000000, //! Mask for non-printable characters + KEY_NP_MASK = 0x20000000, //! Mask for non-printable characters /** * \name Special Keys @@ -109,7 +127,7 @@ enum eTplKeyboard_KeyCodes { * \brief These keye usually alter the character stream sent to the user * \{ */ - KEY_MODIFIERS = 0x60000000, + KEY_MODIFIERS = 0x30000000, KEY_LCTRL, KEY_RCTRL, KEY_LALT, KEY_RALT, KEY_LSHIFT, KEY_RSHIFT, diff --git a/Modules/Input/PS2KbMouse/kb.c b/Modules/Input/PS2KbMouse/kb.c index e53f0930..56c98c27 100644 --- a/Modules/Input/PS2KbMouse/kb.c +++ b/Modules/Input/PS2KbMouse/kb.c @@ -64,6 +64,7 @@ int KB_Install(char **Arguments) void KB_HandleScancode(Uint8 scancode) { Uint32 ch; + int bCaseSwitch = (gbKB_ShiftState != 0) != (gbKB_CapsState != 0); //Log_Debug("Keyboard", "scancode = %02x", scancode); @@ -99,12 +100,23 @@ void KB_HandleScancode(Uint8 scancode) gbKB_KeyUp = 1; } #endif + + if( gKB_Callback ) + gKB_Callback( (giKB_KeyLayer << 8) | scancode | KEY_ACTION_RAWSYM ); // Translate - ch = gpKB_Map[giKB_KeyLayer][scancode]; + ch = gpKB_Map[giKB_KeyLayer*2+bCaseSwitch][scancode]; + // - Unknown characters in the shift layer fall through to lower + if(bCaseSwitch && ch == 0) + ch = gpKB_Map[giKB_KeyLayer*2][scancode]; // Check for unknown key - if(!ch && !gbKB_KeyUp) - Log_Warning("Keyboard", "UNK %i %x", giKB_KeyLayer, scancode); + if(!ch) + { + if(!gbKB_KeyUp) + Log_Warning("Keyboard", "UNK %i %x", giKB_KeyLayer, scancode); +// return ; + // Can pass through to ensure each raw message has a up/down with it + } // Key Up? if (gbKB_KeyUp) @@ -121,14 +133,21 @@ void KB_HandleScancode(Uint8 scancode) if(ch == KEY_RSHIFT) gbKB_ShiftState &= ~2; // Call callback - if(ch != 0 && gKB_Callback) - gKB_Callback( ch & 0x80000000 ); + if(gKB_Callback) gKB_Callback( ch | KEY_ACTION_RELEASE ); // Reset Layer giKB_KeyLayer = 0; return; } + // Refire? + if( gbaKB_States[giKB_KeyLayer][scancode] == 1 ) + { + if(gKB_Callback) gKB_Callback(ch | KEY_ACTION_REFIRE); + giKB_KeyLayer = 0; + return ; + } + // Set the bit relating to the key gbaKB_States[giKB_KeyLayer][scancode] = 1; // Set shift key bits @@ -141,12 +160,6 @@ void KB_HandleScancode(Uint8 scancode) KB_UpdateLEDs(); } - // Reset Layer - giKB_KeyLayer = 0; - - // Ignore Non-Printable Characters - if(ch == 0) return; - // --- Check for Kernel Magic Combos #if USE_KERNEL_MAGIC if(ch == KEY_LCTRL) { @@ -190,42 +203,11 @@ void KB_HandleScancode(Uint8 scancode) } #endif - // Capitals required? - if( (gbKB_ShiftState != 0) != (gbKB_CapsState != 0)) - { - // TODO: Move this to the keyboard map header - switch(ch) - { - case 0: break; - case '`': ch = '~'; break; - case '1': ch = '!'; break; - case '2': ch = '@'; break; - case '3': ch = '#'; break; - case '4': ch = '$'; break; - case '5': ch = '%'; break; - case '6': ch = '^'; break; - case '7': ch = '&'; break; - case '8': ch = '*'; break; - case '9': ch = '('; break; - case '0': ch = ')'; break; - case '-': ch = '_'; break; - case '=': ch = '+'; break; - case '[': ch = '{'; break; - case ']': ch = '}'; break; - case '\\': ch = '|'; break; - case ';': ch = ':'; break; - case '\'': ch = '"'; break; - case ',': ch = '<'; break; - case '.': ch = '>'; break; - case '/': ch = '?'; break; - default: - if('a' <= ch && ch <= 'z') - ch -= 0x20; - break; - } - } + if(gKB_Callback) + gKB_Callback(ch | KEY_ACTION_PRESS); - if(gKB_Callback && ch != 0) gKB_Callback(ch); + // Reset Layer + giKB_KeyLayer = 0; } /** diff --git a/Modules/Input/PS2KbMouse/kb_kbdus.h b/Modules/Input/PS2KbMouse/kb_kbdus.h index 441b19a5..523935f4 100644 --- a/Modules/Input/PS2KbMouse/kb_kbdus.h +++ b/Modules/Input/PS2KbMouse/kb_kbdus.h @@ -2,28 +2,34 @@ #ifndef _KBDUS_H #define _KBDUS_H -// - BASE (NO PREFIX) +// - Base (NO PREFIX) Uint32 gpKBDUS1[256] = { -/*00*/ 0, KEY_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t', -/*10*/ 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', KEY_LCTRL, 'a', 's', -/*20*/ 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', '`', KEY_LSHIFT,'\\', 'z', 'x', 'c', 'v', -/*30*/ 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT, KEY_KPSTAR, - KEY_LALT, ' ', KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, -/*40*/ KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_KPHOME, - KEY_KPUP, KEY_KPPGUP, KEY_KPMINUS, KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT, KEY_KPPLUS, KEY_KPEND, -/*50*/ KEY_KPDOWN, KEY_KPPGDN, KEY_KPINS, KEY_KPDEL, 0, 0, 0, KEY_F11, - KEY_F12, 0, 0, 0, 0, 0, 0, 0, + 0, + KEY_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', // 0x01 - 0x0e + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', // 0x0f - 0x1c + KEY_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';','\'', // 0x1d - 0x28 + '`', KEY_LSHIFT,'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT, // 0x29 - 0x3e + KEY_KPSTAR, + KEY_LALT, ' ', KEY_CAPSLOCK, + KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, + KEY_NUMLOCK, KEY_SCROLLLOCK, + KEY_KPHOME, KEY_KPUP, KEY_KPPGUP, KEY_KPMINUS, + KEY_KPLEFT, KEY_KP5, KEY_KPRIGHT, KEY_KPPLUS, + KEY_KPEND, KEY_KPDOWN, KEY_KPPGDN, + KEY_KPINS, KEY_KPDEL, + 0, 0, 0, KEY_F11, KEY_F12, 0, 0, 0, 0, 0, 0, 0, /*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +// Shift Key pressed +Uint32 gpKBDUS1s[256] = { + 0, + KEY_ESC, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', // 0x01 - 0x0e + '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', // 0x0f - 0x1c + KEY_LCTRL, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':','"', // 0x1d - 0x28 + '~', KEY_LSHIFT,'|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', KEY_RSHIFT, // 0x29 - 0x3e + 0 + }; // - 0xE0 Prefixed Uint32 gpKBDUS2[256] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F @@ -37,14 +43,6 @@ Uint32 gpKBDUS2[256] = { 0, 0, KEY_WIN, 0, 0, KEY_MENU, 0, 0, /*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // - 0xE1 Prefixed Uint32 gpKBDUS3[256] = { @@ -57,17 +55,9 @@ Uint32 gpKBDUS3[256] = { /*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*60*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*A0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*B0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*C0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*D0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*E0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -/*F0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -Uint32 *gpKBDUS[3] = { gpKBDUS1, gpKBDUS2, gpKBDUS3 }; +Uint32 *gpKBDUS[6] = { gpKBDUS1, gpKBDUS1s, gpKBDUS2, gpKBDUS2, gpKBDUS3, gpKBDUS3 }; #endif -- 2.20.1