445 lines
13 KiB
Rust
445 lines
13 KiB
Rust
use crate::{
|
|
DecodedKey, HandleControl, KeyCode, KeyboardLayout, LayoutEntry, LayoutEntryKind, Modifiers,
|
|
};
|
|
|
|
pub struct CustomLayout {
|
|
mapping: [LayoutEntry; 256],
|
|
}
|
|
|
|
impl Default for CustomLayout {
|
|
fn default() -> Self {
|
|
Self::new_us104key()
|
|
}
|
|
}
|
|
|
|
impl CustomLayout {
|
|
pub fn new_us104key() -> Self {
|
|
let mut mapping = Self {
|
|
mapping: [LayoutEntry::default(); 256],
|
|
};
|
|
|
|
mapping.set(
|
|
KeyCode::BackTick,
|
|
LayoutEntry::regular().unshifted('`').shifted('`'),
|
|
);
|
|
mapping.set(KeyCode::Escape, LayoutEntry::regular().unshifted('\x1B'));
|
|
mapping.set(
|
|
KeyCode::Key0,
|
|
LayoutEntry::regular().unshifted('0').shifted(')'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key1,
|
|
LayoutEntry::regular().unshifted('1').shifted('!'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key2,
|
|
LayoutEntry::regular().unshifted('2').shifted('@'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key3,
|
|
LayoutEntry::regular().unshifted('3').shifted('#'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key4,
|
|
LayoutEntry::regular().unshifted('4').shifted('$'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key5,
|
|
LayoutEntry::regular().unshifted('5').shifted('%'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key6,
|
|
LayoutEntry::regular().unshifted('6').shifted('^'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key7,
|
|
LayoutEntry::regular().unshifted('7').shifted('&'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key8,
|
|
LayoutEntry::regular().unshifted('8').shifted('*'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key9,
|
|
LayoutEntry::regular().unshifted('9').shifted('('),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Minus,
|
|
LayoutEntry::regular().unshifted('-').shifted('_'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Equals,
|
|
LayoutEntry::regular().unshifted('=').shifted('+'),
|
|
);
|
|
mapping.set(KeyCode::Backspace, LayoutEntry::regular().all('\x08'));
|
|
mapping.set(KeyCode::Tab, LayoutEntry::regular().all('\x09'));
|
|
mapping.set(
|
|
KeyCode::Q,
|
|
LayoutEntry::alphabet()
|
|
.low('q')
|
|
.high('Q')
|
|
.raw_unicode('\u{0011}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::W,
|
|
LayoutEntry::alphabet()
|
|
.low('w')
|
|
.high('W')
|
|
.raw_unicode('\u{0017}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::E,
|
|
LayoutEntry::alphabet()
|
|
.low('e')
|
|
.high('E')
|
|
.raw_unicode('\u{0005}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::R,
|
|
LayoutEntry::alphabet()
|
|
.low('r')
|
|
.high('R')
|
|
.raw_unicode('\u{0012}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::T,
|
|
LayoutEntry::alphabet()
|
|
.low('t')
|
|
.high('T')
|
|
.raw_unicode('\u{0014}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Y,
|
|
LayoutEntry::alphabet()
|
|
.low('y')
|
|
.high('Y')
|
|
.raw_unicode('\u{0019}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::U,
|
|
LayoutEntry::alphabet()
|
|
.low('u')
|
|
.high('U')
|
|
.raw_unicode('\u{0015}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::I,
|
|
LayoutEntry::alphabet()
|
|
.low('i')
|
|
.high('I')
|
|
.raw_unicode('\u{0009}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::O,
|
|
LayoutEntry::alphabet()
|
|
.low('o')
|
|
.high('O')
|
|
.raw_unicode('\u{000F}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::P,
|
|
LayoutEntry::alphabet()
|
|
.low('p')
|
|
.high('P')
|
|
.raw_unicode('\u{0010}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::A,
|
|
LayoutEntry::alphabet()
|
|
.low('a')
|
|
.high('A')
|
|
.raw_unicode('\u{0001}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::S,
|
|
LayoutEntry::alphabet()
|
|
.low('s')
|
|
.high('S')
|
|
.raw_unicode('\u{0013}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::D,
|
|
LayoutEntry::alphabet()
|
|
.low('d')
|
|
.high('D')
|
|
.raw_unicode('\u{0004}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::F,
|
|
LayoutEntry::alphabet()
|
|
.low('f')
|
|
.high('F')
|
|
.raw_unicode('\u{0006}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::G,
|
|
LayoutEntry::alphabet()
|
|
.low('g')
|
|
.high('G')
|
|
.raw_unicode('\u{0007}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::H,
|
|
LayoutEntry::alphabet()
|
|
.low('h')
|
|
.high('H')
|
|
.raw_unicode('\u{0008}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::J,
|
|
LayoutEntry::alphabet()
|
|
.low('j')
|
|
.high('J')
|
|
.raw_unicode('\u{000A}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::K,
|
|
LayoutEntry::alphabet()
|
|
.low('k')
|
|
.high('K')
|
|
.raw_unicode('\u{000B}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::L,
|
|
LayoutEntry::alphabet()
|
|
.low('l')
|
|
.high('L')
|
|
.raw_unicode('\u{000C}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Z,
|
|
LayoutEntry::alphabet()
|
|
.low('z')
|
|
.high('Z')
|
|
.raw_unicode('\u{001A}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::X,
|
|
LayoutEntry::alphabet()
|
|
.low('x')
|
|
.high('X')
|
|
.raw_unicode('\u{0018}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::C,
|
|
LayoutEntry::alphabet()
|
|
.low('c')
|
|
.high('C')
|
|
.raw_unicode('\u{0003}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::V,
|
|
LayoutEntry::alphabet()
|
|
.low('v')
|
|
.high('V')
|
|
.raw_unicode('\u{0016}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::B,
|
|
LayoutEntry::alphabet()
|
|
.low('b')
|
|
.high('B')
|
|
.raw_unicode('\u{0002}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::N,
|
|
LayoutEntry::alphabet()
|
|
.low('n')
|
|
.high('N')
|
|
.raw_unicode('\u{000E}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::M,
|
|
LayoutEntry::alphabet()
|
|
.low('m')
|
|
.high('M')
|
|
.raw_unicode('\u{000D}'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::BracketSquareLeft,
|
|
LayoutEntry::regular().unshifted('{').shifted('['),
|
|
);
|
|
mapping.set(
|
|
KeyCode::BracketSquareRight,
|
|
LayoutEntry::regular().unshifted('}').shifted(']'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::BackSlash,
|
|
LayoutEntry::regular().unshifted('|').shifted('\\'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::SemiColon,
|
|
LayoutEntry::regular().unshifted(';').shifted(':'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Quote,
|
|
LayoutEntry::regular().unshifted('\'').shifted('"'),
|
|
);
|
|
mapping.set(KeyCode::Enter, LayoutEntry::regular().all('\x0A'));
|
|
mapping.set(
|
|
KeyCode::Comma,
|
|
LayoutEntry::regular().unshifted(',').shifted('<'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Fullstop,
|
|
LayoutEntry::regular().unshifted('.').shifted('>'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Slash,
|
|
LayoutEntry::regular().unshifted('/').shifted('?'),
|
|
);
|
|
mapping.set(KeyCode::Spacebar, LayoutEntry::regular().all(' '));
|
|
mapping.set(KeyCode::Delete, LayoutEntry::regular().all('\x7F'));
|
|
mapping.set(KeyCode::NumpadSlash, LayoutEntry::numpad().all('/'));
|
|
mapping.set(KeyCode::NumpadStar, LayoutEntry::numpad().all('*'));
|
|
mapping.set(KeyCode::NumpadMinus, LayoutEntry::numpad().all('-'));
|
|
mapping.set(
|
|
KeyCode::Numpad7,
|
|
LayoutEntry::numpad().low('7').high(KeyCode::Home),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Numpad8,
|
|
LayoutEntry::numpad().low('8').high(KeyCode::ArrowUp),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Numpad9,
|
|
LayoutEntry::numpad().low('9').high(KeyCode::PageUp),
|
|
);
|
|
mapping.set(KeyCode::NumpadPlus, LayoutEntry::numpad().all('+'));
|
|
mapping.set(
|
|
KeyCode::Numpad4,
|
|
LayoutEntry::numpad().low('4').high(KeyCode::ArrowLeft),
|
|
);
|
|
mapping.set(KeyCode::Numpad5, LayoutEntry::numpad().all('5'));
|
|
mapping.set(
|
|
KeyCode::Numpad6,
|
|
LayoutEntry::numpad().low('6').high(KeyCode::ArrowRight),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Numpad1,
|
|
LayoutEntry::numpad().low('1').high(KeyCode::End),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Numpad2,
|
|
LayoutEntry::numpad().low('2').high(KeyCode::ArrowDown),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Numpad3,
|
|
LayoutEntry::numpad().low('3').high(KeyCode::PageDown),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Numpad0,
|
|
LayoutEntry::numpad().low('0').high(KeyCode::Insert),
|
|
);
|
|
mapping.set(
|
|
KeyCode::NumpadPeriod,
|
|
LayoutEntry::numpad().low('.').high('\x7F'),
|
|
);
|
|
mapping.set(KeyCode::NumpadEnter, LayoutEntry::numpad().all('\x0A'));
|
|
mapping
|
|
}
|
|
pub fn new_us105key() -> Self {
|
|
let mut mapping = Self::new_us104key();
|
|
mapping.set(
|
|
KeyCode::BackTick,
|
|
LayoutEntry::regular()
|
|
.unshifted('`')
|
|
.shifted('¬')
|
|
.altgr('|'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key2,
|
|
LayoutEntry::regular().unshifted('2').shifted('"'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Quote,
|
|
LayoutEntry::regular().unshifted('\'').shifted('@'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::Key3,
|
|
LayoutEntry::regular().unshifted('3').shifted('£'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::BackTick,
|
|
LayoutEntry::regular()
|
|
.unshifted('4')
|
|
.shifted('$')
|
|
.altgr('€'),
|
|
);
|
|
mapping.set(
|
|
KeyCode::HashTilde,
|
|
LayoutEntry::regular().unshifted('#').shifted('~'),
|
|
);
|
|
mapping
|
|
}
|
|
|
|
pub fn set(&mut self, pos: KeyCode, entry: LayoutEntry) {
|
|
self.mapping[pos as usize] = entry;
|
|
}
|
|
}
|
|
|
|
impl KeyboardLayout for CustomLayout {
|
|
fn map_keycode(
|
|
&self,
|
|
keycode: KeyCode,
|
|
modifiers: &Modifiers,
|
|
handle_ctrl: HandleControl,
|
|
) -> DecodedKey {
|
|
let map_to_unicode = handle_ctrl == HandleControl::MapLettersToUnicode;
|
|
let spot = &self.mapping[keycode as usize];
|
|
if let Some(k) = if map_to_unicode && modifiers.is_ctrl() {
|
|
match spot.kind {
|
|
LayoutEntryKind::Regular => spot.raw_unicode,
|
|
LayoutEntryKind::Numlockable => None,
|
|
LayoutEntryKind::Capslockable => spot.raw_unicode,
|
|
}
|
|
} else if modifiers.alt_gr {
|
|
match spot.kind {
|
|
LayoutEntryKind::Regular => spot.altgr,
|
|
LayoutEntryKind::Numlockable => None,
|
|
LayoutEntryKind::Capslockable => spot.altgr,
|
|
}
|
|
} else if modifiers.is_shifted() {
|
|
match spot.kind {
|
|
LayoutEntryKind::Regular => spot.shifted,
|
|
LayoutEntryKind::Numlockable => {
|
|
if modifiers.numlock {
|
|
spot.locked_shifted
|
|
} else {
|
|
spot.shifted
|
|
}
|
|
}
|
|
LayoutEntryKind::Capslockable => {
|
|
if modifiers.is_caps() {
|
|
spot.locked_shifted
|
|
} else {
|
|
spot.shifted
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
match spot.kind {
|
|
LayoutEntryKind::Regular => spot.unshifted,
|
|
LayoutEntryKind::Numlockable => {
|
|
if modifiers.numlock {
|
|
spot.locked
|
|
} else {
|
|
spot.unshifted
|
|
}
|
|
}
|
|
LayoutEntryKind::Capslockable => {
|
|
if modifiers.is_caps() {
|
|
spot.locked
|
|
} else {
|
|
spot.unshifted
|
|
}
|
|
}
|
|
}
|
|
} {
|
|
k
|
|
} else {
|
|
DecodedKey::RawKey(keycode as u8)
|
|
}
|
|
}
|
|
}
|