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