746 lines
29 KiB
Rust
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,
|
|
}
|
|
}
|
|
}
|