xref: /DragonOS/kernel/src/libs/keyboard_parser.rs (revision 338f6903262c5031abad3c8e361813355a27fcdb)
1 use core::sync::atomic::Ordering;
2 
3 use alloc::sync::Arc;
4 
5 use crate::driver::tty::{
6     tty_port::{TtyPort, TTY_PORTS},
7     virtual_terminal::virtual_console::CURRENT_VCNUM,
8 };
9 
10 #[allow(dead_code)]
11 pub const NUM_SCAN_CODES: u8 = 0x80;
12 #[allow(dead_code)]
13 pub const TYPE1_KEYCODE_MAP_TABLE_COLS: u8 = 2;
14 
15 #[allow(dead_code)]
16 pub const TYPE1_KEYCODE_FLAG_BREAK: u8 = 0x80; // 用于判断按键是否被按下
17 
18 /// 标志状态
19 #[repr(u8)]
20 #[derive(Debug, PartialEq, Eq)]
21 #[allow(dead_code)]
22 pub enum KeyFlag {
23     NoneFlag = 0 as u8,
24     PauseBreak = 1 as u8,
25     PrintScreenPress = 2 as u8,
26     PrintScreenRelease = 4 as u8,
27     OtherKey = 8 as u8, // 除了上面两个按键以外的功能按键(不包括下面的第三类按键)
28 }
29 
30 /// @brief A FSM to parse type one keyboard scan code
31 #[derive(Debug)]
32 #[allow(dead_code)]
33 pub struct TypeOneFSM {
34     status: ScanCodeStatus,
35     current_state: TypeOneFSMState,
36 }
37 
38 impl TypeOneFSM {
39     #[allow(dead_code)]
40     pub fn new() -> Self {
41         Self {
42             status: ScanCodeStatus::new(),
43             current_state: TypeOneFSMState::Start,
44         }
45     }
46 
47     /// @brief 解析扫描码
48     #[allow(dead_code)]
49     pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState {
50         self.current_state = self.current_state.parse(scancode, &mut self.status);
51         self.current_state
52     }
53 }
54 
55 /// @brief 第一类扫描码状态机的状态
56 #[derive(Debug, Copy, Clone)]
57 pub enum TypeOneFSMState {
58     /// 起始状态
59     Start,
60     /// PauseBreak 第n个扫描码
61     PauseBreak(u8),
62     /// 多扫描码功能键起始状态
63     Func0,
64     /// 第三类扫描码或字符
65     Type3,
66 
67     PrtscPress(u8),
68     PrtscRelease(u8),
69 }
70 
71 impl TypeOneFSMState {
72     /// @brief 状态机总控程序
73     fn parse(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
74         // kdebug!("the code is {:#x}\n", scancode);
75         match self {
76             TypeOneFSMState::Start => {
77                 return self.handle_start(scancode, scancode_status);
78             }
79             TypeOneFSMState::PauseBreak(n) => {
80                 return self.handle_pause_break(*n, scancode_status);
81             }
82             TypeOneFSMState::Func0 => {
83                 return self.handle_func0(scancode, scancode_status);
84             }
85             TypeOneFSMState::Type3 => {
86                 return self.handle_type3(scancode, scancode_status);
87             }
88             TypeOneFSMState::PrtscPress(n) => return self.handle_prtsc_press(*n, scancode_status),
89             TypeOneFSMState::PrtscRelease(n) => {
90                 return self.handle_prtsc_release(*n, scancode_status)
91             }
92         }
93     }
94 
95     /// @brief 处理起始状态
96     fn handle_start(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
97         //kdebug!("in handle_start the code is {:#x}\n",scancode);
98         match scancode {
99             0xe1 => {
100                 return TypeOneFSMState::PauseBreak(1);
101             }
102             0xe0 => {
103                 return TypeOneFSMState::Func0;
104             }
105             _ => {
106                 //kdebug!("in _d the code is {:#x}\n",scancode);
107                 return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status);
108             }
109         }
110     }
111 
112     /// @brief 处理PauseBreak状态
113     fn handle_pause_break(
114         &self,
115         scancode: u8,
116         scancode_status: &mut ScanCodeStatus,
117     ) -> TypeOneFSMState {
118         static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5];
119         let i = match self {
120             TypeOneFSMState::PauseBreak(i) => *i,
121             _ => {
122                 return self.handle_type3(scancode, scancode_status);
123             }
124         };
125         if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] {
126             return self.handle_type3(scancode, scancode_status);
127         } else {
128             if i == 5 {
129                 // 所有Pause Break扫描码都被清除
130                 return TypeOneFSMState::Start;
131             } else {
132                 return TypeOneFSMState::PauseBreak(i + 1);
133             }
134         }
135     }
136 
137     fn handle_func0(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
138         //0xE0
139         match scancode {
140             0x2a => {
141                 return TypeOneFSMState::PrtscPress(2);
142             }
143             0xb7 => {
144                 return TypeOneFSMState::PrtscRelease(2);
145             }
146             0x1d => {
147                 // 按下右边的ctrl
148                 scancode_status.ctrl_r = true;
149             }
150             0x9d => {
151                 // 松开右边的ctrl
152                 scancode_status.ctrl_r = false;
153             }
154             0x38 => {
155                 // 按下右边的alt
156                 scancode_status.alt_r = true;
157             }
158             0xb8 => {
159                 // 松开右边的alt
160                 scancode_status.alt_r = false;
161             }
162             0x5b => {
163                 scancode_status.gui_l = true;
164             }
165             0xdb => {
166                 scancode_status.gui_l = false;
167             }
168             0x5c => {
169                 scancode_status.gui_r = true;
170             }
171             0xdc => {
172                 scancode_status.gui_r = false;
173             }
174             0x5d => {
175                 scancode_status.apps = true;
176             }
177             0xdd => {
178                 scancode_status.apps = false;
179             }
180             0x52 => {
181                 scancode_status.insert = true;
182             }
183             0xd2 => {
184                 scancode_status.insert = false;
185             }
186             0x47 => {
187                 scancode_status.home = true;
188             }
189             0xc7 => {
190                 scancode_status.home = false;
191             }
192             0x49 => {
193                 scancode_status.pgup = true;
194             }
195             0xc9 => {
196                 scancode_status.pgup = false;
197             }
198             0x53 => {
199                 scancode_status.del = true;
200                 Self::emit(127);
201             }
202             0xd3 => {
203                 scancode_status.del = false;
204             }
205             0x4f => {
206                 scancode_status.end = true;
207             }
208             0xcf => {
209                 scancode_status.end = false;
210             }
211             0x51 => {
212                 scancode_status.pgdn = true;
213             }
214             0xd1 => {
215                 scancode_status.pgdn = false;
216             }
217             0x48 => {
218                 scancode_status.arrow_u = true;
219                 Self::emit(224);
220                 Self::emit(72);
221             }
222             0xc8 => {
223                 scancode_status.arrow_u = false;
224             }
225             0x4b => {
226                 scancode_status.arrow_l = true;
227                 Self::emit(224);
228                 Self::emit(75);
229             }
230             0xcb => {
231                 scancode_status.arrow_l = false;
232             }
233             0x50 => {
234                 scancode_status.arrow_d = true;
235                 Self::emit(224);
236                 Self::emit(80);
237             }
238             0xd0 => {
239                 scancode_status.arrow_d = false;
240             }
241             0x4d => {
242                 scancode_status.arrow_r = true;
243                 Self::emit(224);
244                 Self::emit(77);
245             }
246             0xcd => {
247                 scancode_status.arrow_r = false;
248             }
249 
250             0x35 => {
251                 // 数字小键盘的 / 符号
252                 scancode_status.kp_forward_slash = true;
253 
254                 let ch = '/' as u8;
255                 Self::emit(ch);
256             }
257             0xb5 => {
258                 scancode_status.kp_forward_slash = false;
259             }
260             0x1c => {
261                 scancode_status.kp_enter = true;
262                 Self::emit('\n' as u8);
263             }
264             0x9c => {
265                 scancode_status.kp_enter = false;
266             }
267             _ => {
268                 return TypeOneFSMState::Start;
269             }
270         }
271         return TypeOneFSMState::Start;
272     }
273 
274     fn handle_type3(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
275         // 判断按键是被按下还是抬起
276         let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 {
277             false //up
278         } else {
279             true //down
280         };
281 
282         // 计算扫描码位于码表的第几行
283         let mut col: bool = false;
284         let index = scancode & 0x7f;
285 
286         //kdebug!("in type3 ch is {:#x}\n",ch);
287         let mut key = KeyFlag::OtherKey; // 可视字符
288 
289         match index {
290             0x2a => {
291                 scancode_status.shift_l = flag_make;
292                 key = KeyFlag::NoneFlag;
293             }
294             0x36 => {
295                 scancode_status.shift_r = flag_make;
296                 key = KeyFlag::NoneFlag;
297             }
298             0x1d => {
299                 scancode_status.ctrl_l = flag_make;
300                 key = KeyFlag::NoneFlag;
301             }
302             0x38 => {
303                 scancode_status.alt_r = flag_make;
304                 key = KeyFlag::NoneFlag;
305             }
306             0x3A => {
307                 if scancode_status.caps_lock {
308                     scancode_status.caps_lock = !flag_make;
309                 }
310                 //if caps_lock: true, flag_make: true => cap_lock: false
311                 else {
312                     scancode_status.caps_lock = flag_make;
313                 } //else false => cap_lock: true
314                 key = KeyFlag::NoneFlag;
315             }
316             _ => {
317                 if flag_make == false {
318                     // kdebug!("in type3 ch is {:#x}\n",ch);
319                     key = KeyFlag::NoneFlag;
320                 }
321             }
322         }
323 
324         // shift被按下
325         if scancode_status.shift_l || scancode_status.shift_r {
326             col = true;
327         }
328 
329         if scancode_status.caps_lock {
330             if index >= 0x10 && index <= 0x19 {
331                 col = !col;
332             } else if index >= 0x1e && index <= 0x26 {
333                 col = !col;
334             } else if index >= 0x2c && index <= 0x32 {
335                 col = !col;
336             }
337         }
338 
339         let mut ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize];
340         if key != KeyFlag::NoneFlag {
341             // kdebug!("EMIT: ch is '{}', keyflag is {:?}\n", ch as char, key);
342             if scancode_status.ctrl_l || scancode_status.ctrl_r {
343                 ch = Self::to_ctrl(ch);
344             }
345             Self::emit(ch);
346         }
347         return TypeOneFSMState::Start;
348     }
349 
350     #[inline]
351     fn to_ctrl(ch: u8) -> u8 {
352         return match ch as char {
353             'a'..='z' => ch - 0x40,
354             'A'..='Z' => ch - 0x40,
355             '@'..='_' => ch - 0x40,
356             _ => ch,
357         };
358     }
359 
360     #[inline(always)]
361     fn emit(ch: u8) {
362         // 发送到tty
363         let _ = Self::current_port().receive_buf(&[ch], &[], 1);
364     }
365 
366     #[inline]
367     fn current_port() -> Arc<dyn TtyPort> {
368         TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone()
369     }
370 
371     /// @brief 处理Prtsc按下事件
372     fn handle_prtsc_press(
373         &self,
374         scancode: u8,
375         scancode_status: &mut ScanCodeStatus,
376     ) -> TypeOneFSMState {
377         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
378         let i = match self {
379             TypeOneFSMState::PrtscPress(i) => *i,
380             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
381         };
382         if i > 3 {
383             // 解析错误,返回起始状态
384             return TypeOneFSMState::Start;
385         }
386         if scancode != PRTSC_SCAN_CODE[i as usize] {
387             return self.handle_type3(scancode, scancode_status);
388         } else {
389             if i == 3 {
390                 // 成功解析出PrtscPress
391                 return TypeOneFSMState::Start;
392             } else {
393                 // 继续解析
394                 return TypeOneFSMState::PrtscPress(i + 1);
395             }
396         }
397     }
398 
399     fn handle_prtsc_release(
400         &self,
401         scancode: u8,
402         scancode_status: &mut ScanCodeStatus,
403     ) -> TypeOneFSMState {
404         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
405         let i = match self {
406             TypeOneFSMState::PrtscRelease(i) => *i,
407             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
408         };
409         if i > 3 {
410             // 解析错误,返回起始状态
411             return TypeOneFSMState::Start;
412         }
413         if scancode != PRTSC_SCAN_CODE[i as usize] {
414             return self.handle_type3(scancode, scancode_status);
415         } else {
416             if i == 3 {
417                 // 成功解析出PrtscRelease
418                 return TypeOneFSMState::Start;
419             } else {
420                 // 继续解析
421                 return TypeOneFSMState::PrtscRelease(i + 1);
422             }
423         }
424     }
425 }
426 
427 /// 按键状态
428 #[derive(Debug)]
429 #[allow(dead_code)]
430 pub struct ScanCodeStatus {
431     // Shift 按键
432     shift_l: bool,
433     shift_r: bool,
434     // Ctrl 按键
435     ctrl_l: bool,
436     ctrl_r: bool,
437     // Alt 按键
438     alt_l: bool,
439     alt_r: bool,
440     //
441     gui_l: bool,
442     gui_r: bool,
443     //
444     apps: bool,
445     insert: bool,
446     // page up/down
447     pgup: bool,
448     pgdn: bool,
449     del: bool,
450     home: bool,
451     end: bool,
452     arrow_u: bool,
453     arrow_l: bool,
454     arrow_d: bool,
455     arrow_r: bool,
456     // 斜杠
457     kp_forward_slash: bool,
458     // 回车
459     kp_enter: bool,
460     caps_lock: bool,
461 }
462 
463 impl ScanCodeStatus {
464     fn new() -> Self {
465         ScanCodeStatus {
466             shift_l: false,
467             shift_r: false,
468             ctrl_l: false,
469             ctrl_r: false,
470             alt_l: false,
471             alt_r: false,
472             gui_l: false,
473             gui_r: false,
474             apps: false,
475             insert: false,
476             pgup: false,
477             pgdn: false,
478             del: false,
479             home: false,
480             end: false,
481             arrow_u: false,
482             arrow_l: false,
483             arrow_d: false,
484             arrow_r: false,
485             kp_forward_slash: false,
486             kp_enter: false,
487             caps_lock: false,
488         }
489     }
490 }
491 
492 const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [
493     /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC
494     /*0x02*/ '1' as u8, '!' as u8, /*0x03*/ '2' as u8, '@' as u8,
495     /*0x04*/ '3' as u8, '#' as u8, /*0x05*/ '4' as u8, '$' as u8,
496     /*0x06*/ '5' as u8, '%' as u8, /*0x07*/ '6' as u8, '^' as u8,
497     /*0x08*/ '7' as u8, '&' as u8, /*0x09*/ '8' as u8, '*' as u8,
498     /*0x0a*/ '9' as u8, '(' as u8, /*0x0b*/ '0' as u8, ')' as u8,
499     /*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8,
500     /*0x0e  \b */ 8 as u8, 8 as u8, // BACKSPACE
501     /*0x0f*/ '\t' as u8, '\t' as u8, // TAB
502     ////////////////////////character///////////////////////////
503     /*0x10*/ 'q' as u8,
504     'Q' as u8, /*0x11*/ 'w' as u8, 'W' as u8, /*0x12*/ 'e' as u8, 'E' as u8,
505     /*0x13*/ 'r' as u8, 'R' as u8, /*0x14*/ 't' as u8, 'T' as u8,
506     /*0x15*/ 'y' as u8, 'Y' as u8, /*0x16*/ 'u' as u8, 'U' as u8,
507     /*0x17*/ 'i' as u8, 'I' as u8, /*0x18*/ 'o' as u8, 'O' as u8,
508     /*0x19*/ 'p' as u8, 'P' as u8,
509     ////////////////////////character///////////////////////////
510 
511     /*0x1a*/ '[' as u8,
512     '{' as u8, /*0x1b*/ ']' as u8, '}' as u8, /*0x1c*/ '\n' as u8,
513     '\n' as u8, // ENTER
514     /*0x1d*/ 0x1d, 0x1d, // CTRL Left
515     ////////////////////////character///////////////////////////
516     /*0x1e*/ 'a' as u8,
517     'A' as u8, /*0x1f*/ 's' as u8, 'S' as u8, /*0x20*/ 'd' as u8, 'D' as u8,
518     /*0x21*/ 'f' as u8, 'F' as u8, /*0x22*/ 'g' as u8, 'G' as u8,
519     /*0x23*/ 'h' as u8, 'H' as u8, /*0x24*/ 'j' as u8, 'J' as u8,
520     /*0x25*/ 'k' as u8, 'K' as u8, /*0x26*/ 'l' as u8, 'L' as u8,
521     ////////////////////////character///////////////////////////
522 
523     /*0x27*/ ';' as u8,
524     ':' as u8, /*0x28*/ '\'' as u8, '"' as u8, /*0x29*/ '`' as u8, '~' as u8,
525     /*0x2a*/ 0x2a, 0x2a, // SHIFT Left
526     /*0x2b*/ '\\' as u8, '|' as u8,
527     ////////////////////////character///////////////////////////
528     /*0x2c*/ 'z' as u8,
529     'Z' as u8, /*0x2d*/ 'x' as u8, 'X' as u8, /*0x2e*/ 'c' as u8, 'C' as u8,
530     /*0x2f*/ 'v' as u8, 'V' as u8, /*0x30*/ 'b' as u8, 'B' as u8,
531     /*0x31*/ 'n' as u8, 'N' as u8, /*0x32*/ 'm' as u8, 'M' as u8,
532     ////////////////////////character///////////////////////////
533 
534     /*0x33*/ ',' as u8,
535     '<' as u8, /*0x34*/ '.' as u8, '>' as u8, /*0x35*/ '/' as u8, '?' as u8,
536     /*0x36*/ 0x36, 0x36, // SHIFT Right
537     /*0x37*/ '*' as u8, '*' as u8, /*0x38*/ 0x38, 0x38, // ALT Left
538     /*0x39*/ ' ' as u8, ' ' as u8, /*0x3a*/ 0, 0, // CAPS LOCK
539     /*0x3b*/ 0, 0, // F1
540     /*0x3c*/ 0, 0, // F2
541     /*0x3d*/ 0, 0, // F3
542     /*0x3e*/ 0, 0, // F4
543     /*0x3f*/ 0, 0, // F5
544     /*0x40*/ 0, 0, // F6
545     /*0x41*/ 0, 0, // F7
546     /*0x42*/ 0, 0, // F8
547     /*0x43*/ 0, 0, // F9
548     /*0x44*/ 0, 0, // F10
549     /*0x45*/ 0, 0, // NUM LOCK
550     /*0x46*/ 0, 0, // SCROLL LOCK
551     /*0x47*/ '7' as u8, 0, /*PAD HONE*/
552     /*0x48*/ '8' as u8, 0, /*PAD UP*/
553     /*0x49*/ '9' as u8, 0, /*PAD PAGEUP*/
554     /*0x4a*/ '-' as u8, 0, /*PAD MINUS*/
555     /*0x4b*/ '4' as u8, 0, /*PAD LEFT*/
556     /*0x4c*/ '5' as u8, 0, /*PAD MID*/
557     /*0x4d*/ '6' as u8, 0, /*PAD RIGHT*/
558     /*0x4e*/ '+' as u8, 0, /*PAD PLUS*/
559     /*0x4f*/ '1' as u8, 0, /*PAD END*/
560     /*0x50*/ '2' as u8, 0, /*PAD DOWN*/
561     /*0x51*/ '3' as u8, 0, /*PAD PAGEDOWN*/
562     /*0x52*/ '0' as u8, 0, /*PAD INS*/
563     /*0x53*/ '.' as u8, 0, /*PAD DOT*/
564     /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11
565     /*0x58*/ 0, 0, // F12
566     /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0,
567     /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0,
568     /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0,
569     /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0,
570     /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0,
571     /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0,
572     /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0,
573     /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0,
574     /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0,
575     /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0,
576 ];
577