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