1pub const KEYBOARD_PATH: &str = "/devices/keyboard";
2
3pub mod modifier {
4 pub const SHIFT: u8 = 1 << 0;
5 pub const CTRL: u8 = 1 << 1;
6 pub const ALT: u8 = 1 << 2;
7
8 pub const CAPS_LOCK: u8 = 1 << 3;
9 pub const NUM_LOCK: u8 = 1 << 4;
10 pub const SCROLL_LOCK: u8 = 1 << 5;
11 pub const EXTENDED: u8 = 1 << 6;
12
13 pub const PRESSED: u8 = 1 << 7;
15}
16
17const US_KEYTYPE_KEYMAP: [u8; 127] = [
19 0, 27, b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'0', b'-', b'=', b'\x08', b'\t',
20 b'q', b'w', b'e', b'r', b't', b'y', b'u', b'i', b'o', b'p', b'[', b']', b'\n', 0, b'a', b's',
21 b'd', b'f', b'g', b'h', b'j', b'k', b'l', b';', b'\'', b'`', 0, b'\\', b'z', b'x', b'c', b'v',
22 b'b', b'n', b'm', b',', b'.', b'/', 0, b'*', 0, b' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
23 b'7', b'8', b'9', b'-', b'4', b'5', b'6', b'+', b'1', b'2', b'3', b'0', b'.', 0, 0, 0, 0, 0, 0,
24 0, b'\n', 0, 0, 0, 0, 0, 0, 0, 0, b'/', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25 0, 0, 0, 0, 0, 0, 0, 0,
26];
27
28const US_KEYTYPE_KEYMAP_SHIFTED: [u8; 127] = [
30 0, 27, b'!', b'@', b'#', b'$', b'%', b'^', b'&', b'*', b'(', b')', b'_', b'+', b'\x08', b'\t',
31 b'Q', b'W', b'E', b'R', b'T', b'Y', b'U', b'I', b'O', b'P', b'{', b'}', b'\n', 0, b'A', b'S',
32 b'D', b'F', b'G', b'H', b'J', b'K', b'L', b':', b'"', b'~', 0, b'|', b'Z', b'X', b'C', b'V',
33 b'B', b'N', b'M', b'<', b'>', b'?', 0, b'*', 0, b' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, b'-', 0, b'5', 0, b'+', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
36];
37
38#[repr(u8)]
39#[derive(Debug, Clone, Copy, PartialEq)]
40pub enum KeyType {
41 _None1,
43 Escape,
44 Num1,
45 Num2,
46 Num3,
47 Num4,
48 Num5,
49 Num6,
50 Num7,
51 Num8,
52 Num9,
53 Num0,
54 Minus,
55 Equals,
56 Backspace,
57 Tab,
58 Q,
59 W,
60 E,
61 R,
62 T,
63 Y,
64 U,
65 I,
66 O,
67 P,
68 LeftBracket,
69 RightBracket,
70 Enter,
71 LeftCtrl,
72 A,
73 S,
74 D,
75 F,
76 G,
77 H,
78 J,
79 K,
80 L,
81 Semicolon,
82 SingleQuote,
83 Backtick,
84 LeftShift,
85 Backslash,
86 Z,
87 X,
88 C,
89 V,
90 B,
91 N,
92 M,
93 Comma,
94 Dot,
95 Slash,
96 RightShift,
97 KeypadAsterisk,
98 LeftAlt,
99 Space,
100 CapsLock,
101 F1,
102 F2,
103 F3,
104 F4,
105 F5,
106 F6,
107 F7,
108 F8,
109 F9,
110 F10,
111 NumLock,
112 ScrollLock,
113 Keypad7,
114 Keypad8,
115 Keypad9,
116 KeypadMinus,
117 Keypad4,
118 Keypad5,
119 Keypad6,
120 KeypadPlus,
121 Keypad1,
122 Keypad2,
123 Keypad3,
124 Keypad0,
125 KeypadDot,
126 _None2,
127 _None3,
128 _None4,
129 F11,
130 F12,
131
132 MultimediaPreviousTrack,
134 MultimediaNextTrack,
135 KeypadEnter,
136 RightCtrl,
137 MultimediaMute,
138 Calculator,
139 MultimediaPlayPause,
140 MultimediaStop,
141 VolumeDown,
142 VolumeUp,
143 WWWHome,
144 KeypadSlash,
145 RightAlt,
146 Home,
147 UpArrow,
148 PageUp,
149 LeftArrow,
150 RightArrow,
151 End,
152 DownArrow,
153 PageDown,
154 Insert,
155 Delete,
156 LeftGUI,
157 RightGUI,
158 Application,
159 Power,
160 Sleep,
161 Wake,
162 WWWSearch,
163 WWWFavorites,
164 WWWRefresh,
165 WWWStop,
166 WWWForward,
167 WWWBack,
168 MyComputer,
169 Email,
170 MultimediaSelect,
171}
172
173impl KeyType {
174 pub fn virtual_key(&self, shifted: bool) -> Option<u8> {
175 let index = *self as usize;
176 let mappings = if shifted {
177 &US_KEYTYPE_KEYMAP_SHIFTED
178 } else {
179 &US_KEYTYPE_KEYMAP
180 };
181
182 assert!(index < mappings.len());
183 let value = mappings[index];
184
185 if value == 0 {
186 None
187 } else {
188 Some(value)
189 }
190 }
191}
192
193#[derive(Debug, Clone, Copy)]
194pub struct Key {
195 pub pressed: bool,
196 pub modifiers: u8,
197 pub key_type: KeyType,
198}
199
200impl Key {
201 pub const BYTES_SIZE: usize = 2;
202
203 pub unsafe fn from_bytes(bytes: [u8; Self::BYTES_SIZE]) -> Self {
207 let pressed = bytes[0] & modifier::PRESSED != 0;
208 let modifiers = bytes[0] & !modifier::PRESSED;
209 let key_type = core::mem::transmute::<u8, KeyType>(bytes[1]);
212
213 Self {
214 pressed,
215 modifiers,
216 key_type,
217 }
218 }
219
220 pub fn as_bytes(&self) -> [u8; 2] {
221 let mut bytes = [0; 2];
222 bytes[0] = (self.modifiers & !modifier::PRESSED)
223 | if self.pressed { modifier::PRESSED } else { 0 };
224 bytes[1] = self.key_type as u8;
225 bytes
226 }
227
228 pub fn virtual_char(&self) -> Option<u8> {
229 let shifted = self.modifiers & modifier::SHIFT != 0;
230 self.key_type.virtual_key(shifted)
231 }
232}