nulfos/src/hard/keyboard.rs

746 lines
29 KiB
Rust

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<Keyboard> = Mutex::new(Keyboard::init());
}
pub struct Keyboard {
on_code: Option<Box<dyn FnMut(Code) + Send>>,
keymap: Box<dyn KeyMap + Send>,
}
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<u8, 4>,
}
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<u8, 4>,
}
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,
}
}
}