use alloc::boxed::Box; use lazy_static::lazy_static; use spin::{Mutex, MutexGuard}; use crate::{println, util::ArrayQueue}; pub fn keyboard<'r>() -> MutexGuard<'r, Keyboard> { KEYBOARD.lock() } lazy_static! { static ref KEYBOARD: Mutex = Mutex::new(Keyboard::init()); } pub struct Keyboard { on_code: Option>, keymap: Box, } impl Keyboard { pub fn init() -> Self { let on_code = None; let keymap = Box::new(Qwerty::default()); Self { on_code, keymap } } pub fn keymap(&mut self, keymap: impl KeyMap + Send + 'static) { self.keymap = Box::new(keymap) as _; } pub fn on_code(&mut self, op: impl FnMut(Code) + Send + 'static) { self.on_code = Some(Box::new(op) as _); } pub fn record(&mut self, scan_code: u8) { match self.keymap.parse(scan_code) { KeyMapRes::Ok(c) if let Some(op) = self.on_code.as_mut() => op(c), KeyMapRes::Ok(c) => println!("Ignoring {c:?}"), KeyMapRes::Partial => (), KeyMapRes::Unknown => println!("Unknown code : {scan_code:?}"), }; } } #[derive(Debug, Clone, Copy)] pub enum Code { Down(Key), Up(Key), } #[derive(Debug, Clone, Copy)] pub enum Key { Char(char), Fun(u8), BackSpace, Insert, Home, PageUp, Delete, End, Escape, PageDown, ArrowUp, ArrowLeft, ArrowDown, ArrowRight, ShiftLeft, ShiftRight, CtrlLeft, CtrlRight, AltLeft, AltRight, } #[derive(Debug, Default)] pub struct KeyModState { ctrl: bool, shift: bool, alt: bool, } impl KeyModState { pub fn translate(&mut self, keymap: &impl KeyMap, key: Code) -> Code { self.update(key); match key { Code::Down(Key::Char(c)) => Code::Down(Key::Char(keymap.apply_mod(c, &self))), Code::Up(Key::Char(c)) => Code::Up(Key::Char(keymap.apply_mod(c, &self))), _ => key, } } fn update(&mut self, key: Code) { match key { Code::Down(Key::AltLeft) => self.alt = true, Code::Down(Key::AltRight) => self.alt = true, Code::Down(Key::CtrlLeft) => self.ctrl = true, Code::Down(Key::CtrlRight) => self.ctrl = true, Code::Down(Key::ShiftLeft) => self.shift = true, Code::Down(Key::ShiftRight) => self.shift = true, Code::Up(Key::AltLeft) => self.alt = false, Code::Up(Key::AltRight) => self.alt = false, Code::Up(Key::CtrlLeft) => self.ctrl = false, Code::Up(Key::CtrlRight) => self.ctrl = false, Code::Up(Key::ShiftLeft) => self.shift = false, Code::Up(Key::ShiftRight) => self.shift = false, _ => (), } } } pub enum KeyMapRes { Ok(Code), Partial, Unknown, } pub trait KeyMap { fn parse(&mut self, scan_code: u8) -> KeyMapRes; fn apply_mod(&self, key: char, _state: &KeyModState) -> char { key } } #[derive(Debug, Default, Clone)] pub struct Qwerty { lasts: ArrayQueue, } impl KeyMap for Qwerty { fn parse(&mut self, scan_code: u8) -> KeyMapRes { use Code::*; use KeyMapRes::*; self.lasts.add(scan_code); let res = match *self.lasts.content() { [Some(0x1E), None, _, _] => Ok(Down(Key::Char('a'))), [Some(0x30), None, _, _] => Ok(Down(Key::Char('b'))), [Some(0x2E), None, _, _] => Ok(Down(Key::Char('c'))), [Some(0x20), None, _, _] => Ok(Down(Key::Char('d'))), [Some(0x12), None, _, _] => Ok(Down(Key::Char('e'))), [Some(0x21), None, _, _] => Ok(Down(Key::Char('f'))), [Some(0x22), None, _, _] => Ok(Down(Key::Char('g'))), [Some(0x23), None, _, _] => Ok(Down(Key::Char('h'))), [Some(0x17), None, _, _] => Ok(Down(Key::Char('i'))), [Some(0x24), None, _, _] => Ok(Down(Key::Char('j'))), [Some(0x25), None, _, _] => Ok(Down(Key::Char('k'))), [Some(0x26), None, _, _] => Ok(Down(Key::Char('l'))), [Some(0x32), None, _, _] => Ok(Down(Key::Char('m'))), [Some(0x31), None, _, _] => Ok(Down(Key::Char('n'))), [Some(0x18), None, _, _] => Ok(Down(Key::Char('o'))), [Some(0x19), None, _, _] => Ok(Down(Key::Char('p'))), [Some(0x10), None, _, _] => Ok(Down(Key::Char('q'))), [Some(0x13), None, _, _] => Ok(Down(Key::Char('r'))), [Some(0x1F), None, _, _] => Ok(Down(Key::Char('s'))), [Some(0x14), None, _, _] => Ok(Down(Key::Char('t'))), [Some(0x16), None, _, _] => Ok(Down(Key::Char('u'))), [Some(0x2F), None, _, _] => Ok(Down(Key::Char('v'))), [Some(0x11), None, _, _] => Ok(Down(Key::Char('w'))), [Some(0x2D), None, _, _] => Ok(Down(Key::Char('x'))), [Some(0x15), None, _, _] => Ok(Down(Key::Char('y'))), [Some(0x2C), None, _, _] => Ok(Down(Key::Char('z'))), [Some(0x0B), None, _, _] => Ok(Down(Key::Char('0'))), [Some(0x02), None, _, _] => Ok(Down(Key::Char('1'))), [Some(0x03), None, _, _] => Ok(Down(Key::Char('2'))), [Some(0x04), None, _, _] => Ok(Down(Key::Char('3'))), [Some(0x05), None, _, _] => Ok(Down(Key::Char('4'))), [Some(0x06), None, _, _] => Ok(Down(Key::Char('5'))), [Some(0x07), None, _, _] => Ok(Down(Key::Char('6'))), [Some(0x08), None, _, _] => Ok(Down(Key::Char('7'))), [Some(0x09), None, _, _] => Ok(Down(Key::Char('8'))), [Some(0x0A), None, _, _] => Ok(Down(Key::Char('9'))), [Some(0x29), None, _, _] => Ok(Down(Key::Char('`'))), [Some(0x0C), None, _, _] => Ok(Down(Key::Char('-'))), [Some(0x0D), None, _, _] => Ok(Down(Key::Char('='))), [Some(0x2B), None, _, _] => Ok(Down(Key::Char('\\'))), [Some(0x1A), None, _, _] => Ok(Down(Key::Char('['))), [Some(0x34), None, _, _] => Ok(Down(Key::Char('.'))), [Some(0x35), None, _, _] => Ok(Down(Key::Char('/'))), [Some(0x1B), None, _, _] => Ok(Down(Key::Char(']'))), [Some(0x27), None, _, _] => Ok(Down(Key::Char(';'))), [Some(0x28), None, _, _] => Ok(Down(Key::Char('\''))), [Some(0x33), None, _, _] => Ok(Down(Key::Char(','))), [Some(0x1C), None, _, _] => Ok(Down(Key::Char('\n'))), [Some(0x39), None, _, _] => Ok(Down(Key::Char(' '))), [Some(0x0F), None, _, _] => Ok(Down(Key::Char('\t'))), [Some(0x0E), None, _, _] => Ok(Down(Key::BackSpace)), [Some(0x01), None, _, _] => Ok(Down(Key::Escape)), [Some(0x2A), None, _, _] => Ok(Down(Key::ShiftLeft)), [Some(0x1D), None, _, _] => Ok(Down(Key::CtrlLeft)), [Some(0x38), None, _, _] => Ok(Down(Key::AltLeft)), [Some(0x36), None, _, _] => Ok(Down(Key::ShiftRight)), [Some(0x50), None, _, _] => Ok(Down(Key::Char('2'))), // KeyPad variant [Some(0x51), None, _, _] => Ok(Down(Key::Char('3'))), // KeyPad variant [Some(0x4B), None, _, _] => Ok(Down(Key::Char('4'))), // KeyPad variant [Some(0x4C), None, _, _] => Ok(Down(Key::Char('5'))), // KeyPad variant [Some(0x4D), None, _, _] => Ok(Down(Key::Char('6'))), // KeyPad variant [Some(0x47), None, _, _] => Ok(Down(Key::Char('7'))), // KeyPad variant [Some(0x48), None, _, _] => Ok(Down(Key::Char('8'))), // KeyPad variant [Some(0x49), None, _, _] => Ok(Down(Key::Char('9'))), // KeyPad variant [Some(0x37), None, _, _] => Ok(Down(Key::Char('*'))), // KeyPad variant [Some(0x4A), None, _, _] => Ok(Down(Key::Char('-'))), // KeyPad variant [Some(0x4E), None, _, _] => Ok(Down(Key::Char('+'))), // KeyPad variant [Some(0x53), None, _, _] => Ok(Down(Key::Char('.'))), // KeyPad variant [Some(0x52), None, _, _] => Ok(Down(Key::Char('0'))), // KeyPad variant [Some(0x4F), None, _, _] => Ok(Down(Key::Char('1'))), // KeyPad variant [Some(0x3B), None, _, _] => Ok(Down(Key::Fun(1))), [Some(0x3C), None, _, _] => Ok(Down(Key::Fun(2))), [Some(0x3D), None, _, _] => Ok(Down(Key::Fun(3))), [Some(0x3E), None, _, _] => Ok(Down(Key::Fun(4))), [Some(0x3F), None, _, _] => Ok(Down(Key::Fun(5))), [Some(0x40), None, _, _] => Ok(Down(Key::Fun(6))), [Some(0x41), None, _, _] => Ok(Down(Key::Fun(7))), [Some(0x42), None, _, _] => Ok(Down(Key::Fun(8))), [Some(0x43), None, _, _] => Ok(Down(Key::Fun(9))), [Some(0x44), None, _, _] => Ok(Down(Key::Fun(10))), [Some(0x57), None, _, _] => Ok(Down(Key::Fun(11))), [Some(0x58), None, _, _] => Ok(Down(Key::Fun(12))), [Some(0x9E), None, _, _] => Ok(Up(Key::Char('a'))), [Some(0xB0), None, _, _] => Ok(Up(Key::Char('b'))), [Some(0xAE), None, _, _] => Ok(Up(Key::Char('c'))), [Some(0xA0), None, _, _] => Ok(Up(Key::Char('d'))), [Some(0x92), None, _, _] => Ok(Up(Key::Char('e'))), [Some(0xA1), None, _, _] => Ok(Up(Key::Char('f'))), [Some(0xA2), None, _, _] => Ok(Up(Key::Char('g'))), [Some(0xA3), None, _, _] => Ok(Up(Key::Char('h'))), [Some(0x97), None, _, _] => Ok(Up(Key::Char('i'))), [Some(0xA4), None, _, _] => Ok(Up(Key::Char('j'))), [Some(0xA5), None, _, _] => Ok(Up(Key::Char('k'))), [Some(0xA6), None, _, _] => Ok(Up(Key::Char('l'))), [Some(0xB2), None, _, _] => Ok(Up(Key::Char('m'))), [Some(0xB1), None, _, _] => Ok(Up(Key::Char('n'))), [Some(0x98), None, _, _] => Ok(Up(Key::Char('o'))), [Some(0x99), None, _, _] => Ok(Up(Key::Char('p'))), [Some(0x90), None, _, _] => Ok(Up(Key::Char('q'))), [Some(0x93), None, _, _] => Ok(Up(Key::Char('r'))), [Some(0x9F), None, _, _] => Ok(Up(Key::Char('s'))), [Some(0x94), None, _, _] => Ok(Up(Key::Char('t'))), [Some(0x96), None, _, _] => Ok(Up(Key::Char('u'))), [Some(0xAF), None, _, _] => Ok(Up(Key::Char('v'))), [Some(0x91), None, _, _] => Ok(Up(Key::Char('w'))), [Some(0xAD), None, _, _] => Ok(Up(Key::Char('x'))), [Some(0x95), None, _, _] => Ok(Up(Key::Char('y'))), [Some(0xAC), None, _, _] => Ok(Up(Key::Char('z'))), [Some(0x8B), None, _, _] => Ok(Up(Key::Char('0'))), [Some(0x82), None, _, _] => Ok(Up(Key::Char('1'))), [Some(0x83), None, _, _] => Ok(Up(Key::Char('2'))), [Some(0x84), None, _, _] => Ok(Up(Key::Char('3'))), [Some(0x85), None, _, _] => Ok(Up(Key::Char('4'))), [Some(0x86), None, _, _] => Ok(Up(Key::Char('5'))), [Some(0x87), None, _, _] => Ok(Up(Key::Char('6'))), [Some(0x88), None, _, _] => Ok(Up(Key::Char('7'))), [Some(0x89), None, _, _] => Ok(Up(Key::Char('8'))), [Some(0x8A), None, _, _] => Ok(Up(Key::Char('9'))), [Some(0xA9), None, _, _] => Ok(Up(Key::Char('`'))), [Some(0x8C), None, _, _] => Ok(Up(Key::Char('-'))), [Some(0x8D), None, _, _] => Ok(Up(Key::Char('='))), [Some(0xAB), None, _, _] => Ok(Up(Key::Char('\\'))), [Some(0x9A), None, _, _] => Ok(Up(Key::Char('['))), [Some(0xB4), None, _, _] => Ok(Up(Key::Char('.'))), [Some(0xB5), None, _, _] => Ok(Up(Key::Char('/'))), [Some(0x9B), None, _, _] => Ok(Up(Key::Char(']'))), [Some(0xA7), None, _, _] => Ok(Up(Key::Char(';'))), [Some(0xA8), None, _, _] => Ok(Up(Key::Char('\''))), [Some(0xB3), None, _, _] => Ok(Up(Key::Char(','))), [Some(0x9C), None, _, _] => Ok(Up(Key::Char('\n'))), [Some(0xB9), None, _, _] => Ok(Up(Key::Char(' '))), [Some(0x8F), None, _, _] => Ok(Up(Key::Char('\t'))), [Some(0x8E), None, _, _] => Ok(Up(Key::BackSpace)), [Some(0x81), None, _, _] => Ok(Up(Key::Escape)), [Some(0xAA), None, _, _] => Ok(Up(Key::ShiftLeft)), [Some(0x9D), None, _, _] => Ok(Up(Key::CtrlLeft)), [Some(0xB8), None, _, _] => Ok(Up(Key::AltLeft)), [Some(0xB6), None, _, _] => Ok(Up(Key::ShiftRight)), [Some(0xD0), None, _, _] => Ok(Up(Key::Char('2'))), // KeyPad variant [Some(0xD1), None, _, _] => Ok(Up(Key::Char('3'))), // KeyPad variant [Some(0xCB), None, _, _] => Ok(Up(Key::Char('4'))), // KeyPad variant [Some(0xCC), None, _, _] => Ok(Up(Key::Char('5'))), // KeyPad variant [Some(0xCD), None, _, _] => Ok(Up(Key::Char('6'))), // KeyPad variant [Some(0xC7), None, _, _] => Ok(Up(Key::Char('7'))), // KeyPad variant [Some(0xC8), None, _, _] => Ok(Up(Key::Char('8'))), // KeyPad variant [Some(0xC9), None, _, _] => Ok(Up(Key::Char('9'))), // KeyPad variant [Some(0xB7), None, _, _] => Ok(Up(Key::Char('*'))), // KeyPad variant [Some(0xCA), None, _, _] => Ok(Up(Key::Char('-'))), // KeyPad variant [Some(0xCE), None, _, _] => Ok(Up(Key::Char('+'))), // KeyPad variant [Some(0xD3), None, _, _] => Ok(Up(Key::Char('.'))), // KeyPad variant [Some(0xD2), None, _, _] => Ok(Up(Key::Char('0'))), // KeyPad variant [Some(0xCF), None, _, _] => Ok(Up(Key::Char('1'))), // KeyPad variant [Some(0xBB), None, _, _] => Ok(Up(Key::Fun(1))), [Some(0xBC), None, _, _] => Ok(Up(Key::Fun(2))), [Some(0xBD), None, _, _] => Ok(Up(Key::Fun(3))), [Some(0xBE), None, _, _] => Ok(Up(Key::Fun(4))), [Some(0xBF), None, _, _] => Ok(Up(Key::Fun(5))), [Some(0xC0), None, _, _] => Ok(Up(Key::Fun(6))), [Some(0xC1), None, _, _] => Ok(Up(Key::Fun(7))), [Some(0xC2), None, _, _] => Ok(Up(Key::Fun(8))), [Some(0xC3), None, _, _] => Ok(Up(Key::Fun(9))), [Some(0xC4), None, _, _] => Ok(Up(Key::Fun(10))), [Some(0xD7), None, _, _] => Ok(Up(Key::Fun(11))), [Some(0xD8), None, _, _] => Ok(Up(Key::Fun(12))), [Some(0xE0), None, _, _] => KeyMapRes::Partial, [Some(0x35), Some(0xE0), None, _] => Ok(Down(Key::Char('/'))), // KeyPad variant [Some(0x52), Some(0xE0), None, _] => Ok(Down(Key::Insert)), [Some(0x47), Some(0xE0), None, _] => Ok(Down(Key::Home)), [Some(0x49), Some(0xE0), None, _] => Ok(Down(Key::PageUp)), [Some(0x53), Some(0xE0), None, _] => Ok(Down(Key::Delete)), [Some(0x4F), Some(0xE0), None, _] => Ok(Down(Key::End)), [Some(0x51), Some(0xE0), None, _] => Ok(Down(Key::PageDown)), [Some(0x48), Some(0xE0), None, _] => Ok(Down(Key::ArrowUp)), [Some(0x4B), Some(0xE0), None, _] => Ok(Down(Key::ArrowLeft)), [Some(0x50), Some(0xE0), None, _] => Ok(Down(Key::ArrowDown)), [Some(0x4D), Some(0xE0), None, _] => Ok(Down(Key::ArrowRight)), [Some(0x1D), Some(0xE0), None, _] => Ok(Down(Key::CtrlRight)), [Some(0x38), Some(0xE0), None, _] => Ok(Down(Key::AltRight)), [Some(0xB5), Some(0xE0), None, _] => Ok(Up(Key::Char('/'))), // KeyPad variant [Some(0xD2), Some(0xE0), None, _] => Ok(Up(Key::Insert)), [Some(0x97), Some(0xE0), None, _] => Ok(Up(Key::Home)), [Some(0xC9), Some(0xE0), None, _] => Ok(Up(Key::PageUp)), [Some(0xD3), Some(0xE0), None, _] => Ok(Up(Key::Delete)), [Some(0xCF), Some(0xE0), None, _] => Ok(Up(Key::End)), [Some(0xD1), Some(0xE0), None, _] => Ok(Up(Key::PageDown)), [Some(0xC8), Some(0xE0), None, _] => Ok(Up(Key::ArrowUp)), [Some(0xCB), Some(0xE0), None, _] => Ok(Up(Key::ArrowLeft)), [Some(0xD0), Some(0xE0), None, _] => Ok(Up(Key::ArrowDown)), [Some(0xCD), Some(0xE0), None, _] => Ok(Up(Key::ArrowRight)), [Some(0x9D), Some(0xE0), None, _] => Ok(Up(Key::CtrlRight)), [Some(0xB8), Some(0xE0), None, _] => Ok(Up(Key::AltRight)), _ => KeyMapRes::Unknown, }; if let KeyMapRes::Ok(_) | KeyMapRes::Unknown = res { self.lasts.flush(); } res } fn apply_mod(&self, key: char, state: &KeyModState) -> char { match key { '0' if state.shift => ')', '1' if state.shift => '!', '2' if state.shift => '@', '3' if state.shift => '#', '4' if state.shift => '$', '5' if state.shift => '%', '6' if state.shift => '^', '7' if state.shift => '&', '8' if state.shift => '*', '9' if state.shift => '(', '`' if state.shift => '~', '-' if state.shift => '_', '=' if state.shift => '+', '[' if state.shift => '{', ']' if state.shift => '}', '\\' if state.shift => '|', ';' if state.shift => ':', '\'' if state.shift => '"', ',' if state.shift => '<', '.' if state.shift => '>', '/' if state.shift => '?', c if state.shift && c.is_alphabetic() => c.to_uppercase().next().unwrap(), _ => key, } } } /* char table A 1E 9E B 30 B0 C 2E AE D 20 A0 E 12 92 F 21 A1 G 22 A2 H 23 A3 I 17 97 J 24 A4 K 25 A5 L 26 A6 M 32 B2 N 31 B1 O 18 98 P 19 99 Q 10 90 R 13 93 S 1F 9F T 14 94 U 16 96 V 2F AF W 11 91 X 2D AD Y 15 95 Z 2C AC 0 0B 8B 1 02 82 2 03 83 3 04 84 4 05 85 5 06 86 6 07 87 7 08 88 8 09 89 9 0A 8A ` 29 89 - 0C 8C = 0D 8D \ 2B AB [ 1A 9A . 34 B4 / 35 B5 ] 1B 9B ; 27 A7 ' 28 A8 , 33 B3 ENTER 1C 9C SPACE 39 B9 TAB 0F 8F BKSP 0E 8E ESC 01 81 CAPS 3A BA L_SHFT 2A AA L_CTRL 1D 9D INSERT E0,52 E0,D2 HOME E0,47 E0,97 PG_UP E0,49 E0,C9 DELETE E0,53 E0,D3 END E0,4F E0,CF PG_DN E0,51 E0,D1 U_ARROW E0,48 E0,C8 L_ARROW E0,4B E0,CB D_ARROW E0,50 E0,D0 R_ARROW E0,4D E0,CD L_GUI E0,5B E0,DB L_ALT 38 B8 R_SHFT 36 B6 R_CTRL E0,1D E0,9D R_GUI E0,5C E0,DC R_ALT E0,38 E0,B8 APPS E0,5D E0,DD F1 3B BB F2 3C BC F3 3D BD F4 3E BE F5 3F BF F6 40 C0 F7 41 C1 F8 42 C2 F9 43 C3 F10 44 C4 F11 57 D7 F12 58 D8 SCROLL 46 C6 KP_2 50 D0 KP_3 51 D1 KP_4 4B CB KP_5 4C CC KP_6 4D CD KP_7 47 C7 KP_8 48 C8 KP_9 49 C9 NUM 45 C5 KP_/ E0,35 E0,B5 KP_* 37 B7 KP_- 4A CA KP_+ 4E CE KP_EN E0,1C E0,9C KP_. 53 D3 KP_0 52 D2 KP_1 4F CF */ #[derive(Debug, Default, Clone)] pub struct Azerty { lasts: ArrayQueue, } impl KeyMap for Azerty { fn parse(&mut self, scan_code: u8) -> KeyMapRes { use Code::*; use KeyMapRes::*; self.lasts.add(scan_code); let res = match *self.lasts.content() { [Some(0x0B), None, _, _] => Ok(Down(Key::Char('à'))), [Some(0x02), None, _, _] => Ok(Down(Key::Char('&'))), [Some(0x03), None, _, _] => Ok(Down(Key::Char('é'))), [Some(0x04), None, _, _] => Ok(Down(Key::Char('"'))), [Some(0x05), None, _, _] => Ok(Down(Key::Char('\''))), [Some(0x06), None, _, _] => Ok(Down(Key::Char('('))), [Some(0x07), None, _, _] => Ok(Down(Key::Char('-'))), [Some(0x08), None, _, _] => Ok(Down(Key::Char('è'))), [Some(0x09), None, _, _] => Ok(Down(Key::Char('_'))), [Some(0x0A), None, _, _] => Ok(Down(Key::Char('ç'))), [Some(0x8B), None, _, _] => Ok(Up(Key::Char('à'))), [Some(0x82), None, _, _] => Ok(Up(Key::Char('&'))), [Some(0x83), None, _, _] => Ok(Up(Key::Char('é'))), [Some(0x84), None, _, _] => Ok(Up(Key::Char('"'))), [Some(0x85), None, _, _] => Ok(Up(Key::Char('\''))), [Some(0x86), None, _, _] => Ok(Up(Key::Char('('))), [Some(0x87), None, _, _] => Ok(Up(Key::Char('-'))), [Some(0x88), None, _, _] => Ok(Up(Key::Char('è'))), [Some(0x89), None, _, _] => Ok(Up(Key::Char('_'))), [Some(0x8A), None, _, _] => Ok(Up(Key::Char('ç'))), [Some(1), None, _, _] => Ok(Down(Key::Escape)), [Some(129), None, _, _] => Ok(Up(Key::Escape)), [Some(14), None, _, _] => Ok(Down(Key::BackSpace)), [Some(142), None, _, _] => Ok(Up(Key::BackSpace)), // [Some(111), None, _, _] => Ok(Down(Key::BackSpace)), // [Some(239), None, _, _] => Ok(Up(Key::BackSpace)), [Some(12), None, _, _] => Ok(Down(Key::Char(')'))), [Some(140), None, _, _] => Ok(Up(Key::Char(')'))), [Some(13), None, _, _] => Ok(Down(Key::Char('='))), [Some(141), None, _, _] => Ok(Up(Key::Char('='))), [Some(15), None, _, _] => Ok(Down(Key::Char('\t'))), [Some(143), None, _, _] => Ok(Up(Key::Char('\t'))), [Some(16), None, _, _] => Ok(Down(Key::Char('a'))), [Some(144), None, _, _] => Ok(Up(Key::Char('a'))), [Some(17), None, _, _] => Ok(Down(Key::Char('z'))), [Some(145), None, _, _] => Ok(Up(Key::Char('z'))), [Some(18), None, _, _] => Ok(Down(Key::Char('e'))), [Some(146), None, _, _] => Ok(Up(Key::Char('e'))), [Some(19), None, _, _] => Ok(Down(Key::Char('r'))), [Some(147), None, _, _] => Ok(Up(Key::Char('r'))), [Some(20), None, _, _] => Ok(Down(Key::Char('t'))), [Some(148), None, _, _] => Ok(Up(Key::Char('t'))), [Some(21), None, _, _] => Ok(Down(Key::Char('y'))), [Some(149), None, _, _] => Ok(Up(Key::Char('y'))), [Some(22), None, _, _] => Ok(Down(Key::Char('u'))), [Some(150), None, _, _] => Ok(Up(Key::Char('u'))), [Some(23), None, _, _] => Ok(Down(Key::Char('i'))), [Some(151), None, _, _] => Ok(Up(Key::Char('i'))), [Some(24), None, _, _] => Ok(Down(Key::Char('o'))), [Some(152), None, _, _] => Ok(Up(Key::Char('o'))), [Some(25), None, _, _] => Ok(Down(Key::Char('p'))), [Some(153), None, _, _] => Ok(Up(Key::Char('p'))), [Some(27), None, _, _] => Ok(Down(Key::Char('$'))), [Some(155), None, _, _] => Ok(Up(Key::Char('$'))), [Some(28), None, _, _] => Ok(Down(Key::Char('\n'))), [Some(156), None, _, _] => Ok(Up(Key::Char('\n'))), [Some(29), None, _, _] => Ok(Down(Key::CtrlLeft)), [Some(157), None, _, _] => Ok(Up(Key::CtrlLeft)), [Some(30), None, _, _] => Ok(Down(Key::Char('q'))), [Some(158), None, _, _] => Ok(Up(Key::Char('q'))), [Some(31), None, _, _] => Ok(Down(Key::Char('s'))), [Some(159), None, _, _] => Ok(Up(Key::Char('s'))), [Some(32), None, _, _] => Ok(Down(Key::Char('d'))), [Some(160), None, _, _] => Ok(Up(Key::Char('d'))), [Some(33), None, _, _] => Ok(Down(Key::Char('f'))), [Some(161), None, _, _] => Ok(Up(Key::Char('f'))), [Some(34), None, _, _] => Ok(Down(Key::Char('g'))), [Some(162), None, _, _] => Ok(Up(Key::Char('g'))), [Some(35), None, _, _] => Ok(Down(Key::Char('h'))), [Some(163), None, _, _] => Ok(Up(Key::Char('h'))), [Some(36), None, _, _] => Ok(Down(Key::Char('j'))), [Some(164), None, _, _] => Ok(Up(Key::Char('j'))), [Some(37), None, _, _] => Ok(Down(Key::Char('k'))), [Some(165), None, _, _] => Ok(Up(Key::Char('k'))), [Some(38), None, _, _] => Ok(Down(Key::Char('l'))), [Some(166), None, _, _] => Ok(Up(Key::Char('l'))), [Some(39), None, _, _] => Ok(Down(Key::Char('m'))), [Some(167), None, _, _] => Ok(Up(Key::Char('m'))), [Some(41), None, _, _] => Ok(Down(Key::Char('*'))), [Some(169), None, _, _] => Ok(Up(Key::Char('*'))), [Some(42), None, _, _] => Ok(Down(Key::ShiftLeft)), [Some(170), None, _, _] => Ok(Up(Key::ShiftLeft)), [Some(43), None, _, _] => Ok(Down(Key::Char('*'))), [Some(171), None, _, _] => Ok(Up(Key::Char('*'))), [Some(44), None, _, _] => Ok(Down(Key::Char('w'))), [Some(172), None, _, _] => Ok(Up(Key::Char('w'))), [Some(45), None, _, _] => Ok(Down(Key::Char('x'))), [Some(173), None, _, _] => Ok(Up(Key::Char('x'))), [Some(46), None, _, _] => Ok(Down(Key::Char('c'))), [Some(174), None, _, _] => Ok(Up(Key::Char('c'))), [Some(47), None, _, _] => Ok(Down(Key::Char('v'))), [Some(175), None, _, _] => Ok(Up(Key::Char('v'))), [Some(48), None, _, _] => Ok(Down(Key::Char('b'))), [Some(176), None, _, _] => Ok(Up(Key::Char('b'))), [Some(49), None, _, _] => Ok(Down(Key::Char('n'))), [Some(177), None, _, _] => Ok(Up(Key::Char('n'))), [Some(50), None, _, _] => Ok(Down(Key::Char(','))), [Some(178), None, _, _] => Ok(Up(Key::Char(','))), [Some(51), None, _, _] => Ok(Down(Key::Char(';'))), [Some(179), None, _, _] => Ok(Up(Key::Char(';'))), [Some(52), None, _, _] => Ok(Down(Key::Char(':'))), [Some(180), None, _, _] => Ok(Up(Key::Char(':'))), [Some(53), None, _, _] => Ok(Down(Key::Char('!'))), [Some(181), None, _, _] => Ok(Up(Key::Char('!'))), [Some(54), None, _, _] => Ok(Down(Key::ShiftRight)), [Some(182), None, _, _] => Ok(Up(Key::ShiftRight)), [Some(55), None, _, _] => Ok(Down(Key::Char('*'))), // Keypad Variant [Some(183), None, _, _] => Ok(Up(Key::Char('*'))), // Keypad Variant [Some(56), None, _, _] => Ok(Down(Key::AltLeft)), [Some(184), None, _, _] => Ok(Up(Key::AltLeft)), [Some(57), None, _, _] => Ok(Down(Key::Char(' '))), [Some(185), None, _, _] => Ok(Up(Key::Char(' '))), [Some(59), None, _, _] => Ok(Down(Key::Fun(1))), [Some(187), None, _, _] => Ok(Up(Key::Fun(1))), [Some(60), None, _, _] => Ok(Down(Key::Fun(2))), [Some(188), None, _, _] => Ok(Up(Key::Fun(2))), [Some(61), None, _, _] => Ok(Down(Key::Fun(3))), [Some(189), None, _, _] => Ok(Up(Key::Fun(3))), [Some(62), None, _, _] => Ok(Down(Key::Fun(4))), [Some(190), None, _, _] => Ok(Up(Key::Fun(4))), [Some(63), None, _, _] => Ok(Down(Key::Fun(5))), [Some(191), None, _, _] => Ok(Up(Key::Fun(5))), [Some(64), None, _, _] => Ok(Down(Key::Fun(6))), [Some(192), None, _, _] => Ok(Up(Key::Fun(6))), [Some(65), None, _, _] => Ok(Down(Key::Fun(7))), [Some(193), None, _, _] => Ok(Up(Key::Fun(7))), [Some(66), None, _, _] => Ok(Down(Key::Fun(8))), [Some(194), None, _, _] => Ok(Up(Key::Fun(8))), [Some(67), None, _, _] => Ok(Down(Key::Fun(9))), [Some(195), None, _, _] => Ok(Up(Key::Fun(9))), [Some(68), None, _, _] => Ok(Down(Key::Fun(10))), [Some(196), None, _, _] => Ok(Up(Key::Fun(10))), [Some(71), None, _, _] => Ok(Down(Key::Char('7'))), // Keypad Variant [Some(199), None, _, _] => Ok(Up(Key::Char('7'))), // Keypad Variant [Some(72), None, _, _] => Ok(Down(Key::Char('8'))), // Keypad Variant [Some(200), None, _, _] => Ok(Up(Key::Char('8'))), // Keypad Variant [Some(73), None, _, _] => Ok(Down(Key::Char('9'))), // Keypad Variant [Some(201), None, _, _] => Ok(Up(Key::Char('9'))), // Keypad Variant [Some(75), None, _, _] => Ok(Down(Key::Char('4'))), // Keypad Variant [Some(203), None, _, _] => Ok(Up(Key::Char('4'))), // Keypad Variant [Some(76), None, _, _] => Ok(Down(Key::Char('5'))), // Keypad Variant [Some(204), None, _, _] => Ok(Up(Key::Char('5'))), // Keypad Variant [Some(77), None, _, _] => Ok(Down(Key::Char('6'))), // Keypad Variant [Some(205), None, _, _] => Ok(Up(Key::Char('6'))), // Keypad Variant [Some(80), None, _, _] => Ok(Down(Key::Char('2'))), // Keypad Variant [Some(208), None, _, _] => Ok(Up(Key::Char('2'))), // Keypad Variant [Some(81), None, _, _] => Ok(Down(Key::Char('3'))), // Keypad Variant [Some(209), None, _, _] => Ok(Up(Key::Char('3'))), // Keypad Variant [Some(82), None, _, _] => Ok(Down(Key::Char('0'))), // Keypad Variant [Some(210), None, _, _] => Ok(Up(Key::Char('0'))), // Keypad Variant [Some(79), None, _, _] => Ok(Down(Key::Char('1'))), // Keypad Variant [Some(207), None, _, _] => Ok(Up(Key::Char('1'))), // Keypad Variant [Some(83), None, _, _] => Ok(Down(Key::Char('.'))), // Keypad Variant [Some(211), None, _, _] => Ok(Up(Key::Char('.'))), // Keypad Variant [Some(78), None, _, _] => Ok(Down(Key::Char('+'))), // Keypad Variant [Some(206), None, _, _] => Ok(Up(Key::Char('+'))), // Keypad Variant [Some(74), None, _, _] => Ok(Down(Key::Char('-'))), // Keypad Variant [Some(202), None, _, _] => Ok(Up(Key::Char('-'))), // Keypad Variant [Some(86), None, _, _] => Ok(Down(Key::Char('<'))), // Keypad Variant [Some(214), None, _, _] => Ok(Up(Key::Char('<'))), // Keypad Variant [Some(87), None, _, _] => Ok(Down(Key::Fun(11))), [Some(215), None, _, _] => Ok(Up(Key::Fun(11))), [Some(88), None, _, _] => Ok(Down(Key::Fun(12))), [Some(216), None, _, _] => Ok(Up(Key::Fun(12))), [Some(96), None, _, _] => Ok(Down(Key::Char('\n'))), [Some(224), None, _, _] => Ok(Up(Key::Char('\n'))), [Some(98), None, _, _] => Ok(Down(Key::Char('/'))), // Keypad Variant [Some(226), None, _, _] => Ok(Up(Key::Char('/'))), // Keypad Variant // [Some(101), None, _, _] => Ok(Down(Key::Char('Break'))), // [Some(101), None, _, _] => Ok(Down(Key::Char('Break'))), // [Some(119), None, _, _] => Ok(Down(Key::Char('Pause'))), // [Some(26), None, _, _] => Ok(Down(Key::Char('asciicircum'))), // [Some(40), None, _, _] => Ok(Down(Key::Char('bar'))), // [Some(58), None, _, _] => Ok(Down(Key::Char('Caps_Lock'))), // [Some(69), None, _, _] => Ok(Down(Key::Char('Num_Lock'))), // [Some(70), None, _, _] => Ok(Down(Key::Char('Scroll_Lock'))), // [Some(84), None, _, _] => Ok(Down(Key::Char('Last_Console'))), // [Some(84), None, _, _] => Ok(Down(Key::Char('Last_Console'))), // [Some(99), None, _, _] => Ok(Down(Key::Char('Compose'))), [Some(0x35), Some(0xE0), None, _] => Ok(Down(Key::Char('/'))), // KeyPad variant [Some(0x52), Some(0xE0), None, _] => Ok(Down(Key::Insert)), [Some(0x47), Some(0xE0), None, _] => Ok(Down(Key::Home)), [Some(0x49), Some(0xE0), None, _] => Ok(Down(Key::PageUp)), [Some(0x53), Some(0xE0), None, _] => Ok(Down(Key::Delete)), [Some(0x4F), Some(0xE0), None, _] => Ok(Down(Key::End)), [Some(0x51), Some(0xE0), None, _] => Ok(Down(Key::PageDown)), [Some(0x48), Some(0xE0), None, _] => Ok(Down(Key::ArrowUp)), [Some(0x4B), Some(0xE0), None, _] => Ok(Down(Key::ArrowLeft)), [Some(0x50), Some(0xE0), None, _] => Ok(Down(Key::ArrowDown)), [Some(0x4D), Some(0xE0), None, _] => Ok(Down(Key::ArrowRight)), [Some(0x1D), Some(0xE0), None, _] => Ok(Down(Key::CtrlRight)), [Some(0x38), Some(0xE0), None, _] => Ok(Down(Key::AltRight)), [Some(0xB5), Some(0xE0), None, _] => Ok(Up(Key::Char('/'))), // KeyPad variant [Some(0xD2), Some(0xE0), None, _] => Ok(Up(Key::Insert)), [Some(0x97), Some(0xE0), None, _] => Ok(Up(Key::Home)), [Some(0xC9), Some(0xE0), None, _] => Ok(Up(Key::PageUp)), [Some(0xD3), Some(0xE0), None, _] => Ok(Up(Key::Delete)), [Some(0xCF), Some(0xE0), None, _] => Ok(Up(Key::End)), [Some(0xD1), Some(0xE0), None, _] => Ok(Up(Key::PageDown)), [Some(0xC8), Some(0xE0), None, _] => Ok(Up(Key::ArrowUp)), [Some(0xCB), Some(0xE0), None, _] => Ok(Up(Key::ArrowLeft)), [Some(0xD0), Some(0xE0), None, _] => Ok(Up(Key::ArrowDown)), [Some(0xCD), Some(0xE0), None, _] => Ok(Up(Key::ArrowRight)), [Some(0x9D), Some(0xE0), None, _] => Ok(Up(Key::CtrlRight)), [Some(0xB8), Some(0xE0), None, _] => Ok(Up(Key::AltRight)), _ => KeyMapRes::Unknown, }; if let KeyMapRes::Ok(_) | KeyMapRes::Unknown = res { self.lasts.flush(); } res } fn apply_mod(&self, key: char, state: &KeyModState) -> char { match key { 'à' if state.shift => '0', '&' if state.shift => '1', 'é' if state.shift => '2', '"' if state.shift => '3', '\'' if state.shift => '4', '(' if state.shift => '5', '-' if state.shift => '6', 'è' if state.shift => '7', '_' if state.shift => '8', 'ç' if state.shift => '9', '^' if state.shift => '¨', '$' if state.shift => '£', 'ù' if state.shift => '%', '*' if state.shift => 'µ', ')' if state.shift => '°', '=' if state.shift => '+', '<' if state.shift => '>', ',' if state.shift => '?', ';' if state.shift => '.', ':' if state.shift => '/', '!' if state.shift => '§', '&' if state.alt => '¹', 'é' if state.alt => '~', '"' if state.alt => '#', '\'' if state.alt => '{', '(' if state.alt => '[', '-' if state.alt => '|', 'è' if state.alt => '`', '_' if state.alt => '\\', 'ç' if state.alt => '^', 'à' if state.alt => '@', ')' if state.alt => ']', '=' if state.alt => '}', '$' if state.alt => '¤', // '' if state.alt => '', c if state.shift && c.is_alphabetic() => c.to_uppercase().next().unwrap(), _ => key, } } }