xref: /DragonOS/kernel/src/libs/keyboard_parser.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
159fdb447SLoGin 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 {
16*b5b571e0SLoGin     NoneFlag = 0_u8,
17*b5b571e0SLoGin     PauseBreak = 1_u8,
18*b5b571e0SLoGin     PrintScreenPress = 2_u8,
19*b5b571e0SLoGin     PrintScreenRelease = 4_u8,
20*b5b571e0SLoGin     OtherKey = 8_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);
120*b5b571e0SLoGin         } else if i == 5 {
1215fb12ce4SGou Ngai             // 所有Pause Break扫描码都被清除
1225fb12ce4SGou Ngai             return TypeOneFSMState::Start;
1235fb12ce4SGou Ngai         } else {
1245fb12ce4SGou Ngai             return TypeOneFSMState::PauseBreak(i + 1);
1255fb12ce4SGou Ngai         }
1265fb12ce4SGou Ngai     }
1275fb12ce4SGou Ngai 
12852da9a59SGnoCiYeH     fn handle_func0(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
1295fb12ce4SGou Ngai         //0xE0
1305fb12ce4SGou Ngai         match scancode {
1315fb12ce4SGou Ngai             0x2a => {
1325fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscPress(2);
1335fb12ce4SGou Ngai             }
1345fb12ce4SGou Ngai             0xb7 => {
1355fb12ce4SGou Ngai                 return TypeOneFSMState::PrtscRelease(2);
1365fb12ce4SGou Ngai             }
1375fb12ce4SGou Ngai             0x1d => {
1385fb12ce4SGou Ngai                 // 按下右边的ctrl
1395fb12ce4SGou Ngai                 scancode_status.ctrl_r = true;
1405fb12ce4SGou Ngai             }
1415fb12ce4SGou Ngai             0x9d => {
1425fb12ce4SGou Ngai                 // 松开右边的ctrl
1435fb12ce4SGou Ngai                 scancode_status.ctrl_r = false;
1445fb12ce4SGou Ngai             }
1455fb12ce4SGou Ngai             0x38 => {
1465fb12ce4SGou Ngai                 // 按下右边的alt
1475fb12ce4SGou Ngai                 scancode_status.alt_r = true;
1485fb12ce4SGou Ngai             }
1495fb12ce4SGou Ngai             0xb8 => {
1505fb12ce4SGou Ngai                 // 松开右边的alt
1515fb12ce4SGou Ngai                 scancode_status.alt_r = false;
1525fb12ce4SGou Ngai             }
1535fb12ce4SGou Ngai             0x5b => {
1545fb12ce4SGou Ngai                 scancode_status.gui_l = true;
1555fb12ce4SGou Ngai             }
1565fb12ce4SGou Ngai             0xdb => {
1575fb12ce4SGou Ngai                 scancode_status.gui_l = false;
1585fb12ce4SGou Ngai             }
1595fb12ce4SGou Ngai             0x5c => {
1605fb12ce4SGou Ngai                 scancode_status.gui_r = true;
1615fb12ce4SGou Ngai             }
1625fb12ce4SGou Ngai             0xdc => {
1635fb12ce4SGou Ngai                 scancode_status.gui_r = false;
1645fb12ce4SGou Ngai             }
1655fb12ce4SGou Ngai             0x5d => {
1665fb12ce4SGou Ngai                 scancode_status.apps = true;
1675fb12ce4SGou Ngai             }
1685fb12ce4SGou Ngai             0xdd => {
1695fb12ce4SGou Ngai                 scancode_status.apps = false;
1705fb12ce4SGou Ngai             }
1715fb12ce4SGou Ngai             0x52 => {
1725fb12ce4SGou Ngai                 scancode_status.insert = true;
1735fb12ce4SGou Ngai             }
1745fb12ce4SGou Ngai             0xd2 => {
1755fb12ce4SGou Ngai                 scancode_status.insert = false;
1765fb12ce4SGou Ngai             }
1775fb12ce4SGou Ngai             0x47 => {
1785fb12ce4SGou Ngai                 scancode_status.home = true;
1795fb12ce4SGou Ngai             }
1805fb12ce4SGou Ngai             0xc7 => {
1815fb12ce4SGou Ngai                 scancode_status.home = false;
1825fb12ce4SGou Ngai             }
1835fb12ce4SGou Ngai             0x49 => {
1845fb12ce4SGou Ngai                 scancode_status.pgup = true;
1855fb12ce4SGou Ngai             }
1865fb12ce4SGou Ngai             0xc9 => {
1875fb12ce4SGou Ngai                 scancode_status.pgup = false;
1885fb12ce4SGou Ngai             }
1895fb12ce4SGou Ngai             0x53 => {
1905fb12ce4SGou Ngai                 scancode_status.del = true;
19152da9a59SGnoCiYeH                 Self::emit(127);
1925fb12ce4SGou Ngai             }
1935fb12ce4SGou Ngai             0xd3 => {
1945fb12ce4SGou Ngai                 scancode_status.del = false;
1955fb12ce4SGou Ngai             }
1965fb12ce4SGou Ngai             0x4f => {
1975fb12ce4SGou Ngai                 scancode_status.end = true;
1985fb12ce4SGou Ngai             }
1995fb12ce4SGou Ngai             0xcf => {
2005fb12ce4SGou Ngai                 scancode_status.end = false;
2015fb12ce4SGou Ngai             }
2025fb12ce4SGou Ngai             0x51 => {
2035fb12ce4SGou Ngai                 scancode_status.pgdn = true;
2045fb12ce4SGou Ngai             }
2055fb12ce4SGou Ngai             0xd1 => {
2065fb12ce4SGou Ngai                 scancode_status.pgdn = false;
2075fb12ce4SGou Ngai             }
2085fb12ce4SGou Ngai             0x48 => {
2095fb12ce4SGou Ngai                 scancode_status.arrow_u = true;
21052da9a59SGnoCiYeH                 Self::emit(224);
21152da9a59SGnoCiYeH                 Self::emit(72);
2125fb12ce4SGou Ngai             }
2135fb12ce4SGou Ngai             0xc8 => {
2145fb12ce4SGou Ngai                 scancode_status.arrow_u = false;
2155fb12ce4SGou Ngai             }
2165fb12ce4SGou Ngai             0x4b => {
2175fb12ce4SGou Ngai                 scancode_status.arrow_l = true;
21852da9a59SGnoCiYeH                 Self::emit(224);
21952da9a59SGnoCiYeH                 Self::emit(75);
2205fb12ce4SGou Ngai             }
2215fb12ce4SGou Ngai             0xcb => {
2225fb12ce4SGou Ngai                 scancode_status.arrow_l = false;
2235fb12ce4SGou Ngai             }
2245fb12ce4SGou Ngai             0x50 => {
2255fb12ce4SGou Ngai                 scancode_status.arrow_d = true;
22652da9a59SGnoCiYeH                 Self::emit(224);
22752da9a59SGnoCiYeH                 Self::emit(80);
2285fb12ce4SGou Ngai             }
2295fb12ce4SGou Ngai             0xd0 => {
2305fb12ce4SGou Ngai                 scancode_status.arrow_d = false;
2315fb12ce4SGou Ngai             }
2325fb12ce4SGou Ngai             0x4d => {
2335fb12ce4SGou Ngai                 scancode_status.arrow_r = true;
23452da9a59SGnoCiYeH                 Self::emit(224);
23552da9a59SGnoCiYeH                 Self::emit(77);
2365fb12ce4SGou Ngai             }
2375fb12ce4SGou Ngai             0xcd => {
2385fb12ce4SGou Ngai                 scancode_status.arrow_r = false;
2395fb12ce4SGou Ngai             }
2405fb12ce4SGou Ngai 
2415fb12ce4SGou Ngai             0x35 => {
2425fb12ce4SGou Ngai                 // 数字小键盘的 / 符号
2435fb12ce4SGou Ngai                 scancode_status.kp_forward_slash = true;
2445fb12ce4SGou Ngai 
245*b5b571e0SLoGin                 let ch = b'/';
24652da9a59SGnoCiYeH                 Self::emit(ch);
2475fb12ce4SGou Ngai             }
2485fb12ce4SGou Ngai             0xb5 => {
2495fb12ce4SGou Ngai                 scancode_status.kp_forward_slash = false;
2505fb12ce4SGou Ngai             }
2515fb12ce4SGou Ngai             0x1c => {
2525fb12ce4SGou Ngai                 scancode_status.kp_enter = true;
253*b5b571e0SLoGin                 Self::emit(b'\n');
2545fb12ce4SGou Ngai             }
2555fb12ce4SGou Ngai             0x9c => {
2565fb12ce4SGou Ngai                 scancode_status.kp_enter = false;
2575fb12ce4SGou Ngai             }
2585fb12ce4SGou Ngai             _ => {
2595fb12ce4SGou Ngai                 return TypeOneFSMState::Start;
2605fb12ce4SGou Ngai             }
2615fb12ce4SGou Ngai         }
2625fb12ce4SGou Ngai         return TypeOneFSMState::Start;
2635fb12ce4SGou Ngai     }
2645fb12ce4SGou Ngai 
26552da9a59SGnoCiYeH     fn handle_type3(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState {
2665fb12ce4SGou Ngai         // 判断按键是被按下还是抬起
267*b5b571e0SLoGin         let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK)) > 0 {
268d7b31a96SGou Ngai             false //up
2695fb12ce4SGou Ngai         } else {
270d7b31a96SGou Ngai             true //down
2715fb12ce4SGou Ngai         };
2725fb12ce4SGou Ngai 
2735fb12ce4SGou Ngai         // 计算扫描码位于码表的第几行
274d7b31a96SGou Ngai         let mut col: bool = false;
2755fb12ce4SGou Ngai         let index = scancode & 0x7f;
2765fb12ce4SGou Ngai 
2775fb12ce4SGou Ngai         //kdebug!("in type3 ch is {:#x}\n",ch);
2785fb12ce4SGou Ngai         let mut key = KeyFlag::OtherKey; // 可视字符
2795fb12ce4SGou Ngai 
2805fb12ce4SGou Ngai         match index {
2815fb12ce4SGou Ngai             0x2a => {
2825fb12ce4SGou Ngai                 scancode_status.shift_l = flag_make;
2835fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
2845fb12ce4SGou Ngai             }
2855fb12ce4SGou Ngai             0x36 => {
2865fb12ce4SGou Ngai                 scancode_status.shift_r = flag_make;
2875fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
2885fb12ce4SGou Ngai             }
2895fb12ce4SGou Ngai             0x1d => {
2905fb12ce4SGou Ngai                 scancode_status.ctrl_l = flag_make;
2915fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
2925fb12ce4SGou Ngai             }
2935fb12ce4SGou Ngai             0x38 => {
294d7b31a96SGou Ngai                 scancode_status.alt_r = flag_make;
295d7b31a96SGou Ngai                 key = KeyFlag::NoneFlag;
296d7b31a96SGou Ngai             }
297d7b31a96SGou Ngai             0x3A => {
298d7b31a96SGou Ngai                 if scancode_status.caps_lock {
299d7b31a96SGou Ngai                     scancode_status.caps_lock = !flag_make;
300d7b31a96SGou Ngai                 }
301d7b31a96SGou Ngai                 //if caps_lock: true, flag_make: true => cap_lock: false
302d7b31a96SGou Ngai                 else {
303d7b31a96SGou Ngai                     scancode_status.caps_lock = flag_make;
304d7b31a96SGou Ngai                 } //else false => cap_lock: true
3055fb12ce4SGou Ngai                 key = KeyFlag::NoneFlag;
3065fb12ce4SGou Ngai             }
3075fb12ce4SGou Ngai             _ => {
308*b5b571e0SLoGin                 if !flag_make {
3095fb12ce4SGou Ngai                     // kdebug!("in type3 ch is {:#x}\n",ch);
3105fb12ce4SGou Ngai                     key = KeyFlag::NoneFlag;
3115fb12ce4SGou Ngai                 }
3125fb12ce4SGou Ngai             }
3135fb12ce4SGou Ngai         }
3145fb12ce4SGou Ngai 
315d7b31a96SGou Ngai         // shift被按下
316d7b31a96SGou Ngai         if scancode_status.shift_l || scancode_status.shift_r {
317d7b31a96SGou Ngai             col = true;
318d7b31a96SGou Ngai         }
319d7b31a96SGou Ngai 
320*b5b571e0SLoGin         if scancode_status.caps_lock
321*b5b571e0SLoGin             && ((0x10..=0x19).contains(&index)
322*b5b571e0SLoGin                 || (0x1e..=0x26).contains(&index)
323*b5b571e0SLoGin                 || (0x2c..=0x32).contains(&index))
324*b5b571e0SLoGin         {
325d7b31a96SGou Ngai             col = !col;
326d7b31a96SGou Ngai         }
327d7b31a96SGou Ngai 
32852da9a59SGnoCiYeH         let mut ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize];
3295fb12ce4SGou Ngai         if key != KeyFlag::NoneFlag {
33001bd5258SLoGin             // kdebug!("EMIT: ch is '{}', keyflag is {:?}\n", ch as char, key);
33152da9a59SGnoCiYeH             if scancode_status.ctrl_l || scancode_status.ctrl_r {
33252da9a59SGnoCiYeH                 ch = Self::to_ctrl(ch);
33352da9a59SGnoCiYeH             }
33452da9a59SGnoCiYeH             Self::emit(ch);
3355fb12ce4SGou Ngai         }
3365fb12ce4SGou Ngai         return TypeOneFSMState::Start;
3375fb12ce4SGou Ngai     }
3385fb12ce4SGou Ngai 
33952da9a59SGnoCiYeH     #[inline]
34052da9a59SGnoCiYeH     fn to_ctrl(ch: u8) -> u8 {
34152da9a59SGnoCiYeH         return match ch as char {
34252da9a59SGnoCiYeH             'a'..='z' => ch - 0x40,
34352da9a59SGnoCiYeH             'A'..='Z' => ch - 0x40,
34452da9a59SGnoCiYeH             '@'..='_' => ch - 0x40,
34552da9a59SGnoCiYeH             _ => ch,
34652da9a59SGnoCiYeH         };
34752da9a59SGnoCiYeH     }
34852da9a59SGnoCiYeH 
34920e3152eSlogin     #[inline(always)]
35052da9a59SGnoCiYeH     fn emit(ch: u8) {
35120e3152eSlogin         // 发送到tty
35259fdb447SLoGin         send_to_tty_refresh_thread(&[ch]);
3535fb12ce4SGou Ngai     }
3545fb12ce4SGou Ngai 
3555fb12ce4SGou Ngai     /// @brief 处理Prtsc按下事件
3565fb12ce4SGou Ngai     fn handle_prtsc_press(
3575fb12ce4SGou Ngai         &self,
3585fb12ce4SGou Ngai         scancode: u8,
3595fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
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] {
37152da9a59SGnoCiYeH             return self.handle_type3(scancode, scancode_status);
372*b5b571e0SLoGin         } else if i == 3 {
3735fb12ce4SGou Ngai             // 成功解析出PrtscPress
3745fb12ce4SGou Ngai             return TypeOneFSMState::Start;
3755fb12ce4SGou Ngai         } else {
3765fb12ce4SGou Ngai             // 继续解析
3775fb12ce4SGou Ngai             return TypeOneFSMState::PrtscPress(i + 1);
3785fb12ce4SGou Ngai         }
3795fb12ce4SGou Ngai     }
3805fb12ce4SGou Ngai 
3815fb12ce4SGou Ngai     fn handle_prtsc_release(
3825fb12ce4SGou Ngai         &self,
3835fb12ce4SGou Ngai         scancode: u8,
3845fb12ce4SGou Ngai         scancode_status: &mut ScanCodeStatus,
3855fb12ce4SGou Ngai     ) -> TypeOneFSMState {
3865fb12ce4SGou Ngai         static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa];
3875fb12ce4SGou Ngai         let i = match self {
3885fb12ce4SGou Ngai             TypeOneFSMState::PrtscRelease(i) => *i,
3895fb12ce4SGou Ngai             _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态
3905fb12ce4SGou Ngai         };
3915fb12ce4SGou Ngai         if i > 3 {
3925fb12ce4SGou Ngai             // 解析错误,返回起始状态
3935fb12ce4SGou Ngai             return TypeOneFSMState::Start;
3945fb12ce4SGou Ngai         }
3955fb12ce4SGou Ngai         if scancode != PRTSC_SCAN_CODE[i as usize] {
39652da9a59SGnoCiYeH             return self.handle_type3(scancode, scancode_status);
397*b5b571e0SLoGin         } else if i == 3 {
3985fb12ce4SGou Ngai             // 成功解析出PrtscRelease
3995fb12ce4SGou Ngai             return TypeOneFSMState::Start;
4005fb12ce4SGou Ngai         } else {
4015fb12ce4SGou Ngai             // 继续解析
4025fb12ce4SGou Ngai             return TypeOneFSMState::PrtscRelease(i + 1);
4035fb12ce4SGou Ngai         }
4045fb12ce4SGou Ngai     }
4055fb12ce4SGou Ngai }
4065fb12ce4SGou Ngai 
4075fb12ce4SGou Ngai /// 按键状态
4085fb12ce4SGou Ngai #[derive(Debug)]
409d7b31a96SGou Ngai #[allow(dead_code)]
4105fb12ce4SGou Ngai pub struct ScanCodeStatus {
4115fb12ce4SGou Ngai     // Shift 按键
4125fb12ce4SGou Ngai     shift_l: bool,
4135fb12ce4SGou Ngai     shift_r: bool,
4145fb12ce4SGou Ngai     // Ctrl 按键
4155fb12ce4SGou Ngai     ctrl_l: bool,
4165fb12ce4SGou Ngai     ctrl_r: bool,
4175fb12ce4SGou Ngai     // Alt 按键
4185fb12ce4SGou Ngai     alt_l: bool,
4195fb12ce4SGou Ngai     alt_r: bool,
4205fb12ce4SGou Ngai     //
4215fb12ce4SGou Ngai     gui_l: bool,
4225fb12ce4SGou Ngai     gui_r: bool,
4235fb12ce4SGou Ngai     //
4245fb12ce4SGou Ngai     apps: bool,
4255fb12ce4SGou Ngai     insert: bool,
4265fb12ce4SGou Ngai     // page up/down
4275fb12ce4SGou Ngai     pgup: bool,
4285fb12ce4SGou Ngai     pgdn: bool,
4295fb12ce4SGou Ngai     del: bool,
4305fb12ce4SGou Ngai     home: bool,
4315fb12ce4SGou Ngai     end: bool,
4325fb12ce4SGou Ngai     arrow_u: bool,
4335fb12ce4SGou Ngai     arrow_l: bool,
4345fb12ce4SGou Ngai     arrow_d: bool,
4355fb12ce4SGou Ngai     arrow_r: bool,
4365fb12ce4SGou Ngai     // 斜杠
4375fb12ce4SGou Ngai     kp_forward_slash: bool,
4385fb12ce4SGou Ngai     // 回车
4395fb12ce4SGou Ngai     kp_enter: bool,
440d7b31a96SGou Ngai     caps_lock: bool,
4415fb12ce4SGou Ngai }
4425fb12ce4SGou Ngai 
4435fb12ce4SGou Ngai impl ScanCodeStatus {
4445fb12ce4SGou Ngai     fn new() -> Self {
4455fb12ce4SGou Ngai         ScanCodeStatus {
4465fb12ce4SGou Ngai             shift_l: false,
4475fb12ce4SGou Ngai             shift_r: false,
4485fb12ce4SGou Ngai             ctrl_l: false,
4495fb12ce4SGou Ngai             ctrl_r: false,
4505fb12ce4SGou Ngai             alt_l: false,
4515fb12ce4SGou Ngai             alt_r: false,
4525fb12ce4SGou Ngai             gui_l: false,
4535fb12ce4SGou Ngai             gui_r: false,
4545fb12ce4SGou Ngai             apps: false,
4555fb12ce4SGou Ngai             insert: false,
4565fb12ce4SGou Ngai             pgup: false,
4575fb12ce4SGou Ngai             pgdn: false,
4585fb12ce4SGou Ngai             del: false,
4595fb12ce4SGou Ngai             home: false,
4605fb12ce4SGou Ngai             end: false,
4615fb12ce4SGou Ngai             arrow_u: false,
4625fb12ce4SGou Ngai             arrow_l: false,
4635fb12ce4SGou Ngai             arrow_d: false,
4645fb12ce4SGou Ngai             arrow_r: false,
4655fb12ce4SGou Ngai             kp_forward_slash: false,
4665fb12ce4SGou Ngai             kp_enter: false,
467d7b31a96SGou Ngai             caps_lock: false,
4685fb12ce4SGou Ngai         }
4695fb12ce4SGou Ngai     }
4705fb12ce4SGou Ngai }
4715fb12ce4SGou Ngai 
4725fb12ce4SGou Ngai const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [
4735fb12ce4SGou Ngai     /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC
474*b5b571e0SLoGin     /*0x02*/ b'1', b'!', /*0x03*/ b'2', b'@', /*0x04*/ b'3', b'#',
475*b5b571e0SLoGin     /*0x05*/ b'4', b'$', /*0x06*/ b'5', b'%', /*0x07*/ b'6', b'^',
476*b5b571e0SLoGin     /*0x08*/ b'7', b'&', /*0x09*/ b'8', b'*', /*0x0a*/ b'9', b'(',
477*b5b571e0SLoGin     /*0x0b*/ b'0', b')', /*0x0c*/ b'-', b'_', /*0x0d*/ b'=', b'+',
478*b5b571e0SLoGin     /*0x0e  \b */ 8, 8, // BACKSPACE
479*b5b571e0SLoGin     /*0x0f*/ b'\t', b'\t', // TAB
480d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
481*b5b571e0SLoGin     /*0x10*/ b'q', b'Q',
482*b5b571e0SLoGin     /*0x11*/ b'w', b'W', /*0x12*/ b'e', b'E', /*0x13*/ b'r', b'R',
483*b5b571e0SLoGin     /*0x14*/ b't', b'T', /*0x15*/ b'y', b'Y', /*0x16*/ b'u', b'U',
484*b5b571e0SLoGin     /*0x17*/ b'i', b'I', /*0x18*/ b'o', b'O', /*0x19*/ b'p', b'P',
485d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
486d7b31a96SGou Ngai 
487*b5b571e0SLoGin     /*0x1a*/ b'[', b'{',
488*b5b571e0SLoGin     /*0x1b*/ b']', b'}', /*0x1c*/ b'\n', b'\n', // ENTER
4895fb12ce4SGou Ngai     /*0x1d*/ 0x1d, 0x1d, // CTRL Left
490d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
491*b5b571e0SLoGin     /*0x1e*/ b'a', b'A',
492*b5b571e0SLoGin     /*0x1f*/ b's', b'S', /*0x20*/ b'd', b'D', /*0x21*/ b'f', b'F',
493*b5b571e0SLoGin     /*0x22*/ b'g', b'G', /*0x23*/ b'h', b'H', /*0x24*/ b'j', b'J',
494*b5b571e0SLoGin     /*0x25*/ b'k', b'K', /*0x26*/ b'l', b'L',
495d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
496d7b31a96SGou Ngai 
497*b5b571e0SLoGin     /*0x27*/ b';', b':',
498*b5b571e0SLoGin     /*0x28*/ b'\'', b'"', /*0x29*/ b'`', b'~', /*0x2a*/ 0x2a,
499*b5b571e0SLoGin     0x2a, // SHIFT Left
500*b5b571e0SLoGin     /*0x2b*/ b'\\', b'|',
501d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
502*b5b571e0SLoGin     /*0x2c*/ b'z', b'Z',
503*b5b571e0SLoGin     /*0x2d*/ b'x', b'X', /*0x2e*/ b'c', b'C', /*0x2f*/ b'v', b'V',
504*b5b571e0SLoGin     /*0x30*/ b'b', b'B', /*0x31*/ b'n', b'N', /*0x32*/ b'm', b'M',
505d7b31a96SGou Ngai     ////////////////////////character///////////////////////////
506d7b31a96SGou Ngai 
507*b5b571e0SLoGin     /*0x33*/ b',', b'<',
508*b5b571e0SLoGin     /*0x34*/ b'.', b'>', /*0x35*/ b'/', b'?', /*0x36*/ 0x36,
509*b5b571e0SLoGin     0x36, // SHIFT Right
510*b5b571e0SLoGin     /*0x37*/ b'*', b'*', /*0x38*/ 0x38, 0x38, // ALT Left
511*b5b571e0SLoGin     /*0x39*/ b' ', b' ', /*0x3a*/ 0, 0, // CAPS LOCK
5125fb12ce4SGou Ngai     /*0x3b*/ 0, 0, // F1
5135fb12ce4SGou Ngai     /*0x3c*/ 0, 0, // F2
5145fb12ce4SGou Ngai     /*0x3d*/ 0, 0, // F3
5155fb12ce4SGou Ngai     /*0x3e*/ 0, 0, // F4
5165fb12ce4SGou Ngai     /*0x3f*/ 0, 0, // F5
5175fb12ce4SGou Ngai     /*0x40*/ 0, 0, // F6
5185fb12ce4SGou Ngai     /*0x41*/ 0, 0, // F7
5195fb12ce4SGou Ngai     /*0x42*/ 0, 0, // F8
5205fb12ce4SGou Ngai     /*0x43*/ 0, 0, // F9
5215fb12ce4SGou Ngai     /*0x44*/ 0, 0, // F10
5225fb12ce4SGou Ngai     /*0x45*/ 0, 0, // NUM LOCK
5235fb12ce4SGou Ngai     /*0x46*/ 0, 0, // SCROLL LOCK
524*b5b571e0SLoGin     /*0x47*/ b'7', 0, /*PAD HONE*/
525*b5b571e0SLoGin     /*0x48*/ b'8', 0, /*PAD UP*/
526*b5b571e0SLoGin     /*0x49*/ b'9', 0, /*PAD PAGEUP*/
527*b5b571e0SLoGin     /*0x4a*/ b'-', 0, /*PAD MINUS*/
528*b5b571e0SLoGin     /*0x4b*/ b'4', 0, /*PAD LEFT*/
529*b5b571e0SLoGin     /*0x4c*/ b'5', 0, /*PAD MID*/
530*b5b571e0SLoGin     /*0x4d*/ b'6', 0, /*PAD RIGHT*/
531*b5b571e0SLoGin     /*0x4e*/ b'+', 0, /*PAD PLUS*/
532*b5b571e0SLoGin     /*0x4f*/ b'1', 0, /*PAD END*/
533*b5b571e0SLoGin     /*0x50*/ b'2', 0, /*PAD DOWN*/
534*b5b571e0SLoGin     /*0x51*/ b'3', 0, /*PAD PAGEDOWN*/
535*b5b571e0SLoGin     /*0x52*/ b'0', 0, /*PAD INS*/
536*b5b571e0SLoGin     /*0x53*/ b'.', 0, /*PAD DOT*/
5375fb12ce4SGou Ngai     /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11
5385fb12ce4SGou Ngai     /*0x58*/ 0, 0, // F12
5395fb12ce4SGou Ngai     /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0,
5405fb12ce4SGou Ngai     /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0,
5415fb12ce4SGou Ngai     /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0,
5425fb12ce4SGou Ngai     /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0,
5435fb12ce4SGou Ngai     /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0,
5445fb12ce4SGou Ngai     /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0,
5455fb12ce4SGou Ngai     /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0,
5465fb12ce4SGou Ngai     /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0,
5475fb12ce4SGou Ngai     /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0,
5485fb12ce4SGou Ngai     /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0,
5495fb12ce4SGou Ngai ];
550