strat9_kernel/arch/x86_64/
keyboard_layout.rs1use core::sync::atomic::{AtomicBool, Ordering};
8use spin::Mutex;
9
10pub static AZERTY_NORMAL: [u8; 128] = {
12 let mut t = [0u8; 128];
13 t[0x01] = 0x1B;
14 t[0x02] = b'&';
15 t[0x03] = b'e';
16 t[0x04] = b'"';
17 t[0x05] = b'\'';
18 t[0x06] = b'(';
19 t[0x07] = b'-';
20 t[0x08] = b'e';
21 t[0x09] = b'_';
22 t[0x0A] = b'c';
23 t[0x0B] = b'a';
24 t[0x0C] = b')';
25 t[0x0D] = b'+';
26 t[0x0E] = 0x08;
27 t[0x0F] = b'\t';
28 t[0x10] = b'a';
29 t[0x11] = b'z';
30 t[0x12] = b'e';
31 t[0x13] = b'r';
32 t[0x14] = b't';
33 t[0x15] = b'y';
34 t[0x16] = b'u';
35 t[0x17] = b'i';
36 t[0x18] = b'o';
37 t[0x19] = b'p';
38 t[0x1A] = b'^';
39 t[0x1B] = b'$';
40 t[0x1C] = b'\n';
41 t[0x1E] = b'q';
42 t[0x1F] = b's';
43 t[0x20] = b'd';
44 t[0x21] = b'f';
45 t[0x22] = b'g';
46 t[0x23] = b'h';
47 t[0x24] = b'j';
48 t[0x25] = b'k';
49 t[0x26] = b'l';
50 t[0x27] = b'm';
51 t[0x28] = b'u';
52 t[0x29] = b'*';
53 t[0x2A] = 0x00;
54 t[0x2B] = b'<';
55 t[0x2C] = b'w';
56 t[0x2D] = b'x';
57 t[0x2E] = b'c';
58 t[0x2F] = b'v';
59 t[0x30] = b'b';
60 t[0x31] = b'n';
61 t[0x32] = b',';
62 t[0x33] = b';';
63 t[0x34] = b'.';
64 t[0x35] = b'/';
65 t[0x36] = 0x00;
66 t[0x37] = b'*';
67 t[0x38] = 0x00;
68 t[0x39] = b' ';
69 t[0x3A] = 0x00;
70 t[0x56] = b'<';
71 t[0x47] = b'7';
72 t[0x48] = b'8';
73 t[0x49] = b'9';
74 t[0x4A] = b'-';
75 t[0x4B] = b'4';
76 t[0x4C] = b'5';
77 t[0x4D] = b'6';
78 t[0x4E] = b'+';
79 t[0x4F] = b'1';
80 t[0x50] = b'2';
81 t[0x51] = b'3';
82 t[0x52] = b'0';
83 t[0x53] = b'.';
84 t
85};
86
87pub static AZERTY_SHIFT: [u8; 128] = {
89 let mut t = [0u8; 128];
90 t[0x01] = 0x1B;
91 t[0x02] = b'1';
92 t[0x03] = b'2';
93 t[0x04] = b'3';
94 t[0x05] = b'4';
95 t[0x06] = b'5';
96 t[0x07] = b'6';
97 t[0x08] = b'7';
98 t[0x09] = b'8';
99 t[0x0A] = b'9';
100 t[0x0B] = b'0';
101 t[0x0C] = b')';
102 t[0x0D] = b'+';
103 t[0x0E] = 0x08;
104 t[0x0F] = b'\t';
105 t[0x10] = b'A';
106 t[0x11] = b'Z';
107 t[0x12] = b'E';
108 t[0x13] = b'R';
109 t[0x14] = b'T';
110 t[0x15] = b'Y';
111 t[0x16] = b'U';
112 t[0x17] = b'I';
113 t[0x18] = b'O';
114 t[0x19] = b'P';
115 t[0x1A] = b'l';
116 t[0x1B] = b'*';
117 t[0x1C] = b'\n';
118 t[0x1E] = b'Q';
119 t[0x1F] = b'S';
120 t[0x20] = b'D';
121 t[0x21] = b'F';
122 t[0x22] = b'G';
123 t[0x23] = b'H';
124 t[0x24] = b'J';
125 t[0x25] = b'K';
126 t[0x26] = b'L';
127 t[0x27] = b'M';
128 t[0x28] = b'%';
129 t[0x29] = b'u';
130 t[0x2B] = b'>';
131 t[0x2C] = b'W';
132 t[0x2D] = b'X';
133 t[0x2E] = b'C';
134 t[0x2F] = b'V';
135 t[0x30] = b'B';
136 t[0x31] = b'N';
137 t[0x32] = b'?';
138 t[0x33] = b'.';
139 t[0x34] = b':';
140 t[0x35] = b'/';
141 t[0x36] = 0x00;
142 t[0x37] = b'*';
143 t[0x38] = 0x00;
144 t[0x39] = b' ';
145 t[0x3A] = 0x00;
146 t[0x56] = b'>';
147 t[0x47] = b'7';
148 t[0x48] = b'8';
149 t[0x49] = b'9';
150 t[0x4A] = b'-';
151 t[0x4B] = b'4';
152 t[0x4C] = b'5';
153 t[0x4D] = b'6';
154 t[0x4E] = b'+';
155 t[0x4F] = b'1';
156 t[0x50] = b'2';
157 t[0x51] = b'3';
158 t[0x52] = b'0';
159 t[0x53] = b'.';
160 t
161};
162
163pub static QWERTY_NORMAL: [u8; 128] = {
165 let mut t = [0u8; 128];
166 t[0x01] = 0x1B;
167 t[0x02] = b'1';
168 t[0x03] = b'2';
169 t[0x04] = b'3';
170 t[0x05] = b'4';
171 t[0x06] = b'5';
172 t[0x07] = b'6';
173 t[0x08] = b'7';
174 t[0x09] = b'8';
175 t[0x0A] = b'9';
176 t[0x0B] = b'0';
177 t[0x0C] = b'-';
178 t[0x0D] = b'=';
179 t[0x0E] = 0x08;
180 t[0x0F] = b'\t';
181 t[0x10] = b'q';
182 t[0x11] = b'w';
183 t[0x12] = b'e';
184 t[0x13] = b'r';
185 t[0x14] = b't';
186 t[0x15] = b'y';
187 t[0x16] = b'u';
188 t[0x17] = b'i';
189 t[0x18] = b'o';
190 t[0x19] = b'p';
191 t[0x1A] = b'[';
192 t[0x1B] = b']';
193 t[0x1C] = b'\n';
194 t[0x1E] = b'a';
195 t[0x1F] = b's';
196 t[0x20] = b'd';
197 t[0x21] = b'f';
198 t[0x22] = b'g';
199 t[0x23] = b'h';
200 t[0x24] = b'j';
201 t[0x25] = b'k';
202 t[0x26] = b'l';
203 t[0x27] = b';';
204 t[0x28] = b'\'';
205 t[0x29] = b'`';
206 t[0x2A] = 0x00;
207 t[0x2B] = b'\\';
208 t[0x2C] = b'z';
209 t[0x2D] = b'x';
210 t[0x2E] = b'c';
211 t[0x2F] = b'v';
212 t[0x30] = b'b';
213 t[0x31] = b'n';
214 t[0x32] = b'm';
215 t[0x33] = b',';
216 t[0x34] = b'.';
217 t[0x35] = b'/';
218 t[0x36] = 0x00;
219 t[0x37] = b'*';
220 t[0x38] = 0x00;
221 t[0x39] = b' ';
222 t[0x3A] = 0x00;
223 t[0x47] = b'7';
224 t[0x48] = b'8';
225 t[0x49] = b'9';
226 t[0x4A] = b'-';
227 t[0x4B] = b'4';
228 t[0x4C] = b'5';
229 t[0x4D] = b'6';
230 t[0x4E] = b'+';
231 t[0x4F] = b'1';
232 t[0x50] = b'2';
233 t[0x51] = b'3';
234 t[0x52] = b'0';
235 t[0x53] = b'.';
236 t
237};
238
239pub static QWERTY_SHIFT: [u8; 128] = {
241 let mut t = [0u8; 128];
242 t[0x01] = 0x1B;
243 t[0x02] = b'!';
244 t[0x03] = b'@';
245 t[0x04] = b'#';
246 t[0x05] = b'$';
247 t[0x06] = b'%';
248 t[0x07] = b'^';
249 t[0x08] = b'&';
250 t[0x09] = b'*';
251 t[0x0A] = b'(';
252 t[0x0B] = b')';
253 t[0x0C] = b'_';
254 t[0x0D] = b'+';
255 t[0x0E] = 0x08;
256 t[0x0F] = b'\t';
257 t[0x10] = b'Q';
258 t[0x11] = b'W';
259 t[0x12] = b'E';
260 t[0x13] = b'R';
261 t[0x14] = b'T';
262 t[0x15] = b'Y';
263 t[0x16] = b'U';
264 t[0x17] = b'I';
265 t[0x18] = b'O';
266 t[0x19] = b'P';
267 t[0x1A] = b'{';
268 t[0x1B] = b'}';
269 t[0x1C] = b'\n';
270 t[0x1E] = b'A';
271 t[0x1F] = b'S';
272 t[0x20] = b'D';
273 t[0x21] = b'F';
274 t[0x22] = b'G';
275 t[0x23] = b'H';
276 t[0x24] = b'J';
277 t[0x25] = b'K';
278 t[0x26] = b'L';
279 t[0x27] = b':';
280 t[0x28] = b'"';
281 t[0x29] = b'~';
282 t[0x2B] = b'|';
283 t[0x2C] = b'Z';
284 t[0x2D] = b'X';
285 t[0x2E] = b'C';
286 t[0x2F] = b'V';
287 t[0x30] = b'B';
288 t[0x31] = b'N';
289 t[0x32] = b'M';
290 t[0x33] = b'<';
291 t[0x34] = b'>';
292 t[0x35] = b'?';
293 t[0x36] = 0x00;
294 t[0x37] = b'*';
295 t[0x38] = 0x00;
296 t[0x39] = b' ';
297 t[0x3A] = 0x00;
298 t[0x47] = b'7';
299 t[0x48] = b'8';
300 t[0x49] = b'9';
301 t[0x4A] = b'-';
302 t[0x4B] = b'4';
303 t[0x4C] = b'5';
304 t[0x4D] = b'6';
305 t[0x4E] = b'+';
306 t[0x4F] = b'1';
307 t[0x50] = b'2';
308 t[0x51] = b'3';
309 t[0x52] = b'0';
310 t[0x53] = b'.';
311 t
312};
313
314static USE_FRENCH_LAYOUT: AtomicBool = AtomicBool::new(true);
317
318pub fn set_french_layout() {
320 USE_FRENCH_LAYOUT.store(true, Ordering::Relaxed);
321}
322
323pub fn set_us_layout() {
325 USE_FRENCH_LAYOUT.store(false, Ordering::Relaxed);
326}
327
328pub fn is_french_layout() -> bool {
330 USE_FRENCH_LAYOUT.load(Ordering::Relaxed)
331}
332
333pub struct KeyboardState {
335 pub left_shift: bool,
336 pub right_shift: bool,
337 pub caps_lock: bool,
338 pub ctrl: bool,
339 pub alt: bool,
340 pub extended_scancode: bool,
341}
342
343impl KeyboardState {
344 pub const fn new() -> Self {
345 Self {
346 left_shift: false,
347 right_shift: false,
348 caps_lock: false,
349 ctrl: false,
350 alt: false,
351 extended_scancode: false,
352 }
353 }
354
355 pub fn shift_active(&self) -> bool {
356 self.left_shift || self.right_shift
357 }
358}
359
360pub static KEYBOARD: Mutex<KeyboardState> = Mutex::new(KeyboardState::new());
362
363pub const KEY_UP: u8 = 0x80;
365pub const KEY_DOWN: u8 = 0x81;
366pub const KEY_LEFT: u8 = 0x82;
367pub const KEY_RIGHT: u8 = 0x83;
368pub const KEY_HOME: u8 = 0x84;
369pub const KEY_END: u8 = 0x85;
370
371pub fn process_scancode(scancode: u8, normal: &[u8; 128], shift: &[u8; 128]) -> Option<u8> {
377 let mut kbd = KEYBOARD.lock();
378
379 if scancode == 0xE0 {
381 kbd.extended_scancode = true;
382 return None;
383 }
384
385 let is_extended = kbd.extended_scancode;
386 kbd.extended_scancode = false;
387
388 if scancode & 0x80 != 0 {
390 match scancode & 0x7F {
391 0x2A => kbd.left_shift = false,
392 0x36 => kbd.right_shift = false,
393 0x1D => kbd.ctrl = false,
394 0x38 => kbd.alt = false,
395 _ => {}
396 }
397 return None;
398 }
399
400 match scancode {
402 0x2A => {
403 kbd.left_shift = true;
404 return None;
405 }
406 0x36 => {
407 kbd.right_shift = true;
408 return None;
409 }
410 0x1D => {
411 kbd.ctrl = true;
412 return None;
413 }
414 0x38 => {
415 kbd.alt = true;
416 return None;
417 }
418 0x3A => {
419 kbd.caps_lock = !kbd.caps_lock;
420 return None;
421 }
422 _ => {}
423 }
424
425 if is_extended {
427 return match scancode {
428 0x48 => Some(KEY_UP),
429 0x50 => Some(KEY_DOWN),
430 0x4B => Some(KEY_LEFT),
431 0x4D => Some(KEY_RIGHT),
432 0x47 => Some(KEY_HOME),
433 0x4F => Some(KEY_END),
434 0x53 => Some(b'\x7F'),
435 _ => None,
436 };
437 }
438
439 if scancode < 128 {
441 let shift_active = kbd.shift_active();
442 let ch = if shift_active {
443 shift[scancode as usize]
444 } else {
445 normal[scancode as usize]
446 };
447
448 if kbd.caps_lock && ch.is_ascii_alphabetic() {
449 let ch = if shift_active {
450 ch.to_ascii_lowercase()
451 } else {
452 ch.to_ascii_uppercase()
453 };
454 if ch != 0 {
455 return Some(ch);
456 }
457 }
458
459 if ch != 0 {
460 return Some(ch);
461 }
462 }
463
464 None
465}
466
467pub fn handle_scancode() -> Option<u8> {
469 let scancode = unsafe { super::io::inb(super::keyboard::KEYBOARD_DATA_PORT) };
470 handle_scancode_raw(scancode)
471}
472
473pub fn handle_scancode_raw(scancode: u8) -> Option<u8> {
475 if is_french_layout() {
476 process_scancode(scancode, &AZERTY_NORMAL, &AZERTY_SHIFT)
477 } else {
478 process_scancode(scancode, &QWERTY_NORMAL, &QWERTY_SHIFT)
479 }
480}