1*52da9a59SGnoCiYeH use core::sync::atomic::Ordering; 2*52da9a59SGnoCiYeH 320e3152eSlogin use alloc::sync::Arc; 420e3152eSlogin 5*52da9a59SGnoCiYeH use crate::driver::tty::{ 6*52da9a59SGnoCiYeH tty_port::{TtyPort, TTY_PORTS}, 7*52da9a59SGnoCiYeH virtual_terminal::virtual_console::CURRENT_VCNUM, 8*52da9a59SGnoCiYeH }; 95fb12ce4SGou Ngai 105fb12ce4SGou Ngai #[allow(dead_code)] 115fb12ce4SGou Ngai pub const NUM_SCAN_CODES: u8 = 0x80; 125fb12ce4SGou Ngai #[allow(dead_code)] 135fb12ce4SGou Ngai pub const TYPE1_KEYCODE_MAP_TABLE_COLS: u8 = 2; 145fb12ce4SGou Ngai 155fb12ce4SGou Ngai #[allow(dead_code)] 165fb12ce4SGou Ngai pub const TYPE1_KEYCODE_FLAG_BREAK: u8 = 0x80; // 用于判断按键是否被按下 175fb12ce4SGou Ngai 185fb12ce4SGou Ngai /// 标志状态 195fb12ce4SGou Ngai #[repr(u8)] 205fb12ce4SGou Ngai #[derive(Debug, PartialEq, Eq)] 215fb12ce4SGou Ngai #[allow(dead_code)] 225fb12ce4SGou Ngai pub enum KeyFlag { 235fb12ce4SGou Ngai NoneFlag = 0 as u8, 245fb12ce4SGou Ngai PauseBreak = 1 as u8, 255fb12ce4SGou Ngai PrintScreenPress = 2 as u8, 265fb12ce4SGou Ngai PrintScreenRelease = 4 as u8, 275fb12ce4SGou Ngai OtherKey = 8 as u8, // 除了上面两个按键以外的功能按键(不包括下面的第三类按键) 285fb12ce4SGou Ngai } 295fb12ce4SGou Ngai 305fb12ce4SGou Ngai /// @brief A FSM to parse type one keyboard scan code 315fb12ce4SGou Ngai #[derive(Debug)] 325fb12ce4SGou Ngai #[allow(dead_code)] 335fb12ce4SGou Ngai pub struct TypeOneFSM { 345fb12ce4SGou Ngai status: ScanCodeStatus, 355fb12ce4SGou Ngai current_state: TypeOneFSMState, 365fb12ce4SGou Ngai } 375fb12ce4SGou Ngai 385fb12ce4SGou Ngai impl TypeOneFSM { 395fb12ce4SGou Ngai #[allow(dead_code)] 40*52da9a59SGnoCiYeH pub fn new() -> Self { 415fb12ce4SGou Ngai Self { 425fb12ce4SGou Ngai status: ScanCodeStatus::new(), 435fb12ce4SGou Ngai current_state: TypeOneFSMState::Start, 445fb12ce4SGou Ngai } 455fb12ce4SGou Ngai } 465fb12ce4SGou Ngai 475fb12ce4SGou Ngai /// @brief 解析扫描码 485fb12ce4SGou Ngai #[allow(dead_code)] 495fb12ce4SGou Ngai pub fn parse(&mut self, scancode: u8) -> TypeOneFSMState { 50*52da9a59SGnoCiYeH self.current_state = self.current_state.parse(scancode, &mut self.status); 515fb12ce4SGou Ngai self.current_state 525fb12ce4SGou Ngai } 535fb12ce4SGou Ngai } 545fb12ce4SGou Ngai 555fb12ce4SGou Ngai /// @brief 第一类扫描码状态机的状态 565fb12ce4SGou Ngai #[derive(Debug, Copy, Clone)] 575fb12ce4SGou Ngai pub enum TypeOneFSMState { 585fb12ce4SGou Ngai /// 起始状态 595fb12ce4SGou Ngai Start, 605fb12ce4SGou Ngai /// PauseBreak 第n个扫描码 615fb12ce4SGou Ngai PauseBreak(u8), 625fb12ce4SGou Ngai /// 多扫描码功能键起始状态 635fb12ce4SGou Ngai Func0, 645fb12ce4SGou Ngai /// 第三类扫描码或字符 655fb12ce4SGou Ngai Type3, 665fb12ce4SGou Ngai 675fb12ce4SGou Ngai PrtscPress(u8), 685fb12ce4SGou Ngai PrtscRelease(u8), 695fb12ce4SGou Ngai } 705fb12ce4SGou Ngai 715fb12ce4SGou Ngai impl TypeOneFSMState { 725fb12ce4SGou Ngai /// @brief 状态机总控程序 73*52da9a59SGnoCiYeH fn parse(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState { 745fb12ce4SGou Ngai // kdebug!("the code is {:#x}\n", scancode); 755fb12ce4SGou Ngai match self { 765fb12ce4SGou Ngai TypeOneFSMState::Start => { 77*52da9a59SGnoCiYeH return self.handle_start(scancode, scancode_status); 785fb12ce4SGou Ngai } 795fb12ce4SGou Ngai TypeOneFSMState::PauseBreak(n) => { 80*52da9a59SGnoCiYeH return self.handle_pause_break(*n, scancode_status); 815fb12ce4SGou Ngai } 825fb12ce4SGou Ngai TypeOneFSMState::Func0 => { 83*52da9a59SGnoCiYeH return self.handle_func0(scancode, scancode_status); 845fb12ce4SGou Ngai } 855fb12ce4SGou Ngai TypeOneFSMState::Type3 => { 86*52da9a59SGnoCiYeH return self.handle_type3(scancode, scancode_status); 875fb12ce4SGou Ngai } 88*52da9a59SGnoCiYeH TypeOneFSMState::PrtscPress(n) => return self.handle_prtsc_press(*n, scancode_status), 895fb12ce4SGou Ngai TypeOneFSMState::PrtscRelease(n) => { 90*52da9a59SGnoCiYeH return self.handle_prtsc_release(*n, scancode_status) 915fb12ce4SGou Ngai } 925fb12ce4SGou Ngai } 935fb12ce4SGou Ngai } 945fb12ce4SGou Ngai 955fb12ce4SGou Ngai /// @brief 处理起始状态 96*52da9a59SGnoCiYeH fn handle_start(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState { 975fb12ce4SGou Ngai //kdebug!("in handle_start the code is {:#x}\n",scancode); 985fb12ce4SGou Ngai match scancode { 995fb12ce4SGou Ngai 0xe1 => { 1005fb12ce4SGou Ngai return TypeOneFSMState::PauseBreak(1); 1015fb12ce4SGou Ngai } 1025fb12ce4SGou Ngai 0xe0 => { 1035fb12ce4SGou Ngai return TypeOneFSMState::Func0; 1045fb12ce4SGou Ngai } 1055fb12ce4SGou Ngai _ => { 1065fb12ce4SGou Ngai //kdebug!("in _d the code is {:#x}\n",scancode); 107*52da9a59SGnoCiYeH return TypeOneFSMState::Type3.handle_type3(scancode, scancode_status); 1085fb12ce4SGou Ngai } 1095fb12ce4SGou Ngai } 1105fb12ce4SGou Ngai } 1115fb12ce4SGou Ngai 1125fb12ce4SGou Ngai /// @brief 处理PauseBreak状态 1135fb12ce4SGou Ngai fn handle_pause_break( 1145fb12ce4SGou Ngai &self, 1155fb12ce4SGou Ngai scancode: u8, 1165fb12ce4SGou Ngai scancode_status: &mut ScanCodeStatus, 1175fb12ce4SGou Ngai ) -> TypeOneFSMState { 1185fb12ce4SGou Ngai static PAUSE_BREAK_SCAN_CODE: [u8; 6] = [0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5]; 1195fb12ce4SGou Ngai let i = match self { 1205fb12ce4SGou Ngai TypeOneFSMState::PauseBreak(i) => *i, 1215fb12ce4SGou Ngai _ => { 122*52da9a59SGnoCiYeH return self.handle_type3(scancode, scancode_status); 1235fb12ce4SGou Ngai } 1245fb12ce4SGou Ngai }; 1255fb12ce4SGou Ngai if scancode != PAUSE_BREAK_SCAN_CODE[i as usize] { 126*52da9a59SGnoCiYeH return self.handle_type3(scancode, scancode_status); 1275fb12ce4SGou Ngai } else { 1285fb12ce4SGou Ngai if i == 5 { 1295fb12ce4SGou Ngai // 所有Pause Break扫描码都被清除 1305fb12ce4SGou Ngai return TypeOneFSMState::Start; 1315fb12ce4SGou Ngai } else { 1325fb12ce4SGou Ngai return TypeOneFSMState::PauseBreak(i + 1); 1335fb12ce4SGou Ngai } 1345fb12ce4SGou Ngai } 1355fb12ce4SGou Ngai } 1365fb12ce4SGou Ngai 137*52da9a59SGnoCiYeH fn handle_func0(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState { 1385fb12ce4SGou Ngai //0xE0 1395fb12ce4SGou Ngai match scancode { 1405fb12ce4SGou Ngai 0x2a => { 1415fb12ce4SGou Ngai return TypeOneFSMState::PrtscPress(2); 1425fb12ce4SGou Ngai } 1435fb12ce4SGou Ngai 0xb7 => { 1445fb12ce4SGou Ngai return TypeOneFSMState::PrtscRelease(2); 1455fb12ce4SGou Ngai } 1465fb12ce4SGou Ngai 0x1d => { 1475fb12ce4SGou Ngai // 按下右边的ctrl 1485fb12ce4SGou Ngai scancode_status.ctrl_r = true; 1495fb12ce4SGou Ngai } 1505fb12ce4SGou Ngai 0x9d => { 1515fb12ce4SGou Ngai // 松开右边的ctrl 1525fb12ce4SGou Ngai scancode_status.ctrl_r = false; 1535fb12ce4SGou Ngai } 1545fb12ce4SGou Ngai 0x38 => { 1555fb12ce4SGou Ngai // 按下右边的alt 1565fb12ce4SGou Ngai scancode_status.alt_r = true; 1575fb12ce4SGou Ngai } 1585fb12ce4SGou Ngai 0xb8 => { 1595fb12ce4SGou Ngai // 松开右边的alt 1605fb12ce4SGou Ngai scancode_status.alt_r = false; 1615fb12ce4SGou Ngai } 1625fb12ce4SGou Ngai 0x5b => { 1635fb12ce4SGou Ngai scancode_status.gui_l = true; 1645fb12ce4SGou Ngai } 1655fb12ce4SGou Ngai 0xdb => { 1665fb12ce4SGou Ngai scancode_status.gui_l = false; 1675fb12ce4SGou Ngai } 1685fb12ce4SGou Ngai 0x5c => { 1695fb12ce4SGou Ngai scancode_status.gui_r = true; 1705fb12ce4SGou Ngai } 1715fb12ce4SGou Ngai 0xdc => { 1725fb12ce4SGou Ngai scancode_status.gui_r = false; 1735fb12ce4SGou Ngai } 1745fb12ce4SGou Ngai 0x5d => { 1755fb12ce4SGou Ngai scancode_status.apps = true; 1765fb12ce4SGou Ngai } 1775fb12ce4SGou Ngai 0xdd => { 1785fb12ce4SGou Ngai scancode_status.apps = false; 1795fb12ce4SGou Ngai } 1805fb12ce4SGou Ngai 0x52 => { 1815fb12ce4SGou Ngai scancode_status.insert = true; 1825fb12ce4SGou Ngai } 1835fb12ce4SGou Ngai 0xd2 => { 1845fb12ce4SGou Ngai scancode_status.insert = false; 1855fb12ce4SGou Ngai } 1865fb12ce4SGou Ngai 0x47 => { 1875fb12ce4SGou Ngai scancode_status.home = true; 1885fb12ce4SGou Ngai } 1895fb12ce4SGou Ngai 0xc7 => { 1905fb12ce4SGou Ngai scancode_status.home = false; 1915fb12ce4SGou Ngai } 1925fb12ce4SGou Ngai 0x49 => { 1935fb12ce4SGou Ngai scancode_status.pgup = true; 1945fb12ce4SGou Ngai } 1955fb12ce4SGou Ngai 0xc9 => { 1965fb12ce4SGou Ngai scancode_status.pgup = false; 1975fb12ce4SGou Ngai } 1985fb12ce4SGou Ngai 0x53 => { 1995fb12ce4SGou Ngai scancode_status.del = true; 200*52da9a59SGnoCiYeH Self::emit(127); 2015fb12ce4SGou Ngai } 2025fb12ce4SGou Ngai 0xd3 => { 2035fb12ce4SGou Ngai scancode_status.del = false; 2045fb12ce4SGou Ngai } 2055fb12ce4SGou Ngai 0x4f => { 2065fb12ce4SGou Ngai scancode_status.end = true; 2075fb12ce4SGou Ngai } 2085fb12ce4SGou Ngai 0xcf => { 2095fb12ce4SGou Ngai scancode_status.end = false; 2105fb12ce4SGou Ngai } 2115fb12ce4SGou Ngai 0x51 => { 2125fb12ce4SGou Ngai scancode_status.pgdn = true; 2135fb12ce4SGou Ngai } 2145fb12ce4SGou Ngai 0xd1 => { 2155fb12ce4SGou Ngai scancode_status.pgdn = false; 2165fb12ce4SGou Ngai } 2175fb12ce4SGou Ngai 0x48 => { 2185fb12ce4SGou Ngai scancode_status.arrow_u = true; 219*52da9a59SGnoCiYeH Self::emit(224); 220*52da9a59SGnoCiYeH Self::emit(72); 2215fb12ce4SGou Ngai } 2225fb12ce4SGou Ngai 0xc8 => { 2235fb12ce4SGou Ngai scancode_status.arrow_u = false; 2245fb12ce4SGou Ngai } 2255fb12ce4SGou Ngai 0x4b => { 2265fb12ce4SGou Ngai scancode_status.arrow_l = true; 227*52da9a59SGnoCiYeH Self::emit(224); 228*52da9a59SGnoCiYeH Self::emit(75); 2295fb12ce4SGou Ngai } 2305fb12ce4SGou Ngai 0xcb => { 2315fb12ce4SGou Ngai scancode_status.arrow_l = false; 2325fb12ce4SGou Ngai } 2335fb12ce4SGou Ngai 0x50 => { 2345fb12ce4SGou Ngai scancode_status.arrow_d = true; 235*52da9a59SGnoCiYeH Self::emit(224); 236*52da9a59SGnoCiYeH Self::emit(80); 2375fb12ce4SGou Ngai } 2385fb12ce4SGou Ngai 0xd0 => { 2395fb12ce4SGou Ngai scancode_status.arrow_d = false; 2405fb12ce4SGou Ngai } 2415fb12ce4SGou Ngai 0x4d => { 2425fb12ce4SGou Ngai scancode_status.arrow_r = true; 243*52da9a59SGnoCiYeH Self::emit(224); 244*52da9a59SGnoCiYeH Self::emit(77); 2455fb12ce4SGou Ngai } 2465fb12ce4SGou Ngai 0xcd => { 2475fb12ce4SGou Ngai scancode_status.arrow_r = false; 2485fb12ce4SGou Ngai } 2495fb12ce4SGou Ngai 2505fb12ce4SGou Ngai 0x35 => { 2515fb12ce4SGou Ngai // 数字小键盘的 / 符号 2525fb12ce4SGou Ngai scancode_status.kp_forward_slash = true; 2535fb12ce4SGou Ngai 2545fb12ce4SGou Ngai let ch = '/' as u8; 255*52da9a59SGnoCiYeH Self::emit(ch); 2565fb12ce4SGou Ngai } 2575fb12ce4SGou Ngai 0xb5 => { 2585fb12ce4SGou Ngai scancode_status.kp_forward_slash = false; 2595fb12ce4SGou Ngai } 2605fb12ce4SGou Ngai 0x1c => { 2615fb12ce4SGou Ngai scancode_status.kp_enter = true; 262*52da9a59SGnoCiYeH Self::emit('\n' as u8); 2635fb12ce4SGou Ngai } 2645fb12ce4SGou Ngai 0x9c => { 2655fb12ce4SGou Ngai scancode_status.kp_enter = false; 2665fb12ce4SGou Ngai } 2675fb12ce4SGou Ngai _ => { 2685fb12ce4SGou Ngai return TypeOneFSMState::Start; 2695fb12ce4SGou Ngai } 2705fb12ce4SGou Ngai } 2715fb12ce4SGou Ngai return TypeOneFSMState::Start; 2725fb12ce4SGou Ngai } 2735fb12ce4SGou Ngai 274*52da9a59SGnoCiYeH fn handle_type3(&self, scancode: u8, scancode_status: &mut ScanCodeStatus) -> TypeOneFSMState { 2755fb12ce4SGou Ngai // 判断按键是被按下还是抬起 2765fb12ce4SGou Ngai let flag_make = if (scancode & (TYPE1_KEYCODE_FLAG_BREAK as u8)) > 0 { 277d7b31a96SGou Ngai false //up 2785fb12ce4SGou Ngai } else { 279d7b31a96SGou Ngai true //down 2805fb12ce4SGou Ngai }; 2815fb12ce4SGou Ngai 2825fb12ce4SGou Ngai // 计算扫描码位于码表的第几行 283d7b31a96SGou Ngai let mut col: bool = false; 2845fb12ce4SGou Ngai let index = scancode & 0x7f; 2855fb12ce4SGou Ngai 2865fb12ce4SGou Ngai //kdebug!("in type3 ch is {:#x}\n",ch); 2875fb12ce4SGou Ngai let mut key = KeyFlag::OtherKey; // 可视字符 2885fb12ce4SGou Ngai 2895fb12ce4SGou Ngai match index { 2905fb12ce4SGou Ngai 0x2a => { 2915fb12ce4SGou Ngai scancode_status.shift_l = flag_make; 2925fb12ce4SGou Ngai key = KeyFlag::NoneFlag; 2935fb12ce4SGou Ngai } 2945fb12ce4SGou Ngai 0x36 => { 2955fb12ce4SGou Ngai scancode_status.shift_r = flag_make; 2965fb12ce4SGou Ngai key = KeyFlag::NoneFlag; 2975fb12ce4SGou Ngai } 2985fb12ce4SGou Ngai 0x1d => { 2995fb12ce4SGou Ngai scancode_status.ctrl_l = flag_make; 3005fb12ce4SGou Ngai key = KeyFlag::NoneFlag; 3015fb12ce4SGou Ngai } 3025fb12ce4SGou Ngai 0x38 => { 303d7b31a96SGou Ngai scancode_status.alt_r = flag_make; 304d7b31a96SGou Ngai key = KeyFlag::NoneFlag; 305d7b31a96SGou Ngai } 306d7b31a96SGou Ngai 0x3A => { 307d7b31a96SGou Ngai if scancode_status.caps_lock { 308d7b31a96SGou Ngai scancode_status.caps_lock = !flag_make; 309d7b31a96SGou Ngai } 310d7b31a96SGou Ngai //if caps_lock: true, flag_make: true => cap_lock: false 311d7b31a96SGou Ngai else { 312d7b31a96SGou Ngai scancode_status.caps_lock = flag_make; 313d7b31a96SGou Ngai } //else false => cap_lock: true 3145fb12ce4SGou Ngai key = KeyFlag::NoneFlag; 3155fb12ce4SGou Ngai } 3165fb12ce4SGou Ngai _ => { 3175fb12ce4SGou Ngai if flag_make == false { 3185fb12ce4SGou Ngai // kdebug!("in type3 ch is {:#x}\n",ch); 3195fb12ce4SGou Ngai key = KeyFlag::NoneFlag; 3205fb12ce4SGou Ngai } 3215fb12ce4SGou Ngai } 3225fb12ce4SGou Ngai } 3235fb12ce4SGou Ngai 324d7b31a96SGou Ngai // shift被按下 325d7b31a96SGou Ngai if scancode_status.shift_l || scancode_status.shift_r { 326d7b31a96SGou Ngai col = true; 327d7b31a96SGou Ngai } 328d7b31a96SGou Ngai 329d7b31a96SGou Ngai if scancode_status.caps_lock { 330d7b31a96SGou Ngai if index >= 0x10 && index <= 0x19 { 331d7b31a96SGou Ngai col = !col; 332d7b31a96SGou Ngai } else if index >= 0x1e && index <= 0x26 { 333d7b31a96SGou Ngai col = !col; 334d7b31a96SGou Ngai } else if index >= 0x2c && index <= 0x32 { 335d7b31a96SGou Ngai col = !col; 336d7b31a96SGou Ngai } 337d7b31a96SGou Ngai } 338d7b31a96SGou Ngai 339*52da9a59SGnoCiYeH let mut ch = TYPE1_KEY_CODE_MAPTABLE[col as usize + 2 * index as usize]; 3405fb12ce4SGou Ngai if key != KeyFlag::NoneFlag { 34101bd5258SLoGin // kdebug!("EMIT: ch is '{}', keyflag is {:?}\n", ch as char, key); 342*52da9a59SGnoCiYeH if scancode_status.ctrl_l || scancode_status.ctrl_r { 343*52da9a59SGnoCiYeH ch = Self::to_ctrl(ch); 344*52da9a59SGnoCiYeH } 345*52da9a59SGnoCiYeH Self::emit(ch); 3465fb12ce4SGou Ngai } 3475fb12ce4SGou Ngai return TypeOneFSMState::Start; 3485fb12ce4SGou Ngai } 3495fb12ce4SGou Ngai 350*52da9a59SGnoCiYeH #[inline] 351*52da9a59SGnoCiYeH fn to_ctrl(ch: u8) -> u8 { 352*52da9a59SGnoCiYeH return match ch as char { 353*52da9a59SGnoCiYeH 'a'..='z' => ch - 0x40, 354*52da9a59SGnoCiYeH 'A'..='Z' => ch - 0x40, 355*52da9a59SGnoCiYeH '@'..='_' => ch - 0x40, 356*52da9a59SGnoCiYeH _ => ch, 357*52da9a59SGnoCiYeH }; 358*52da9a59SGnoCiYeH } 359*52da9a59SGnoCiYeH 36020e3152eSlogin #[inline(always)] 361*52da9a59SGnoCiYeH fn emit(ch: u8) { 36220e3152eSlogin // 发送到tty 363*52da9a59SGnoCiYeH let _ = Self::current_port().receive_buf(&[ch], &[], 1); 364*52da9a59SGnoCiYeH } 365*52da9a59SGnoCiYeH 366*52da9a59SGnoCiYeH #[inline] 367*52da9a59SGnoCiYeH fn current_port() -> Arc<dyn TtyPort> { 368*52da9a59SGnoCiYeH TTY_PORTS[CURRENT_VCNUM.load(Ordering::SeqCst) as usize].clone() 3695fb12ce4SGou Ngai } 3705fb12ce4SGou Ngai 3715fb12ce4SGou Ngai /// @brief 处理Prtsc按下事件 3725fb12ce4SGou Ngai fn handle_prtsc_press( 3735fb12ce4SGou Ngai &self, 3745fb12ce4SGou Ngai scancode: u8, 3755fb12ce4SGou Ngai scancode_status: &mut ScanCodeStatus, 3765fb12ce4SGou Ngai ) -> TypeOneFSMState { 3775fb12ce4SGou Ngai static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0x2a, 0xe0, 0x37]; 3785fb12ce4SGou Ngai let i = match self { 3795fb12ce4SGou Ngai TypeOneFSMState::PrtscPress(i) => *i, 3805fb12ce4SGou Ngai _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态 3815fb12ce4SGou Ngai }; 3825fb12ce4SGou Ngai if i > 3 { 3835fb12ce4SGou Ngai // 解析错误,返回起始状态 3845fb12ce4SGou Ngai return TypeOneFSMState::Start; 3855fb12ce4SGou Ngai } 3865fb12ce4SGou Ngai if scancode != PRTSC_SCAN_CODE[i as usize] { 387*52da9a59SGnoCiYeH return self.handle_type3(scancode, scancode_status); 3885fb12ce4SGou Ngai } else { 3895fb12ce4SGou Ngai if i == 3 { 3905fb12ce4SGou Ngai // 成功解析出PrtscPress 3915fb12ce4SGou Ngai return TypeOneFSMState::Start; 3925fb12ce4SGou Ngai } else { 3935fb12ce4SGou Ngai // 继续解析 3945fb12ce4SGou Ngai return TypeOneFSMState::PrtscPress(i + 1); 3955fb12ce4SGou Ngai } 3965fb12ce4SGou Ngai } 3975fb12ce4SGou Ngai } 3985fb12ce4SGou Ngai 3995fb12ce4SGou Ngai fn handle_prtsc_release( 4005fb12ce4SGou Ngai &self, 4015fb12ce4SGou Ngai scancode: u8, 4025fb12ce4SGou Ngai scancode_status: &mut ScanCodeStatus, 4035fb12ce4SGou Ngai ) -> TypeOneFSMState { 4045fb12ce4SGou Ngai static PRTSC_SCAN_CODE: [u8; 4] = [0xe0, 0xb7, 0xe0, 0xaa]; 4055fb12ce4SGou Ngai let i = match self { 4065fb12ce4SGou Ngai TypeOneFSMState::PrtscRelease(i) => *i, 4075fb12ce4SGou Ngai _ => return TypeOneFSMState::Start, // 解析错误,返回起始状态 4085fb12ce4SGou Ngai }; 4095fb12ce4SGou Ngai if i > 3 { 4105fb12ce4SGou Ngai // 解析错误,返回起始状态 4115fb12ce4SGou Ngai return TypeOneFSMState::Start; 4125fb12ce4SGou Ngai } 4135fb12ce4SGou Ngai if scancode != PRTSC_SCAN_CODE[i as usize] { 414*52da9a59SGnoCiYeH return self.handle_type3(scancode, scancode_status); 4155fb12ce4SGou Ngai } else { 4165fb12ce4SGou Ngai if i == 3 { 4175fb12ce4SGou Ngai // 成功解析出PrtscRelease 4185fb12ce4SGou Ngai return TypeOneFSMState::Start; 4195fb12ce4SGou Ngai } else { 4205fb12ce4SGou Ngai // 继续解析 4215fb12ce4SGou Ngai return TypeOneFSMState::PrtscRelease(i + 1); 4225fb12ce4SGou Ngai } 4235fb12ce4SGou Ngai } 4245fb12ce4SGou Ngai } 4255fb12ce4SGou Ngai } 4265fb12ce4SGou Ngai 4275fb12ce4SGou Ngai /// 按键状态 4285fb12ce4SGou Ngai #[derive(Debug)] 429d7b31a96SGou Ngai #[allow(dead_code)] 4305fb12ce4SGou Ngai pub struct ScanCodeStatus { 4315fb12ce4SGou Ngai // Shift 按键 4325fb12ce4SGou Ngai shift_l: bool, 4335fb12ce4SGou Ngai shift_r: bool, 4345fb12ce4SGou Ngai // Ctrl 按键 4355fb12ce4SGou Ngai ctrl_l: bool, 4365fb12ce4SGou Ngai ctrl_r: bool, 4375fb12ce4SGou Ngai // Alt 按键 4385fb12ce4SGou Ngai alt_l: bool, 4395fb12ce4SGou Ngai alt_r: bool, 4405fb12ce4SGou Ngai // 4415fb12ce4SGou Ngai gui_l: bool, 4425fb12ce4SGou Ngai gui_r: bool, 4435fb12ce4SGou Ngai // 4445fb12ce4SGou Ngai apps: bool, 4455fb12ce4SGou Ngai insert: bool, 4465fb12ce4SGou Ngai // page up/down 4475fb12ce4SGou Ngai pgup: bool, 4485fb12ce4SGou Ngai pgdn: bool, 4495fb12ce4SGou Ngai del: bool, 4505fb12ce4SGou Ngai home: bool, 4515fb12ce4SGou Ngai end: bool, 4525fb12ce4SGou Ngai arrow_u: bool, 4535fb12ce4SGou Ngai arrow_l: bool, 4545fb12ce4SGou Ngai arrow_d: bool, 4555fb12ce4SGou Ngai arrow_r: bool, 4565fb12ce4SGou Ngai // 斜杠 4575fb12ce4SGou Ngai kp_forward_slash: bool, 4585fb12ce4SGou Ngai // 回车 4595fb12ce4SGou Ngai kp_enter: bool, 460d7b31a96SGou Ngai caps_lock: bool, 4615fb12ce4SGou Ngai } 4625fb12ce4SGou Ngai 4635fb12ce4SGou Ngai impl ScanCodeStatus { 4645fb12ce4SGou Ngai fn new() -> Self { 4655fb12ce4SGou Ngai ScanCodeStatus { 4665fb12ce4SGou Ngai shift_l: false, 4675fb12ce4SGou Ngai shift_r: false, 4685fb12ce4SGou Ngai ctrl_l: false, 4695fb12ce4SGou Ngai ctrl_r: false, 4705fb12ce4SGou Ngai alt_l: false, 4715fb12ce4SGou Ngai alt_r: false, 4725fb12ce4SGou Ngai gui_l: false, 4735fb12ce4SGou Ngai gui_r: false, 4745fb12ce4SGou Ngai apps: false, 4755fb12ce4SGou Ngai insert: false, 4765fb12ce4SGou Ngai pgup: false, 4775fb12ce4SGou Ngai pgdn: false, 4785fb12ce4SGou Ngai del: false, 4795fb12ce4SGou Ngai home: false, 4805fb12ce4SGou Ngai end: false, 4815fb12ce4SGou Ngai arrow_u: false, 4825fb12ce4SGou Ngai arrow_l: false, 4835fb12ce4SGou Ngai arrow_d: false, 4845fb12ce4SGou Ngai arrow_r: false, 4855fb12ce4SGou Ngai kp_forward_slash: false, 4865fb12ce4SGou Ngai kp_enter: false, 487d7b31a96SGou Ngai caps_lock: false, 4885fb12ce4SGou Ngai } 4895fb12ce4SGou Ngai } 4905fb12ce4SGou Ngai } 4915fb12ce4SGou Ngai 4925fb12ce4SGou Ngai const TYPE1_KEY_CODE_MAPTABLE: [u8; 256] = [ 4935fb12ce4SGou Ngai /*0x00*/ 0, 0, /*0x01*/ 0, 0, // ESC 4945fb12ce4SGou Ngai /*0x02*/ '1' as u8, '!' as u8, /*0x03*/ '2' as u8, '@' as u8, 4955fb12ce4SGou Ngai /*0x04*/ '3' as u8, '#' as u8, /*0x05*/ '4' as u8, '$' as u8, 4965fb12ce4SGou Ngai /*0x06*/ '5' as u8, '%' as u8, /*0x07*/ '6' as u8, '^' as u8, 4975fb12ce4SGou Ngai /*0x08*/ '7' as u8, '&' as u8, /*0x09*/ '8' as u8, '*' as u8, 4985fb12ce4SGou Ngai /*0x0a*/ '9' as u8, '(' as u8, /*0x0b*/ '0' as u8, ')' as u8, 4995fb12ce4SGou Ngai /*0x0c*/ '-' as u8, '_' as u8, /*0x0d*/ '=' as u8, '+' as u8, 50020e3152eSlogin /*0x0e \b */ 8 as u8, 8 as u8, // BACKSPACE 5015fb12ce4SGou Ngai /*0x0f*/ '\t' as u8, '\t' as u8, // TAB 502d7b31a96SGou Ngai ////////////////////////character/////////////////////////// 503d7b31a96SGou Ngai /*0x10*/ 'q' as u8, 504d7b31a96SGou Ngai 'Q' as u8, /*0x11*/ 'w' as u8, 'W' as u8, /*0x12*/ 'e' as u8, 'E' as u8, 505d7b31a96SGou Ngai /*0x13*/ 'r' as u8, 'R' as u8, /*0x14*/ 't' as u8, 'T' as u8, 506d7b31a96SGou Ngai /*0x15*/ 'y' as u8, 'Y' as u8, /*0x16*/ 'u' as u8, 'U' as u8, 507d7b31a96SGou Ngai /*0x17*/ 'i' as u8, 'I' as u8, /*0x18*/ 'o' as u8, 'O' as u8, 508d7b31a96SGou Ngai /*0x19*/ 'p' as u8, 'P' as u8, 509d7b31a96SGou Ngai ////////////////////////character/////////////////////////// 510d7b31a96SGou Ngai 511d7b31a96SGou Ngai /*0x1a*/ '[' as u8, 512d7b31a96SGou Ngai '{' as u8, /*0x1b*/ ']' as u8, '}' as u8, /*0x1c*/ '\n' as u8, 513d7b31a96SGou Ngai '\n' as u8, // ENTER 5145fb12ce4SGou Ngai /*0x1d*/ 0x1d, 0x1d, // CTRL Left 515d7b31a96SGou Ngai ////////////////////////character/////////////////////////// 516d7b31a96SGou Ngai /*0x1e*/ 'a' as u8, 517d7b31a96SGou Ngai 'A' as u8, /*0x1f*/ 's' as u8, 'S' as u8, /*0x20*/ 'd' as u8, 'D' as u8, 518d7b31a96SGou Ngai /*0x21*/ 'f' as u8, 'F' as u8, /*0x22*/ 'g' as u8, 'G' as u8, 519d7b31a96SGou Ngai /*0x23*/ 'h' as u8, 'H' as u8, /*0x24*/ 'j' as u8, 'J' as u8, 520d7b31a96SGou Ngai /*0x25*/ 'k' as u8, 'K' as u8, /*0x26*/ 'l' as u8, 'L' as u8, 521d7b31a96SGou Ngai ////////////////////////character/////////////////////////// 522d7b31a96SGou Ngai 523d7b31a96SGou Ngai /*0x27*/ ';' as u8, 524d7b31a96SGou Ngai ':' as u8, /*0x28*/ '\'' as u8, '"' as u8, /*0x29*/ '`' as u8, '~' as u8, 525d7b31a96SGou Ngai /*0x2a*/ 0x2a, 0x2a, // SHIFT Left 526d7b31a96SGou Ngai /*0x2b*/ '\\' as u8, '|' as u8, 527d7b31a96SGou Ngai ////////////////////////character/////////////////////////// 528d7b31a96SGou Ngai /*0x2c*/ 'z' as u8, 529d7b31a96SGou Ngai 'Z' as u8, /*0x2d*/ 'x' as u8, 'X' as u8, /*0x2e*/ 'c' as u8, 'C' as u8, 5305fb12ce4SGou Ngai /*0x2f*/ 'v' as u8, 'V' as u8, /*0x30*/ 'b' as u8, 'B' as u8, 5315fb12ce4SGou Ngai /*0x31*/ 'n' as u8, 'N' as u8, /*0x32*/ 'm' as u8, 'M' as u8, 532d7b31a96SGou Ngai ////////////////////////character/////////////////////////// 533d7b31a96SGou Ngai 534d7b31a96SGou Ngai /*0x33*/ ',' as u8, 535d7b31a96SGou Ngai '<' as u8, /*0x34*/ '.' as u8, '>' as u8, /*0x35*/ '/' as u8, '?' as u8, 536d7b31a96SGou Ngai /*0x36*/ 0x36, 0x36, // SHIFT Right 5375fb12ce4SGou Ngai /*0x37*/ '*' as u8, '*' as u8, /*0x38*/ 0x38, 0x38, // ALT Left 5385fb12ce4SGou Ngai /*0x39*/ ' ' as u8, ' ' as u8, /*0x3a*/ 0, 0, // CAPS LOCK 5395fb12ce4SGou Ngai /*0x3b*/ 0, 0, // F1 5405fb12ce4SGou Ngai /*0x3c*/ 0, 0, // F2 5415fb12ce4SGou Ngai /*0x3d*/ 0, 0, // F3 5425fb12ce4SGou Ngai /*0x3e*/ 0, 0, // F4 5435fb12ce4SGou Ngai /*0x3f*/ 0, 0, // F5 5445fb12ce4SGou Ngai /*0x40*/ 0, 0, // F6 5455fb12ce4SGou Ngai /*0x41*/ 0, 0, // F7 5465fb12ce4SGou Ngai /*0x42*/ 0, 0, // F8 5475fb12ce4SGou Ngai /*0x43*/ 0, 0, // F9 5485fb12ce4SGou Ngai /*0x44*/ 0, 0, // F10 5495fb12ce4SGou Ngai /*0x45*/ 0, 0, // NUM LOCK 5505fb12ce4SGou Ngai /*0x46*/ 0, 0, // SCROLL LOCK 5515fb12ce4SGou Ngai /*0x47*/ '7' as u8, 0, /*PAD HONE*/ 5525fb12ce4SGou Ngai /*0x48*/ '8' as u8, 0, /*PAD UP*/ 5535fb12ce4SGou Ngai /*0x49*/ '9' as u8, 0, /*PAD PAGEUP*/ 5545fb12ce4SGou Ngai /*0x4a*/ '-' as u8, 0, /*PAD MINUS*/ 5555fb12ce4SGou Ngai /*0x4b*/ '4' as u8, 0, /*PAD LEFT*/ 5565fb12ce4SGou Ngai /*0x4c*/ '5' as u8, 0, /*PAD MID*/ 5575fb12ce4SGou Ngai /*0x4d*/ '6' as u8, 0, /*PAD RIGHT*/ 5585fb12ce4SGou Ngai /*0x4e*/ '+' as u8, 0, /*PAD PLUS*/ 5595fb12ce4SGou Ngai /*0x4f*/ '1' as u8, 0, /*PAD END*/ 5605fb12ce4SGou Ngai /*0x50*/ '2' as u8, 0, /*PAD DOWN*/ 5615fb12ce4SGou Ngai /*0x51*/ '3' as u8, 0, /*PAD PAGEDOWN*/ 5625fb12ce4SGou Ngai /*0x52*/ '0' as u8, 0, /*PAD INS*/ 5635fb12ce4SGou Ngai /*0x53*/ '.' as u8, 0, /*PAD DOT*/ 5645fb12ce4SGou Ngai /*0x54*/ 0, 0, /*0x55*/ 0, 0, /*0x56*/ 0, 0, /*0x57*/ 0, 0, // F11 5655fb12ce4SGou Ngai /*0x58*/ 0, 0, // F12 5665fb12ce4SGou Ngai /*0x59*/ 0, 0, /*0x5a*/ 0, 0, /*0x5b*/ 0, 0, /*0x5c*/ 0, 0, 5675fb12ce4SGou Ngai /*0x5d*/ 0, 0, /*0x5e*/ 0, 0, /*0x5f*/ 0, 0, /*0x60*/ 0, 0, 5685fb12ce4SGou Ngai /*0x61*/ 0, 0, /*0x62*/ 0, 0, /*0x63*/ 0, 0, /*0x64*/ 0, 0, 5695fb12ce4SGou Ngai /*0x65*/ 0, 0, /*0x66*/ 0, 0, /*0x67*/ 0, 0, /*0x68*/ 0, 0, 5705fb12ce4SGou Ngai /*0x69*/ 0, 0, /*0x6a*/ 0, 0, /*0x6b*/ 0, 0, /*0x6c*/ 0, 0, 5715fb12ce4SGou Ngai /*0x6d*/ 0, 0, /*0x6e*/ 0, 0, /*0x6f*/ 0, 0, /*0x70*/ 0, 0, 5725fb12ce4SGou Ngai /*0x71*/ 0, 0, /*0x72*/ 0, 0, /*0x73*/ 0, 0, /*0x74*/ 0, 0, 5735fb12ce4SGou Ngai /*0x75*/ 0, 0, /*0x76*/ 0, 0, /*0x77*/ 0, 0, /*0x78*/ 0, 0, 5745fb12ce4SGou Ngai /*0x79*/ 0, 0, /*0x7a*/ 0, 0, /*0x7b*/ 0, 0, /*0x7c*/ 0, 0, 5755fb12ce4SGou Ngai /*0x7d*/ 0, 0, /*0x7e*/ 0, 0, /*0x7f*/ 0, 0, 5765fb12ce4SGou Ngai ]; 577