Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
keyboard.cpp
Go to the documentation of this file.
1#include "input.h"
3#include <str.h>
4#include <usb-hid/keyboard.hpp>
5#include <vfs/cache.h>
6#include <vfs/dentry.h>
7
8static HIDKeyboard* instance = 0;
9
11
13
15 dev_ = dev;
16
17 // setup usb interrupt pipe
19
20 auto desc = (struct USBInterruptPipeDesc){
21 .dev_addr = dev_->addr,
22 .endpoint = (uint8_t)(dev_->endpoints[0].address & 0xF),
23 .speed = 2, // high speed
24 .interval_ms = dev_->endpoints[0].interval,
25 .buffer_size = 256,
26 };
27 pipe->open(desc, HIDKeyboard::fireHandler);
28}
29
30#pragma clang diagnostic push
31#pragma clang diagnostic ignored "-Wc99-designator"
32// In a fully symbolic mode, we just map HID Usage ID to the enum value.
33// We don't really need the [2] for shift here if we want the kernel to handle
34// the shift state, but to keep your "table" request, we'll map both to the same KEY_ enum.
35static const uint16_t hid_keymap[256] = {
36 [0x04] = KEY_A, [0x05] = KEY_B, [0x06] = KEY_C, [0x07] = KEY_D,
37 [0x08] = KEY_E, [0x09] = KEY_F, [0x0A] = KEY_G, [0x0B] = KEY_H,
38 [0x0C] = KEY_I, [0x0D] = KEY_J, [0x0E] = KEY_K, [0x0F] = KEY_L,
39 [0x10] = KEY_M, [0x11] = KEY_N, [0x12] = KEY_O, [0x13] = KEY_P,
40 [0x14] = KEY_Q, [0x15] = KEY_R, [0x16] = KEY_S, [0x17] = KEY_T,
41 [0x18] = KEY_U, [0x19] = KEY_V, [0x1A] = KEY_W, [0x1B] = KEY_X,
42 [0x1C] = KEY_Y, [0x1D] = KEY_Z,
43
44 [0x1E] = KEY_1, [0x1F] = KEY_2, [0x20] = KEY_3, [0x21] = KEY_4,
45 [0x22] = KEY_5, [0x23] = KEY_6, [0x24] = KEY_7, [0x25] = KEY_8,
46 [0x26] = KEY_9, [0x27] = KEY_0,
47
48 [0x28] = KEY_ENTER,
49 [0x29] = KEY_ESC,
50 [0x2A] = KEY_BACKSPACE,
51 [0x2B] = KEY_TAB,
52 [0x2C] = KEY_SPACE,
53
54 [0x2D] = KEY_MINUS, [0x2E] = KEY_EQUAL, [0x2F] = KEY_LEFTBRACE,
55 [0x30] = KEY_RIGHTBRACE, [0x31] = KEY_BACKSLASH, [0x32] = KEY_HASHTILDE,
56 [0x33] = KEY_SEMICOLON, [0x34] = KEY_APOSTROPHE, [0x35] = KEY_GRAVE,
57 [0x36] = KEY_COMMA, [0x37] = KEY_DOT, [0x38] = KEY_SLASH,
58 [0x39] = KEY_CAPS_LOCK,
59
60 // Function Keys
61 [0x3A] = KEY_F1, [0x3B] = KEY_F2, [0x3C] = KEY_F3, [0x3D] = KEY_F4,
62 [0x3E] = KEY_F5, [0x3F] = KEY_F6, [0x40] = KEY_F7, [0x41] = KEY_F8,
63 [0x42] = KEY_F9, [0x43] = KEY_F10, [0x44] = KEY_F11, [0x45] = KEY_F12,
64
65 // Navigation & Control
66 [0x46] = KEY_PRINT_SCREEN, [0x47] = KEY_SCROLL_LOCK, [0x48] = KEY_PAUSE,
67 [0x49] = KEY_INSERT, [0x4A] = KEY_HOME, [0x4B] = KEY_PAGE_UP,
68 [0x4C] = KEY_DELETE, [0x4D] = KEY_END, [0x4E] = KEY_PAGE_DOWN,
69 [0x4F] = KEY_RIGHT, [0x50] = KEY_LEFT, [0x51] = KEY_DOWN, [0x52] = KEY_UP,
70
71 // Keypad
72 [0x53] = KEY_NUM_LOCK, [0x54] = KEY_KP_DIVIDE, [0x55] = KEY_KP_MULTIPLY,
73 [0x56] = KEY_KP_MINUS, [0x57] = KEY_KP_PLUS, [0x58] = KEY_KP_ENTER,
74 [0x59] = KEY_KP_1, [0x5A] = KEY_KP_2, [0x5B] = KEY_KP_3, [0x5C] = KEY_KP_4,
75 [0x5D] = KEY_KP_5, [0x5E] = KEY_KP_6, [0x5F] = KEY_KP_7, [0x60] = KEY_KP_8,
76 [0x61] = KEY_KP_9, [0x62] = KEY_KP_0, [0x63] = KEY_KP_DOT,
77
78 // International & Extra Keys (ThinkPad L14 specific / Regional)
79 [0x87] = KEY_RO, // Key between / and RShift
80 [0x88] = KEY_KATAKANAHIRAGANA,
81 [0x89] = KEY_YEN, // Key near Backspace (International 3)
82 [0x8A] = KEY_HENKAN,
83 [0x8B] = KEY_MUHENKAN,
84 [0x8C] = KEY_KPJPCOMMA,
85
86 // Media Keys (Sometimes reported in Keyboard page)
87 [0x7F] = KEY_MUTE,
88 [0x80] = KEY_VOLUMEUP,
89 [0x81] = KEY_VOLUMEDOWN,
90
91 // Fn Key (Vendor specific or some laptops report 0xFF)
92 [0xFF] = KEY_FN,
93};
94#pragma clang diagnostic pop
95
97 if (len < 8)
98 return;
99
100 uint8_t modifier = data[0];
101 static uint8_t last_modifier = 0;
102
103 // Handle Modifiers (Check for bit changes)
104 uint16_t mod_keys[] = {
107 };
108
109 for (int i = 0; i < 8; i++) {
110 bool current = (modifier >> i) & 1;
111 bool last = (last_modifier >> i) & 1;
112 if (current != last) {
113 input_report_key(&instance->dev_->controller->service,
114 mod_keys[i], current ? 1 : 0);
115 }
116 }
117 last_modifier = modifier;
118
119 // Tracking previous keys to detect new presses (simplified)
120 static uint8_t prev_keys[6] = {0};
121 uint8_t current_keys[6];
122 for (int i = 0; i < 6; i++)
123 current_keys[i] = data[i + 2];
124
125 for (int i = 0; i < 6; i++) {
126 uint8_t key = current_keys[i];
127 if (key == 0)
128 continue;
129
130 // Check if it's a new press
131 bool is_new = true;
132 for (int j = 0; j < 6; j++) {
133 if (key == prev_keys[j]) {
134 is_new = false;
135 break;
136 }
137 }
138
139 if (is_new) {
140 uint16_t code = hid_keymap[key];
141 if (code != KEY_NONE) {
142 input_report_key(&instance->dev_->controller->service,
143 code, 1);
144 // Immediately report release for simplicity in
145 // this stub
146 input_report_key(&instance->dev_->controller->service,
147 code, 0);
148 }
149 }
150 }
151
152 for (int i = 0; i < 6; i++)
153 prev_keys[i] = current_keys[i];
154}
155
156void HIDKeyboard::fireHandler(const uint8_t* data, size_t len) {
157 if (!instance) {
158 return;
159 }
160
161 (void)data;
162 (void)len;
163
164 // parse report
165 instance->parse_report(data, len);
166}
static AHCIModule instance
Definition init.cpp:5
ioforge_usb_device * dev_
Definition keyboard.hpp:16
void load(ioforge_usb_device *dev)
Definition keyboard.cpp:17
void init_vfs()
Definition keyboard.cpp:12
void parse_report(const uint8_t *data, size_t len)
Definition keyboard.cpp:96
static void fireHandler(const uint8_t *data, size_t len)
Definition keyboard.cpp:81
struct fs_data data
Definition filesystem.h:1
void input_report_key(struct ioforge_device *dev, uint16_t code, int value)
Definition input.c:16
@ KEY_KP_0
Definition input.h:129
@ KEY_F4
Definition input.h:88
@ KEY_SPACE
Definition input.h:58
@ KEY_YEN
Definition input.h:140
@ KEY_UP
Definition input.h:111
@ KEY_P
Definition input.h:29
@ KEY_M
Definition input.h:26
@ KEY_B
Definition input.h:15
@ KEY_RO
Definition input.h:137
@ KEY_F9
Definition input.h:93
@ KEY_2
Definition input.h:43
@ KEY_F6
Definition input.h:90
@ KEY_INSERT
Definition input.h:102
@ KEY_KP_5
Definition input.h:124
@ KEY_KP_DIVIDE
Definition input.h:115
@ KEY_SEMICOLON
Definition input.h:67
@ KEY_ENTER
Definition input.h:54
@ KEY_E
Definition input.h:18
@ KEY_KP_7
Definition input.h:126
@ KEY_I
Definition input.h:22
@ KEY_W
Definition input.h:36
@ KEY_D
Definition input.h:17
@ KEY_6
Definition input.h:47
@ KEY_F7
Definition input.h:91
@ KEY_SCROLL_LOCK
Definition input.h:100
@ KEY_1
Definition input.h:42
@ KEY_GRAVE
Definition input.h:69
@ RIGHT_ALT
Definition input.h:81
@ KEY_F10
Definition input.h:94
@ KEY_F
Definition input.h:19
@ KEY_PRINT_SCREEN
Definition input.h:99
@ KEY_VOLUMEDOWN
Definition input.h:152
@ KEY_H
Definition input.h:21
@ KEY_X
Definition input.h:37
@ KEY_KP_4
Definition input.h:123
@ KEY_G
Definition input.h:20
@ KEY_SLASH
Definition input.h:72
@ KEY_KP_1
Definition input.h:120
@ KEY_Y
Definition input.h:38
@ KEY_MINUS
Definition input.h:61
@ KEY_9
Definition input.h:50
@ KEY_TAB
Definition input.h:57
@ KEY_LEFT
Definition input.h:109
@ KEY_T
Definition input.h:33
@ KEY_RIGHT
Definition input.h:108
@ KEY_F5
Definition input.h:89
@ KEY_K
Definition input.h:24
@ KEY_0
Definition input.h:51
@ KEY_FN
Definition input.h:134
@ KEY_HASHTILDE
Definition input.h:66
@ KEY_KP_ENTER
Definition input.h:119
@ KEY_KATAKANAHIRAGANA
Definition input.h:139
@ KEY_F12
Definition input.h:96
@ KEY_KP_9
Definition input.h:128
@ KEY_F2
Definition input.h:86
@ KEY_KP_3
Definition input.h:122
@ KEY_NONE
Definition input.h:11
@ LEFT_ALT
Definition input.h:77
@ KEY_F3
Definition input.h:87
@ KEY_KP_PLUS
Definition input.h:118
@ KEY_KP_MINUS
Definition input.h:117
@ KEY_C
Definition input.h:16
@ RIGHT_CTRL
Definition input.h:79
@ KEY_F8
Definition input.h:92
@ LEFT_GUI
Definition input.h:78
@ KEY_BACKSPACE
Definition input.h:56
@ KEY_R
Definition input.h:31
@ KEY_N
Definition input.h:27
@ LEFT_SHIFT
Definition input.h:76
@ LEFT_CTRL
Definition input.h:75
@ KEY_A
Definition input.h:14
@ KEY_END
Definition input.h:106
@ KEY_DOWN
Definition input.h:110
@ KEY_8
Definition input.h:49
@ KEY_LEFTBRACE
Definition input.h:63
@ KEY_Z
Definition input.h:39
@ KEY_MUTE
Definition input.h:150
@ KEY_DOT
Definition input.h:71
@ KEY_KP_DOT
Definition input.h:130
@ KEY_S
Definition input.h:32
@ KEY_J
Definition input.h:23
@ KEY_CAPS_LOCK
Definition input.h:133
@ KEY_Q
Definition input.h:30
@ KEY_HENKAN
Definition input.h:141
@ KEY_KP_MULTIPLY
Definition input.h:116
@ KEY_EQUAL
Definition input.h:62
@ KEY_VOLUMEUP
Definition input.h:151
@ KEY_PAUSE
Definition input.h:101
@ KEY_PAGE_UP
Definition input.h:104
@ KEY_U
Definition input.h:34
@ KEY_F11
Definition input.h:95
@ KEY_HOME
Definition input.h:103
@ KEY_KP_6
Definition input.h:125
@ KEY_NUM_LOCK
Definition input.h:114
@ RIGHT_SHIFT
Definition input.h:80
@ KEY_PAGE_DOWN
Definition input.h:107
@ KEY_KPJPCOMMA
Definition input.h:143
@ KEY_MUHENKAN
Definition input.h:142
@ KEY_KP_8
Definition input.h:127
@ KEY_ESC
Definition input.h:55
@ KEY_7
Definition input.h:48
@ KEY_DELETE
Definition input.h:105
@ KEY_O
Definition input.h:28
@ KEY_RIGHTBRACE
Definition input.h:64
@ KEY_4
Definition input.h:45
@ KEY_APOSTROPHE
Definition input.h:68
@ KEY_L
Definition input.h:25
@ KEY_5
Definition input.h:46
@ KEY_3
Definition input.h:44
@ RIGHT_GUI
Definition input.h:82
@ KEY_BACKSLASH
Definition input.h:65
@ KEY_COMMA
Definition input.h:70
@ KEY_V
Definition input.h:35
@ KEY_KP_2
Definition input.h:121
@ KEY_F1
Definition input.h:85
uint8_t code
Definition icmp.h:1
static const uint16_t hid_keymap[256]
Definition keyboard.cpp:35
size_t len
Definition oct2bin.h:7
unsigned short uint16_t
Definition type.h:13
unsigned char uint8_t
Definition type.h:7