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