From d3025668a43cc3d370e621527466ff94af38243d Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Fri, 29 Dec 2023 21:47:00 +0100 Subject: [PATCH] Revert "Kernel+Userland: Implement support for PS2 scan code set 2" This reverts commit 61a385fc019ed873a554d605a6561c30d8fe3903. The commit broke the shift and caps lock key from working. --- Kernel/API/KeyCode.h | 244 +++---- Kernel/Arch/x86_64/ISABus/I8042Controller.cpp | 14 +- Kernel/Arch/x86_64/ISABus/I8042Controller.h | 7 +- Kernel/Devices/HID/Definitions.h | 32 - Kernel/Devices/HID/KeyboardDevice.cpp | 301 +++++++- Kernel/Devices/HID/KeyboardDevice.h | 11 +- Kernel/Devices/HID/Management.cpp | 19 +- Kernel/Devices/HID/Management.h | 2 +- Kernel/Devices/HID/PS2/KeyboardDevice.cpp | 686 +----------------- Kernel/Devices/HID/PS2/KeyboardDevice.h | 31 +- Kernel/Devices/HID/ScanCodeEvent.h | 7 +- .../LibWeb/UIEvents/KeyboardEvent.cpp | 68 +- 12 files changed, 440 insertions(+), 982 deletions(-) delete mode 100644 Kernel/Devices/HID/Definitions.h diff --git a/Kernel/API/KeyCode.h b/Kernel/API/KeyCode.h index c7f191f515..eab009d07d 100644 --- a/Kernel/API/KeyCode.h +++ b/Kernel/API/KeyCode.h @@ -8,140 +8,113 @@ #include -#define ENUMERATE_KEY_CODES \ - __ENUMERATE_KEY_CODE(Invalid, "Invalid") \ - __ENUMERATE_KEY_CODE(Escape, "Escape") \ - __ENUMERATE_KEY_CODE(Tab, "Tab") \ - __ENUMERATE_KEY_CODE(Backspace, "Backspace") \ - __ENUMERATE_KEY_CODE(Return, "Return") \ - __ENUMERATE_KEY_CODE(Insert, "Insert") \ - __ENUMERATE_KEY_CODE(Delete, "Delete") \ - __ENUMERATE_KEY_CODE(PrintScreen, "PrintScreen") \ - __ENUMERATE_KEY_CODE(PauseBreak, "PauseBreak") \ - __ENUMERATE_KEY_CODE(SysRq, "SysRq") \ - __ENUMERATE_KEY_CODE(Home, "Home") \ - __ENUMERATE_KEY_CODE(End, "End") \ - __ENUMERATE_KEY_CODE(Left, "Left") \ - __ENUMERATE_KEY_CODE(Up, "Up") \ - __ENUMERATE_KEY_CODE(Right, "Right") \ - __ENUMERATE_KEY_CODE(Down, "Down") \ - __ENUMERATE_KEY_CODE(PageUp, "PageUp") \ - __ENUMERATE_KEY_CODE(PageDown, "PageDown") \ - __ENUMERATE_KEY_CODE(LeftShift, "LeftShift") \ - __ENUMERATE_KEY_CODE(RightShift, "RightShift") \ - __ENUMERATE_KEY_CODE(Control, "Ctrl") \ - __ENUMERATE_KEY_CODE(RightControl, "RightCtrl") \ - __ENUMERATE_KEY_CODE(Alt, "Alt") \ - __ENUMERATE_KEY_CODE(RightAlt, "Alt") \ - __ENUMERATE_KEY_CODE(CapsLock, "CapsLock") \ - __ENUMERATE_KEY_CODE(NumLock, "NumLock") \ - __ENUMERATE_KEY_CODE(ScrollLock, "ScrollLock") \ - __ENUMERATE_KEY_CODE(F1, "F1") \ - __ENUMERATE_KEY_CODE(F2, "F2") \ - __ENUMERATE_KEY_CODE(F3, "F3") \ - __ENUMERATE_KEY_CODE(F4, "F4") \ - __ENUMERATE_KEY_CODE(F5, "F5") \ - __ENUMERATE_KEY_CODE(F6, "F6") \ - __ENUMERATE_KEY_CODE(F7, "F7") \ - __ENUMERATE_KEY_CODE(F8, "F8") \ - __ENUMERATE_KEY_CODE(F9, "F9") \ - __ENUMERATE_KEY_CODE(F10, "F10") \ - __ENUMERATE_KEY_CODE(F11, "F11") \ - __ENUMERATE_KEY_CODE(F12, "F12") \ - __ENUMERATE_KEY_CODE(Space, "Space") \ - __ENUMERATE_KEY_CODE(ExclamationPoint, "!") \ - __ENUMERATE_KEY_CODE(DoubleQuote, "\"") \ - __ENUMERATE_KEY_CODE(Hashtag, "#") \ - __ENUMERATE_KEY_CODE(Dollar, "$") \ - __ENUMERATE_KEY_CODE(Percent, "%") \ - __ENUMERATE_KEY_CODE(Ampersand, "&") \ - __ENUMERATE_KEY_CODE(Apostrophe, "'") \ - __ENUMERATE_KEY_CODE(LeftParen, "(") \ - __ENUMERATE_KEY_CODE(RightParen, ")") \ - __ENUMERATE_KEY_CODE(Asterisk, "*") \ - __ENUMERATE_KEY_CODE(Plus, "+") \ - __ENUMERATE_KEY_CODE(Comma, ",") \ - __ENUMERATE_KEY_CODE(Minus, "-") \ - __ENUMERATE_KEY_CODE(Period, ".") \ - __ENUMERATE_KEY_CODE(Slash, "/") \ - __ENUMERATE_KEY_CODE(0, "0") \ - __ENUMERATE_KEY_CODE(1, "1") \ - __ENUMERATE_KEY_CODE(2, "2") \ - __ENUMERATE_KEY_CODE(3, "3") \ - __ENUMERATE_KEY_CODE(4, "4") \ - __ENUMERATE_KEY_CODE(5, "5") \ - __ENUMERATE_KEY_CODE(6, "6") \ - __ENUMERATE_KEY_CODE(7, "7") \ - __ENUMERATE_KEY_CODE(8, "8") \ - __ENUMERATE_KEY_CODE(9, "9") \ - __ENUMERATE_KEY_CODE(Colon, ":") \ - __ENUMERATE_KEY_CODE(Semicolon, ";") \ - __ENUMERATE_KEY_CODE(LessThan, "<") \ - __ENUMERATE_KEY_CODE(Equal, "=") \ - __ENUMERATE_KEY_CODE(GreaterThan, ">") \ - __ENUMERATE_KEY_CODE(QuestionMark, "?") \ - __ENUMERATE_KEY_CODE(AtSign, "@") \ - __ENUMERATE_KEY_CODE(A, "A") \ - __ENUMERATE_KEY_CODE(B, "B") \ - __ENUMERATE_KEY_CODE(C, "C") \ - __ENUMERATE_KEY_CODE(D, "D") \ - __ENUMERATE_KEY_CODE(E, "E") \ - __ENUMERATE_KEY_CODE(F, "F") \ - __ENUMERATE_KEY_CODE(G, "G") \ - __ENUMERATE_KEY_CODE(H, "H") \ - __ENUMERATE_KEY_CODE(I, "I") \ - __ENUMERATE_KEY_CODE(J, "J") \ - __ENUMERATE_KEY_CODE(K, "K") \ - __ENUMERATE_KEY_CODE(L, "L") \ - __ENUMERATE_KEY_CODE(M, "M") \ - __ENUMERATE_KEY_CODE(N, "N") \ - __ENUMERATE_KEY_CODE(O, "O") \ - __ENUMERATE_KEY_CODE(P, "P") \ - __ENUMERATE_KEY_CODE(Q, "Q") \ - __ENUMERATE_KEY_CODE(R, "R") \ - __ENUMERATE_KEY_CODE(S, "S") \ - __ENUMERATE_KEY_CODE(T, "T") \ - __ENUMERATE_KEY_CODE(U, "U") \ - __ENUMERATE_KEY_CODE(V, "V") \ - __ENUMERATE_KEY_CODE(W, "W") \ - __ENUMERATE_KEY_CODE(X, "X") \ - __ENUMERATE_KEY_CODE(Y, "Y") \ - __ENUMERATE_KEY_CODE(Z, "Z") \ - __ENUMERATE_KEY_CODE(LeftBracket, "[") \ - __ENUMERATE_KEY_CODE(RightBracket, "]") \ - __ENUMERATE_KEY_CODE(Backslash, "\\") \ - __ENUMERATE_KEY_CODE(Circumflex, "^") \ - __ENUMERATE_KEY_CODE(Underscore, "_") \ - __ENUMERATE_KEY_CODE(LeftBrace, "{") \ - __ENUMERATE_KEY_CODE(RightBrace, "}") \ - __ENUMERATE_KEY_CODE(Pipe, "|") \ - __ENUMERATE_KEY_CODE(Tilde, "~") \ - __ENUMERATE_KEY_CODE(Backtick, "`") \ - __ENUMERATE_KEY_CODE(Super, "Super") \ - __ENUMERATE_KEY_CODE(BrowserSearch, "BrowserSearch") \ - __ENUMERATE_KEY_CODE(BrowserFavorites, "BrowserFavorites") \ - __ENUMERATE_KEY_CODE(BrowserHome, "BrowserHome") \ - __ENUMERATE_KEY_CODE(PreviousTrack, "PreviousTrack") \ - __ENUMERATE_KEY_CODE(BrowserBack, "BrowserBack") \ - __ENUMERATE_KEY_CODE(BrowserForward, "BrowserForward") \ - __ENUMERATE_KEY_CODE(BrowserRefresh, "BrowserRefresh") \ - __ENUMERATE_KEY_CODE(BrowserStop, "BrowserStop") \ - __ENUMERATE_KEY_CODE(VolumeDown, "VolumeDown") \ - __ENUMERATE_KEY_CODE(VolumeUp, "VolumeUp") \ - __ENUMERATE_KEY_CODE(Wake, "Wake") \ - __ENUMERATE_KEY_CODE(Sleep, "Sleep") \ - __ENUMERATE_KEY_CODE(NextTrack, "NextTrack") \ - __ENUMERATE_KEY_CODE(MediaSelect, "MediaSelect") \ - __ENUMERATE_KEY_CODE(Email, "Email") \ - __ENUMERATE_KEY_CODE(MyComputer, "MyComputer") \ - __ENUMERATE_KEY_CODE(Power, "Power") \ - __ENUMERATE_KEY_CODE(Stop, "Stop") \ - __ENUMERATE_KEY_CODE(LeftGUI, "LeftGUI") \ - __ENUMERATE_KEY_CODE(Mute, "Mute") \ - __ENUMERATE_KEY_CODE(RightGUI, "RightGUI") \ - __ENUMERATE_KEY_CODE(Calculator, "Calculator") \ - __ENUMERATE_KEY_CODE(Apps, "Apps") \ - __ENUMERATE_KEY_CODE(PlayPause, "PlayPause") \ +#define ENUMERATE_KEY_CODES \ + __ENUMERATE_KEY_CODE(Invalid, "Invalid") \ + __ENUMERATE_KEY_CODE(Escape, "Escape") \ + __ENUMERATE_KEY_CODE(Tab, "Tab") \ + __ENUMERATE_KEY_CODE(Backspace, "Backspace") \ + __ENUMERATE_KEY_CODE(Return, "Return") \ + __ENUMERATE_KEY_CODE(Insert, "Insert") \ + __ENUMERATE_KEY_CODE(Delete, "Delete") \ + __ENUMERATE_KEY_CODE(PrintScreen, "PrintScreen") \ + __ENUMERATE_KEY_CODE(SysRq, "SysRq") \ + __ENUMERATE_KEY_CODE(Home, "Home") \ + __ENUMERATE_KEY_CODE(End, "End") \ + __ENUMERATE_KEY_CODE(Left, "Left") \ + __ENUMERATE_KEY_CODE(Up, "Up") \ + __ENUMERATE_KEY_CODE(Right, "Right") \ + __ENUMERATE_KEY_CODE(Down, "Down") \ + __ENUMERATE_KEY_CODE(PageUp, "PageUp") \ + __ENUMERATE_KEY_CODE(PageDown, "PageDown") \ + __ENUMERATE_KEY_CODE(LeftShift, "LeftShift") \ + __ENUMERATE_KEY_CODE(RightShift, "RightShift") \ + __ENUMERATE_KEY_CODE(Control, "Ctrl") \ + __ENUMERATE_KEY_CODE(Alt, "Alt") \ + __ENUMERATE_KEY_CODE(CapsLock, "CapsLock") \ + __ENUMERATE_KEY_CODE(NumLock, "NumLock") \ + __ENUMERATE_KEY_CODE(ScrollLock, "ScrollLock") \ + __ENUMERATE_KEY_CODE(F1, "F1") \ + __ENUMERATE_KEY_CODE(F2, "F2") \ + __ENUMERATE_KEY_CODE(F3, "F3") \ + __ENUMERATE_KEY_CODE(F4, "F4") \ + __ENUMERATE_KEY_CODE(F5, "F5") \ + __ENUMERATE_KEY_CODE(F6, "F6") \ + __ENUMERATE_KEY_CODE(F7, "F7") \ + __ENUMERATE_KEY_CODE(F8, "F8") \ + __ENUMERATE_KEY_CODE(F9, "F9") \ + __ENUMERATE_KEY_CODE(F10, "F10") \ + __ENUMERATE_KEY_CODE(F11, "F11") \ + __ENUMERATE_KEY_CODE(F12, "F12") \ + __ENUMERATE_KEY_CODE(Space, "Space") \ + __ENUMERATE_KEY_CODE(ExclamationPoint, "!") \ + __ENUMERATE_KEY_CODE(DoubleQuote, "\"") \ + __ENUMERATE_KEY_CODE(Hashtag, "#") \ + __ENUMERATE_KEY_CODE(Dollar, "$") \ + __ENUMERATE_KEY_CODE(Percent, "%") \ + __ENUMERATE_KEY_CODE(Ampersand, "&") \ + __ENUMERATE_KEY_CODE(Apostrophe, "'") \ + __ENUMERATE_KEY_CODE(LeftParen, "(") \ + __ENUMERATE_KEY_CODE(RightParen, ")") \ + __ENUMERATE_KEY_CODE(Asterisk, "*") \ + __ENUMERATE_KEY_CODE(Plus, "+") \ + __ENUMERATE_KEY_CODE(Comma, ",") \ + __ENUMERATE_KEY_CODE(Minus, "-") \ + __ENUMERATE_KEY_CODE(Period, ".") \ + __ENUMERATE_KEY_CODE(Slash, "/") \ + __ENUMERATE_KEY_CODE(0, "0") \ + __ENUMERATE_KEY_CODE(1, "1") \ + __ENUMERATE_KEY_CODE(2, "2") \ + __ENUMERATE_KEY_CODE(3, "3") \ + __ENUMERATE_KEY_CODE(4, "4") \ + __ENUMERATE_KEY_CODE(5, "5") \ + __ENUMERATE_KEY_CODE(6, "6") \ + __ENUMERATE_KEY_CODE(7, "7") \ + __ENUMERATE_KEY_CODE(8, "8") \ + __ENUMERATE_KEY_CODE(9, "9") \ + __ENUMERATE_KEY_CODE(Colon, ":") \ + __ENUMERATE_KEY_CODE(Semicolon, ";") \ + __ENUMERATE_KEY_CODE(LessThan, "<") \ + __ENUMERATE_KEY_CODE(Equal, "=") \ + __ENUMERATE_KEY_CODE(GreaterThan, ">") \ + __ENUMERATE_KEY_CODE(QuestionMark, "?") \ + __ENUMERATE_KEY_CODE(AtSign, "@") \ + __ENUMERATE_KEY_CODE(A, "A") \ + __ENUMERATE_KEY_CODE(B, "B") \ + __ENUMERATE_KEY_CODE(C, "C") \ + __ENUMERATE_KEY_CODE(D, "D") \ + __ENUMERATE_KEY_CODE(E, "E") \ + __ENUMERATE_KEY_CODE(F, "F") \ + __ENUMERATE_KEY_CODE(G, "G") \ + __ENUMERATE_KEY_CODE(H, "H") \ + __ENUMERATE_KEY_CODE(I, "I") \ + __ENUMERATE_KEY_CODE(J, "J") \ + __ENUMERATE_KEY_CODE(K, "K") \ + __ENUMERATE_KEY_CODE(L, "L") \ + __ENUMERATE_KEY_CODE(M, "M") \ + __ENUMERATE_KEY_CODE(N, "N") \ + __ENUMERATE_KEY_CODE(O, "O") \ + __ENUMERATE_KEY_CODE(P, "P") \ + __ENUMERATE_KEY_CODE(Q, "Q") \ + __ENUMERATE_KEY_CODE(R, "R") \ + __ENUMERATE_KEY_CODE(S, "S") \ + __ENUMERATE_KEY_CODE(T, "T") \ + __ENUMERATE_KEY_CODE(U, "U") \ + __ENUMERATE_KEY_CODE(V, "V") \ + __ENUMERATE_KEY_CODE(W, "W") \ + __ENUMERATE_KEY_CODE(X, "X") \ + __ENUMERATE_KEY_CODE(Y, "Y") \ + __ENUMERATE_KEY_CODE(Z, "Z") \ + __ENUMERATE_KEY_CODE(LeftBracket, "[") \ + __ENUMERATE_KEY_CODE(RightBracket, "]") \ + __ENUMERATE_KEY_CODE(Backslash, "\\") \ + __ENUMERATE_KEY_CODE(Circumflex, "^") \ + __ENUMERATE_KEY_CODE(Underscore, "_") \ + __ENUMERATE_KEY_CODE(LeftBrace, "{") \ + __ENUMERATE_KEY_CODE(RightBrace, "}") \ + __ENUMERATE_KEY_CODE(Pipe, "|") \ + __ENUMERATE_KEY_CODE(Tilde, "~") \ + __ENUMERATE_KEY_CODE(Backtick, "`") \ + __ENUMERATE_KEY_CODE(Super, "Super") \ __ENUMERATE_KEY_CODE(Menu, "Menu") enum KeyCode : u8 { @@ -170,10 +143,11 @@ enum KeyModifier { struct KeyEvent { KeyCode key { Key_Invalid }; u8 map_entry_index { 0 }; - u64 scancode { 0 }; + u32 scancode { 0 }; u32 code_point { 0 }; u8 flags { 0 }; bool caps_lock_on { false }; + bool e0_prefix { false }; bool alt() const { return flags & Mod_Alt; } bool ctrl() const { return flags & Mod_Ctrl; } bool shift() const { return flags & Mod_Shift; } diff --git a/Kernel/Arch/x86_64/ISABus/I8042Controller.cpp b/Kernel/Arch/x86_64/ISABus/I8042Controller.cpp index 1155d783ac..0fd6cce927 100644 --- a/Kernel/Arch/x86_64/ISABus/I8042Controller.cpp +++ b/Kernel/Arch/x86_64/ISABus/I8042Controller.cpp @@ -120,7 +120,7 @@ UNMAP_AFTER_INIT bool I8042Controller::check_existence_via_probing(Badge I8042Controller::detect_devices(EnableKeyboardFirstPortTranslation enable_first_port_translation) +UNMAP_AFTER_INIT ErrorOr I8042Controller::detect_devices() { u8 configuration; { @@ -135,13 +135,7 @@ UNMAP_AFTER_INIT ErrorOr I8042Controller::detect_devices(EnableKeyboardFir configuration = TRY(do_wait_then_read_any_input(I8042Port::Buffer)); configuration &= ~I8042ConfigurationFlag::FirstPS2PortInterrupt; configuration &= ~I8042ConfigurationFlag::SecondPS2PortInterrupt; - - // FIXME: Don't enable translation for the first i8042 port if nothing is connected - // or even worse - a mouse device, because we will get garbage data. - if (enable_first_port_translation == EnableKeyboardFirstPortTranslation::Yes) - configuration |= I8042ConfigurationFlag::FirstPS2PortTranslation; - else - configuration &= ~I8042ConfigurationFlag::FirstPS2PortTranslation; + configuration |= I8042ConfigurationFlag::FirstPS2PortTranslation; TRY(do_wait_then_write(I8042Port::Command, I8042Command::WriteConfiguration)); TRY(do_wait_then_write(I8042Port::Buffer, configuration)); @@ -203,9 +197,7 @@ UNMAP_AFTER_INIT ErrorOr I8042Controller::detect_devices(EnableKeyboardFir // FIXME: Actually figure out the connected PS2 device type m_first_ps2_port.device_type = PS2DeviceType::StandardKeyboard; auto keyboard_device = TRY(KeyboardDevice::try_to_initialize()); - // FIXME: Determine if the user wants to operate in scan code set 3. - auto keyboard_device_scan_code_set = enable_first_port_translation == EnableKeyboardFirstPortTranslation::Yes ? ScanCodeSet::Set1 : ScanCodeSet::Set2; - auto error_or_device = PS2KeyboardDevice::try_to_initialize(*this, I8042PortIndex::FirstPort, keyboard_device_scan_code_set, *keyboard_device); + auto error_or_device = PS2KeyboardDevice::try_to_initialize(*this, I8042PortIndex::FirstPort, *keyboard_device); if (error_or_device.is_error()) { dbgln("I8042: Keyboard device failed to initialize, disable"); m_first_port_available = false; diff --git a/Kernel/Arch/x86_64/ISABus/I8042Controller.h b/Kernel/Arch/x86_64/ISABus/I8042Controller.h index 69be77416b..833c6e978f 100644 --- a/Kernel/Arch/x86_64/ISABus/I8042Controller.h +++ b/Kernel/Arch/x86_64/ISABus/I8042Controller.h @@ -94,12 +94,7 @@ class I8042Controller final : public SerialIOController { public: static ErrorOr> create(); - enum class EnableKeyboardFirstPortTranslation { - Yes, - No - }; - ErrorOr detect_devices(EnableKeyboardFirstPortTranslation); - + ErrorOr detect_devices(); virtual ErrorOr send_command(PortIndex, DeviceCommand command) override; virtual ErrorOr send_command(PortIndex, DeviceCommand command, u8 data) override; diff --git a/Kernel/Devices/HID/Definitions.h b/Kernel/Devices/HID/Definitions.h deleted file mode 100644 index cc00914d6a..0000000000 --- a/Kernel/Devices/HID/Definitions.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2023, Liav A. - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace Kernel { - -enum class ScanCodeSet { - Set1 = 1, - Set2 = 2, - Set3 = 3, -}; - -struct KeyCodeEntry { - KeyCode key_code; - u8 map_entry_index; -}; - -struct RawKeyEvent { - KeyCodeEntry code_entry; - u64 scancode { 0 }; - bool is_press_down { false }; - bool is_press() const { return is_press_down; } -}; - -} diff --git a/Kernel/Devices/HID/KeyboardDevice.cpp b/Kernel/Devices/HID/KeyboardDevice.cpp index 8e571d59c7..8fb25f0a40 100644 --- a/Kernel/Devices/HID/KeyboardDevice.cpp +++ b/Kernel/Devices/HID/KeyboardDevice.cpp @@ -20,43 +20,310 @@ namespace Kernel { -void KeyboardDevice::handle_input_event(KeyEvent queued_event) +static constexpr KeyCode unshifted_key_map[0x80] = { + Key_Invalid, + Key_Escape, + Key_1, + Key_2, + Key_3, + Key_4, + Key_5, + Key_6, + Key_7, + Key_8, + Key_9, + Key_0, + Key_Minus, + Key_Equal, + Key_Backspace, + Key_Tab, // 15 + Key_Q, + Key_W, + Key_E, + Key_R, + Key_T, + Key_Y, + Key_U, + Key_I, + Key_O, + Key_P, + Key_LeftBracket, + Key_RightBracket, + Key_Return, // 28 + Key_Control, // 29 + Key_A, + Key_S, + Key_D, + Key_F, + Key_G, + Key_H, + Key_J, + Key_K, + Key_L, + Key_Semicolon, + Key_Apostrophe, + Key_Backtick, + Key_LeftShift, // 42 + Key_Backslash, + Key_Z, + Key_X, + Key_C, + Key_V, + Key_B, + Key_N, + Key_M, + Key_Comma, + Key_Period, + Key_Slash, + Key_RightShift, // 54 + Key_Asterisk, + Key_Alt, // 56 + Key_Space, // 57 + Key_CapsLock, // 58 + Key_F1, + Key_F2, + Key_F3, + Key_F4, + Key_F5, + Key_F6, + Key_F7, + Key_F8, + Key_F9, + Key_F10, + Key_NumLock, + Key_Invalid, // 70 + Key_Home, + Key_Up, + Key_PageUp, + Key_Minus, + Key_Left, + Key_Invalid, + Key_Right, // 77 + Key_Plus, + Key_End, + Key_Down, // 80 + Key_PageDown, + Key_Insert, + Key_Delete, // 83 + Key_Invalid, + Key_Invalid, + Key_Backslash, + Key_F11, + Key_F12, + Key_Invalid, + Key_Invalid, + Key_Super, + Key_Invalid, + Key_Menu, +}; + +static constexpr KeyCode shifted_key_map[0x100] = { + Key_Invalid, + Key_Escape, + Key_ExclamationPoint, + Key_AtSign, + Key_Hashtag, + Key_Dollar, + Key_Percent, + Key_Circumflex, + Key_Ampersand, + Key_Asterisk, + Key_LeftParen, + Key_RightParen, + Key_Underscore, + Key_Plus, + Key_Backspace, + Key_Tab, + Key_Q, + Key_W, + Key_E, + Key_R, + Key_T, + Key_Y, + Key_U, + Key_I, + Key_O, + Key_P, + Key_LeftBrace, + Key_RightBrace, + Key_Return, + Key_Control, + Key_A, + Key_S, + Key_D, + Key_F, + Key_G, + Key_H, + Key_J, + Key_K, + Key_L, + Key_Colon, + Key_DoubleQuote, + Key_Tilde, + Key_LeftShift, // 42 + Key_Pipe, + Key_Z, + Key_X, + Key_C, + Key_V, + Key_B, + Key_N, + Key_M, + Key_LessThan, + Key_GreaterThan, + Key_QuestionMark, + Key_RightShift, // 54 + Key_Asterisk, + Key_Alt, + Key_Space, // 57 + Key_CapsLock, // 58 + Key_F1, + Key_F2, + Key_F3, + Key_F4, + Key_F5, + Key_F6, + Key_F7, + Key_F8, + Key_F9, + Key_F10, + Key_NumLock, + Key_Invalid, // 70 + Key_Home, + Key_Up, + Key_PageUp, + Key_Minus, + Key_Left, + Key_Invalid, + Key_Right, // 77 + Key_Plus, + Key_End, + Key_Down, // 80 + Key_PageDown, + Key_Insert, + Key_Delete, // 83 + Key_Invalid, + Key_Invalid, + Key_Pipe, + Key_F11, + Key_F12, + Key_Invalid, + Key_Invalid, + Key_Super, + Key_Invalid, + Key_Menu, +}; + +void KeyboardDevice::handle_scan_code_input_event(ScanCodeEvent event) { - if (queued_event.key == Key_NumLock && queued_event.is_press()) - m_num_lock_on = !m_num_lock_on; + m_entropy_source.add_random_event(event.scan_code_value); + switch (event.scan_code_value) { + case 0x38: + if (event.e0_prefix) + update_modifier(Mod_AltGr, event.pressed); + else + update_modifier(Mod_Alt, event.pressed); + break; + case 0x1d: + update_modifier(Mod_Ctrl, event.pressed); + break; + case 0x5b: + m_left_super_pressed = event.pressed; + update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed); + break; + case 0x5c: + m_right_super_pressed = event.pressed; + update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed); + break; + case 0x2a: + m_left_shift_pressed = event.pressed; + update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); + break; + case 0x36: + m_right_shift_pressed = event.pressed; + update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); + break; + case 0x1c: + case 0x35: + if (event.e0_prefix) + update_modifier(Mod_Keypad, event.pressed); + break; + case 0x37: + case 0x47: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + case 0x50: + case 0x51: + case 0x52: + case 0x53: + if (!event.e0_prefix) + update_modifier(Mod_Keypad, event.pressed); + break; + } - queued_event.flags |= m_modifiers; - queued_event.caps_lock_on = m_caps_lock_on; + KeyCode key = (m_modifiers & Mod_Shift) ? shifted_key_map[event.scan_code_value] : unshifted_key_map[event.scan_code_value]; - if (queued_event.is_press() && (m_modifiers == (Mod_Alt | Mod_Shift) || m_modifiers == (Mod_Ctrl | Mod_Alt | Mod_Shift)) && queued_event.key == Key_F12) { + if ((m_modifiers == (Mod_Alt | Mod_Shift) || m_modifiers == (Mod_Ctrl | Mod_Alt | Mod_Shift)) && key == Key_F12) { // Alt+Shift+F12 pressed, dump some kernel state to the debug console. ConsoleManagement::the().switch_to_debug(); Scheduler::dump_scheduler_state(m_modifiers == (Mod_Ctrl | Mod_Alt | Mod_Shift)); } - { - auto key = queued_event.key; - if (queued_event.is_press() && (m_modifiers & Mod_Alt) != 0 && key >= Key_1 && key < Key_1 + ConsoleManagement::s_max_virtual_consoles) { - // FIXME: Do something sanely here if we can't allocate a work queue? - MUST(g_io_work->try_queue([key]() { - ConsoleManagement::the().switch_to(key - Key_1); - })); + if ((m_modifiers & Mod_Alt) != 0 && key >= Key_1 && key < Key_1 + ConsoleManagement::s_max_virtual_consoles) { + // FIXME: Do something sanely here if we can't allocate a work queue? + MUST(g_io_work->try_queue([key]() { + ConsoleManagement::the().switch_to(key - Key_1); + })); + } + + if (key == Key_NumLock && event.pressed) + m_num_lock_on = !m_num_lock_on; + + if (m_num_lock_on && !event.e0_prefix) { + if (event.scan_code_value >= 0x47 && event.scan_code_value <= 0x53) { + u8 index = event.scan_code_value - 0x47; + constexpr KeyCode numpad_key_map[13] = { Key_7, Key_8, Key_9, Key_Invalid, Key_4, Key_5, Key_6, Key_Invalid, Key_1, Key_2, Key_3, Key_0, Key_Comma }; + KeyCode newKey = numpad_key_map[index]; + + if (newKey != Key_Invalid) { + key = newKey; + } } } + Event queued_event; + queued_event.key = key; + queued_event.map_entry_index = event.scan_code_value & 0xFF; + queued_event.scancode = event.e0_prefix ? 0xe000 + event.scan_code_value : event.scan_code_value; + queued_event.flags = m_modifiers; + queued_event.e0_prefix = event.e0_prefix; + queued_event.caps_lock_on = m_caps_lock_on; + queued_event.code_point = HIDManagement::the().get_char_from_character_map(queued_event, m_num_lock_on); + // If using a non-QWERTY layout, queued_event.key needs to be updated to be the same as event.code_point KeyCode mapped_key = code_point_to_key_code(queued_event.code_point); - if (mapped_key != KeyCode::Key_Invalid) + if (mapped_key != KeyCode::Key_Invalid) { queued_event.key = mapped_key; + key = mapped_key; + } - if (!g_caps_lock_remapped_to_ctrl && queued_event.key == Key_CapsLock && queued_event.is_press()) + if (!g_caps_lock_remapped_to_ctrl && key == Key_CapsLock && event.pressed) m_caps_lock_on = !m_caps_lock_on; - if (g_caps_lock_remapped_to_ctrl && queued_event.key == Key_CapsLock) { - m_caps_lock_to_ctrl_pressed = queued_event.is_press(); + if (g_caps_lock_remapped_to_ctrl && key == Key_CapsLock) { + m_caps_lock_to_ctrl_pressed = event.pressed; update_modifier(Mod_Ctrl, m_caps_lock_to_ctrl_pressed); } + if (event.pressed) + queued_event.flags |= Is_Press; + { SpinlockLocker locker(HIDManagement::the().m_client_lock); if (HIDManagement::the().m_client) diff --git a/Kernel/Devices/HID/KeyboardDevice.h b/Kernel/Devices/HID/KeyboardDevice.h index 10b70de12a..9c7d7042c3 100644 --- a/Kernel/Devices/HID/KeyboardDevice.h +++ b/Kernel/Devices/HID/KeyboardDevice.h @@ -34,6 +34,8 @@ public: virtual ErrorOr write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override { return EINVAL; } virtual bool can_write(OpenFileDescription const&, u64) const override { return true; } + void handle_scan_code_input_event(ScanCodeEvent); + // ^File virtual ErrorOr ioctl(OpenFileDescription&, unsigned request, Userspace arg) override; @@ -45,11 +47,6 @@ public: m_modifiers &= ~modifier; } - u8 modifiers() const { return m_modifiers; } - - void handle_input_event(KeyEvent); - bool num_lock_on() const { return m_num_lock_on; } - protected: KeyboardDevice(); mutable Spinlock m_queue_lock {}; @@ -61,6 +58,10 @@ protected: bool m_caps_lock_to_ctrl_pressed { false }; bool m_caps_lock_on { false }; bool m_num_lock_on { false }; + bool m_left_shift_pressed { false }; + bool m_right_shift_pressed { false }; + bool m_left_super_pressed { false }; + bool m_right_super_pressed { false }; void key_state_changed(u8 raw, bool pressed); }; diff --git a/Kernel/Devices/HID/Management.cpp b/Kernel/Devices/HID/Management.cpp index 912302abdc..6badd34b8c 100644 --- a/Kernel/Devices/HID/Management.cpp +++ b/Kernel/Devices/HID/Management.cpp @@ -167,7 +167,7 @@ UNMAP_AFTER_INIT ErrorOr HIDManagement::enumerate() // Note: If we happen to not have i8042 just return "gracefully" for now. if (!has_i8042_controller) return {}; - if (auto result_or_error = i8042_controller->detect_devices(I8042Controller::EnableKeyboardFirstPortTranslation::No); result_or_error.is_error()) + if (auto result_or_error = i8042_controller->detect_devices(); result_or_error.is_error()) return {}; m_hid_serial_io_controllers.with([&](auto& list) { list.append(i8042_controller); @@ -188,10 +188,10 @@ HIDManagement& HIDManagement::the() return *s_the; } -u32 HIDManagement::get_char_from_character_map(KeyEvent event, u8 index) const +u32 HIDManagement::get_char_from_character_map(KeyEvent event, bool num_lock_on) const { - VERIFY(index < CHAR_MAP_SIZE); auto modifiers = event.modifiers(); + auto index = event.scancode & 0xFF; // Index is last byte of scan code. auto caps_lock_on = event.caps_lock_on; u32 code_point = 0; @@ -215,6 +215,19 @@ u32 HIDManagement::get_char_from_character_map(KeyEvent event, u8 index) const code_point |= 0x20; } + if (event.e0_prefix && event.key == Key_Slash) { + // If Key_Slash (scancode = 0x35) mapped to other form "/", we fix num pad key of "/" with this case. + code_point = '/'; + } else if (event.e0_prefix && event.key != Key_Return) { + // Except for `keypad-/` and 'keypad-return', all e0 scan codes are not actually characters. i.e., `keypad-0` and + // `Insert` have the same scancode except for the prefix, but insert should not have a code_point. + code_point = 0; + } else if (!num_lock_on && !event.e0_prefix && event.scancode >= 0x47 && event.scancode <= 0x53 && event.key != Key_Minus && event.key != Key_Plus) { + // When Num Lock is off, some numpad keys have the same function as some of the extended keys like Home, End, PgDown, arrows etc. + // These keys should have the code_point set to 0. + code_point = 0; + } + return code_point; } diff --git a/Kernel/Devices/HID/Management.h b/Kernel/Devices/HID/Management.h index 31f5c6dcc8..5dc07b416a 100644 --- a/Kernel/Devices/HID/Management.h +++ b/Kernel/Devices/HID/Management.h @@ -48,7 +48,7 @@ public: SpinlockProtected& keymap_data() { return m_keymap_data; } - u32 get_char_from_character_map(KeyEvent, u8) const; + u32 get_char_from_character_map(KeyEvent, bool) const; void set_client(KeyboardClient* client); void set_maps(NonnullOwnPtr character_map_name, Keyboard::CharacterMapData const& character_map); diff --git a/Kernel/Devices/HID/PS2/KeyboardDevice.cpp b/Kernel/Devices/HID/PS2/KeyboardDevice.cpp index 8cfdeab572..59d5e7fb6a 100644 --- a/Kernel/Devices/HID/PS2/KeyboardDevice.cpp +++ b/Kernel/Devices/HID/PS2/KeyboardDevice.cpp @@ -19,693 +19,28 @@ namespace Kernel { -// clang-format off -static constexpr KeyCodeEntry unshifted_scan_code_set1_key_map[0x80] = { - { Key_Invalid, 0xFF }, { Key_Escape, 1 }, { Key_1, 2 }, { Key_2, 3 }, - { Key_3, 4 }, { Key_4, 5 }, { Key_5, 6 }, { Key_6, 7 }, - { Key_7, 8 }, { Key_8, 9 }, { Key_9, 0x0A }, { Key_0, 0x0B }, - { Key_Minus, 0x0C }, { Key_Equal, 0x0D }, { Key_Backspace, 0x0E }, { Key_Tab, 0x0F }, - { Key_Q, 0x10 }, { Key_W, 0x11 }, { Key_E, 0x12 }, { Key_R, 0x13 }, - { Key_T, 0x14 }, { Key_Y, 0x15 }, { Key_U, 0x16 }, { Key_I, 0x17 }, - { Key_O, 0x18 }, { Key_P, 0x19 }, { Key_LeftBracket, 0x1A }, { Key_RightBracket, 0x1B }, - { Key_Return, 0x1C }, { Key_Control, 0x1D }, { Key_A, 0x1E }, { Key_S, 0x1F }, - { Key_D, 0x20 }, { Key_F, 0x21 }, { Key_G, 0x22 }, { Key_H, 0x23 }, - { Key_J, 0x24 }, { Key_K, 0x25 }, { Key_L, 0x26 }, { Key_Semicolon, 0x27 }, - { Key_Apostrophe, 0x28 }, { Key_Backtick, 0x29 }, { Key_LeftShift, 0xFF }, { Key_Backslash, 0x2B }, - { Key_Z, 0x2C }, { Key_X, 0x2D }, { Key_C, 0x2E }, { Key_V, 0x2F }, - { Key_B, 0x30 }, { Key_N, 0x31 }, { Key_M, 0x32 }, { Key_Comma, 0x33 }, - { Key_Period, 0x34 }, { Key_Slash, 0x35 }, { Key_RightShift, 0xFF }, { Key_Asterisk, 0x37 }, - { Key_Alt, 0xFF }, { Key_Space, 0x39 }, { Key_CapsLock, 0xFF }, { Key_F1, 0xFF }, - { Key_F2, 0xFF }, { Key_F3, 0xFF }, { Key_F4, 0xFF }, { Key_F5, 0xFF }, - { Key_F6, 0xFF }, { Key_F7, 0xFF }, { Key_F8, 0xFF }, { Key_F9, 0xFF }, - { Key_F10, 0xFF }, { Key_NumLock, 0xFF }, { Key_ScrollLock, 0xFF }, { Key_Home, 0xFF }, - { Key_Up, 0xFF }, { Key_PageUp, 0xFF }, { Key_Minus, 0x4A }, { Key_Left, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Right, 0xFF }, { Key_Plus, 0xFF }, { Key_End, 0xFF }, - { Key_Down, 0xFF }, { Key_PageDown, 0xFF }, { Key_Insert, 0xFF }, { Key_Delete, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Backslash, 0x56 }, { Key_F11, 0xFF }, - { Key_F12, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Super, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Menu, 0xFF }, -}; -// clang-format on - -// clang-format off -static constexpr KeyCodeEntry shifted_scan_code_set1_key_map[0x100] = { - { Key_Invalid, 0xFF }, { Key_Escape, 1 }, { Key_Escape, 2 }, { Key_AtSign, 3 }, - { Key_Hashtag, 4 }, { Key_Dollar, 5 }, { Key_Percent, 6 }, { Key_Circumflex, 7 }, - { Key_Ampersand, 8 }, { Key_Asterisk, 9 }, { Key_LeftParen, 0x0A }, { Key_RightParen, 0x0B }, - { Key_Underscore, 0xC }, { Key_Plus, 0xFF }, { Key_Backspace, 0x0E }, { Key_Tab, 0x0F }, - { Key_Q, 0x10 }, { Key_W, 0x11 }, { Key_E, 0x12 }, { Key_R, 0x13 }, - { Key_T, 0x14 }, { Key_Y, 0x15 }, { Key_U, 0x16 }, { Key_I, 0x17 }, - { Key_O, 0x18 }, { Key_P, 0x19 }, { Key_LeftBrace, 0x1A }, { Key_RightBrace, 0x1B }, - { Key_Return, 0x1C }, { Key_Control, 0x1D }, { Key_A, 0x1E }, { Key_S, 0x1F }, - { Key_D, 0x20 }, { Key_F, 0x21 }, { Key_G, 0x22 }, { Key_H, 0x23 }, - { Key_J, 0x24 }, { Key_K, 0x25 }, { Key_L, 0x26 }, { Key_Colon, 0x27 }, - { Key_DoubleQuote, 0x28 }, { Key_Tilde, 0x29 }, { Key_LeftShift, 0xFF }, { Key_Pipe, 0x2B }, - { Key_Z, 0x2C }, { Key_X, 0x2D }, { Key_C, 0x2E }, { Key_V, 0x2F }, - { Key_B, 0x30 }, { Key_N, 0x31 }, { Key_M, 0x32 }, { Key_LessThan, 0x33 }, - { Key_GreaterThan, 0x34 }, { Key_QuestionMark, 0x35 }, { Key_RightShift, 0x36 }, { Key_Asterisk, 0x37 }, - { Key_Alt, 0x38 }, { Key_Space, 0x39 }, { Key_CapsLock, 0x3A }, { Key_F1, 0x3B }, - { Key_F2, 0x3C }, { Key_F3, 0x3D }, { Key_F4, 0x3E }, { Key_F5, 0x3F }, - { Key_F6, 0x40 }, { Key_F7, 0x41 }, { Key_F8, 0x42 }, { Key_F9, 0x43 }, - { Key_F10, 0x44 }, { Key_NumLock, 0x45 }, { Key_ScrollLock, 0x46 }, { Key_Home, 0x47 }, - { Key_Up, 0x48 }, { Key_PageUp, 0x49 }, { Key_Minus, 0x0C }, { Key_Left, 0x4B }, - { Key_Invalid, 0xFF }, { Key_Right, 0xFF }, { Key_Plus, 0xFF }, { Key_End, 0xFF }, - { Key_Down, 0xFF }, { Key_PageDown, 0xFF }, { Key_Insert, 0xFF }, { Key_Delete, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Pipe, 0x56 }, { Key_F11, 0xFF }, - { Key_F12, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Super, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Menu, 0xFF }, -}; -// clang-format on - -// clang-format off -static constexpr KeyCodeEntry unshifted_simple_scan_code_set2_key_map_with_key_num_pad[0x84] = { - { Key_Invalid, 0xFF }, { Key_F9, 0x43 }, { Key_Invalid, 0xFF }, { Key_F5, 0x3F }, - { Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF }, - { Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 }, - { Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF }, - { Key_Control, 0x1D }, { Key_Q, 0x10 }, { Key_1, 2 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F }, - { Key_A, 0x1E }, { Key_W, 0x11 }, { Key_2, 3 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 }, - { Key_E, 0x12 }, { Key_4, 5 }, { Key_3, 4 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Space, 0x39 }, { Key_V, 0x2F }, { Key_F, 0x21 }, - { Key_T, 0x14 }, { Key_R, 0x13 }, { Key_5, 6 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_N, 0x31 }, { Key_B, 0x30 }, { Key_H, 0x23 }, - { Key_G, 0x22 }, { Key_Y, 0x15 }, { Key_6, 7 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_M, 0x32 }, { Key_J, 0x24 }, - { Key_U, 0x16 }, { Key_7, 8 }, { Key_8, 9 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Comma, 0x33 }, { Key_K, 0x25 }, { Key_I, 0x17 }, - { Key_O, 0x18 }, { Key_0, 0x0B }, { Key_9, 0x0A }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Period, 0x34 }, { Key_Slash, 0x35 }, { Key_L, 0x26 }, - { Key_Semicolon, 0x27 }, { Key_P, 0x19 }, { Key_Minus, 0x0C }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Apostrophe, 0x28 }, { Key_Invalid, 0xFF }, - { Key_LeftBracket, 0x1A }, { Key_Equal, 0x0D }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_CapsLock, 0x3A }, { Key_RightShift, 0x36 }, { Key_Return, 0x1C }, { Key_RightBracket, 0x1B }, - { Key_Invalid, 0xFF }, { Key_Backslash, 0x2B }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Backspace, 0x0E }, { Key_Invalid, 0xFF }, - // Keypad numbers from here - { Key_Invalid, 0xFF }, { Key_1, 2 }, { Key_Invalid, 0xFF }, { Key_4, 5 }, - { Key_7, 8 }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_0, 0x0B }, { Key_Period, 0x34 }, { Key_2, 3 }, { Key_5, 6 }, - { Key_6, 7 }, { Key_8, 9 }, { Key_Escape, 1 }, { Key_NumLock, 0x45 }, - { Key_F11, 0xFF }, { Key_Plus, 0xFF }, { Key_3, 4 }, { Key_Minus, 0x0C }, - { Key_Asterisk, 0x37 }, { Key_9, 0x0A }, { Key_ScrollLock, 0x46 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_F7, 0x41 }, -}; -// clang-format on - -// clang-format off -static constexpr KeyCodeEntry unshifted_simple_scan_code_set2_key_map_with_disabled_key_num_pad[0x84] = { - { Key_Invalid, 0xFF }, { Key_F9, 0x43 }, { Key_Invalid, 0xFF }, { Key_F5, 0x3F }, - { Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF }, - { Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 }, - { Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF }, - { Key_Control, 0x1D }, { Key_Q, 0x10 }, { Key_1, 2 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F }, - { Key_A, 0x1E }, { Key_W, 0x11 }, { Key_2, 3 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 }, - { Key_E, 0x12 }, { Key_4, 5 }, { Key_3, 4 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Space, 0x39 }, { Key_V, 0x2F }, { Key_F, 0x21 }, - { Key_T, 0x14 }, { Key_R, 0x13 }, { Key_5, 6 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_N, 0x31 }, { Key_B, 0x30 }, { Key_H, 0x23 }, - { Key_G, 0x22 }, { Key_Y, 0x15 }, { Key_6, 7 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_M, 0x32 }, { Key_J, 0x24 }, - { Key_U, 0x16 }, { Key_7, 8 }, { Key_8, 9 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Comma, 0x33 }, { Key_K, 0x25 }, { Key_I, 0x17 }, - { Key_O, 0x18 }, { Key_0, 0x0B }, { Key_9, 0x0A }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Period, 0x34 }, { Key_Slash, 0x35 }, { Key_L, 0x26 }, - { Key_Semicolon, 0x27 }, { Key_P, 0x19 }, { Key_Underscore, 0x0C }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Apostrophe, 0x28 }, { Key_Invalid, 0xFF }, - { Key_LeftBracket, 0x1A }, { Key_Equal, 0x0D }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_CapsLock, 0x3A }, { Key_RightShift, 0x36 }, { Key_Return, 0x1C }, { Key_RightBracket, 0x1B }, - { Key_Invalid, 0xFF }, { Key_Backslash, 0x2B }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Backspace, 0x0E }, { Key_Invalid, 0xFF }, - // Keypad numbers from here, and disabled or converted to arrows - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Left, 0x4B }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Insert, 0xFF }, { Key_Delete, 0xFF }, { Key_Down, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Right, 0xFF }, { Key_Up, 0x48 }, { Key_Escape, 1 }, { Key_NumLock, 0x45 }, - { Key_F11, 0xFF }, { Key_Plus, 0xFF }, { Key_Invalid, 0xFF }, { Key_Minus, 0x0C }, - { Key_Asterisk, 0x37 }, { Key_Invalid, 0xFF }, { Key_ScrollLock, 0x46 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_F7, 0x41 }, -}; -// clang-format on - -// clang-format off -static constexpr KeyCodeEntry shifted_simple_scan_code_set2_key_map_with_key_num_pad[0x84] = { - { Key_Invalid, 0xFF }, { Key_F9, 0x43 }, { Key_Invalid, 0xFF }, { Key_F5, 0x3F }, - { Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF }, - { Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 }, - { Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF }, - { Key_Control, 0x1D }, { Key_Slash, 0x35 }, { Key_Escape, 2 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F }, - { Key_A, 0x1E }, { Key_W, 0x11 }, { Key_AtSign, 3 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 }, - { Key_E, 0x12 }, { Key_Dollar, 5 }, { Key_Hashtag, 4 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Space, 0x39 }, { Key_V, 0x2F }, { Key_F, 0x21 }, - { Key_T, 0x14 }, { Key_R, 0x13 }, { Key_Percent, 6 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_N, 0x31 }, { Key_B, 0x30 }, { Key_H, 0x23 }, - { Key_G, 0x22 }, { Key_Y, 0x15 }, { Key_Circumflex, 7 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_M, 0x32 }, { Key_J, 0x24 }, - { Key_U, 0x16 }, { Key_Ampersand, 8 }, { Key_Asterisk, 0x37 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_LessThan, 0x33 }, { Key_K, 0x25 }, { Key_I, 0x17 }, - { Key_O, 0x18 }, { Key_RightParen, 0x0B }, { Key_LeftParen, 0x0A }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_GreaterThan, 0x34 }, { Key_Slash, 0x35 }, { Key_L, 0x26 }, - { Key_Semicolon, 0x27 }, { Key_P, 0x19 }, { Key_Minus, 0x0C }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_DoubleQuote, 0x28 }, { Key_Invalid, 0xFF }, - { Key_LeftBrace, 0x1A }, { Key_Plus, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_CapsLock, 0x3A }, { Key_RightShift, 0x36 }, { Key_Return, 0x1C }, { Key_RightBrace, 0x1B }, - { Key_Invalid, 0xFF }, { Key_Pipe, 0x2B }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Backspace, 0x0E }, { Key_Invalid, 0xFF }, - // Keypad numbers from here - { Key_Invalid, 0xFF }, { Key_1, 2 }, { Key_Invalid, 0xFF }, { Key_4, 5 }, - { Key_7, 8 }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_0, 0x0B }, { Key_Period, 0x34 }, { Key_2, 3 }, { Key_5, 6 }, - { Key_6, 7 }, { Key_8, 9 }, { Key_Escape, 1 }, { Key_NumLock, 0x45 }, - { Key_F11, 0xFF }, { Key_Plus, 0xFF }, { Key_3, 4 }, { Key_Minus, 0x0C }, - { Key_Asterisk, 0x37 }, { Key_9, 0x0A }, { Key_ScrollLock, 0x46 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_F7, 0x41 }, -}; -// clang-format on - -// clang-format off -static constexpr KeyCodeEntry shifted_simple_scan_code_set2_key_map_with_disabled_key_num_pad[0x84] = { - { Key_Invalid, 0xFF }, { Key_F9, 0x43 }, { Key_Invalid, 0xFF }, { Key_F5, 0x3F }, - { Key_F3, 0x3D }, { Key_F1, 0x3B }, { Key_F2, 0x3C }, { Key_F12, 0xFF }, - { Key_Invalid, 0xFF }, { Key_F10, 0x44 }, { Key_F8, 0x42 }, { Key_F6, 0x40 }, - { Key_F4, 0x3E }, { Key_Tab, 0x0F }, { Key_Backtick, 0x29 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Alt, 0x38 }, { Key_LeftShift, 0x2A }, { Key_Invalid, 0xFF }, - { Key_Control, 0x1D }, { Key_Slash, 0x35 }, { Key_Escape, 2 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Z, 0x2C }, { Key_S, 0x1F }, - { Key_A, 0x1E }, { Key_W, 0x11 }, { Key_AtSign, 3 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_C, 0x2E }, { Key_X, 0x2D }, { Key_D, 0x20 }, - { Key_E, 0x12 }, { Key_Dollar, 5 }, { Key_Hashtag, 4 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Space, 0x39 }, { Key_V, 0x2F }, { Key_F, 0x21 }, - { Key_T, 0x14 }, { Key_R, 0x13 }, { Key_Percent, 6 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_N, 0x31 }, { Key_B, 0x30 }, { Key_H, 0x23 }, - { Key_G, 0x22 }, { Key_Y, 0x15 }, { Key_Circumflex, 7 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_M, 0x32 }, { Key_J, 0x24 }, - { Key_U, 0x16 }, { Key_Ampersand, 8 }, { Key_Asterisk, 0x37 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_LessThan, 0xFF}, { Key_K, 0x25 }, { Key_I, 0x17 }, - { Key_O, 0x18 }, { Key_RightParen, 0x0B }, { Key_LeftParen, 0x0A }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Period, 0x34 }, { Key_Slash, 0x35 }, { Key_L, 0x26 }, - { Key_Semicolon, 0x27 }, { Key_P, 0x19 }, { Key_Underscore, 0x0C }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_DoubleQuote, 0x28 }, { Key_Invalid, 0xFF }, - { Key_LeftBrace, 0x1A }, { Key_Plus, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_CapsLock, 0x3A }, { Key_RightShift, 0x36 }, { Key_Return, 0x1C }, { Key_RightBrace, 0x1B }, - { Key_Invalid, 0xFF }, { Key_Pipe, 0x2B }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Backspace, 0x0E }, { Key_Invalid, 0xFF }, - // Keypad numbers from here, and disabled or converted to arrows - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Left, 0x4B }, - { Key_7, 8 }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Insert, 0xFF }, { Key_Delete, 0xFF }, { Key_Down, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Right, 0xFF }, { Key_Up, 0x48 }, { Key_Escape, 1 }, { Key_NumLock, 0x45 }, - { Key_F11, 0xFF }, { Key_Plus, 0xFF }, { Key_Invalid, 0xFF }, { Key_Minus, 0x0C }, - { Key_Asterisk, 0x37 }, { Key_Invalid, 0xFF }, { Key_ScrollLock, 0x46 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_F7, 0x41 }, -}; -// clang-format on - -// Note: First scan code starts at actual 0xE0, 0x10, but we start from 0xE0, 0x0 -// Note: All keycode are for pressing buttons, not releasing... -// clang-format off -static constexpr KeyCodeEntry unshifted_scan_code_set2_e0_key_map[0x80] = { - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_BrowserSearch, 0xFF }, { Key_RightAlt, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_RightControl, 0xFF }, { Key_PreviousTrack, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_BrowserFavorites, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_LeftGUI, 0xFF }, - { Key_BrowserRefresh, 0xFF }, { Key_VolumeDown, 0xFF }, { Key_Invalid, 0xFF }, { Key_Mute, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_RightGUI, 0xFF }, - { Key_BrowserStop, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Calculator, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Apps, 0xFF }, - { Key_BrowserForward, 0xFF }, { Key_Invalid, 0xFF }, { Key_VolumeUp, 0xFF }, { Key_Invalid, 0xFF }, - { Key_PlayPause, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Power, 0xFF }, - { Key_BrowserBack, 0xFF }, { Key_Invalid, 0xFF }, { Key_BrowserHome, 0xFF }, { Key_Stop, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Sleep, 0xFF }, - { Key_MyComputer, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Email, 0xFF }, { Key_Invalid, 0xFF }, { Key_Slash, 0x35 }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_NextTrack, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_MediaSelect, 0xFF}, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Return, 0x1C }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Wake, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_End, 0xFF }, { Key_Invalid, 0xFF }, { Key_Left, 0xFF }, - { Key_Home, 0x47 }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Insert, 0xFF }, { Key_Delete, 0xFF }, { Key_Down, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Right, 0xFF }, { Key_Up, 0xFF }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, { Key_PageDown, 0xFF }, { Key_Invalid, 0xFF }, - { Key_Invalid, 0xFF }, { Key_PageUp, 0x49 }, { Key_Invalid, 0xFF }, { Key_Invalid, 0xFF }, -}; -// clang-format on - -RawKeyEvent PS2KeyboardDevice::generate_raw_key_event_input_from_set1(ScanCodeEvent event) -{ - RawKeyEvent key_event {}; - VERIFY(event.sent_scan_code_set == ScanCodeSet::Set1); - bool has_e0_prefix = event.scan_code_bytes[0] == 0xe0; - if (has_e0_prefix) - VERIFY(event.bytes_count == 2); - else - VERIFY(event.bytes_count == 1); - - u8 byte = has_e0_prefix ? event.scan_code_bytes[1] : event.scan_code_bytes[0]; - bool pressed = !(byte & 0x80); - u8 ch = byte & 0x7f; - - key_event.is_press_down = pressed; - - m_entropy_source.add_random_event(byte); - - switch (ch) { - case 0x38: - if (has_e0_prefix) - m_keyboard_device->update_modifier(Mod_AltGr, key_event.is_press()); - else - m_keyboard_device->update_modifier(Mod_Alt, key_event.is_press()); - break; - case 0x1d: - m_keyboard_device->update_modifier(Mod_Ctrl, key_event.is_press()); - break; - case 0x5b: - m_left_super_pressed = key_event.is_press(); - m_keyboard_device->update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed); - break; - case 0x5c: - m_right_super_pressed = key_event.is_press(); - m_keyboard_device->update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed); - break; - case 0x2a: - m_left_shift_pressed = key_event.is_press(); - m_keyboard_device->update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); - break; - case 0x36: - m_right_shift_pressed = key_event.is_press(); - m_keyboard_device->update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); - break; - case 0x1c: - case 0x35: - if (has_e0_prefix) - m_keyboard_device->update_modifier(Mod_Keypad, key_event.is_press()); - break; - case 0x37: - case 0x47: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - case 0x50: - case 0x51: - case 0x52: - case 0x53: - if (!has_e0_prefix) - m_keyboard_device->update_modifier(Mod_Keypad, key_event.is_press()); - break; - } - - key_event.code_entry = (m_keyboard_device->modifiers() & Mod_Shift) ? shifted_scan_code_set1_key_map[ch] : unshifted_scan_code_set1_key_map[ch]; - key_event.scancode = has_e0_prefix ? 0xe000 + ch : ch; - return key_event; -} - -RawKeyEvent PS2KeyboardDevice::generate_raw_key_event_input_from_set2(ScanCodeEvent event) -{ - VERIFY(event.sent_scan_code_set == ScanCodeSet::Set2); - - auto get_key_from_standard_key_map = [this](u8 byte) -> KeyCodeEntry { - if (!(m_keyboard_device->modifiers() & Mod_Shift)) - return (m_keyboard_device->num_lock_on()) ? unshifted_simple_scan_code_set2_key_map_with_key_num_pad[byte] : unshifted_simple_scan_code_set2_key_map_with_disabled_key_num_pad[byte]; - return (m_keyboard_device->num_lock_on()) ? shifted_simple_scan_code_set2_key_map_with_key_num_pad[byte] : shifted_simple_scan_code_set2_key_map_with_disabled_key_num_pad[byte]; - }; - - RawKeyEvent key_event {}; - if (event.bytes_count == 1) { - auto byte = event.scan_code_bytes[0]; - key_event.code_entry = get_key_from_standard_key_map(byte); - key_event.scancode = byte; - key_event.is_press_down = true; - m_entropy_source.add_random_event(byte); - } else if (event.bytes_count == 2) { - auto byte_prefix = event.scan_code_bytes[0]; - auto byte = event.scan_code_bytes[1]; - if (byte_prefix == 0xe0) { - key_event.code_entry = unshifted_scan_code_set2_e0_key_map[byte]; - key_event.scancode = 0xe000 + byte; - key_event.is_press_down = true; - } else if (byte_prefix == 0xf0) { - key_event.code_entry = get_key_from_standard_key_map(byte); - key_event.scancode = 0xf000 + byte; - } else { - VERIFY_NOT_REACHED(); - } - m_entropy_source.add_random_event(byte); - } else if (event.bytes_count == 3) { - auto first_byte_prefix = event.scan_code_bytes[0]; - auto second_byte_prefix = event.scan_code_bytes[1]; - VERIFY(first_byte_prefix == 0xe0); - VERIFY(second_byte_prefix == 0xf0); - auto byte = event.scan_code_bytes[2]; - key_event.code_entry = unshifted_scan_code_set2_e0_key_map[byte]; - key_event.scancode = 0xe0f000 + byte; - m_entropy_source.add_random_event(byte); - } else if (event.bytes_count == 4) { - // 0xE0, 0x12, 0xE0, 0x7C - print screen pressed - auto first_byte_prefix = event.scan_code_bytes[0]; - auto second_byte_prefix = event.scan_code_bytes[1]; - auto third_byte_prefix = event.scan_code_bytes[2]; - auto fourth_byte_prefix = event.scan_code_bytes[3]; - VERIFY(first_byte_prefix == 0xe0); - VERIFY(second_byte_prefix == 0x12); - VERIFY(third_byte_prefix == 0xe0); - VERIFY(fourth_byte_prefix == 0x7c); - key_event.code_entry = KeyCodeEntry { Key_PrintScreen, 0xFF }; - key_event.scancode = 0xe012e07c; - key_event.is_press_down = true; - } else if (event.bytes_count == 6) { - // 0xE0, 0xF0, 0x7C, 0xE0, 0xF0, 0x12 - print screen released - auto first_byte_prefix = event.scan_code_bytes[0]; - auto second_byte_prefix = event.scan_code_bytes[1]; - auto third_byte_prefix = event.scan_code_bytes[2]; - auto fourth_byte_prefix = event.scan_code_bytes[3]; - auto fifth_byte_prefix = event.scan_code_bytes[4]; - auto sixth_byte_prefix = event.scan_code_bytes[5]; - VERIFY(first_byte_prefix == 0xe0); - VERIFY(second_byte_prefix == 0xf0); - VERIFY(third_byte_prefix == 0x7c); - VERIFY(fourth_byte_prefix == 0xe0); - VERIFY(fifth_byte_prefix == 0xf0); - VERIFY(sixth_byte_prefix == 0x12); - key_event.code_entry = KeyCodeEntry { Key_PrintScreen, 0xFF }; - key_event.scancode = 0xe0f07ce0f012; - } else if (event.bytes_count == 8) { - // 0xE1, 0x14, 0x77, 0xE1, 0xF0, 0x14, 0xF0, 0x77 - pause pressed - auto first_byte_prefix = event.scan_code_bytes[0]; - auto second_byte_prefix = event.scan_code_bytes[1]; - auto third_byte_prefix = event.scan_code_bytes[2]; - auto fourth_byte_prefix = event.scan_code_bytes[3]; - auto fifth_byte_prefix = event.scan_code_bytes[4]; - auto sixth_byte_prefix = event.scan_code_bytes[5]; - auto seventh_byte_prefix = event.scan_code_bytes[6]; - auto eight_byte_prefix = event.scan_code_bytes[7]; - VERIFY(first_byte_prefix == 0xe1); - VERIFY(second_byte_prefix == 0x14); - VERIFY(third_byte_prefix == 0x77); - VERIFY(fourth_byte_prefix == 0xe1); - VERIFY(fifth_byte_prefix == 0xf0); - VERIFY(sixth_byte_prefix == 0x14); - VERIFY(seventh_byte_prefix == 0xf0); - VERIFY(eight_byte_prefix == 0x77); - key_event.code_entry = KeyCodeEntry { Key_PauseBreak, 0xFF }; - key_event.scancode = 0xe11477e1f014f077; - } - - switch (key_event.code_entry.key_code) { - case Key_RightAlt: - m_keyboard_device->update_modifier(Mod_AltGr, key_event.is_press()); - break; - case Key_Alt: - m_keyboard_device->update_modifier(Mod_Alt, key_event.is_press()); - break; - case Key_Control: - m_keyboard_device->update_modifier(Mod_Ctrl, key_event.is_press()); - break; - case Key_Super: - m_left_super_pressed = key_event.is_press(); - m_keyboard_device->update_modifier(Mod_Super, m_left_super_pressed || m_right_super_pressed); - break; - case Key_LeftShift: - m_left_shift_pressed = key_event.is_press(); - m_keyboard_device->update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); - break; - case Key_RightShift: - m_right_shift_pressed = key_event.is_press(); - m_keyboard_device->update_modifier(Mod_Shift, m_left_shift_pressed || m_right_shift_pressed); - break; - default: - break; - } - - return key_event; -} - -void PS2KeyboardDevice::handle_scan_code_input_event(ScanCodeEvent event) -{ - RawKeyEvent raw_event {}; - if (event.sent_scan_code_set == ScanCodeSet::Set1) { - raw_event = generate_raw_key_event_input_from_set1(event); - } else if (event.sent_scan_code_set == ScanCodeSet::Set2) { - raw_event = generate_raw_key_event_input_from_set2(event); - } else if (event.sent_scan_code_set == ScanCodeSet::Set3) { - // FIXME: Implement support for scan code set 3! - VERIFY_NOT_REACHED(); - } else { - VERIFY_NOT_REACHED(); - } - - KeyEvent queued_event = { - .key = raw_event.code_entry.key_code, - .map_entry_index = raw_event.code_entry.map_entry_index, - .scancode = raw_event.scancode, - .flags = raw_event.is_press() ? (u8)Is_Press : (u8)0, - }; - - // NOTE: This piece of code is needed for the ScanCodeSet::Set1 to ensure some keys could - // function properly. - if (event.sent_scan_code_set == ScanCodeSet::Set1) { - if ((queued_event.scancode & 0xe000) && queued_event.key == Key_Slash) { - // If Key_Slash (scancode = 0x35) mapped to other form "/", we fix num pad key of "/" with this case. - queued_event.code_point = '/'; - } else if ((queued_event.scancode & 0xe000) && queued_event.key != Key_Return) { - // Except for `keypad-/` and 'keypad-return', all e0 scan codes are not actually characters. i.e., `keypad-0` and - // `Insert` have the same scancode except for the prefix, but insert should not have a code_point. - queued_event.code_point = 0; - } - } - - // NOTE: This piece of code is needed for the ScanCodeSet::Set1 when NumLock is enabled - // because we don't have special mappings when NumLock is enabled for this scan code set. - // Scan code set 2 handling code in handle_scan_code_input_event_set2() already handles this fine. - if (event.sent_scan_code_set == ScanCodeSet::Set1 && m_keyboard_device->num_lock_on() && !(queued_event.scancode & 0xe000)) { - if (queued_event.scancode >= 0x47 && queued_event.scancode <= 0x53) { - u8 index = queued_event.scancode - 0x47; - constexpr KeyCode numpad_key_map[13] = { Key_7, Key_8, Key_9, Key_Invalid, Key_4, Key_5, Key_6, Key_Invalid, Key_1, Key_2, Key_3, Key_0, Key_Comma }; - KeyCode newKey = numpad_key_map[index]; - - if (newKey != Key_Invalid) { - queued_event.key = newKey; - } - } - } - - if (raw_event.code_entry.map_entry_index != 0xFF) - queued_event.code_point = HIDManagement::the().get_char_from_character_map(queued_event, raw_event.code_entry.map_entry_index); - - m_keyboard_device->handle_input_event(queued_event); -} - -void PS2KeyboardDevice::handle_byte_read_for_scan_code_set1(u8 byte) +void PS2KeyboardDevice::handle_byte_read_from_serial_input(u8 byte) { u8 ch = byte & 0x7f; bool pressed = !(byte & 0x80); - dbgln_if(KEYBOARD_DEBUG, "Keyboard::handle_byte_read_for_scan_code_set1: {:#02x} {}", ch, (pressed ? "down" : "up")); if (byte == 0xe0) { m_has_e0_prefix = true; return; } ScanCodeEvent event {}; - event.sent_scan_code_set = ScanCodeSet::Set1; - if (m_has_e0_prefix) { - event.scan_code_bytes[0] = 0xe0; - event.scan_code_bytes[1] = byte; - event.bytes_count = 2; - } else { - event.scan_code_bytes[0] = byte; - event.bytes_count = 1; - } + event.pressed = pressed; + event.e0_prefix = m_has_e0_prefix; m_has_e0_prefix = false; - handle_scan_code_input_event(event); + + dbgln_if(KEYBOARD_DEBUG, "Keyboard::handle_byte_read_from_serial_input: {:#02x} {}", ch, (pressed ? "down" : "up")); + event.scan_code_value = ch; + m_keyboard_device->handle_scan_code_input_event(event); } -void PS2KeyboardDevice::handle_byte_read_for_scan_code_set2(u8 byte) +UNMAP_AFTER_INIT ErrorOr> PS2KeyboardDevice::try_to_initialize(SerialIOController const& serial_io_controller, SerialIOController::PortIndex port_index, KeyboardDevice const& keyboard_device) { - dbgln_if(KEYBOARD_DEBUG, "Keyboard::handle_byte_read_for_scan_code_set2: {:#02x}", byte); - - ScanCodeEvent event {}; - event.sent_scan_code_set = ScanCodeSet::Set2; - if (m_received_bytes_count == 0) { - if (byte == 0xe0 || byte == 0xf0 || byte == 0xe1) { - m_received_bytes[0] = byte; - m_received_bytes_count++; - return; - } - event.scan_code_bytes[0] = byte; - event.bytes_count = 1; - m_received_bytes_count = 0; - handle_scan_code_input_event(event); - return; - } else if (m_received_bytes_count == 1) { - if (byte == 0xf0) { - VERIFY(m_received_bytes[0] == 0xe0); - m_received_bytes[1] = byte; - m_received_bytes_count++; - return; - } - if (m_received_bytes[0] == 0xe0 && byte == 0x12) { - m_received_bytes[1] = byte; - m_received_bytes_count++; - return; - } - - if (m_received_bytes[0] == 0xe1 && byte == 0x14) { - m_received_bytes[1] = byte; - m_received_bytes_count++; - return; - } - - event.scan_code_bytes[0] = m_received_bytes[0]; - event.scan_code_bytes[1] = byte; - event.bytes_count = 2; - m_received_bytes_count = 0; - handle_scan_code_input_event(event); - return; - } else if (m_received_bytes_count == 2) { - if (m_received_bytes[0] == 0xe0 && m_received_bytes[1] == 0x12 && byte == 0xe0) { - m_received_bytes[2] = byte; - m_received_bytes_count++; - return; - } - - if (m_received_bytes[0] == 0xe0 && m_received_bytes[1] == 0xf0 && byte == 0x7c) { - m_received_bytes[2] = byte; - m_received_bytes_count++; - return; - } - - if (m_received_bytes[0] == 0xe1) { - VERIFY(m_received_bytes[1] == 0x14); - m_received_bytes[2] = byte; - m_received_bytes_count++; - return; - } - - event.scan_code_bytes[0] = m_received_bytes[0]; - event.scan_code_bytes[1] = m_received_bytes[1]; - event.scan_code_bytes[2] = byte; - event.bytes_count = 3; - m_received_bytes_count = 0; - handle_scan_code_input_event(event); - return; - } else if (m_received_bytes_count == 3) { - if (m_received_bytes[0] == 0xe0 - && m_received_bytes[1] == 0x12 - && m_received_bytes[2] == 0xe0 - && byte == 0x7c) { - ScanCodeEvent event {}; - event.sent_scan_code_set = ScanCodeSet::Set2; - event.scan_code_bytes[0] = m_received_bytes[0]; - event.scan_code_bytes[1] = m_received_bytes[1]; - event.scan_code_bytes[2] = m_received_bytes[2]; - event.scan_code_bytes[3] = byte; - event.bytes_count = 4; - m_received_bytes_count = 0; - handle_scan_code_input_event(event); - return; - } - - m_received_bytes[3] = byte; - m_received_bytes_count++; - return; - } else if (m_received_bytes_count == 4) { - m_received_bytes[4] = byte; - m_received_bytes_count++; - return; - } else if (m_received_bytes_count == 5) { - if (m_received_bytes[0] == 0xe0 - && m_received_bytes[1] == 0xf0 - && m_received_bytes[2] == 0x7c - && m_received_bytes[3] == 0xe0 - && m_received_bytes[4] == 0xf0 - && byte == 0x12) { - - event.scan_code_bytes[0] = m_received_bytes[0]; - event.scan_code_bytes[1] = m_received_bytes[1]; - event.scan_code_bytes[2] = m_received_bytes[2]; - event.scan_code_bytes[3] = m_received_bytes[3]; - event.scan_code_bytes[4] = m_received_bytes[4]; - event.scan_code_bytes[5] = byte; - event.bytes_count = 6; - m_received_bytes_count = 0; - handle_scan_code_input_event(event); - return; - } - m_received_bytes[5] = byte; - m_received_bytes_count++; - return; - } else if (m_received_bytes_count == 6) { - m_received_bytes[6] = byte; - m_received_bytes_count++; - return; - } else if (m_received_bytes_count == 7) { - VERIFY(m_received_bytes[0] == 0xe1); - VERIFY(m_received_bytes[1] == 0x14); - VERIFY(m_received_bytes[2] == 0x77); - VERIFY(m_received_bytes[3] == 0xe1); - VERIFY(m_received_bytes[4] == 0xf0); - VERIFY(m_received_bytes[5] == 0x14); - VERIFY(m_received_bytes[6] == 0xf0); - VERIFY(m_received_bytes[7] == 0x77); - event.scan_code_bytes[0] = m_received_bytes[0]; - event.scan_code_bytes[1] = m_received_bytes[1]; - event.scan_code_bytes[2] = m_received_bytes[2]; - event.scan_code_bytes[3] = m_received_bytes[3]; - event.scan_code_bytes[4] = m_received_bytes[4]; - event.scan_code_bytes[5] = m_received_bytes[5]; - event.scan_code_bytes[6] = m_received_bytes[6]; - event.scan_code_bytes[7] = byte; - event.bytes_count = 8; - m_received_bytes_count = 0; - handle_scan_code_input_event(event); - return; - } else { - VERIFY_NOT_REACHED(); - } -} - -void PS2KeyboardDevice::handle_byte_read_from_serial_input(u8 byte) -{ - switch (m_scan_code_set) { - case ScanCodeSet::Set1: - handle_byte_read_for_scan_code_set1(byte); - break; - case ScanCodeSet::Set2: - handle_byte_read_for_scan_code_set2(byte); - break; - default: - VERIFY_NOT_REACHED(); - } -} - -UNMAP_AFTER_INIT ErrorOr> PS2KeyboardDevice::try_to_initialize(SerialIOController const& serial_io_controller, SerialIOController::PortIndex port_index, ScanCodeSet scan_code_set, KeyboardDevice const& keyboard_device) -{ - auto device = TRY(adopt_nonnull_own_or_enomem(new (nothrow) PS2KeyboardDevice(serial_io_controller, port_index, scan_code_set, keyboard_device))); + auto device = TRY(adopt_nonnull_own_or_enomem(new (nothrow) PS2KeyboardDevice(serial_io_controller, port_index, keyboard_device))); TRY(device->initialize()); return device; } @@ -739,10 +74,9 @@ UNMAP_AFTER_INIT ErrorOr PS2KeyboardDevice::initialize() // FIXME: UNMAP_AFTER_INIT might not be correct, because in practice PS/2 devices // are hot pluggable. -UNMAP_AFTER_INIT PS2KeyboardDevice::PS2KeyboardDevice(SerialIOController const& serial_io_controller, SerialIOController::PortIndex port_index, ScanCodeSet scan_code_set, KeyboardDevice const& keyboard_device) +UNMAP_AFTER_INIT PS2KeyboardDevice::PS2KeyboardDevice(SerialIOController const& serial_io_controller, SerialIOController::PortIndex port_index, KeyboardDevice const& keyboard_device) : SerialIODevice(serial_io_controller, port_index) , m_keyboard_device(keyboard_device) - , m_scan_code_set(scan_code_set) { } diff --git a/Kernel/Devices/HID/PS2/KeyboardDevice.h b/Kernel/Devices/HID/PS2/KeyboardDevice.h index 95dbcc8fe1..66387b4792 100644 --- a/Kernel/Devices/HID/PS2/KeyboardDevice.h +++ b/Kernel/Devices/HID/PS2/KeyboardDevice.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -20,7 +19,7 @@ class PS2KeyboardDevice final : public SerialIODevice { friend class DeviceManagement; public: - static ErrorOr> try_to_initialize(SerialIOController const&, SerialIOController::PortIndex port_index, ScanCodeSet scan_code_set, KeyboardDevice const&); + static ErrorOr> try_to_initialize(SerialIOController const&, SerialIOController::PortIndex port_index, KeyboardDevice const&); virtual ~PS2KeyboardDevice() override; ErrorOr initialize(); @@ -28,37 +27,11 @@ public: virtual void handle_byte_read_from_serial_input(u8 byte) override; private: - PS2KeyboardDevice(SerialIOController const&, SerialIOController::PortIndex port_index, ScanCodeSet scan_code_set, KeyboardDevice const&); + PS2KeyboardDevice(SerialIOController const&, SerialIOController::PortIndex port_index, KeyboardDevice const&); - RawKeyEvent generate_raw_key_event_input_from_set1(ScanCodeEvent); - RawKeyEvent generate_raw_key_event_input_from_set2(ScanCodeEvent); - - void handle_scan_code_input_event(ScanCodeEvent event); - - void handle_byte_read_for_scan_code_set1(u8 byte); - void handle_byte_read_for_scan_code_set2(u8 byte); - - // NOTE: This boolean variable is only used with ScanCodeSet::Set1 - // because it only has one prefix defined in the scan code set. bool m_has_e0_prefix { false }; - // NOTE: This array and its counter are used only when m_scan_code_set - // is set to ScanCodeSet::Set2, because that scan code requires us to - // manage scan codes with multiple bytes. - // According to the scan code set 2 table, a key press (or release) - // can generate up to 8 bytes. - Array m_received_bytes; - size_t m_received_bytes_count { 0 }; - - bool m_left_shift_pressed { false }; - bool m_right_shift_pressed { false }; - bool m_left_super_pressed { false }; - bool m_right_super_pressed { false }; - NonnullRefPtr const m_keyboard_device; - ScanCodeSet const m_scan_code_set { ScanCodeSet::Set1 }; - - EntropySource m_entropy_source; }; } diff --git a/Kernel/Devices/HID/ScanCodeEvent.h b/Kernel/Devices/HID/ScanCodeEvent.h index 3a1d8a44c9..d89e8fc5fb 100644 --- a/Kernel/Devices/HID/ScanCodeEvent.h +++ b/Kernel/Devices/HID/ScanCodeEvent.h @@ -7,14 +7,13 @@ #pragma once #include -#include namespace Kernel { struct ScanCodeEvent { - Array scan_code_bytes; - ScanCodeSet sent_scan_code_set { ScanCodeSet::Set1 }; - u8 bytes_count { 0 }; + u32 scan_code_value { 0 }; + bool pressed { false }; + bool e0_prefix { false }; }; } diff --git a/Userland/Libraries/LibWeb/UIEvents/KeyboardEvent.cpp b/Userland/Libraries/LibWeb/UIEvents/KeyboardEvent.cpp index 13b7712fb7..cab4243ab0 100644 --- a/Userland/Libraries/LibWeb/UIEvents/KeyboardEvent.cpp +++ b/Userland/Libraries/LibWeb/UIEvents/KeyboardEvent.cpp @@ -143,9 +143,8 @@ static ErrorOr> get_event_named_key(KeyCode platform_key) // 3.2. Modifier Keys, https://www.w3.org/TR/uievents-key/#keys-modifier case KeyCode::Key_Alt: - return "AltLeft"_string; - case KeyCode::Key_RightAlt: - return "AltRight"_string; + return "Alt"_string; + // FIXME: AltGraph case KeyCode::Key_CapsLock: return "CapsLock"_string; case KeyCode::Key_Control: @@ -458,9 +457,7 @@ static ErrorOr get_event_code(KeyCode platform_key, unsigned modifiers) // 3.1.2. Functional Keys, https://www.w3.org/TR/uievents-code/#key-alphanumeric-functional case KeyCode::Key_Alt: - return "AltLeft"_string; - case KeyCode::Key_RightAlt: - return "AltRight"_string; + return "Alt"_string; // FIXME: Detect left vs. right key. case KeyCode::Key_Backspace: return "Backspace"_string; case KeyCode::Key_CapsLock: @@ -468,9 +465,7 @@ static ErrorOr get_event_code(KeyCode platform_key, unsigned modifiers) case KeyCode::Key_Menu: return "ContextMenu"_string; case KeyCode::Key_Control: - return "ControlLeft"_string; - case KeyCode::Key_RightControl: - return "ControlRight"_string; + return "Control"_string; // FIXME: Detect left vs. right key. case KeyCode::Key_Return: return "Enter"_string; case KeyCode::Key_Super: @@ -545,60 +540,7 @@ static ErrorOr get_event_code(KeyCode platform_key, unsigned modifiers) return "PrintScreen"_string; case KeyCode::Key_ScrollLock: return "ScrollLock"_string; - case KeyCode::Key_PauseBreak: - return "Pause"_string; - - // 3.6. Media Section, https://www.w3.org/TR/uievents-code/#media-keys - case KeyCode::Key_BrowserSearch: - return "BrowserSearch"_string; - case KeyCode::Key_BrowserFavorites: - return "BrowserFavorites"_string; - case KeyCode::Key_BrowserHome: - return "BrowserHome"_string; - case KeyCode::Key_PreviousTrack: - return "PreviousTrack"_string; - case KeyCode::Key_BrowserBack: - return "BrowserBack"_string; - case KeyCode::Key_BrowserForward: - return "BrowserForward"_string; - case KeyCode::Key_BrowserRefresh: - return "BrowserRefresh"_string; - case KeyCode::Key_BrowserStop: - return "BrowserStop"_string; - case KeyCode::Key_VolumeDown: - return "AudioVolumeDown"_string; - case KeyCode::Key_VolumeUp: - return "AudioVolumeUp"_string; - case KeyCode::Key_Wake: - return "WakeUp"_string; - case KeyCode::Key_Sleep: - return "Sleep"_string; - case KeyCode::Key_NextTrack: - return "NextTrack"_string; - case KeyCode::Key_MediaSelect: - return "MediaSelect"_string; - case KeyCode::Key_Email: - return "LaunchMail"_string; - - case KeyCode::Key_Power: - return "Power"_string; - case KeyCode::Key_Stop: - return "MediaStop"_string; - case KeyCode::Key_PlayPause: - return "MediaPlayPause"_string; - case KeyCode::Key_Mute: - return "AudioVolumeMute"_string; - case KeyCode::Key_Calculator: - return "LaunchApp2"_string; - case KeyCode::Key_MyComputer: - return "LaunchApp1"_string; - - // FIXME: Are these correct? - case KeyCode::Key_LeftGUI: - return "LaunchApp2"_string; - case KeyCode::Key_RightGUI: - case KeyCode::Key_Apps: - return "LaunchApp1"_string; + // FIXME: Pause // 3.7. Legacy, Non-Standard and Special Keys, https://www.w3.org/TR/uievents-code/#key-legacy case KeyCode::Key_Invalid: