xref: /DragonOS/kernel/src/libs/keyboard_parser.rs (revision 59fdb447ee4f7b53b1d9c56ec1442aa8c597ac2b)
1*59fdb447SLoGin use crate::driver::tty::kthread::send_to_tty_refresh_thread;
25fb12ce4SGou Ngai 
35fb12ce4SGou Ngai #[allow(dead_code)]
45fb12ce4SGou Ngai pub const NUM_SCAN_CODES: u8 = 0x80;
55fb12ce4SGou Ngai #[allow(dead_code)]
65fb12ce4SGou Ngai pub const TYPE1_KEYCODE_MAP_TABLE_COLS: u8 = 2;
75fb12ce4SGou Ngai 
85fb12ce4SGou Ngai #[allow(dead_code)]
95fb12ce4SGou Ngai pub const TYPE1_KEYCODE_FLAG_BREAK: u8 = 0x80; // 用于判断按键是否被按下
105fb12ce4SGou Ngai 
115fb12ce4SGou Ngai /// 标志状态
125fb12ce4SGou Ngai #[repr(u8)]
135fb12ce4SGou Ngai #[derive(Debug, PartialEq, Eq)]
145fb12ce4SGou Ngai #[allow(dead_code)]
155fb12ce4SGou Ngai pub enum KeyFlag {
165fb12ce4SGou Ngai     NoneFlag = 0 as u8,
175fb12ce4SGou Ngai     PauseBreak = 1 as u8,
185fb12ce4SGou Ngai     PrintScreenPress = 2 as u8,
195fb12ce4SGou Ngai     PrintScreenRelease = 4 as u8,
205fb12ce4SGou Ngai     OtherKey = 8 as u8, // 除了上面两个按键以外的功能按键(不包括下面的第三类按键)
215fb12ce4SGou Ngai }
225fb12ce4SGou Ngai 
235fb12ce4SGou Ngai /// @brief A FSM to parse type one keyboard scan code
245fb12ce4SGou Ngai #[derive(Debug)]
255fb12ce4SGou Ngai #[allow(dead_code)]
265fb12ce4SGou Ngai pub struct TypeOneFSM {
275fb12ce4SGou Ngai     status: ScanCodeStatus,
285fb12ce4SGou Ngai     current_state: TypeOneFSMState,
295fb12ce4SGou Ngai }
305fb12ce4SGou Ngai 
315fb12ce4SGou Ngai impl TypeOneFSM {
325fb12ce4SGou Ngai     #[allow(dead_code)]
3352da9a59SGnoCiYeH     pub fn new() -> Self {
345fb12ce4SGou Ngai         Self {
355fb12ce4SGou Ngai             status: ScanCodeStatus::new(),
365fb12ce4SGou Ngai             current_state: TypeOneFSMState::Start,
375fb12ce4SGou Ngai         }
385fb12ce4SGou Ngai     }
395fb12ce4SGou Ngai 
405fb12ce4SGou Ngai     /// @brief 解析扫描码
415fb12ce4SGou Ngai     #[allow(dead_code)]
425fb12ce4SGou Ngai     pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState {
4352da9a59SGnoCiYeH         self.current_state = self.current_state.parse(scancode, &mut self.status);
445fb12ce4SGou Ngai         self.current_state
455fb12ce4SGou Ngai     }
465fb12ce4SGou Ngai }
475fb12ce4SGou Ngai 
485fb12ce4SGou Ngai /// @brief 第一类扫描码状态机的状态
495fb12ce4SGou Ngai #[derive(Debug, Copy, Clone)]
505fb12ce4SGou Ngai pub enum TypeOneFSMState {
515fb12ce4SGou Ngai     /// 起始状态
525fb12ce4SGou Ngai     Start,
535fb12ce4SGou Ngai     /// PauseBreak 第n个扫描码
545fb12ce4SGou Ngai     PauseBreak(u8),
555fb12ce4SGou Ngai     /// 多扫描码功能键起始状态
565fb12ce4SGou Ngai     Func0,
575fb12ce4SGou Ngai     /// 第三类扫描码或字符
585fb12ce4SGou Ngai     Type3,
595fb12ce4SGou Ngai 
605fb12ce4SGou Ngai     PrtscPress(u8),
615fb12ce4SGou Ngai     PrtscRelease(u8),
625fb12ce4SGou Ngai }
635fb12ce4SGou Ngai 
645fb12ce4SGou Ngai impl TypeOneFSMState {
655fb12ce4SGou Ngai     /// @brief 状态机总控程序
6652da9a59SGnoCiYeH     fn parse(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
675fb12ce4SGou Ngai         // kdebug!("the code is {:#x}\n", scancode);
685fb12ce4SGou Ngai         match self {
695fb12ce4SGou Ngai             TypeOneFSMState::Start => {
7052da9a59SGnoCiYeH                 return self.handle_start(scancode, scancode_status);
715fb12ce4SGou Ngai             }
725fb12ce4SGou Ngai             TypeOneFSMState::PauseBreak(n) => {
7352da9a59SGnoCiYeH                 return self.handle_pause_break(*n, scancode_status);
745fb12ce4SGou Ngai             }
755fb12ce4SGou Ngai             TypeOneFSMState::Func0 => {
7652da9a59SGnoCiYeH                 return self.handle_func0(scancode, scancode_status);
775fb12ce4SGou Ngai             }
785fb12ce4SGou Ngai             TypeOneFSMState::Type3 => {
7952da9a59SGnoCiYeH                 return self.handle_type3(scancode, scancode_status);
805fb12ce4SGou Ngai             }
8152da9a59SGnoCiYeH             TypeOneFSMState::PrtscPress(n) => return self.handle_prtsc_press(*n, scancode_status),
825fb12ce4SGou Ngai             TypeOneFSMState::PrtscRelease(n) => {
8352da9a59SGnoCiYeH                 return self.handle_prtsc_release(*n, scancode_status)
845fb12ce4SGou Ngai             }
855fb12ce4SGou Ngai         }
865fb12ce4SGou Ngai     }
875fb12ce4SGou Ngai 
885fb12ce4SGou Ngai     /// @brief 处理起始状态
8952da9a59SGnoCiYeH     fn handle_start(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
905fb12ce4SGou Ngai         //kdebug!("in handle_start the code is {:#x}\n",scancode);
915fb12ce4SGou Ngai         match scancode {
925fb12ce4SGou Ngai             0xe1 => {
935fb12ce4SGou Ngai                 return TypeOneFSMState::PauseBreak(1);
945fb12ce4SGou Ngai             }
955fb12ce4SGou Ngai             0xe0 => {
965fb12ce4SGou Ngai                 return TypeOneFSMState::Func0;
975fb12ce4SGou Ngai             }
985fb12ce4SGou Ngai             _ => {
995fb12ce4SGou Ngai                 //kdebug!("in _d the code is {:#x}\n",scancode);
10052da9a59SGnoCiYeH                 return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status);
1015fb12ce4SGou Ngai             }
1025fb12ce4SGou Ngai         }
1035fb12ce4SGou Ngai     }
1045fb12ce4SGou Ngai 
1055fb12ce4SGou Ngai     /// @brief 处理PauseBreak状态
1065fb12ce4SGou Ngai     fn handle_pause_break(
1075fb12ce4SGou Ngai         &self,
1085fb12ce4SGou Ngai         scancode: u8,
1095fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
1105fb12ce4SGou Ngai     ) -> TypeOneFSMState {
1115fb12ce4SGou Ngai         static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5];
1125fb12ce4SGou Ngai         let i = match self {
1135fb12ce4SGou Ngai             TypeOneFSMState::PauseBreak(i) => *i,
1145fb12ce4SGou Ngai             _ => {
11552da9a59SGnoCiYeH                 return self.handle_type3(scancode, scancode_status);
1165fb12ce4SGou Ngai             }
1175fb12ce4SGou Ngai         };
1185fb12ce4SGou Ngai         if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] {
11952da9a59SGnoCiYeH             return self.handle_type3(scancode, scancode_status);
1205fb12ce4SGou Ngai         } else {
1215fb12ce4SGou Ngai             if i == 5 {
1225fb12ce4SGou Ngai                 // 所有Pause Break扫描码都被清除
1235fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
1245fb12ce4SGou Ngai             } else {
1255fb12ce4SGou Ngai                 return TypeOneFSMState::PauseBreak(i + 1);
1265fb12ce4SGou Ngai             }
1275fb12ce4SGou Ngai         }
1285fb12ce4SGou Ngai     }
1295fb12ce4SGou Ngai 
13052da9a59SGnoCiYeH     fn handle_func0(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
1315fb12ce4SGou Ngai         //0xE0
1325fb12ce4SGou Ngai         match scancode {
1335fb12ce4SGou Ngai             0x2a => {
1345fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscPress(2);
1355fb12ce4SGou Ngai             }
1365fb12ce4SGou Ngai             0xb7 => {
1375fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscRelease(2);
1385fb12ce4SGou Ngai             }
1395fb12ce4SGou Ngai             0x1d => {
1405fb12ce4SGou Ngai                 // 按下右边的ctrl
1415fb12ce4SGou Ngai                 scancode_status.ctrl_r = true;
1425fb12ce4SGou Ngai             }
1435fb12ce4SGou Ngai             0x9d => {
1445fb12ce4SGou Ngai                 // 松开右边的ctrl
1455fb12ce4SGou Ngai                 scancode_status.ctrl_r = false;
1465fb12ce4SGou Ngai             }
1475fb12ce4SGou Ngai             0x38 => {
1485fb12ce4SGou Ngai                 // 按下右边的alt
1495fb12ce4SGou Ngai                 scancode_status.alt_r = true;
1505fb12ce4SGou Ngai             }
1515fb12ce4SGou Ngai             0xb8 => {
1525fb12ce4SGou Ngai                 // 松开右边的alt
1535fb12ce4SGou Ngai                 scancode_status.alt_r = false;
1545fb12ce4SGou Ngai             }
1555fb12ce4SGou Ngai             0x5b => {
1565fb12ce4SGou Ngai                 scancode_status.gui_l = true;
1575fb12ce4SGou Ngai             }
1585fb12ce4SGou Ngai             0xdb => {
1595fb12ce4SGou Ngai                 scancode_status.gui_l = false;
1605fb12ce4SGou Ngai             }
1615fb12ce4SGou Ngai             0x5c => {
1625fb12ce4SGou Ngai                 scancode_status.gui_r = true;
1635fb12ce4SGou Ngai             }
1645fb12ce4SGou Ngai             0xdc => {
1655fb12ce4SGou Ngai                 scancode_status.gui_r = false;
1665fb12ce4SGou Ngai             }
1675fb12ce4SGou Ngai             0x5d => {
1685fb12ce4SGou Ngai                 scancode_status.apps = true;
1695fb12ce4SGou Ngai             }
1705fb12ce4SGou Ngai             0xdd => {
1715fb12ce4SGou Ngai                 scancode_status.apps = false;
1725fb12ce4SGou Ngai             }
1735fb12ce4SGou Ngai             0x52 => {
1745fb12ce4SGou Ngai                 scancode_status.insert = true;
1755fb12ce4SGou Ngai             }
1765fb12ce4SGou Ngai             0xd2 => {
1775fb12ce4SGou Ngai                 scancode_status.insert = false;
1785fb12ce4SGou Ngai             }
1795fb12ce4SGou Ngai             0x47 => {
1805fb12ce4SGou Ngai                 scancode_status.home = true;
1815fb12ce4SGou Ngai             }
1825fb12ce4SGou Ngai             0xc7 => {
1835fb12ce4SGou Ngai                 scancode_status.home = false;
1845fb12ce4SGou Ngai             }
1855fb12ce4SGou Ngai             0x49 => {
1865fb12ce4SGou Ngai                 scancode_status.pgup = true;
1875fb12ce4SGou Ngai             }
1885fb12ce4SGou Ngai             0xc9 => {
1895fb12ce4SGou Ngai                 scancode_status.pgup = false;
1905fb12ce4SGou Ngai             }
1915fb12ce4SGou Ngai             0x53 => {
1925fb12ce4SGou Ngai                 scancode_status.del = true;
19352da9a59SGnoCiYeH                 Self::emit(127);
1945fb12ce4SGou Ngai             }
1955fb12ce4SGou Ngai             0xd3 => {
1965fb12ce4SGou Ngai                 scancode_status.del = false;
1975fb12ce4SGou Ngai             }
1985fb12ce4SGou Ngai             0x4f => {
1995fb12ce4SGou Ngai                 scancode_status.end = true;
2005fb12ce4SGou Ngai             }
2015fb12ce4SGou Ngai             0xcf => {
2025fb12ce4SGou Ngai                 scancode_status.end = false;
2035fb12ce4SGou Ngai             }
2045fb12ce4SGou Ngai             0x51 => {
2055fb12ce4SGou Ngai                 scancode_status.pgdn = true;
2065fb12ce4SGou Ngai             }
2075fb12ce4SGou Ngai             0xd1 => {
2085fb12ce4SGou Ngai                 scancode_status.pgdn = false;
2095fb12ce4SGou Ngai             }
2105fb12ce4SGou Ngai             0x48 => {
2115fb12ce4SGou Ngai                 scancode_status.arrow_u = true;
21252da9a59SGnoCiYeH                 Self::emit(224);
21352da9a59SGnoCiYeH                 Self::emit(72);
2145fb12ce4SGou Ngai             }
2155fb12ce4SGou Ngai             0xc8 => {
2165fb12ce4SGou Ngai                 scancode_status.arrow_u = false;
2175fb12ce4SGou Ngai             }
2185fb12ce4SGou Ngai             0x4b => {
2195fb12ce4SGou Ngai                 scancode_status.arrow_l = true;
22052da9a59SGnoCiYeH                 Self::emit(224);
22152da9a59SGnoCiYeH                 Self::emit(75);
2225fb12ce4SGou Ngai             }
2235fb12ce4SGou Ngai             0xcb => {
2245fb12ce4SGou Ngai                 scancode_status.arrow_l = false;
2255fb12ce4SGou Ngai             }
2265fb12ce4SGou Ngai             0x50 => {
2275fb12ce4SGou Ngai                 scancode_status.arrow_d = true;
22852da9a59SGnoCiYeH                 Self::emit(224);
22952da9a59SGnoCiYeH                 Self::emit(80);
2305fb12ce4SGou Ngai             }
2315fb12ce4SGou Ngai             0xd0 => {
2325fb12ce4SGou Ngai                 scancode_status.arrow_d = false;
2335fb12ce4SGou Ngai             }
2345fb12ce4SGou Ngai             0x4d => {
2355fb12ce4SGou Ngai                 scancode_status.arrow_r = true;
23652da9a59SGnoCiYeH                 Self::emit(224);
23752da9a59SGnoCiYeH                 Self::emit(77);
2385fb12ce4SGou Ngai             }
2395fb12ce4SGou Ngai             0xcd => {
2405fb12ce4SGou Ngai                 scancode_status.arrow_r = false;
2415fb12ce4SGou Ngai             }
2425fb12ce4SGou Ngai 
2435fb12ce4SGou Ngai             0x35 => {
2445fb12ce4SGou Ngai                 // 数字小键盘的 / 符号
2455fb12ce4SGou Ngai                 scancode_status.kp_forward_slash = true;
2465fb12ce4SGou Ngai 
2475fb12ce4SGou Ngai                 let ch = '/' as u8;
24852da9a59SGnoCiYeH                 Self::emit(ch);
2495fb12ce4SGou Ngai             }
2505fb12ce4SGou Ngai             0xb5 => {
2515fb12ce4SGou Ngai                 scancode_status.kp_forward_slash = false;
2525fb12ce4SGou Ngai             }
2535fb12ce4SGou Ngai             0x1c => {
2545fb12ce4SGou Ngai                 scancode_status.kp_enter = true;
25552da9a59SGnoCiYeH                 Self::emit('\n' as u8);
2565fb12ce4SGou Ngai             }
2575fb12ce4SGou Ngai             0x9c => {
2585fb12ce4SGou Ngai                 scancode_status.kp_enter = false;
2595fb12ce4SGou Ngai             }
2605fb12ce4SGou Ngai             _ => {
2615fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
2625fb12ce4SGou Ngai             }
2635fb12ce4SGou Ngai         }
2645fb12ce4SGou Ngai         return TypeOneFSMState::Start;
2655fb12ce4SGou Ngai     }
2665fb12ce4SGou Ngai 
26752da9a59SGnoCiYeH     fn handle_type3(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
2685fb12ce4SGou Ngai         // 判断按键是被按下还是抬起
2695fb12ce4SGou Ngai         let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 {
270d7b31a96SGou Ngai             false //up
2715fb12ce4SGou Ngai         } else {
272d7b31a96SGou Ngai             true //down
2735fb12ce4SGou Ngai         };
2745fb12ce4SGou Ngai 
2755fb12ce4SGou Ngai         // 计算扫描码位于码表的第几行
276d7b31a96SGou Ngai         let mut col: bool = false;
2775fb12ce4SGou Ngai         let index = scancode & 0x7f;
2785fb12ce4SGou Ngai 
2795fb12ce4SGou Ngai         //kdebug!("in type3 ch is {:#x}\n",ch);
2805fb12ce4SGou Ngai         let mut key = KeyFlag::OtherKey; // 可视字符
2815fb12ce4SGou Ngai 
2825fb12ce4SGou Ngai         match index {
2835fb12ce4SGou Ngai             0x2a => {
2845fb12ce4SGou Ngai                 scancode_status.shift_l = flag_make;
2855fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
2865fb12ce4SGou Ngai             }
2875fb12ce4SGou Ngai             0x36 => {
2885fb12ce4SGou Ngai                 scancode_status.shift_r = flag_make;
2895fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
2905fb12ce4SGou Ngai             }
2915fb12ce4SGou Ngai             0x1d => {
2925fb12ce4SGou Ngai                 scancode_status.ctrl_l = flag_make;
2935fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
2945fb12ce4SGou Ngai             }
2955fb12ce4SGou Ngai             0x38 => {
296d7b31a96SGou Ngai                 scancode_status.alt_r = flag_make;
297d7b31a96SGou Ngai                 key = KeyFlag::NoneFlag;
298d7b31a96SGou Ngai             }
299d7b31a96SGou Ngai             0x3A => {
300d7b31a96SGou Ngai                 if scancode_status.caps_lock {
301d7b31a96SGou Ngai                     scancode_status.caps_lock = !flag_make;
302d7b31a96SGou Ngai                 }
303d7b31a96SGou Ngai                 //if caps_lock: true, flag_make: true => cap_lock: false
304d7b31a96SGou Ngai                 else {
305d7b31a96SGou Ngai                     scancode_status.caps_lock = flag_make;
306d7b31a96SGou Ngai                 } //else false => cap_lock: true
3075fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
3085fb12ce4SGou Ngai             }
3095fb12ce4SGou Ngai             _ => {
3105fb12ce4SGou Ngai                 if flag_make == false {
3115fb12ce4SGou Ngai                     // kdebug!("in type3 ch is {:#x}\n",ch);
3125fb12ce4SGou Ngai                     key = KeyFlag::NoneFlag;
3135fb12ce4SGou Ngai                 }
3145fb12ce4SGou Ngai             }
3155fb12ce4SGou Ngai         }
3165fb12ce4SGou Ngai 
317d7b31a96SGou Ngai         // shift被按下
318d7b31a96SGou Ngai         if scancode_status.shift_l || scancode_status.shift_r {
319d7b31a96SGou Ngai             col = true;
320d7b31a96SGou Ngai         }
321d7b31a96SGou Ngai 
322d7b31a96SGou Ngai         if scancode_status.caps_lock {
323d7b31a96SGou Ngai             if index >= 0x10 && index <= 0x19 {
324d7b31a96SGou Ngai                 col = !col;
325d7b31a96SGou Ngai             } else if index >= 0x1e && index <= 0x26 {
326d7b31a96SGou Ngai                 col = !col;
327d7b31a96SGou Ngai             } else if index >= 0x2c && index <= 0x32 {
328d7b31a96SGou Ngai                 col = !col;
329d7b31a96SGou Ngai             }
330d7b31a96SGou Ngai         }
331d7b31a96SGou Ngai 
33252da9a59SGnoCiYeH         let mut ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize];
3335fb12ce4SGou Ngai         if key != KeyFlag::NoneFlag {
33401bd5258SLoGin             // kdebug!("EMIT: ch is '{}', keyflag is {:?}\n", ch as char, key);
33552da9a59SGnoCiYeH             if scancode_status.ctrl_l || scancode_status.ctrl_r {
33652da9a59SGnoCiYeH                 ch = Self::to_ctrl(ch);
33752da9a59SGnoCiYeH             }
33852da9a59SGnoCiYeH             Self::emit(ch);
3395fb12ce4SGou Ngai         }
3405fb12ce4SGou Ngai         return TypeOneFSMState::Start;
3415fb12ce4SGou Ngai     }
3425fb12ce4SGou Ngai 
34352da9a59SGnoCiYeH     #[inline]
34452da9a59SGnoCiYeH     fn to_ctrl(ch: u8) -> u8 {
34552da9a59SGnoCiYeH         return match ch as char {
34652da9a59SGnoCiYeH             'a'..='z' => ch - 0x40,
34752da9a59SGnoCiYeH             'A'..='Z' => ch - 0x40,
34852da9a59SGnoCiYeH             '@'..='_' => ch - 0x40,
34952da9a59SGnoCiYeH             _ => ch,
35052da9a59SGnoCiYeH         };
35152da9a59SGnoCiYeH     }
35252da9a59SGnoCiYeH 
35320e3152eSlogin     #[inline(always)]
35452da9a59SGnoCiYeH     fn emit(ch: u8) {
35520e3152eSlogin         // 发送到tty
356*59fdb447SLoGin         send_to_tty_refresh_thread(&[ch]);
3575fb12ce4SGou Ngai     }
3585fb12ce4SGou Ngai 
3595fb12ce4SGou Ngai     /// @brief 处理Prtsc按下事件
3605fb12ce4SGou Ngai     fn handle_prtsc_press(
3615fb12ce4SGou Ngai         &self,
3625fb12ce4SGou Ngai         scancode: u8,
3635fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
3645fb12ce4SGou Ngai     ) -> TypeOneFSMState {
3655fb12ce4SGou Ngai         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37];
3665fb12ce4SGou Ngai         let i = match self {
3675fb12ce4SGou Ngai             TypeOneFSMState::PrtscPress(i) => *i,
3685fb12ce4SGou Ngai             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
3695fb12ce4SGou Ngai         };
3705fb12ce4SGou Ngai         if i > 3 {
3715fb12ce4SGou Ngai             // 解析错误,返回起始状态
3725fb12ce4SGou Ngai             return TypeOneFSMState::Start;
3735fb12ce4SGou Ngai         }
3745fb12ce4SGou Ngai         if scancode != PRTSC_SCAN_CODE[i as usize] {
37552da9a59SGnoCiYeH             return self.handle_type3(scancode, scancode_status);
3765fb12ce4SGou Ngai         } else {
3775fb12ce4SGou Ngai             if i == 3 {
3785fb12ce4SGou Ngai                 // 成功解析出PrtscPress
3795fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
3805fb12ce4SGou Ngai             } else {
3815fb12ce4SGou Ngai                 // 继续解析
3825fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscPress(i + 1);
3835fb12ce4SGou Ngai             }
3845fb12ce4SGou Ngai         }
3855fb12ce4SGou Ngai     }
3865fb12ce4SGou Ngai 
3875fb12ce4SGou Ngai     fn handle_prtsc_release(
3885fb12ce4SGou Ngai         &self,
3895fb12ce4SGou Ngai         scancode: u8,
3905fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
3915fb12ce4SGou Ngai     ) -> TypeOneFSMState {
3925fb12ce4SGou Ngai         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
3935fb12ce4SGou Ngai         let i = match self {
3945fb12ce4SGou Ngai             TypeOneFSMState::PrtscRelease(i) => *i,
3955fb12ce4SGou Ngai             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
3965fb12ce4SGou Ngai         };
3975fb12ce4SGou Ngai         if i > 3 {
3985fb12ce4SGou Ngai             // 解析错误,返回起始状态
3995fb12ce4SGou Ngai             return TypeOneFSMState::Start;
4005fb12ce4SGou Ngai         }
4015fb12ce4SGou Ngai         if scancode != PRTSC_SCAN_CODE[i as usize] {
40252da9a59SGnoCiYeH             return self.handle_type3(scancode, scancode_status);
4035fb12ce4SGou Ngai         } else {
4045fb12ce4SGou Ngai             if i == 3 {
4055fb12ce4SGou Ngai                 // 成功解析出PrtscRelease
4065fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
4075fb12ce4SGou Ngai             } else {
4085fb12ce4SGou Ngai                 // 继续解析
4095fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscRelease(i + 1);
4105fb12ce4SGou Ngai             }
4115fb12ce4SGou Ngai         }
4125fb12ce4SGou Ngai     }
4135fb12ce4SGou Ngai }
4145fb12ce4SGou Ngai 
4155fb12ce4SGou Ngai /// 按键状态
4165fb12ce4SGou Ngai #[derive(Debug)]
417d7b31a96SGou Ngai #[allow(dead_code)]
4185fb12ce4SGou Ngai pub struct ScanCodeStatus {
4195fb12ce4SGou Ngai     // Shift 按键
4205fb12ce4SGou Ngai     shift_l: bool,
4215fb12ce4SGou Ngai     shift_r: bool,
4225fb12ce4SGou Ngai     // Ctrl 按键
4235fb12ce4SGou Ngai     ctrl_l: bool,
4245fb12ce4SGou Ngai     ctrl_r: bool,
4255fb12ce4SGou Ngai     // Alt 按键
4265fb12ce4SGou Ngai     alt_l: bool,
4275fb12ce4SGou Ngai     alt_r: bool,
4285fb12ce4SGou Ngai     //
4295fb12ce4SGou Ngai     gui_l: bool,
4305fb12ce4SGou Ngai     gui_r: bool,
4315fb12ce4SGou Ngai     //
4325fb12ce4SGou Ngai     apps: bool,
4335fb12ce4SGou Ngai     insert: bool,
4345fb12ce4SGou Ngai     // page up/down
4355fb12ce4SGou Ngai     pgup: bool,
4365fb12ce4SGou Ngai     pgdn: bool,
4375fb12ce4SGou Ngai     del: bool,
4385fb12ce4SGou Ngai     home: bool,
4395fb12ce4SGou Ngai     end: bool,
4405fb12ce4SGou Ngai     arrow_u: bool,
4415fb12ce4SGou Ngai     arrow_l: bool,
4425fb12ce4SGou Ngai     arrow_d: bool,
4435fb12ce4SGou Ngai     arrow_r: bool,
4445fb12ce4SGou Ngai     // 斜杠
4455fb12ce4SGou Ngai     kp_forward_slash: bool,
4465fb12ce4SGou Ngai     // 回车
4475fb12ce4SGou Ngai     kp_enter: bool,
448d7b31a96SGou Ngai     caps_lock: bool,
4495fb12ce4SGou Ngai }
4505fb12ce4SGou Ngai 
4515fb12ce4SGou Ngai impl ScanCodeStatus {
4525fb12ce4SGou Ngai     fn new() -> Self {
4535fb12ce4SGou Ngai         ScanCodeStatus {
4545fb12ce4SGou Ngai             shift_l: false,
4555fb12ce4SGou Ngai             shift_r: false,
4565fb12ce4SGou Ngai             ctrl_l: false,
4575fb12ce4SGou Ngai             ctrl_r: false,
4585fb12ce4SGou Ngai             alt_l: false,
4595fb12ce4SGou Ngai             alt_r: false,
4605fb12ce4SGou Ngai             gui_l: false,
4615fb12ce4SGou Ngai             gui_r: false,
4625fb12ce4SGou Ngai             apps: false,
4635fb12ce4SGou Ngai             insert: false,
4645fb12ce4SGou Ngai             pgup: false,
4655fb12ce4SGou Ngai             pgdn: false,
4665fb12ce4SGou Ngai             del: false,
4675fb12ce4SGou Ngai             home: false,
4685fb12ce4SGou Ngai             end: false,
4695fb12ce4SGou Ngai             arrow_u: false,
4705fb12ce4SGou Ngai             arrow_l: false,
4715fb12ce4SGou Ngai             arrow_d: false,
4725fb12ce4SGou Ngai             arrow_r: false,
4735fb12ce4SGou Ngai             kp_forward_slash: false,
4745fb12ce4SGou Ngai             kp_enter: false,
475d7b31a96SGou Ngai             caps_lock: false,
4765fb12ce4SGou Ngai         }
4775fb12ce4SGou Ngai     }
4785fb12ce4SGou Ngai }
4795fb12ce4SGou Ngai 
4805fb12ce4SGou Ngai const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [
4815fb12ce4SGou Ngai     /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC
4825fb12ce4SGou Ngai     /*0x02*/ '1' as u8, '!' as u8, /*0x03*/ '2' as u8, '@' as u8,
4835fb12ce4SGou Ngai     /*0x04*/ '3' as u8, '#' as u8, /*0x05*/ '4' as u8, '$' as u8,
4845fb12ce4SGou Ngai     /*0x06*/ '5' as u8, '%' as u8, /*0x07*/ '6' as u8, '^' as u8,
4855fb12ce4SGou Ngai     /*0x08*/ '7' as u8, '&' as u8, /*0x09*/ '8' as u8, '*' as u8,
4865fb12ce4SGou Ngai     /*0x0a*/ '9' as u8, '(' as u8, /*0x0b*/ '0' as u8, ')' as u8,
4875fb12ce4SGou Ngai     /*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8,
48820e3152eSlogin     /*0x0e  \b */ 8 as u8, 8 as u8, // BACKSPACE
4895fb12ce4SGou Ngai     /*0x0f*/ '\t' as u8, '\t' as u8, // TAB
490d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
491d7b31a96SGou Ngai     /*0x10*/ 'q' as u8,
492d7b31a96SGou Ngai     'Q' as u8, /*0x11*/ 'w' as u8, 'W' as u8, /*0x12*/ 'e' as u8, 'E' as u8,
493d7b31a96SGou Ngai     /*0x13*/ 'r' as u8, 'R' as u8, /*0x14*/ 't' as u8, 'T' as u8,
494d7b31a96SGou Ngai     /*0x15*/ 'y' as u8, 'Y' as u8, /*0x16*/ 'u' as u8, 'U' as u8,
495d7b31a96SGou Ngai     /*0x17*/ 'i' as u8, 'I' as u8, /*0x18*/ 'o' as u8, 'O' as u8,
496d7b31a96SGou Ngai     /*0x19*/ 'p' as u8, 'P' as u8,
497d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
498d7b31a96SGou Ngai 
499d7b31a96SGou Ngai     /*0x1a*/ '[' as u8,
500d7b31a96SGou Ngai     '{' as u8, /*0x1b*/ ']' as u8, '}' as u8, /*0x1c*/ '\n' as u8,
501d7b31a96SGou Ngai     '\n' as u8, // ENTER
5025fb12ce4SGou Ngai     /*0x1d*/ 0x1d, 0x1d, // CTRL Left
503d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
504d7b31a96SGou Ngai     /*0x1e*/ 'a' as u8,
505d7b31a96SGou Ngai     'A' as u8, /*0x1f*/ 's' as u8, 'S' as u8, /*0x20*/ 'd' as u8, 'D' as u8,
506d7b31a96SGou Ngai     /*0x21*/ 'f' as u8, 'F' as u8, /*0x22*/ 'g' as u8, 'G' as u8,
507d7b31a96SGou Ngai     /*0x23*/ 'h' as u8, 'H' as u8, /*0x24*/ 'j' as u8, 'J' as u8,
508d7b31a96SGou Ngai     /*0x25*/ 'k' as u8, 'K' as u8, /*0x26*/ 'l' as u8, 'L' as u8,
509d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
510d7b31a96SGou Ngai 
511d7b31a96SGou Ngai     /*0x27*/ ';' as u8,
512d7b31a96SGou Ngai     ':' as u8, /*0x28*/ '\'' as u8, '"' as u8, /*0x29*/ '`' as u8, '~' as u8,
513d7b31a96SGou Ngai     /*0x2a*/ 0x2a, 0x2a, // SHIFT Left
514d7b31a96SGou Ngai     /*0x2b*/ '\\' as u8, '|' as u8,
515d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
516d7b31a96SGou Ngai     /*0x2c*/ 'z' as u8,
517d7b31a96SGou Ngai     'Z' as u8, /*0x2d*/ 'x' as u8, 'X' as u8, /*0x2e*/ 'c' as u8, 'C' as u8,
5185fb12ce4SGou Ngai     /*0x2f*/ 'v' as u8, 'V' as u8, /*0x30*/ 'b' as u8, 'B' as u8,
5195fb12ce4SGou Ngai     /*0x31*/ 'n' as u8, 'N' as u8, /*0x32*/ 'm' as u8, 'M' as u8,
520d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
521d7b31a96SGou Ngai 
522d7b31a96SGou Ngai     /*0x33*/ ',' as u8,
523d7b31a96SGou Ngai     '<' as u8, /*0x34*/ '.' as u8, '>' as u8, /*0x35*/ '/' as u8, '?' as u8,
524d7b31a96SGou Ngai     /*0x36*/ 0x36, 0x36, // SHIFT Right
5255fb12ce4SGou Ngai     /*0x37*/ '*' as u8, '*' as u8, /*0x38*/ 0x38, 0x38, // ALT Left
5265fb12ce4SGou Ngai     /*0x39*/ ' ' as u8, ' ' as u8, /*0x3a*/ 0, 0, // CAPS LOCK
5275fb12ce4SGou Ngai     /*0x3b*/ 0, 0, // F1
5285fb12ce4SGou Ngai     /*0x3c*/ 0, 0, // F2
5295fb12ce4SGou Ngai     /*0x3d*/ 0, 0, // F3
5305fb12ce4SGou Ngai     /*0x3e*/ 0, 0, // F4
5315fb12ce4SGou Ngai     /*0x3f*/ 0, 0, // F5
5325fb12ce4SGou Ngai     /*0x40*/ 0, 0, // F6
5335fb12ce4SGou Ngai     /*0x41*/ 0, 0, // F7
5345fb12ce4SGou Ngai     /*0x42*/ 0, 0, // F8
5355fb12ce4SGou Ngai     /*0x43*/ 0, 0, // F9
5365fb12ce4SGou Ngai     /*0x44*/ 0, 0, // F10
5375fb12ce4SGou Ngai     /*0x45*/ 0, 0, // NUM LOCK
5385fb12ce4SGou Ngai     /*0x46*/ 0, 0, // SCROLL LOCK
5395fb12ce4SGou Ngai     /*0x47*/ '7' as u8, 0, /*PAD HONE*/
5405fb12ce4SGou Ngai     /*0x48*/ '8' as u8, 0, /*PAD UP*/
5415fb12ce4SGou Ngai     /*0x49*/ '9' as u8, 0, /*PAD PAGEUP*/
5425fb12ce4SGou Ngai     /*0x4a*/ '-' as u8, 0, /*PAD MINUS*/
5435fb12ce4SGou Ngai     /*0x4b*/ '4' as u8, 0, /*PAD LEFT*/
5445fb12ce4SGou Ngai     /*0x4c*/ '5' as u8, 0, /*PAD MID*/
5455fb12ce4SGou Ngai     /*0x4d*/ '6' as u8, 0, /*PAD RIGHT*/
5465fb12ce4SGou Ngai     /*0x4e*/ '+' as u8, 0, /*PAD PLUS*/
5475fb12ce4SGou Ngai     /*0x4f*/ '1' as u8, 0, /*PAD END*/
5485fb12ce4SGou Ngai     /*0x50*/ '2' as u8, 0, /*PAD DOWN*/
5495fb12ce4SGou Ngai     /*0x51*/ '3' as u8, 0, /*PAD PAGEDOWN*/
5505fb12ce4SGou Ngai     /*0x52*/ '0' as u8, 0, /*PAD INS*/
5515fb12ce4SGou Ngai     /*0x53*/ '.' as u8, 0, /*PAD DOT*/
5525fb12ce4SGou Ngai     /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11
5535fb12ce4SGou Ngai     /*0x58*/ 0, 0, // F12
5545fb12ce4SGou Ngai     /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0,
5555fb12ce4SGou Ngai     /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0,
5565fb12ce4SGou Ngai     /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0,
5575fb12ce4SGou Ngai     /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0,
5585fb12ce4SGou Ngai     /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0,
5595fb12ce4SGou Ngai     /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0,
5605fb12ce4SGou Ngai     /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0,
5615fb12ce4SGou Ngai     /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0,
5625fb12ce4SGou Ngai     /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0,
5635fb12ce4SGou Ngai     /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0,
5645fb12ce4SGou Ngai ];
565