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