xref: /DragonOS/kernel/src/libs/keyboard_parser.rs (revision 20e3152e1eea97f87d644c3023391e172bc83c93)
1*20e3152eSlogin use alloc::sync::Arc;
2*20e3152eSlogin 
3*20e3152eSlogin use crate::driver::tty::tty_device::TtyDevice;
45fb12ce4SGou Ngai 
55fb12ce4SGou Ngai #[allow(dead_code)]
65fb12ce4SGou Ngai pub const NUM_SCAN_CODES: u8 = 0x80;
75fb12ce4SGou Ngai #[allow(dead_code)]
85fb12ce4SGou Ngai pub const TYPE1_KEYCODE_MAP_TABLE_COLS: u8 = 2;
95fb12ce4SGou Ngai 
105fb12ce4SGou Ngai #[allow(dead_code)]
115fb12ce4SGou Ngai pub const TYPE1_KEYCODE_FLAG_BREAK: u8 = 0x80; // 用于判断按键是否被按下
125fb12ce4SGou Ngai 
135fb12ce4SGou Ngai /// 标志状态
145fb12ce4SGou Ngai #[repr(u8)]
155fb12ce4SGou Ngai #[derive(Debug, PartialEq, Eq)]
165fb12ce4SGou Ngai #[allow(dead_code)]
175fb12ce4SGou Ngai pub enum KeyFlag {
185fb12ce4SGou Ngai     NoneFlag = 0 as u8,
195fb12ce4SGou Ngai     PauseBreak = 1 as u8,
205fb12ce4SGou Ngai     PrintScreenPress = 2 as u8,
215fb12ce4SGou Ngai     PrintScreenRelease = 4 as u8,
225fb12ce4SGou Ngai     OtherKey = 8 as u8, // 除了上面两个按键以外的功能按键(不包括下面的第三类按键)
235fb12ce4SGou Ngai }
245fb12ce4SGou Ngai 
255fb12ce4SGou Ngai /// @brief A FSM to parse type one keyboard scan code
265fb12ce4SGou Ngai #[derive(Debug)]
275fb12ce4SGou Ngai #[allow(dead_code)]
285fb12ce4SGou Ngai pub struct TypeOneFSM {
295fb12ce4SGou Ngai     status: ScanCodeStatus,
305fb12ce4SGou Ngai     current_state: TypeOneFSMState,
31*20e3152eSlogin     tty: Arc<TtyDevice>,
325fb12ce4SGou Ngai }
335fb12ce4SGou Ngai 
345fb12ce4SGou Ngai impl TypeOneFSM {
355fb12ce4SGou Ngai     #[allow(dead_code)]
36*20e3152eSlogin     pub fn new(tty: Arc<TtyDevice>) -> Self {
375fb12ce4SGou Ngai         Self {
385fb12ce4SGou Ngai             status: ScanCodeStatus::new(),
395fb12ce4SGou Ngai             current_state: TypeOneFSMState::Start,
40*20e3152eSlogin             tty,
415fb12ce4SGou Ngai         }
425fb12ce4SGou Ngai     }
435fb12ce4SGou Ngai 
445fb12ce4SGou Ngai     /// @brief 解析扫描码
455fb12ce4SGou Ngai     #[allow(dead_code)]
465fb12ce4SGou Ngai     pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState {
47*20e3152eSlogin         self.current_state = self
48*20e3152eSlogin             .current_state
49*20e3152eSlogin             .parse(scancode, &mut self.status, &self.tty);
505fb12ce4SGou Ngai         self.current_state
515fb12ce4SGou Ngai     }
525fb12ce4SGou Ngai }
535fb12ce4SGou Ngai 
545fb12ce4SGou Ngai /// @brief 第一类扫描码状态机的状态
555fb12ce4SGou Ngai #[derive(Debug, Copy, Clone)]
565fb12ce4SGou Ngai pub enum TypeOneFSMState {
575fb12ce4SGou Ngai     /// 起始状态
585fb12ce4SGou Ngai     Start,
595fb12ce4SGou Ngai     /// PauseBreak 第n个扫描码
605fb12ce4SGou Ngai     PauseBreak(u8),
615fb12ce4SGou Ngai     /// 多扫描码功能键起始状态
625fb12ce4SGou Ngai     Func0,
635fb12ce4SGou Ngai     /// 第三类扫描码或字符
645fb12ce4SGou Ngai     Type3,
655fb12ce4SGou Ngai 
665fb12ce4SGou Ngai     PrtscPress(u8),
675fb12ce4SGou Ngai     PrtscRelease(u8),
685fb12ce4SGou Ngai }
695fb12ce4SGou Ngai 
705fb12ce4SGou Ngai impl TypeOneFSMState {
715fb12ce4SGou Ngai     /// @brief 状态机总控程序
72*20e3152eSlogin     fn parse(
73*20e3152eSlogin         &self,
74*20e3152eSlogin         scancode: u8,
75*20e3152eSlogin         scancode_status: &mut ScanCodeStatus,
76*20e3152eSlogin         tty: &Arc<TtyDevice>,
77*20e3152eSlogin     ) -> TypeOneFSMState {
785fb12ce4SGou Ngai         // kdebug!("the code is {:#x}\n", scancode);
795fb12ce4SGou Ngai         match self {
805fb12ce4SGou Ngai             TypeOneFSMState::Start => {
81*20e3152eSlogin                 return self.handle_start(scancode, scancode_status, tty);
825fb12ce4SGou Ngai             }
835fb12ce4SGou Ngai             TypeOneFSMState::PauseBreak(n) => {
84*20e3152eSlogin                 return self.handle_pause_break(*n, scancode_status, tty);
855fb12ce4SGou Ngai             }
865fb12ce4SGou Ngai             TypeOneFSMState::Func0 => {
87*20e3152eSlogin                 return self.handle_func0(scancode, scancode_status, tty);
885fb12ce4SGou Ngai             }
895fb12ce4SGou Ngai             TypeOneFSMState::Type3 => {
90*20e3152eSlogin                 return self.handle_type3(scancode, scancode_status, tty);
915fb12ce4SGou Ngai             }
92*20e3152eSlogin             TypeOneFSMState::PrtscPress(n) => {
93*20e3152eSlogin                 return self.handle_prtsc_press(*n, scancode_status, tty)
94*20e3152eSlogin             }
955fb12ce4SGou Ngai             TypeOneFSMState::PrtscRelease(n) => {
96*20e3152eSlogin                 return self.handle_prtsc_release(*n, scancode_status, tty)
975fb12ce4SGou Ngai             }
985fb12ce4SGou Ngai         }
995fb12ce4SGou Ngai     }
1005fb12ce4SGou Ngai 
1015fb12ce4SGou Ngai     /// @brief 处理起始状态
102*20e3152eSlogin     fn handle_start(
103*20e3152eSlogin         &self,
104*20e3152eSlogin         scancode: u8,
105*20e3152eSlogin         scancode_status: &mut ScanCodeStatus,
106*20e3152eSlogin         tty: &Arc<TtyDevice>,
107*20e3152eSlogin     ) -> TypeOneFSMState {
1085fb12ce4SGou Ngai         //kdebug!("in handle_start the code is {:#x}\n",scancode);
1095fb12ce4SGou Ngai         match scancode {
1105fb12ce4SGou Ngai             0xe1 => {
1115fb12ce4SGou Ngai                 return TypeOneFSMState::PauseBreak(1);
1125fb12ce4SGou Ngai             }
1135fb12ce4SGou Ngai             0xe0 => {
1145fb12ce4SGou Ngai                 return TypeOneFSMState::Func0;
1155fb12ce4SGou Ngai             }
1165fb12ce4SGou Ngai             _ => {
1175fb12ce4SGou Ngai                 //kdebug!("in _d the code is {:#x}\n",scancode);
118*20e3152eSlogin                 return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status, tty);
1195fb12ce4SGou Ngai             }
1205fb12ce4SGou Ngai         }
1215fb12ce4SGou Ngai     }
1225fb12ce4SGou Ngai 
1235fb12ce4SGou Ngai     /// @brief 处理PauseBreak状态
1245fb12ce4SGou Ngai     fn handle_pause_break(
1255fb12ce4SGou Ngai         &self,
1265fb12ce4SGou Ngai         scancode: u8,
1275fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
128*20e3152eSlogin         tty: &Arc<TtyDevice>,
1295fb12ce4SGou Ngai     ) -> TypeOneFSMState {
1305fb12ce4SGou Ngai         static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5];
1315fb12ce4SGou Ngai         let i = match self {
1325fb12ce4SGou Ngai             TypeOneFSMState::PauseBreak(i) => *i,
1335fb12ce4SGou Ngai             _ => {
134*20e3152eSlogin                 return self.handle_type3(scancode, scancode_status, tty);
1355fb12ce4SGou Ngai             }
1365fb12ce4SGou Ngai         };
1375fb12ce4SGou Ngai         if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] {
138*20e3152eSlogin             return self.handle_type3(scancode, scancode_status, tty);
1395fb12ce4SGou Ngai         } else {
1405fb12ce4SGou Ngai             if i == 5 {
1415fb12ce4SGou Ngai                 // 所有Pause Break扫描码都被清除
1425fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
1435fb12ce4SGou Ngai             } else {
1445fb12ce4SGou Ngai                 return TypeOneFSMState::PauseBreak(i + 1);
1455fb12ce4SGou Ngai             }
1465fb12ce4SGou Ngai         }
1475fb12ce4SGou Ngai     }
1485fb12ce4SGou Ngai 
149*20e3152eSlogin     fn handle_func0(
150*20e3152eSlogin         &self,
151*20e3152eSlogin         scancode: u8,
152*20e3152eSlogin         scancode_status: &mut ScanCodeStatus,
153*20e3152eSlogin         tty: &Arc<TtyDevice>,
154*20e3152eSlogin     ) -> TypeOneFSMState {
1555fb12ce4SGou Ngai         //0xE0
1565fb12ce4SGou Ngai         match scancode {
1575fb12ce4SGou Ngai             0x2a => {
1585fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscPress(2);
1595fb12ce4SGou Ngai             }
1605fb12ce4SGou Ngai             0xb7 => {
1615fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscRelease(2);
1625fb12ce4SGou Ngai             }
1635fb12ce4SGou Ngai             0x1d => {
1645fb12ce4SGou Ngai                 // 按下右边的ctrl
1655fb12ce4SGou Ngai                 scancode_status.ctrl_r = true;
1665fb12ce4SGou Ngai             }
1675fb12ce4SGou Ngai             0x9d => {
1685fb12ce4SGou Ngai                 // 松开右边的ctrl
1695fb12ce4SGou Ngai                 scancode_status.ctrl_r = false;
1705fb12ce4SGou Ngai             }
1715fb12ce4SGou Ngai             0x38 => {
1725fb12ce4SGou Ngai                 // 按下右边的alt
1735fb12ce4SGou Ngai                 scancode_status.alt_r = true;
1745fb12ce4SGou Ngai             }
1755fb12ce4SGou Ngai             0xb8 => {
1765fb12ce4SGou Ngai                 // 松开右边的alt
1775fb12ce4SGou Ngai                 scancode_status.alt_r = false;
1785fb12ce4SGou Ngai             }
1795fb12ce4SGou Ngai             0x5b => {
1805fb12ce4SGou Ngai                 scancode_status.gui_l = true;
1815fb12ce4SGou Ngai             }
1825fb12ce4SGou Ngai             0xdb => {
1835fb12ce4SGou Ngai                 scancode_status.gui_l = false;
1845fb12ce4SGou Ngai             }
1855fb12ce4SGou Ngai             0x5c => {
1865fb12ce4SGou Ngai                 scancode_status.gui_r = true;
1875fb12ce4SGou Ngai             }
1885fb12ce4SGou Ngai             0xdc => {
1895fb12ce4SGou Ngai                 scancode_status.gui_r = false;
1905fb12ce4SGou Ngai             }
1915fb12ce4SGou Ngai             0x5d => {
1925fb12ce4SGou Ngai                 scancode_status.apps = true;
1935fb12ce4SGou Ngai             }
1945fb12ce4SGou Ngai             0xdd => {
1955fb12ce4SGou Ngai                 scancode_status.apps = false;
1965fb12ce4SGou Ngai             }
1975fb12ce4SGou Ngai             0x52 => {
1985fb12ce4SGou Ngai                 scancode_status.insert = true;
1995fb12ce4SGou Ngai             }
2005fb12ce4SGou Ngai             0xd2 => {
2015fb12ce4SGou Ngai                 scancode_status.insert = false;
2025fb12ce4SGou Ngai             }
2035fb12ce4SGou Ngai             0x47 => {
2045fb12ce4SGou Ngai                 scancode_status.home = true;
2055fb12ce4SGou Ngai             }
2065fb12ce4SGou Ngai             0xc7 => {
2075fb12ce4SGou Ngai                 scancode_status.home = false;
2085fb12ce4SGou Ngai             }
2095fb12ce4SGou Ngai             0x49 => {
2105fb12ce4SGou Ngai                 scancode_status.pgup = true;
2115fb12ce4SGou Ngai             }
2125fb12ce4SGou Ngai             0xc9 => {
2135fb12ce4SGou Ngai                 scancode_status.pgup = false;
2145fb12ce4SGou Ngai             }
2155fb12ce4SGou Ngai             0x53 => {
2165fb12ce4SGou Ngai                 scancode_status.del = true;
217*20e3152eSlogin                 Self::emit(tty, 127);
2185fb12ce4SGou Ngai             }
2195fb12ce4SGou Ngai             0xd3 => {
2205fb12ce4SGou Ngai                 scancode_status.del = false;
2215fb12ce4SGou Ngai             }
2225fb12ce4SGou Ngai             0x4f => {
2235fb12ce4SGou Ngai                 scancode_status.end = true;
2245fb12ce4SGou Ngai             }
2255fb12ce4SGou Ngai             0xcf => {
2265fb12ce4SGou Ngai                 scancode_status.end = false;
2275fb12ce4SGou Ngai             }
2285fb12ce4SGou Ngai             0x51 => {
2295fb12ce4SGou Ngai                 scancode_status.pgdn = true;
2305fb12ce4SGou Ngai             }
2315fb12ce4SGou Ngai             0xd1 => {
2325fb12ce4SGou Ngai                 scancode_status.pgdn = false;
2335fb12ce4SGou Ngai             }
2345fb12ce4SGou Ngai             0x48 => {
2355fb12ce4SGou Ngai                 scancode_status.arrow_u = true;
236*20e3152eSlogin                 Self::emit(tty, 224);
237*20e3152eSlogin                 Self::emit(tty, 72);
2385fb12ce4SGou Ngai             }
2395fb12ce4SGou Ngai             0xc8 => {
2405fb12ce4SGou Ngai                 scancode_status.arrow_u = false;
2415fb12ce4SGou Ngai             }
2425fb12ce4SGou Ngai             0x4b => {
2435fb12ce4SGou Ngai                 scancode_status.arrow_l = true;
244*20e3152eSlogin                 Self::emit(tty, 224);
245*20e3152eSlogin                 Self::emit(tty, 75);
2465fb12ce4SGou Ngai             }
2475fb12ce4SGou Ngai             0xcb => {
2485fb12ce4SGou Ngai                 scancode_status.arrow_l = false;
2495fb12ce4SGou Ngai             }
2505fb12ce4SGou Ngai             0x50 => {
2515fb12ce4SGou Ngai                 scancode_status.arrow_d = true;
252*20e3152eSlogin                 Self::emit(tty, 224);
253*20e3152eSlogin                 Self::emit(tty, 80);
2545fb12ce4SGou Ngai             }
2555fb12ce4SGou Ngai             0xd0 => {
2565fb12ce4SGou Ngai                 scancode_status.arrow_d = false;
2575fb12ce4SGou Ngai             }
2585fb12ce4SGou Ngai             0x4d => {
2595fb12ce4SGou Ngai                 scancode_status.arrow_r = true;
260*20e3152eSlogin                 Self::emit(tty, 224);
261*20e3152eSlogin                 Self::emit(tty, 77);
2625fb12ce4SGou Ngai             }
2635fb12ce4SGou Ngai             0xcd => {
2645fb12ce4SGou Ngai                 scancode_status.arrow_r = false;
2655fb12ce4SGou Ngai             }
2665fb12ce4SGou Ngai 
2675fb12ce4SGou Ngai             0x35 => {
2685fb12ce4SGou Ngai                 // 数字小键盘的 / 符号
2695fb12ce4SGou Ngai                 scancode_status.kp_forward_slash = true;
2705fb12ce4SGou Ngai 
2715fb12ce4SGou Ngai                 let ch = '/' as u8;
272*20e3152eSlogin                 Self::emit(tty, ch);
2735fb12ce4SGou Ngai             }
2745fb12ce4SGou Ngai             0xb5 => {
2755fb12ce4SGou Ngai                 scancode_status.kp_forward_slash = false;
2765fb12ce4SGou Ngai             }
2775fb12ce4SGou Ngai             0x1c => {
2785fb12ce4SGou Ngai                 scancode_status.kp_enter = true;
279*20e3152eSlogin                 Self::emit(tty, '\n' as u8);
2805fb12ce4SGou Ngai             }
2815fb12ce4SGou Ngai             0x9c => {
2825fb12ce4SGou Ngai                 scancode_status.kp_enter = false;
2835fb12ce4SGou Ngai             }
2845fb12ce4SGou Ngai             _ => {
2855fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
2865fb12ce4SGou Ngai             }
2875fb12ce4SGou Ngai         }
2885fb12ce4SGou Ngai         return TypeOneFSMState::Start;
2895fb12ce4SGou Ngai     }
2905fb12ce4SGou Ngai 
291*20e3152eSlogin     fn handle_type3(
292*20e3152eSlogin         &self,
293*20e3152eSlogin         scancode: u8,
294*20e3152eSlogin         scancode_status: &mut ScanCodeStatus,
295*20e3152eSlogin         tty: &Arc<TtyDevice>,
296*20e3152eSlogin     ) -> TypeOneFSMState {
2975fb12ce4SGou Ngai         // 判断按键是被按下还是抬起
2985fb12ce4SGou Ngai         let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 {
2995fb12ce4SGou Ngai             false
3005fb12ce4SGou Ngai         } else {
3015fb12ce4SGou Ngai             true
3025fb12ce4SGou Ngai         };
3035fb12ce4SGou Ngai 
3045fb12ce4SGou Ngai         // 计算扫描码位于码表的第几行
3055fb12ce4SGou Ngai         let mut col: usize = 0;
3065fb12ce4SGou Ngai         let index = scancode & 0x7f;
3075fb12ce4SGou Ngai 
3085fb12ce4SGou Ngai         // shift被按下
3095fb12ce4SGou Ngai         if scancode_status.shift_l || scancode_status.shift_r {
3105fb12ce4SGou Ngai             col = 1;
3115fb12ce4SGou Ngai         }
3125fb12ce4SGou Ngai 
3135fb12ce4SGou Ngai         let ch = TYPE1_KEY_CODE_MAPTABLE[col + 2 * index as usize];
3145fb12ce4SGou Ngai         //kdebug!("in type3 ch is {:#x}\n",ch);
3155fb12ce4SGou Ngai         let mut key = KeyFlag::OtherKey; // 可视字符
3165fb12ce4SGou Ngai 
3175fb12ce4SGou Ngai         match index {
3185fb12ce4SGou Ngai             0x2a => {
3195fb12ce4SGou Ngai                 scancode_status.shift_l = flag_make;
3205fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
3215fb12ce4SGou Ngai             }
3225fb12ce4SGou Ngai             0x36 => {
3235fb12ce4SGou Ngai                 scancode_status.shift_r = flag_make;
3245fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
3255fb12ce4SGou Ngai             }
3265fb12ce4SGou Ngai             0x1d => {
3275fb12ce4SGou Ngai                 scancode_status.ctrl_l = flag_make;
3285fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
3295fb12ce4SGou Ngai             }
3305fb12ce4SGou Ngai             0x38 => {
3315fb12ce4SGou Ngai                 scancode_status.ctrl_r = flag_make;
3325fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
3335fb12ce4SGou Ngai             }
3345fb12ce4SGou Ngai             _ => {
3355fb12ce4SGou Ngai                 if flag_make == false {
3365fb12ce4SGou Ngai                     //kdebug!("in type3 ch is {:#x}\n",ch);
3375fb12ce4SGou Ngai                     key = KeyFlag::NoneFlag;
3385fb12ce4SGou Ngai                 }
3395fb12ce4SGou Ngai             }
3405fb12ce4SGou Ngai         }
3415fb12ce4SGou Ngai 
3425fb12ce4SGou Ngai         if key != KeyFlag::NoneFlag {
343*20e3152eSlogin             Self::emit(tty, ch);
3445fb12ce4SGou Ngai         }
3455fb12ce4SGou Ngai         return TypeOneFSMState::Start;
3465fb12ce4SGou Ngai     }
3475fb12ce4SGou Ngai 
348*20e3152eSlogin     #[inline(always)]
349*20e3152eSlogin     fn emit(tty: &Arc<TtyDevice>, ch: u8) {
350*20e3152eSlogin         // 发送到tty
351*20e3152eSlogin         tty.input(&[ch]).ok();
3525fb12ce4SGou Ngai     }
3535fb12ce4SGou Ngai 
3545fb12ce4SGou Ngai     /// @brief 处理Prtsc按下事件
3555fb12ce4SGou Ngai     fn handle_prtsc_press(
3565fb12ce4SGou Ngai         &self,
3575fb12ce4SGou Ngai         scancode: u8,
3585fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
359*20e3152eSlogin         tty: &Arc<TtyDevice>,
3605fb12ce4SGou Ngai     ) -> TypeOneFSMState {
3615fb12ce4SGou Ngai         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
3625fb12ce4SGou Ngai         let i = match self {
3635fb12ce4SGou Ngai             TypeOneFSMState::PrtscPress(i) => *i,
3645fb12ce4SGou Ngai             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
3655fb12ce4SGou Ngai         };
3665fb12ce4SGou Ngai         if i > 3 {
3675fb12ce4SGou Ngai             // 解析错误,返回起始状态
3685fb12ce4SGou Ngai             return TypeOneFSMState::Start;
3695fb12ce4SGou Ngai         }
3705fb12ce4SGou Ngai         if scancode != PRTSC_SCAN_CODE[i as usize] {
371*20e3152eSlogin             return self.handle_type3(scancode, scancode_status, tty);
3725fb12ce4SGou Ngai         } else {
3735fb12ce4SGou Ngai             if i == 3 {
3745fb12ce4SGou Ngai                 // 成功解析出PrtscPress
3755fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
3765fb12ce4SGou Ngai             } else {
3775fb12ce4SGou Ngai                 // 继续解析
3785fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscPress(i + 1);
3795fb12ce4SGou Ngai             }
3805fb12ce4SGou Ngai         }
3815fb12ce4SGou Ngai     }
3825fb12ce4SGou Ngai 
3835fb12ce4SGou Ngai     fn handle_prtsc_release(
3845fb12ce4SGou Ngai         &self,
3855fb12ce4SGou Ngai         scancode: u8,
3865fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
387*20e3152eSlogin         tty: &Arc<TtyDevice>,
3885fb12ce4SGou Ngai     ) -> TypeOneFSMState {
3895fb12ce4SGou Ngai         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
3905fb12ce4SGou Ngai         let i = match self {
3915fb12ce4SGou Ngai             TypeOneFSMState::PrtscRelease(i) => *i,
3925fb12ce4SGou Ngai             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
3935fb12ce4SGou Ngai         };
3945fb12ce4SGou Ngai         if i > 3 {
3955fb12ce4SGou Ngai             // 解析错误,返回起始状态
3965fb12ce4SGou Ngai             return TypeOneFSMState::Start;
3975fb12ce4SGou Ngai         }
3985fb12ce4SGou Ngai         if scancode != PRTSC_SCAN_CODE[i as usize] {
399*20e3152eSlogin             return self.handle_type3(scancode, scancode_status, tty);
4005fb12ce4SGou Ngai         } else {
4015fb12ce4SGou Ngai             if i == 3 {
4025fb12ce4SGou Ngai                 // 成功解析出PrtscRelease
4035fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
4045fb12ce4SGou Ngai             } else {
4055fb12ce4SGou Ngai                 // 继续解析
4065fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscRelease(i + 1);
4075fb12ce4SGou Ngai             }
4085fb12ce4SGou Ngai         }
4095fb12ce4SGou Ngai     }
4105fb12ce4SGou Ngai }
4115fb12ce4SGou Ngai 
4125fb12ce4SGou Ngai /// 按键状态
4135fb12ce4SGou Ngai #[derive(Debug)]
4145fb12ce4SGou Ngai pub struct ScanCodeStatus {
4155fb12ce4SGou Ngai     // Shift 按键
4165fb12ce4SGou Ngai     shift_l: bool,
4175fb12ce4SGou Ngai     shift_r: bool,
4185fb12ce4SGou Ngai     // Ctrl 按键
4195fb12ce4SGou Ngai     ctrl_l: bool,
4205fb12ce4SGou Ngai     ctrl_r: bool,
4215fb12ce4SGou Ngai     // Alt 按键
4225fb12ce4SGou Ngai     alt_l: bool,
4235fb12ce4SGou Ngai     alt_r: bool,
4245fb12ce4SGou Ngai     //
4255fb12ce4SGou Ngai     gui_l: bool,
4265fb12ce4SGou Ngai     gui_r: bool,
4275fb12ce4SGou Ngai     //
4285fb12ce4SGou Ngai     apps: bool,
4295fb12ce4SGou Ngai     insert: bool,
4305fb12ce4SGou Ngai     // page up/down
4315fb12ce4SGou Ngai     pgup: bool,
4325fb12ce4SGou Ngai     pgdn: bool,
4335fb12ce4SGou Ngai     del: bool,
4345fb12ce4SGou Ngai     home: bool,
4355fb12ce4SGou Ngai     end: bool,
4365fb12ce4SGou Ngai     arrow_u: bool,
4375fb12ce4SGou Ngai     arrow_l: bool,
4385fb12ce4SGou Ngai     arrow_d: bool,
4395fb12ce4SGou Ngai     arrow_r: bool,
4405fb12ce4SGou Ngai     // 斜杠
4415fb12ce4SGou Ngai     kp_forward_slash: bool,
4425fb12ce4SGou Ngai     // 回车
4435fb12ce4SGou Ngai     kp_enter: bool,
4445fb12ce4SGou Ngai }
4455fb12ce4SGou Ngai 
4465fb12ce4SGou Ngai impl ScanCodeStatus {
4475fb12ce4SGou Ngai     fn new() -> Self {
4485fb12ce4SGou Ngai         ScanCodeStatus {
4495fb12ce4SGou Ngai             shift_l: false,
4505fb12ce4SGou Ngai             shift_r: false,
4515fb12ce4SGou Ngai             ctrl_l: false,
4525fb12ce4SGou Ngai             ctrl_r: false,
4535fb12ce4SGou Ngai             alt_l: false,
4545fb12ce4SGou Ngai             alt_r: false,
4555fb12ce4SGou Ngai             gui_l: false,
4565fb12ce4SGou Ngai             gui_r: false,
4575fb12ce4SGou Ngai             apps: false,
4585fb12ce4SGou Ngai             insert: false,
4595fb12ce4SGou Ngai             pgup: false,
4605fb12ce4SGou Ngai             pgdn: false,
4615fb12ce4SGou Ngai             del: false,
4625fb12ce4SGou Ngai             home: false,
4635fb12ce4SGou Ngai             end: false,
4645fb12ce4SGou Ngai             arrow_u: false,
4655fb12ce4SGou Ngai             arrow_l: false,
4665fb12ce4SGou Ngai             arrow_d: false,
4675fb12ce4SGou Ngai             arrow_r: false,
4685fb12ce4SGou Ngai             kp_forward_slash: false,
4695fb12ce4SGou Ngai             kp_enter: false,
4705fb12ce4SGou Ngai         }
4715fb12ce4SGou Ngai     }
4725fb12ce4SGou Ngai }
4735fb12ce4SGou Ngai 
4745fb12ce4SGou Ngai const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [
4755fb12ce4SGou Ngai     /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC
4765fb12ce4SGou Ngai     /*0x02*/ '1' as u8, '!' as u8, /*0x03*/ '2' as u8, '@' as u8,
4775fb12ce4SGou Ngai     /*0x04*/ '3' as u8, '#' as u8, /*0x05*/ '4' as u8, '$' as u8,
4785fb12ce4SGou Ngai     /*0x06*/ '5' as u8, '%' as u8, /*0x07*/ '6' as u8, '^' as u8,
4795fb12ce4SGou Ngai     /*0x08*/ '7' as u8, '&' as u8, /*0x09*/ '8' as u8, '*' as u8,
4805fb12ce4SGou Ngai     /*0x0a*/ '9' as u8, '(' as u8, /*0x0b*/ '0' as u8, ')' as u8,
4815fb12ce4SGou Ngai     /*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8,
482*20e3152eSlogin     /*0x0e  \b */ 8 as u8, 8 as u8, // BACKSPACE
4835fb12ce4SGou Ngai     /*0x0f*/ '\t' as u8, '\t' as u8, // TAB
4845fb12ce4SGou Ngai     /*0x10*/ 'q' as u8, 'Q' as u8, /*0x11*/ 'w' as u8, 'W' as u8,
4855fb12ce4SGou Ngai     /*0x12*/ 'e' as u8, 'E' as u8, /*0x13*/ 'r' as u8, 'R' as u8,
4865fb12ce4SGou Ngai     /*0x14*/ 't' as u8, 'T' as u8, /*0x15*/ 'y' as u8, 'Y' as u8,
4875fb12ce4SGou Ngai     /*0x16*/ 'u' as u8, 'U' as u8, /*0x17*/ 'i' as u8, 'I' as u8,
4885fb12ce4SGou Ngai     /*0x18*/ 'o' as u8, 'O' as u8, /*0x19*/ 'p' as u8, 'P' as u8,
4895fb12ce4SGou Ngai     /*0x1a*/ '[' as u8, '{' as u8, /*0x1b*/ ']' as u8, '}' as u8,
4905fb12ce4SGou Ngai     /*0x1c*/ '\n' as u8, '\n' as u8, // ENTER
4915fb12ce4SGou Ngai     /*0x1d*/ 0x1d, 0x1d, // CTRL Left
4925fb12ce4SGou Ngai     /*0x1e*/ 'a' as u8, 'A' as u8, /*0x1f*/ 's' as u8, 'S' as u8,
4935fb12ce4SGou Ngai     /*0x20*/ 'd' as u8, 'D' as u8, /*0x21*/ 'f' as u8, 'F' as u8,
4945fb12ce4SGou Ngai     /*0x22*/ 'g' as u8, 'G' as u8, /*0x23*/ 'h' as u8, 'H' as u8,
4955fb12ce4SGou Ngai     /*0x24*/ 'j' as u8, 'J' as u8, /*0x25*/ 'k' as u8, 'K' as u8,
4965fb12ce4SGou Ngai     /*0x26*/ 'l' as u8, 'L' as u8, /*0x27*/ ';' as u8, ':' as u8,
4975fb12ce4SGou Ngai     /*0x28*/ '\'' as u8, '"' as u8, /*0x29*/ '`' as u8, '~' as u8, /*0x2a*/ 0x2a,
4985fb12ce4SGou Ngai     0x2a, // SHIFT Left
4995fb12ce4SGou Ngai     /*0x2b*/ '\\' as u8, '|' as u8, /*0x2c*/ 'z' as u8, 'Z' as u8,
5005fb12ce4SGou Ngai     /*0x2d*/ 'x' as u8, 'X' as u8, /*0x2e*/ 'c' as u8, 'C' as u8,
5015fb12ce4SGou Ngai     /*0x2f*/ 'v' as u8, 'V' as u8, /*0x30*/ 'b' as u8, 'B' as u8,
5025fb12ce4SGou Ngai     /*0x31*/ 'n' as u8, 'N' as u8, /*0x32*/ 'm' as u8, 'M' as u8,
5035fb12ce4SGou Ngai     /*0x33*/ ',' as u8, '<' as u8, /*0x34*/ '.' as u8, '>' as u8,
5045fb12ce4SGou Ngai     /*0x35*/ '/' as u8, '?' as u8, /*0x36*/ 0x36, 0x36, // SHIFT Right
5055fb12ce4SGou Ngai     /*0x37*/ '*' as u8, '*' as u8, /*0x38*/ 0x38, 0x38, // ALT Left
5065fb12ce4SGou Ngai     /*0x39*/ ' ' as u8, ' ' as u8, /*0x3a*/ 0, 0, // CAPS LOCK
5075fb12ce4SGou Ngai     /*0x3b*/ 0, 0, // F1
5085fb12ce4SGou Ngai     /*0x3c*/ 0, 0, // F2
5095fb12ce4SGou Ngai     /*0x3d*/ 0, 0, // F3
5105fb12ce4SGou Ngai     /*0x3e*/ 0, 0, // F4
5115fb12ce4SGou Ngai     /*0x3f*/ 0, 0, // F5
5125fb12ce4SGou Ngai     /*0x40*/ 0, 0, // F6
5135fb12ce4SGou Ngai     /*0x41*/ 0, 0, // F7
5145fb12ce4SGou Ngai     /*0x42*/ 0, 0, // F8
5155fb12ce4SGou Ngai     /*0x43*/ 0, 0, // F9
5165fb12ce4SGou Ngai     /*0x44*/ 0, 0, // F10
5175fb12ce4SGou Ngai     /*0x45*/ 0, 0, // NUM LOCK
5185fb12ce4SGou Ngai     /*0x46*/ 0, 0, // SCROLL LOCK
5195fb12ce4SGou Ngai     /*0x47*/ '7' as u8, 0, /*PAD HONE*/
5205fb12ce4SGou Ngai     /*0x48*/ '8' as u8, 0, /*PAD UP*/
5215fb12ce4SGou Ngai     /*0x49*/ '9' as u8, 0, /*PAD PAGEUP*/
5225fb12ce4SGou Ngai     /*0x4a*/ '-' as u8, 0, /*PAD MINUS*/
5235fb12ce4SGou Ngai     /*0x4b*/ '4' as u8, 0, /*PAD LEFT*/
5245fb12ce4SGou Ngai     /*0x4c*/ '5' as u8, 0, /*PAD MID*/
5255fb12ce4SGou Ngai     /*0x4d*/ '6' as u8, 0, /*PAD RIGHT*/
5265fb12ce4SGou Ngai     /*0x4e*/ '+' as u8, 0, /*PAD PLUS*/
5275fb12ce4SGou Ngai     /*0x4f*/ '1' as u8, 0, /*PAD END*/
5285fb12ce4SGou Ngai     /*0x50*/ '2' as u8, 0, /*PAD DOWN*/
5295fb12ce4SGou Ngai     /*0x51*/ '3' as u8, 0, /*PAD PAGEDOWN*/
5305fb12ce4SGou Ngai     /*0x52*/ '0' as u8, 0, /*PAD INS*/
5315fb12ce4SGou Ngai     /*0x53*/ '.' as u8, 0, /*PAD DOT*/
5325fb12ce4SGou Ngai     /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11
5335fb12ce4SGou Ngai     /*0x58*/ 0, 0, // F12
5345fb12ce4SGou Ngai     /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0,
5355fb12ce4SGou Ngai     /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0,
5365fb12ce4SGou Ngai     /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0,
5375fb12ce4SGou Ngai     /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0,
5385fb12ce4SGou Ngai     /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0,
5395fb12ce4SGou Ngai     /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0,
5405fb12ce4SGou Ngai     /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0,
5415fb12ce4SGou Ngai     /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0,
5425fb12ce4SGou Ngai     /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0,
5435fb12ce4SGou Ngai     /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0,
5445fb12ce4SGou Ngai ];
545