lesavka/client/src/input/keymap.rs

187 lines
7.0 KiB
Rust
Raw Normal View History

2025-06-08 04:11:58 -05:00
// client/src/input/keymap.rs
use evdev::KeyCode;
/// Return Some(usage) if we have a known mapping from evdev::KeyCode -> HID usage code
pub fn keycode_to_usage(key: KeyCode) -> Option<u8> {
match key {
// --- Letters ------------------------------------------------------
2025-06-08 04:11:58 -05:00
KeyCode::KEY_A => Some(0x04),
KeyCode::KEY_B => Some(0x05),
KeyCode::KEY_C => Some(0x06),
KeyCode::KEY_D => Some(0x07),
KeyCode::KEY_E => Some(0x08),
KeyCode::KEY_F => Some(0x09),
KeyCode::KEY_G => Some(0x0A),
KeyCode::KEY_H => Some(0x0B),
KeyCode::KEY_I => Some(0x0C),
KeyCode::KEY_J => Some(0x0D),
KeyCode::KEY_K => Some(0x0E),
KeyCode::KEY_L => Some(0x0F),
KeyCode::KEY_M => Some(0x10),
KeyCode::KEY_N => Some(0x11),
KeyCode::KEY_O => Some(0x12),
KeyCode::KEY_P => Some(0x13),
KeyCode::KEY_Q => Some(0x14),
KeyCode::KEY_R => Some(0x15),
KeyCode::KEY_S => Some(0x16),
KeyCode::KEY_T => Some(0x17),
KeyCode::KEY_U => Some(0x18),
KeyCode::KEY_V => Some(0x19),
KeyCode::KEY_W => Some(0x1A),
KeyCode::KEY_X => Some(0x1B),
KeyCode::KEY_Y => Some(0x1C),
KeyCode::KEY_Z => Some(0x1D),
// --- Number row ---------------------------------------------------
2025-06-08 04:11:58 -05:00
KeyCode::KEY_1 => Some(0x1E),
KeyCode::KEY_2 => Some(0x1F),
KeyCode::KEY_3 => Some(0x20),
KeyCode::KEY_4 => Some(0x21),
KeyCode::KEY_5 => Some(0x22),
KeyCode::KEY_6 => Some(0x23),
KeyCode::KEY_7 => Some(0x24),
KeyCode::KEY_8 => Some(0x25),
KeyCode::KEY_9 => Some(0x26),
KeyCode::KEY_0 => Some(0x27),
// --- Common punctuation -------------------------------------------
2025-06-08 04:11:58 -05:00
KeyCode::KEY_ENTER => Some(0x28),
KeyCode::KEY_ESC => Some(0x29),
KeyCode::KEY_BACKSPACE => Some(0x2A),
KeyCode::KEY_TAB => Some(0x2B),
KeyCode::KEY_SPACE => Some(0x2C),
KeyCode::KEY_MINUS => Some(0x2D),
KeyCode::KEY_EQUAL => Some(0x2E),
KeyCode::KEY_LEFTBRACE => Some(0x2F),
KeyCode::KEY_RIGHTBRACE => Some(0x30),
KeyCode::KEY_BACKSLASH => Some(0x31),
KeyCode::KEY_SEMICOLON => Some(0x33),
KeyCode::KEY_APOSTROPHE => Some(0x34),
KeyCode::KEY_GRAVE => Some(0x35),
KeyCode::KEY_COMMA => Some(0x36),
KeyCode::KEY_DOT => Some(0x37),
KeyCode::KEY_SLASH => Some(0x38),
2025-06-17 08:17:23 -05:00
// --- Function keys ------------------------------------------------
KeyCode::KEY_CAPSLOCK => Some(0x39),
KeyCode::KEY_F1 => Some(0x3A),
KeyCode::KEY_F2 => Some(0x3B),
KeyCode::KEY_F3 => Some(0x3C),
KeyCode::KEY_F4 => Some(0x3D),
KeyCode::KEY_F5 => Some(0x3E),
KeyCode::KEY_F6 => Some(0x3F),
KeyCode::KEY_F7 => Some(0x40),
KeyCode::KEY_F8 => Some(0x41),
KeyCode::KEY_F9 => Some(0x42),
KeyCode::KEY_F10 => Some(0x43),
KeyCode::KEY_F11 => Some(0x44),
KeyCode::KEY_F12 => Some(0x45),
// --- Navigation / editing cluster ---------------------------------
KeyCode::KEY_SYSRQ => Some(0x46), // Print-Screen
KeyCode::KEY_SCROLLLOCK => Some(0x47),
KeyCode::KEY_PAUSE => Some(0x48),
KeyCode::KEY_INSERT => Some(0x49),
KeyCode::KEY_HOME => Some(0x4A),
KeyCode::KEY_PAGEUP => Some(0x4B),
KeyCode::KEY_DELETE => Some(0x4C),
KeyCode::KEY_END => Some(0x4D),
KeyCode::KEY_PAGEDOWN => Some(0x4E),
KeyCode::KEY_RIGHT => Some(0x4F),
KeyCode::KEY_LEFT => Some(0x50),
KeyCode::KEY_DOWN => Some(0x51),
KeyCode::KEY_UP => Some(0x52),
2025-06-28 15:45:35 -05:00
// --- Keypad / Num-lock block --------------------------------------
KeyCode::KEY_NUMLOCK => Some(0x53),
KeyCode::KEY_KPSLASH => Some(0x54),
KeyCode::KEY_KPASTERISK => Some(0x55),
KeyCode::KEY_KPMINUS => Some(0x56),
KeyCode::KEY_KPPLUS => Some(0x57),
KeyCode::KEY_KPENTER => Some(0x58),
KeyCode::KEY_KP1 => Some(0x59),
KeyCode::KEY_KP2 => Some(0x5A),
KeyCode::KEY_KP3 => Some(0x5B),
KeyCode::KEY_KP4 => Some(0x5C),
KeyCode::KEY_KP5 => Some(0x5D),
KeyCode::KEY_KP6 => Some(0x5E),
KeyCode::KEY_KP7 => Some(0x5F),
KeyCode::KEY_KP8 => Some(0x60),
KeyCode::KEY_KP9 => Some(0x61),
KeyCode::KEY_KP0 => Some(0x62),
KeyCode::KEY_KPDOT => Some(0x63),
KeyCode::KEY_KPEQUAL => Some(0x67),
// --- Misc ---------------------------------------------------------
KeyCode::KEY_102ND => Some(0x64), // “<>” on ISO boards
KeyCode::KEY_MENU => Some(0x65), // Application / Compose
2025-06-08 04:11:58 -05:00
// We'll handle modifiers (ctrl, shift, alt, meta) in `is_modifier()`
_ => None,
}
}
/// If a key is a modifier, return the bit(s) to set in HID byte[0].
pub fn is_modifier(key: KeyCode) -> Option<u8> {
match key {
KeyCode::KEY_LEFTCTRL => Some(0x01),
2025-06-08 04:11:58 -05:00
KeyCode::KEY_LEFTSHIFT => Some(0x02),
KeyCode::KEY_LEFTALT => Some(0x04),
KeyCode::KEY_LEFTMETA => Some(0x08),
2025-06-08 04:11:58 -05:00
KeyCode::KEY_RIGHTCTRL => Some(0x10),
KeyCode::KEY_RIGHTSHIFT => Some(0x20),
KeyCode::KEY_RIGHTALT => Some(0x40),
2025-06-08 04:11:58 -05:00
KeyCode::KEY_RIGHTMETA => Some(0x80),
_ => None,
}
}
/// Map a printable character to (usage, modifiers).
/// Modifiers currently only include Shift for uppercase/punctuation.
pub fn char_to_usage(c: char) -> Option<(u8, u8)> {
let shift = 0x02; // left shift in HID modifier byte
match c {
'a'..='z' => Some((0x04 + (c as u8 - b'a'), 0)),
'A'..='Z' => Some((0x04 + (c as u8 - b'A'), shift)),
'1'..='9' => Some((0x1E + (c as u8 - b'1'), 0)),
'0' => Some((0x27, 0)),
'!' => Some((0x1E, shift)),
'@' => Some((0x1F, shift)),
'#' => Some((0x20, shift)),
'$' => Some((0x21, shift)),
'%' => Some((0x22, shift)),
'^' => Some((0x23, shift)),
'&' => Some((0x24, shift)),
'*' => Some((0x25, shift)),
'(' => Some((0x26, shift)),
')' => Some((0x27, shift)),
'-' => Some((0x2D, 0)),
'_' => Some((0x2D, shift)),
'=' => Some((0x2E, 0)),
'+' => Some((0x2E, shift)),
'[' => Some((0x2F, 0)),
'{' => Some((0x2F, shift)),
']' => Some((0x30, 0)),
'}' => Some((0x30, shift)),
'\\' => Some((0x31, 0)),
'|' => Some((0x31, shift)),
';' => Some((0x33, 0)),
':' => Some((0x33, shift)),
'\'' => Some((0x34, 0)),
'"' => Some((0x34, shift)),
'`' => Some((0x35, 0)),
'~' => Some((0x35, shift)),
',' => Some((0x36, 0)),
'<' => Some((0x36, shift)),
'.' => Some((0x37, 0)),
'>' => Some((0x37, shift)),
'/' => Some((0x38, 0)),
'?' => Some((0x38, shift)),
' ' => Some((0x2C, 0)),
'\n' | '\r' => Some((0x28, 0)),
'\t' => Some((0x2B, 0)),
_ => None,
}
}