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