2020-01-18 05:38:21 -03:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
* Copyright (c) 2021-2023, Liav A. <liavalb@hotmail.co.il>
|
2021-07-05 16:14:38 -03:00
|
|
|
* Copyright (c) 2021, Edwin Hoksberg <mail@edwinhoksberg.nl>
|
2020-01-18 05:38:21 -03:00
|
|
|
*
|
2021-04-22 05:24:48 -03:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 05:38:21 -03:00
|
|
|
*/
|
|
|
|
|
|
2019-06-07 06:43:58 -03:00
|
|
|
#include <AK/Assertions.h>
|
|
|
|
|
#include <AK/Types.h>
|
2023-01-07 17:52:06 -03:00
|
|
|
#include <Kernel/API/Ioctl.h>
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
#include <Kernel/API/KeyCode.h>
|
|
|
|
|
#include <Kernel/Devices/DeviceManagement.h>
|
2021-04-02 17:21:35 -03:00
|
|
|
#include <Kernel/Devices/HID/KeyboardDevice.h>
|
2023-07-08 08:18:32 -03:00
|
|
|
#include <Kernel/Devices/TTY/ConsoleManagement.h>
|
|
|
|
|
#include <Kernel/Devices/TTY/VirtualConsole.h>
|
2021-06-22 12:40:16 -03:00
|
|
|
#include <Kernel/Sections.h>
|
2023-02-24 14:45:37 -03:00
|
|
|
#include <Kernel/Tasks/Scheduler.h>
|
|
|
|
|
#include <Kernel/Tasks/WorkQueue.h>
|
2018-10-16 06:01:38 -03:00
|
|
|
|
2020-02-15 21:27:42 -03:00
|
|
|
namespace Kernel {
|
|
|
|
|
|
2021-05-19 11:35:09 -03:00
|
|
|
static constexpr KeyCode unshifted_key_map[0x80] = {
|
2019-06-07 06:43:58 -03:00
|
|
|
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,
|
2021-05-19 11:35:09 -03:00
|
|
|
Key_Tab, // 15
|
2019-06-07 06:43:58 -03:00
|
|
|
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
|
2019-01-21 04:05:31 -02:00
|
|
|
Key_Control, // 29
|
2019-06-07 06:43:58 -03:00
|
|
|
Key_A,
|
|
|
|
|
Key_S,
|
|
|
|
|
Key_D,
|
|
|
|
|
Key_F,
|
|
|
|
|
Key_G,
|
|
|
|
|
Key_H,
|
|
|
|
|
Key_J,
|
|
|
|
|
Key_K,
|
|
|
|
|
Key_L,
|
|
|
|
|
Key_Semicolon,
|
|
|
|
|
Key_Apostrophe,
|
|
|
|
|
Key_Backtick,
|
2019-04-23 15:47:45 -03:00
|
|
|
Key_LeftShift, // 42
|
2019-01-21 04:05:31 -02:00
|
|
|
Key_Backslash,
|
2019-06-07 06:43:58 -03:00
|
|
|
Key_Z,
|
|
|
|
|
Key_X,
|
|
|
|
|
Key_C,
|
|
|
|
|
Key_V,
|
|
|
|
|
Key_B,
|
|
|
|
|
Key_N,
|
|
|
|
|
Key_M,
|
|
|
|
|
Key_Comma,
|
|
|
|
|
Key_Period,
|
|
|
|
|
Key_Slash,
|
2019-04-23 15:47:45 -03:00
|
|
|
Key_RightShift, // 54
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_Asterisk,
|
2020-01-22 07:49:49 -03:00
|
|
|
Key_Alt, // 56
|
|
|
|
|
Key_Space, // 57
|
2019-10-13 16:49:11 -03:00
|
|
|
Key_CapsLock, // 58
|
2019-06-07 06:43:58 -03:00
|
|
|
Key_F1,
|
|
|
|
|
Key_F2,
|
|
|
|
|
Key_F3,
|
|
|
|
|
Key_F4,
|
|
|
|
|
Key_F5,
|
|
|
|
|
Key_F6,
|
|
|
|
|
Key_F7,
|
|
|
|
|
Key_F8,
|
|
|
|
|
Key_F9,
|
|
|
|
|
Key_F10,
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_NumLock,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Invalid, // 70
|
2019-03-07 09:19:05 -03:00
|
|
|
Key_Home,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Up,
|
2019-03-02 19:58:09 -03:00
|
|
|
Key_PageUp,
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_Minus,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Left,
|
|
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Right, // 77
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_Plus,
|
2019-03-07 09:19:05 -03:00
|
|
|
Key_End,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Down, // 80
|
2019-03-02 19:58:09 -03:00
|
|
|
Key_PageDown,
|
2022-07-24 16:09:16 -03:00
|
|
|
Key_Insert,
|
2019-03-07 12:20:00 -03:00
|
|
|
Key_Delete, // 83
|
2019-03-02 22:52:22 -03:00
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Invalid,
|
2019-08-10 09:29:32 -03:00
|
|
|
Key_Backslash,
|
2019-03-02 22:52:22 -03:00
|
|
|
Key_F11,
|
|
|
|
|
Key_F12,
|
2019-03-03 08:56:48 -03:00
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Invalid,
|
2021-03-11 14:50:23 -03:00
|
|
|
Key_Super,
|
2021-02-13 11:22:35 -03:00
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Menu,
|
2019-01-21 04:05:31 -02:00
|
|
|
};
|
|
|
|
|
|
2021-05-19 11:35:09 -03:00
|
|
|
static constexpr KeyCode shifted_key_map[0x100] = {
|
2019-06-07 06:43:58 -03:00
|
|
|
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,
|
2019-03-03 09:34:29 -03:00
|
|
|
Key_Tab,
|
2019-06-07 06:43:58 -03:00
|
|
|
Key_Q,
|
|
|
|
|
Key_W,
|
|
|
|
|
Key_E,
|
|
|
|
|
Key_R,
|
|
|
|
|
Key_T,
|
|
|
|
|
Key_Y,
|
|
|
|
|
Key_U,
|
|
|
|
|
Key_I,
|
|
|
|
|
Key_O,
|
|
|
|
|
Key_P,
|
|
|
|
|
Key_LeftBrace,
|
|
|
|
|
Key_RightBrace,
|
2019-01-21 04:05:31 -02:00
|
|
|
Key_Return,
|
|
|
|
|
Key_Control,
|
2019-06-07 06:43:58 -03:00
|
|
|
Key_A,
|
|
|
|
|
Key_S,
|
|
|
|
|
Key_D,
|
|
|
|
|
Key_F,
|
|
|
|
|
Key_G,
|
|
|
|
|
Key_H,
|
|
|
|
|
Key_J,
|
|
|
|
|
Key_K,
|
|
|
|
|
Key_L,
|
|
|
|
|
Key_Colon,
|
|
|
|
|
Key_DoubleQuote,
|
|
|
|
|
Key_Tilde,
|
2019-04-23 15:47:45 -03:00
|
|
|
Key_LeftShift, // 42
|
2019-01-21 04:05:31 -02:00
|
|
|
Key_Pipe,
|
2019-06-07 06:43:58 -03:00
|
|
|
Key_Z,
|
|
|
|
|
Key_X,
|
|
|
|
|
Key_C,
|
|
|
|
|
Key_V,
|
|
|
|
|
Key_B,
|
|
|
|
|
Key_N,
|
|
|
|
|
Key_M,
|
|
|
|
|
Key_LessThan,
|
|
|
|
|
Key_GreaterThan,
|
|
|
|
|
Key_QuestionMark,
|
2019-04-23 15:47:45 -03:00
|
|
|
Key_RightShift, // 54
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_Asterisk,
|
2019-01-21 04:05:31 -02:00
|
|
|
Key_Alt,
|
2020-01-22 07:49:49 -03:00
|
|
|
Key_Space, // 57
|
2019-10-13 16:49:11 -03:00
|
|
|
Key_CapsLock, // 58
|
2019-06-07 06:43:58 -03:00
|
|
|
Key_F1,
|
|
|
|
|
Key_F2,
|
|
|
|
|
Key_F3,
|
|
|
|
|
Key_F4,
|
|
|
|
|
Key_F5,
|
|
|
|
|
Key_F6,
|
|
|
|
|
Key_F7,
|
|
|
|
|
Key_F8,
|
|
|
|
|
Key_F9,
|
|
|
|
|
Key_F10,
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_NumLock,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Invalid, // 70
|
2019-03-07 09:19:05 -03:00
|
|
|
Key_Home,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Up,
|
2019-03-02 19:58:09 -03:00
|
|
|
Key_PageUp,
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_Minus,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Left,
|
|
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Right, // 77
|
2019-10-13 18:32:26 -03:00
|
|
|
Key_Plus,
|
2019-03-07 09:19:05 -03:00
|
|
|
Key_End,
|
2019-01-30 18:18:13 -02:00
|
|
|
Key_Down, // 80
|
2019-03-02 19:58:09 -03:00
|
|
|
Key_PageDown,
|
2022-07-24 16:09:16 -03:00
|
|
|
Key_Insert,
|
2019-03-07 12:20:00 -03:00
|
|
|
Key_Delete, // 83
|
2019-03-02 22:52:22 -03:00
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Invalid,
|
2019-08-10 09:29:32 -03:00
|
|
|
Key_Pipe,
|
2019-03-02 22:52:22 -03:00
|
|
|
Key_F11,
|
|
|
|
|
Key_F12,
|
2019-03-03 08:56:48 -03:00
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Invalid,
|
2021-03-11 14:50:23 -03:00
|
|
|
Key_Super,
|
2021-02-13 11:22:35 -03:00
|
|
|
Key_Invalid,
|
|
|
|
|
Key_Menu,
|
2019-01-21 04:05:31 -02:00
|
|
|
};
|
|
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
void KeyboardDevice::handle_scan_code_input_event(ScanCodeEvent event)
|
2019-01-21 04:05:31 -02:00
|
|
|
{
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
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;
|
2023-08-15 18:25:12 -03:00
|
|
|
case 0x1c:
|
2023-07-08 16:59:51 -03:00
|
|
|
case 0x35:
|
2023-08-15 18:22:30 -03:00
|
|
|
if (event.e0_prefix)
|
|
|
|
|
update_modifier(Mod_Keypad, event.pressed);
|
|
|
|
|
break;
|
2023-07-08 16:59:51 -03:00
|
|
|
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:
|
2023-08-15 18:22:30 -03:00
|
|
|
if (!event.e0_prefix)
|
|
|
|
|
update_modifier(Mod_Keypad, event.pressed);
|
2023-07-08 16:59:51 -03:00
|
|
|
break;
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
KeyCode key = (m_modifiers & Mod_Shift) ? shifted_key_map[event.scan_code_value] : unshifted_key_map[event.scan_code_value];
|
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-26 13:43:18 -03:00
|
|
|
if ((m_modifiers & Mod_Alt) != 0 && key >= Key_1 && key < Key_1 + ConsoleManagement::s_max_virtual_consoles) {
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
// 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);
|
|
|
|
|
}));
|
|
|
|
|
}
|
2019-10-13 16:49:11 -03:00
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
if (key == Key_NumLock && event.pressed)
|
2019-10-13 18:32:26 -03:00
|
|
|
m_num_lock_on = !m_num_lock_on;
|
|
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
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;
|
2021-05-19 11:35:09 -03:00
|
|
|
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 };
|
2019-10-13 18:32:26 -03:00
|
|
|
KeyCode newKey = numpad_key_map[index];
|
|
|
|
|
|
2020-01-22 07:49:49 -03:00
|
|
|
if (newKey != Key_Invalid) {
|
2019-10-13 18:32:26 -03:00
|
|
|
key = newKey;
|
2019-11-23 04:48:07 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-13 18:32:26 -03:00
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
Event queued_event;
|
|
|
|
|
queued_event.key = key;
|
|
|
|
|
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;
|
2023-08-19 18:49:48 -03:00
|
|
|
queued_event.code_point = HIDManagement::the().get_char_from_character_map(queued_event, m_num_lock_on);
|
2020-06-10 05:22:31 -03:00
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
// 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);
|
2021-12-21 03:46:46 -03:00
|
|
|
if (mapped_key != KeyCode::Key_Invalid) {
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
queued_event.key = mapped_key;
|
2021-12-21 03:46:46 -03:00
|
|
|
key = mapped_key;
|
|
|
|
|
}
|
|
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
if (!g_caps_lock_remapped_to_ctrl && key == Key_CapsLock && event.pressed)
|
2021-12-21 03:46:46 -03:00
|
|
|
m_caps_lock_on = !m_caps_lock_on;
|
|
|
|
|
|
2023-03-31 12:46:36 -03:00
|
|
|
if (g_caps_lock_remapped_to_ctrl && key == Key_CapsLock) {
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
m_caps_lock_to_ctrl_pressed = event.pressed;
|
2021-12-21 03:46:46 -03:00
|
|
|
update_modifier(Mod_Ctrl, m_caps_lock_to_ctrl_pressed);
|
2023-03-31 12:46:36 -03:00
|
|
|
}
|
2021-05-31 09:20:34 -03:00
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
if (event.pressed)
|
|
|
|
|
queued_event.flags |= Is_Press;
|
2022-05-06 08:49:13 -03:00
|
|
|
|
|
|
|
|
{
|
|
|
|
|
SpinlockLocker locker(HIDManagement::the().m_client_lock);
|
|
|
|
|
if (HIDManagement::the().m_client)
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
HIDManagement::the().m_client->on_key_pressed(queued_event);
|
2022-05-06 08:49:13 -03:00
|
|
|
}
|
2020-06-10 05:22:31 -03:00
|
|
|
|
2020-11-07 16:09:28 -03:00
|
|
|
{
|
2021-08-21 20:49:22 -03:00
|
|
|
SpinlockLocker lock(m_queue_lock);
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
m_queue.enqueue(queued_event);
|
2020-11-07 16:09:28 -03:00
|
|
|
}
|
2019-10-13 18:32:26 -03:00
|
|
|
|
2020-11-29 20:05:27 -03:00
|
|
|
evaluate_block_conditions();
|
2018-10-30 11:33:37 -03:00
|
|
|
}
|
2018-10-16 06:01:38 -03:00
|
|
|
|
Kernel/HID: Untie the PS2 protocol, i8042 hardware and generic devices
For a very long time, the kernel had only support for basic PS/2 devices
such as the PS2 AT keyboard and regular PS2 mouse (with a scroll wheel).
To adapt to this, we had very simple abstractions in place, essentially,
the PS2 devices were registered as IRQ handlers (IRQ 1 and 12), and when
an interrupt was triggered, we simply had to tell the I8042Controller to
fetch a byte for us, then send it back to the appropriate device for
further processing and queueing of either a key event, or a mouse packet
so userspace can do something meaningful about it.
When we added the VMWare mouse integration feature it was easily adapted
to this paradigm, requiring small changes across the handling code for
these devices.
This patch is a major cleanup for any future advancements in the HID
subsystem.
It ensures we do things in a much more sane manner:
- We stop using LockRefPtrs. Currently, after the initialization of the
i8042 controller, we never have to change RefPtrs in that class, as we
simply don't support PS2 hotplugging currently.
Also, we remove the unnecessary getters for keyboard and mouse devices
which also returned a LockRefPtr.
- There's a clear separation between PS2 devices and the actual device
nodes that normally exist in /dev. PS2 devices are not polled, because
when the user uses these devices, they will trigger an IRQ which when
is handled, could produce either a MousePacket or KeyEvent, depending
on the device state.
The separation is crucial for buses that are polled, for example - USB
is a polled bus and will not generate an IRQ for HID devices.
- There's a clear separation in roles of each structure. The PS2 devices
which are attached to a I8042Controller object are managing the device
state, while the generic MouseDevice and KeyboardDevice manage all
related tasks of a CharacterDevice, as well as interpreting scan code
events and mouse relative/absolute coordinates.
2023-04-08 11:17:19 -03:00
|
|
|
ErrorOr<NonnullRefPtr<KeyboardDevice>> KeyboardDevice::try_to_initialize()
|
|
|
|
|
{
|
|
|
|
|
return *TRY(DeviceManagement::try_create_device<KeyboardDevice>());
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-02 17:21:35 -03:00
|
|
|
// FIXME: UNMAP_AFTER_INIT is fine for now, but for hot-pluggable devices
|
|
|
|
|
// like USB keyboards, we need to remove this
|
2021-02-19 17:29:46 -03:00
|
|
|
UNMAP_AFTER_INIT KeyboardDevice::KeyboardDevice()
|
2021-04-02 17:21:35 -03:00
|
|
|
: HIDDevice(85, HIDManagement::the().generate_minor_device_number_for_keyboard())
|
2018-10-16 06:01:38 -03:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-02 17:21:35 -03:00
|
|
|
// FIXME: UNMAP_AFTER_INIT is fine for now, but for hot-pluggable devices
|
|
|
|
|
// like USB keyboards, we need to remove this
|
2022-03-16 16:15:15 -03:00
|
|
|
UNMAP_AFTER_INIT KeyboardDevice::~KeyboardDevice() = default;
|
2018-10-16 06:01:38 -03:00
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
bool KeyboardDevice::can_read(OpenFileDescription const&, u64) const
|
2018-10-25 08:07:59 -03:00
|
|
|
{
|
2018-12-02 21:39:25 -02:00
|
|
|
return !m_queue.is_empty();
|
2018-10-25 08:07:59 -03:00
|
|
|
}
|
|
|
|
|
|
2021-11-07 20:51:39 -03:00
|
|
|
ErrorOr<size_t> KeyboardDevice::read(OpenFileDescription&, u64, UserOrKernelBuffer& buffer, size_t size)
|
2018-10-23 05:12:50 -03:00
|
|
|
{
|
2020-08-04 13:02:23 -03:00
|
|
|
size_t nread = 0;
|
2021-08-21 20:49:22 -03:00
|
|
|
SpinlockLocker lock(m_queue_lock);
|
2019-02-25 17:19:57 -03:00
|
|
|
while (nread < size) {
|
2018-12-02 21:39:25 -02:00
|
|
|
if (m_queue.is_empty())
|
2018-10-23 05:12:50 -03:00
|
|
|
break;
|
2019-01-16 14:20:58 -02:00
|
|
|
// Don't return partial data frames.
|
2021-06-16 11:44:15 -03:00
|
|
|
if (size - nread < sizeof(Event))
|
2019-01-16 14:20:58 -02:00
|
|
|
break;
|
2019-01-21 04:05:31 -02:00
|
|
|
auto event = m_queue.dequeue();
|
2020-11-07 16:09:28 -03:00
|
|
|
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
2021-11-07 20:51:39 -03:00
|
|
|
auto result = TRY(buffer.write_buffered<sizeof(Event)>(sizeof(Event), [&](Bytes bytes) {
|
2021-09-01 03:44:55 -03:00
|
|
|
memcpy(bytes.data(), &event, sizeof(Event));
|
|
|
|
|
return bytes.size();
|
2021-11-07 20:51:39 -03:00
|
|
|
}));
|
|
|
|
|
VERIFY(result == sizeof(Event));
|
2019-01-21 04:05:31 -02:00
|
|
|
nread += sizeof(Event);
|
2020-11-07 16:09:28 -03:00
|
|
|
|
|
|
|
|
lock.lock();
|
2018-10-23 05:12:50 -03:00
|
|
|
}
|
|
|
|
|
return nread;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-07 20:51:39 -03:00
|
|
|
ErrorOr<void> KeyboardDevice::ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg)
|
2021-07-05 16:14:38 -03:00
|
|
|
{
|
|
|
|
|
switch (request) {
|
|
|
|
|
case KEYBOARD_IOCTL_GET_NUM_LOCK: {
|
2021-07-26 06:47:00 -03:00
|
|
|
auto output = static_ptr_cast<bool*>(arg);
|
2021-09-05 12:38:37 -03:00
|
|
|
return copy_to_user(output, &m_num_lock_on);
|
2021-07-05 16:14:38 -03:00
|
|
|
}
|
|
|
|
|
case KEYBOARD_IOCTL_SET_NUM_LOCK: {
|
2021-07-26 06:47:00 -03:00
|
|
|
// In this case we expect the value to be a boolean and not a pointer.
|
|
|
|
|
auto num_lock_value = static_cast<u8>(arg.ptr());
|
|
|
|
|
if (num_lock_value != 0 && num_lock_value != 1)
|
2021-07-26 07:47:25 -03:00
|
|
|
return EINVAL;
|
2021-07-26 06:47:00 -03:00
|
|
|
m_num_lock_on = !!num_lock_value;
|
2021-11-07 20:51:39 -03:00
|
|
|
return {};
|
2021-07-05 16:14:38 -03:00
|
|
|
}
|
|
|
|
|
case KEYBOARD_IOCTL_GET_CAPS_LOCK: {
|
2021-07-26 06:47:00 -03:00
|
|
|
auto output = static_ptr_cast<bool*>(arg);
|
2021-09-05 12:38:37 -03:00
|
|
|
return copy_to_user(output, &m_caps_lock_on);
|
2021-07-05 16:14:38 -03:00
|
|
|
}
|
|
|
|
|
case KEYBOARD_IOCTL_SET_CAPS_LOCK: {
|
2021-07-26 06:47:00 -03:00
|
|
|
auto caps_lock_value = static_cast<u8>(arg.ptr());
|
|
|
|
|
if (caps_lock_value != 0 && caps_lock_value != 1)
|
2021-07-26 07:47:25 -03:00
|
|
|
return EINVAL;
|
2021-07-26 06:47:00 -03:00
|
|
|
m_caps_lock_on = !!caps_lock_value;
|
2021-11-07 20:51:39 -03:00
|
|
|
return {};
|
2021-07-05 16:14:38 -03:00
|
|
|
}
|
|
|
|
|
default:
|
2021-07-26 07:47:25 -03:00
|
|
|
return EINVAL;
|
2021-07-05 16:14:38 -03:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-15 21:27:42 -03:00
|
|
|
}
|