xref: /DragonOS/kernel/src/libs/keyboard_parser.rs (revision c635d8a9cfe25bc11779f323ef0c7d7a0f597d4a)
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             }
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         //debug!("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                     // debug!("in type3 ch is {:#x}\n",ch);
310                     key = KeyFlag::NoneFlag;
311                 }
312             }
313         }
314 
315         // shift被按下
316         let shift = scancode_status.shift_l || scancode_status.shift_r;
317         if shift {
318             col = true;
319         }
320 
321         if scancode_status.caps_lock
322             && ((0x10..=0x19).contains(&index)
323                 || (0x1e..=0x26).contains(&index)
324                 || (0x2c..=0x32).contains(&index))
325         {
326             col = !col;
327         }
328 
329         let mut ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize];
330         if key != KeyFlag::NoneFlag {
331             if scancode_status.ctrl_l || scancode_status.ctrl_r {
332                 ch = Self::to_ctrl(ch, shift);
333             }
334             Self::emit(ch);
335         }
336         return TypeOneFSMState::Start;
337     }
338 
339     #[inline]
340     fn to_ctrl(ch: u8, shift: bool) -> u8 {
341         return match ch as char {
342             'a'..='z' => ch - 0x60,
343             'A'..='Z' => {
344                 if shift {
345                     ch
346                 } else {
347                     ch - 0x40
348                 }
349             }
350             '@'..='_' => ch - 0x40,
351             _ => ch,
352         };
353     }
354 
355     #[inline(always)]
356     fn emit(ch: u8) {
357         // 发送到tty
358         send_to_tty_refresh_thread(&[ch]);
359     }
360 
361     /// @brief 处理Prtsc按下事件
362     fn handle_prtsc_press(
363         &self,
364         scancode: u8,
365         scancode_status: &mut ScanCodeStatus,
366     ) -> TypeOneFSMState {
367         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
368         let i = match self {
369             TypeOneFSMState::PrtscPress(i) => *i,
370             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
371         };
372         if i > 3 {
373             // 解析错误,返回起始状态
374             return TypeOneFSMState::Start;
375         }
376         if scancode != PRTSC_SCAN_CODE[i as usize] {
377             return self.handle_type3(scancode, scancode_status);
378         } else if i == 3 {
379             // 成功解析出PrtscPress
380             return TypeOneFSMState::Start;
381         } else {
382             // 继续解析
383             return TypeOneFSMState::PrtscPress(i + 1);
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 if i == 3 {
404             // 成功解析出PrtscRelease
405             return TypeOneFSMState::Start;
406         } else {
407             // 继续解析
408             return TypeOneFSMState::PrtscRelease(i + 1);
409         }
410     }
411 }
412 
413 /// 按键状态
414 #[derive(Debug)]
415 #[allow(dead_code)]
416 pub struct ScanCodeStatus {
417     // Shift 按键
418     shift_l: bool,
419     shift_r: bool,
420     // Ctrl 按键
421     ctrl_l: bool,
422     ctrl_r: bool,
423     // Alt 按键
424     alt_l: bool,
425     alt_r: bool,
426     //
427     gui_l: bool,
428     gui_r: bool,
429     //
430     apps: bool,
431     insert: bool,
432     // page up/down
433     pgup: bool,
434     pgdn: bool,
435     del: bool,
436     home: bool,
437     end: bool,
438     arrow_u: bool,
439     arrow_l: bool,
440     arrow_d: bool,
441     arrow_r: bool,
442     // 斜杠
443     kp_forward_slash: bool,
444     // 回车
445     kp_enter: bool,
446     caps_lock: bool,
447 }
448 
449 impl ScanCodeStatus {
450     fn new() -> Self {
451         ScanCodeStatus {
452             shift_l: false,
453             shift_r: false,
454             ctrl_l: false,
455             ctrl_r: false,
456             alt_l: false,
457             alt_r: false,
458             gui_l: false,
459             gui_r: false,
460             apps: false,
461             insert: false,
462             pgup: false,
463             pgdn: false,
464             del: false,
465             home: false,
466             end: false,
467             arrow_u: false,
468             arrow_l: false,
469             arrow_d: false,
470             arrow_r: false,
471             kp_forward_slash: false,
472             kp_enter: false,
473             caps_lock: false,
474         }
475     }
476 }
477 
478 const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [
479     /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC
480     /*0x02*/ b'1', b'!', /*0x03*/ b'2', b'@', /*0x04*/ b'3', b'#',
481     /*0x05*/ b'4', b'$', /*0x06*/ b'5', b'%', /*0x07*/ b'6', b'^',
482     /*0x08*/ b'7', b'&', /*0x09*/ b'8', b'*', /*0x0a*/ b'9', b'(',
483     /*0x0b*/ b'0', b')', /*0x0c*/ b'-', b'_', /*0x0d*/ b'=', b'+',
484     /*0x0e  \b */ 8, 8, // BACKSPACE
485     /*0x0f*/ b'\t', b'\t', // TAB
486     ////////////////////////character///////////////////////////
487     /*0x10*/ b'q', b'Q',
488     /*0x11*/ b'w', b'W', /*0x12*/ b'e', b'E', /*0x13*/ b'r', b'R',
489     /*0x14*/ b't', b'T', /*0x15*/ b'y', b'Y', /*0x16*/ b'u', b'U',
490     /*0x17*/ b'i', b'I', /*0x18*/ b'o', b'O', /*0x19*/ b'p', b'P',
491     ////////////////////////character///////////////////////////
492 
493     /*0x1a*/ b'[', b'{',
494     /*0x1b*/ b']', b'}', /*0x1c*/ b'\n', b'\n', // ENTER
495     /*0x1d*/ 0x1d, 0x1d, // CTRL Left
496     ////////////////////////character///////////////////////////
497     /*0x1e*/ b'a', b'A',
498     /*0x1f*/ b's', b'S', /*0x20*/ b'd', b'D', /*0x21*/ b'f', b'F',
499     /*0x22*/ b'g', b'G', /*0x23*/ b'h', b'H', /*0x24*/ b'j', b'J',
500     /*0x25*/ b'k', b'K', /*0x26*/ b'l', b'L',
501     ////////////////////////character///////////////////////////
502 
503     /*0x27*/ b';', b':',
504     /*0x28*/ b'\'', b'"', /*0x29*/ b'`', b'~', /*0x2a*/ 0x2a,
505     0x2a, // SHIFT Left
506     /*0x2b*/ b'\\', b'|',
507     ////////////////////////character///////////////////////////
508     /*0x2c*/ b'z', b'Z',
509     /*0x2d*/ b'x', b'X', /*0x2e*/ b'c', b'C', /*0x2f*/ b'v', b'V',
510     /*0x30*/ b'b', b'B', /*0x31*/ b'n', b'N', /*0x32*/ b'm', b'M',
511     ////////////////////////character///////////////////////////
512 
513     /*0x33*/ b',', b'<',
514     /*0x34*/ b'.', b'>', /*0x35*/ b'/', b'?', /*0x36*/ 0x36,
515     0x36, // SHIFT Right
516     /*0x37*/ b'*', b'*', /*0x38*/ 0x38, 0x38, // ALT Left
517     /*0x39*/ b' ', b' ', /*0x3a*/ 0, 0, // CAPS LOCK
518     /*0x3b*/ 0, 0, // F1
519     /*0x3c*/ 0, 0, // F2
520     /*0x3d*/ 0, 0, // F3
521     /*0x3e*/ 0, 0, // F4
522     /*0x3f*/ 0, 0, // F5
523     /*0x40*/ 0, 0, // F6
524     /*0x41*/ 0, 0, // F7
525     /*0x42*/ 0, 0, // F8
526     /*0x43*/ 0, 0, // F9
527     /*0x44*/ 0, 0, // F10
528     /*0x45*/ 0, 0, // NUM LOCK
529     /*0x46*/ 0, 0, // SCROLL LOCK
530     /*0x47*/ b'7', 0, /*PAD HONE*/
531     /*0x48*/ b'8', 0, /*PAD UP*/
532     /*0x49*/ b'9', 0, /*PAD PAGEUP*/
533     /*0x4a*/ b'-', 0, /*PAD MINUS*/
534     /*0x4b*/ b'4', 0, /*PAD LEFT*/
535     /*0x4c*/ b'5', 0, /*PAD MID*/
536     /*0x4d*/ b'6', 0, /*PAD RIGHT*/
537     /*0x4e*/ b'+', 0, /*PAD PLUS*/
538     /*0x4f*/ b'1', 0, /*PAD END*/
539     /*0x50*/ b'2', 0, /*PAD DOWN*/
540     /*0x51*/ b'3', 0, /*PAD PAGEDOWN*/
541     /*0x52*/ b'0', 0, /*PAD INS*/
542     /*0x53*/ b'.', 0, /*PAD DOT*/
543     /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11
544     /*0x58*/ 0, 0, // F12
545     /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0,
546     /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0,
547     /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0,
548     /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0,
549     /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0,
550     /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0,
551     /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0,
552     /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0,
553     /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0,
554     /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0,
555 ];
556