From bc31f47ec613ea371b185f6c31be5f9eb364878e Mon Sep 17 00:00:00 2001 From: Sainan Date: Wed, 30 Oct 2024 16:27:12 +0100 Subject: [PATCH] Rewrite VirtualKey mapping to correctly handle non-translate (#86) * Fix beauty error * Rewrite VirtualKey mapping to correctly handle non-translate --- wooting-analog-sdk/src/keycode.rs | 225 +++++++++++++++++++++++------- 1 file changed, 172 insertions(+), 53 deletions(-) diff --git a/wooting-analog-sdk/src/keycode.rs b/wooting-analog-sdk/src/keycode.rs index 29d1dc4..507d906 100644 --- a/wooting-analog-sdk/src/keycode.rs +++ b/wooting-analog-sdk/src/keycode.rs @@ -174,8 +174,139 @@ lazy_static! { bimap }; - //VirtualKey, Scancode - static ref VIRTUALKEY_OVERRIDE: BiMap = { + // based on US layout + static ref HID_TO_VK_MAP_US: BiMap = { + let mut bimap: BiMap = BiMap::new(); + bimap.insert(0x04, 0x41); // US_A + bimap.insert(0x05, 0x42); // US_B + bimap.insert(0x06, 0x43); // US_C + bimap.insert(0x07, 0x44); // US_D + bimap.insert(0x08, 0x45); // US_E + bimap.insert(0x09, 0x46); // US_F + bimap.insert(0x0a, 0x47); // US_G + bimap.insert(0x0b, 0x48); // US_H + bimap.insert(0x0c, 0x49); // US_I + bimap.insert(0x0d, 0x4A); // US_J + bimap.insert(0x0e, 0x4B); // US_K + bimap.insert(0x0f, 0x4C); // US_L + bimap.insert(0x10, 0x4D); // US_M + bimap.insert(0x11, 0x4E); // US_N + bimap.insert(0x12, 0x4F); // US_O + bimap.insert(0x13, 0x50); // US_P + bimap.insert(0x14, 0x51); // US_Q + bimap.insert(0x15, 0x52); // US_R + bimap.insert(0x16, 0x53); // US_S + bimap.insert(0x17, 0x54); // US_T + bimap.insert(0x18, 0x55); // US_U + bimap.insert(0x19, 0x56); // US_V + bimap.insert(0x1a, 0x57); // US_W + bimap.insert(0x1b, 0x58); // US_X + bimap.insert(0x1c, 0x59); // US_Y + bimap.insert(0x1d, 0x5A); // US_Z + + bimap.insert(0x1e, 0x31); // DIGIT1 + bimap.insert(0x1f, 0x32); // DIGIT2 + bimap.insert(0x20, 0x33); // DIGIT3 + bimap.insert(0x21, 0x34); // DIGIT4 + bimap.insert(0x22, 0x35); // DIGIT5 + bimap.insert(0x23, 0x36); // DIGIT6 + bimap.insert(0x24, 0x37); // DIGIT7 + bimap.insert(0x25, 0x38); // DIGIT8 + bimap.insert(0x26, 0x39); // DIGIT9 + bimap.insert(0x27, 0x30); // DIGIT0 + + bimap.insert(0x28, 0x0D); // ENTER + bimap.insert(0x29, 0x1B); // ESCAPE + bimap.insert(0x2a, 0x08); // BACKSPACE + bimap.insert(0x2b, 0x09); // TAB + bimap.insert(0x2c, 0x20); // SPACE + bimap.insert(0x2d, 0xBD); // MINUS + bimap.insert(0x2e, 0xBB); // EQUAL + bimap.insert(0x2f, 0xDB); // BRACKET_LEFT + + bimap.insert(0x30, 0xDD); // BRACKET_RIGHT + bimap.insert(0x31, 0xDC); // BACKSLASH + + bimap.insert(0x33, 0xBA); // SEMICOLON + bimap.insert(0x34, 0xDE); // QUOTE + bimap.insert(0x35, 0xC0); // BACKQUOTE + bimap.insert(0x36, 0xBC); // COMMA + bimap.insert(0x37, 0xBE); // PERIOD + + bimap.insert(0x38, 0xBF); // SLASH + bimap.insert(0x39, 0x14); // CAPS_LOCK + + bimap.insert(0x3a, 0x70); // F1 + bimap.insert(0x3b, 0x71); // F2 + bimap.insert(0x3c, 0x72); // F3 + bimap.insert(0x3d, 0x73); // F4 + bimap.insert(0x3e, 0x74); // F5 + bimap.insert(0x3f, 0x75); // F6 + bimap.insert(0x40, 0x76); // F7 + bimap.insert(0x41, 0x77); // F8 + bimap.insert(0x42, 0x78); // F9 + bimap.insert(0x43, 0x79); // F10 + bimap.insert(0x44, 0x7A); // F11 + bimap.insert(0x45, 0x7B); // F12 + + bimap.insert(0x46, 0x2C); // PRINT_SCREEN + bimap.insert(0x47, 0x91); // SCROLL_LOCK + + bimap.insert(0x48, 0x13); // PAUSE + bimap.insert(0x49, 0x2D); // INSERT + bimap.insert(0x4a, 0x24); // HOME + bimap.insert(0x4b, 0x21); // PAGE_UP + bimap.insert(0x4c, 0x2E); // DELETE + bimap.insert(0x4d, 0x23); // END + bimap.insert(0x4e, 0x22); // PAGE_DOWN + + bimap.insert(0x4f, 0x27); // ARROW_RIGHT + bimap.insert(0x50, 0x25); // ARROW_LEFT + bimap.insert(0x51, 0x28); // ARROW_DOWN + bimap.insert(0x52, 0x26); // ARROW_UP + + bimap.insert(0x53, 0x90); // NUM_LOCK + bimap.insert(0x54, 0x6F); // NUMPAD_DIVIDE + bimap.insert(0x55, 0x6A); // NUMPAD_MULTIPLY + bimap.insert(0x56, 0x6D); // NUMPAD_SUBTRACT + bimap.insert(0x57, 0x6B); // NUMPAD_ADD + bimap.insert(0x58, 0x0D); // NUMPAD_ENTER + bimap.insert(0x59, 0x61); // NUMPAD1 + bimap.insert(0x5a, 0x62); // NUMPAD2 + bimap.insert(0x5b, 0x63); // NUMPAD3 + bimap.insert(0x5c, 0x64); // NUMPAD4 + bimap.insert(0x5d, 0x65); // NUMPAD5 + bimap.insert(0x5e, 0x66); // NUMPAD6 + bimap.insert(0x5f, 0x67); // NUMPAD7 + bimap.insert(0x60, 0x68); // NUMPAD8 + bimap.insert(0x61, 0x69); // NUMPAD9 + bimap.insert(0x62, 0x60); // NUMPAD0 + bimap.insert(0x63, 0x6E); // NUMPAD_DECIMAL + + bimap.insert(0x64, 0xE2); // INTL_BACKSLASH + bimap.insert(0x65, 0x5D); // CONTEXT_MENU + bimap.insert(0x67, 0x0B); // NUMPAD_EQUAL + + bimap.insert(0x68, 0x7C); // F13 + bimap.insert(0x69, 0x7D); // F14 + bimap.insert(0x6a, 0x7E); // F15 + bimap.insert(0x6b, 0x7F); // F16 + bimap.insert(0x6c, 0x80); // F17 + bimap.insert(0x6d, 0x81); // F18 + bimap.insert(0x6e, 0x82); // F19 + bimap.insert(0x6f, 0x83); // F20 + bimap.insert(0x70, 0x84); // F21 + bimap.insert(0x71, 0x85); // F22 + bimap.insert(0x72, 0x86); // F23 + bimap.insert(0x73, 0x87); // F24 + + bimap.insert(0x75, 0x2F); // HELP + + bimap + }; + + // + static ref VIRTUALKEY_OVERRIDE: BiMap = { let mut bimap: BiMap = BiMap::new(); bimap.insert(0x60, 0x0052); //NUMPAD0 bimap.insert(0x61, 0x004f); //NUMPAD1 @@ -194,33 +325,27 @@ lazy_static! { } #[allow(unused)] -pub fn vk_to_scancode(code: u16, translate: bool) -> Option { +pub fn vk_to_hid(vk: u16, translate: bool) -> Option { #[cfg(windows)] - unsafe { - if let Some(&code) = VIRTUALKEY_OVERRIDE.get_by_left(&(code as u8)) { - return Some(code); - } - - use winapi::um::winuser::{ - GetForegroundWindow, GetKeyboardLayout, GetWindowThreadProcessId, MapVirtualKeyA, - MapVirtualKeyExA, - }; - let scancode: u32; - if translate { - let window_handle = GetForegroundWindow(); - let thread = GetWindowThreadProcessId(window_handle, 0 as *mut u32); - let layout = GetKeyboardLayout(thread); - scancode = MapVirtualKeyExA(code.into(), 4, layout); - //println!("Window handle: {:?}, thread: {:?}, layout: {:?}, code: {} scancode: {}", window_handle, thread, layout, code, scancode); + if translate { + let scancode: u16; + if let Some(&code) = VIRTUALKEY_OVERRIDE.get_by_left(&(vk as u8)) { + scancode = code; } else { - scancode = MapVirtualKeyA(code.into(), 0); - } + use winapi::um::winuser::MapVirtualKeyA; + scancode = unsafe { MapVirtualKeyA(vk.into(), 0) as u16 }; - if scancode == 0 { + if scancode == 0 { + return None; + } + } + return scancode_to_hid(scancode); + } else { + if let Some(&hid) = HID_TO_VK_MAP_US.get_by_right(&(vk as u8)) { + return Some(hid as u16); + } else { return None; } - - return Some(scancode as u16); } #[cfg(not(windows))] @@ -228,33 +353,31 @@ pub fn vk_to_scancode(code: u16, translate: bool) -> Option { } #[allow(unused)] -pub fn scancode_to_vk(code: u16, translate: bool) -> Option { +pub fn hid_to_vk(hid: u16, translate: bool) -> Option { #[cfg(windows)] - unsafe { - if let Some(&code) = VIRTUALKEY_OVERRIDE.get_by_right(&code) { - return Some(code as u16); - } + if translate { + if let Some(scancode) = hid_to_scancode(hid) { + if let Some(&hid) = VIRTUALKEY_OVERRIDE.get_by_right(&scancode) { + return Some(hid as u16); + } + + use winapi::um::winuser::MapVirtualKeyA; + let vk: u32 = unsafe { MapVirtualKeyA(scancode.into(), 3) }; - use winapi::um::winuser::{ - GetForegroundWindow, GetKeyboardLayout, GetWindowThreadProcessId, MapVirtualKeyA, - MapVirtualKeyExA, - }; - let scancode: u32; - if translate { - let window_handle = GetForegroundWindow(); - let thread = GetWindowThreadProcessId(window_handle, 0 as *mut u32); - let layout = GetKeyboardLayout(thread); - scancode = MapVirtualKeyExA(code.into(), 3, layout); - //println!("Window handle: {:?}, thread: {:?}, layout: {:?}, code: {} scancode: {}", window_handle, thread, layout, code, scancode); + if (vk == 0) { + return None; + } + + return Some(vk as u16); } else { - scancode = MapVirtualKeyA(code.into(), 3); + return None; } - - if scancode == 0 { + } else { + if let Some(&vk) = HID_TO_VK_MAP_US.get_by_left(&(hid as u8)) { + return Some(vk as u16); + } else { return None; } - - return Some(scancode as u16); } #[cfg(not(windows))] @@ -302,8 +425,8 @@ pub fn code_to_hid(code: u16, mode: &KeycodeType) -> Option { } } KeycodeType::ScanCode1 => scancode_to_hid(code), - KeycodeType::VirtualKey => vk_to_scancode(code, false).and_then(scancode_to_hid), - KeycodeType::VirtualKeyTranslate => vk_to_scancode(code, true).and_then(scancode_to_hid), + KeycodeType::VirtualKey => vk_to_hid(code, false), + KeycodeType::VirtualKeyTranslate => vk_to_hid(code, true), } } @@ -325,12 +448,8 @@ pub fn hid_to_code(code: u16, mode: &KeycodeType) -> Option { } } KeycodeType::ScanCode1 => hid_to_scancode(code), - KeycodeType::VirtualKey => { - hid_to_scancode(code).and_then(|code| scancode_to_vk(code, false)) - } - KeycodeType::VirtualKeyTranslate => { - hid_to_scancode(code).and_then(|code| scancode_to_vk(code, true)) - } + KeycodeType::VirtualKey => hid_to_vk(code, false), + KeycodeType::VirtualKeyTranslate => hid_to_vk(code, true), } }