Skip to content

Commit bc31f47

Browse files
authored
Rewrite VirtualKey mapping to correctly handle non-translate (#86)
* Fix beauty error * Rewrite VirtualKey mapping to correctly handle non-translate
1 parent 5a746bf commit bc31f47

File tree

1 file changed

+172
-53
lines changed

1 file changed

+172
-53
lines changed

wooting-analog-sdk/src/keycode.rs

Lines changed: 172 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,139 @@ lazy_static! {
174174
bimap
175175
};
176176

177-
//VirtualKey, Scancode
178-
static ref VIRTUALKEY_OVERRIDE: BiMap<u8, u16> = {
177+
//<HID code, VirtualKey> based on US layout
178+
static ref HID_TO_VK_MAP_US: BiMap<u8, u8> = {
179+
let mut bimap: BiMap<u8, u8> = BiMap::new();
180+
bimap.insert(0x04, 0x41); // US_A
181+
bimap.insert(0x05, 0x42); // US_B
182+
bimap.insert(0x06, 0x43); // US_C
183+
bimap.insert(0x07, 0x44); // US_D
184+
bimap.insert(0x08, 0x45); // US_E
185+
bimap.insert(0x09, 0x46); // US_F
186+
bimap.insert(0x0a, 0x47); // US_G
187+
bimap.insert(0x0b, 0x48); // US_H
188+
bimap.insert(0x0c, 0x49); // US_I
189+
bimap.insert(0x0d, 0x4A); // US_J
190+
bimap.insert(0x0e, 0x4B); // US_K
191+
bimap.insert(0x0f, 0x4C); // US_L
192+
bimap.insert(0x10, 0x4D); // US_M
193+
bimap.insert(0x11, 0x4E); // US_N
194+
bimap.insert(0x12, 0x4F); // US_O
195+
bimap.insert(0x13, 0x50); // US_P
196+
bimap.insert(0x14, 0x51); // US_Q
197+
bimap.insert(0x15, 0x52); // US_R
198+
bimap.insert(0x16, 0x53); // US_S
199+
bimap.insert(0x17, 0x54); // US_T
200+
bimap.insert(0x18, 0x55); // US_U
201+
bimap.insert(0x19, 0x56); // US_V
202+
bimap.insert(0x1a, 0x57); // US_W
203+
bimap.insert(0x1b, 0x58); // US_X
204+
bimap.insert(0x1c, 0x59); // US_Y
205+
bimap.insert(0x1d, 0x5A); // US_Z
206+
207+
bimap.insert(0x1e, 0x31); // DIGIT1
208+
bimap.insert(0x1f, 0x32); // DIGIT2
209+
bimap.insert(0x20, 0x33); // DIGIT3
210+
bimap.insert(0x21, 0x34); // DIGIT4
211+
bimap.insert(0x22, 0x35); // DIGIT5
212+
bimap.insert(0x23, 0x36); // DIGIT6
213+
bimap.insert(0x24, 0x37); // DIGIT7
214+
bimap.insert(0x25, 0x38); // DIGIT8
215+
bimap.insert(0x26, 0x39); // DIGIT9
216+
bimap.insert(0x27, 0x30); // DIGIT0
217+
218+
bimap.insert(0x28, 0x0D); // ENTER
219+
bimap.insert(0x29, 0x1B); // ESCAPE
220+
bimap.insert(0x2a, 0x08); // BACKSPACE
221+
bimap.insert(0x2b, 0x09); // TAB
222+
bimap.insert(0x2c, 0x20); // SPACE
223+
bimap.insert(0x2d, 0xBD); // MINUS
224+
bimap.insert(0x2e, 0xBB); // EQUAL
225+
bimap.insert(0x2f, 0xDB); // BRACKET_LEFT
226+
227+
bimap.insert(0x30, 0xDD); // BRACKET_RIGHT
228+
bimap.insert(0x31, 0xDC); // BACKSLASH
229+
230+
bimap.insert(0x33, 0xBA); // SEMICOLON
231+
bimap.insert(0x34, 0xDE); // QUOTE
232+
bimap.insert(0x35, 0xC0); // BACKQUOTE
233+
bimap.insert(0x36, 0xBC); // COMMA
234+
bimap.insert(0x37, 0xBE); // PERIOD
235+
236+
bimap.insert(0x38, 0xBF); // SLASH
237+
bimap.insert(0x39, 0x14); // CAPS_LOCK
238+
239+
bimap.insert(0x3a, 0x70); // F1
240+
bimap.insert(0x3b, 0x71); // F2
241+
bimap.insert(0x3c, 0x72); // F3
242+
bimap.insert(0x3d, 0x73); // F4
243+
bimap.insert(0x3e, 0x74); // F5
244+
bimap.insert(0x3f, 0x75); // F6
245+
bimap.insert(0x40, 0x76); // F7
246+
bimap.insert(0x41, 0x77); // F8
247+
bimap.insert(0x42, 0x78); // F9
248+
bimap.insert(0x43, 0x79); // F10
249+
bimap.insert(0x44, 0x7A); // F11
250+
bimap.insert(0x45, 0x7B); // F12
251+
252+
bimap.insert(0x46, 0x2C); // PRINT_SCREEN
253+
bimap.insert(0x47, 0x91); // SCROLL_LOCK
254+
255+
bimap.insert(0x48, 0x13); // PAUSE
256+
bimap.insert(0x49, 0x2D); // INSERT
257+
bimap.insert(0x4a, 0x24); // HOME
258+
bimap.insert(0x4b, 0x21); // PAGE_UP
259+
bimap.insert(0x4c, 0x2E); // DELETE
260+
bimap.insert(0x4d, 0x23); // END
261+
bimap.insert(0x4e, 0x22); // PAGE_DOWN
262+
263+
bimap.insert(0x4f, 0x27); // ARROW_RIGHT
264+
bimap.insert(0x50, 0x25); // ARROW_LEFT
265+
bimap.insert(0x51, 0x28); // ARROW_DOWN
266+
bimap.insert(0x52, 0x26); // ARROW_UP
267+
268+
bimap.insert(0x53, 0x90); // NUM_LOCK
269+
bimap.insert(0x54, 0x6F); // NUMPAD_DIVIDE
270+
bimap.insert(0x55, 0x6A); // NUMPAD_MULTIPLY
271+
bimap.insert(0x56, 0x6D); // NUMPAD_SUBTRACT
272+
bimap.insert(0x57, 0x6B); // NUMPAD_ADD
273+
bimap.insert(0x58, 0x0D); // NUMPAD_ENTER
274+
bimap.insert(0x59, 0x61); // NUMPAD1
275+
bimap.insert(0x5a, 0x62); // NUMPAD2
276+
bimap.insert(0x5b, 0x63); // NUMPAD3
277+
bimap.insert(0x5c, 0x64); // NUMPAD4
278+
bimap.insert(0x5d, 0x65); // NUMPAD5
279+
bimap.insert(0x5e, 0x66); // NUMPAD6
280+
bimap.insert(0x5f, 0x67); // NUMPAD7
281+
bimap.insert(0x60, 0x68); // NUMPAD8
282+
bimap.insert(0x61, 0x69); // NUMPAD9
283+
bimap.insert(0x62, 0x60); // NUMPAD0
284+
bimap.insert(0x63, 0x6E); // NUMPAD_DECIMAL
285+
286+
bimap.insert(0x64, 0xE2); // INTL_BACKSLASH
287+
bimap.insert(0x65, 0x5D); // CONTEXT_MENU
288+
bimap.insert(0x67, 0x0B); // NUMPAD_EQUAL
289+
290+
bimap.insert(0x68, 0x7C); // F13
291+
bimap.insert(0x69, 0x7D); // F14
292+
bimap.insert(0x6a, 0x7E); // F15
293+
bimap.insert(0x6b, 0x7F); // F16
294+
bimap.insert(0x6c, 0x80); // F17
295+
bimap.insert(0x6d, 0x81); // F18
296+
bimap.insert(0x6e, 0x82); // F19
297+
bimap.insert(0x6f, 0x83); // F20
298+
bimap.insert(0x70, 0x84); // F21
299+
bimap.insert(0x71, 0x85); // F22
300+
bimap.insert(0x72, 0x86); // F23
301+
bimap.insert(0x73, 0x87); // F24
302+
303+
bimap.insert(0x75, 0x2F); // HELP
304+
305+
bimap
306+
};
307+
308+
//<VirtualKey, Scancode>
309+
static ref VIRTUALKEY_OVERRIDE: BiMap<u8, u16> = {
179310
let mut bimap: BiMap<u8, u16> = BiMap::new();
180311
bimap.insert(0x60, 0x0052); //NUMPAD0
181312
bimap.insert(0x61, 0x004f); //NUMPAD1
@@ -194,67 +325,59 @@ lazy_static! {
194325
}
195326

196327
#[allow(unused)]
197-
pub fn vk_to_scancode(code: u16, translate: bool) -> Option<u16> {
328+
pub fn vk_to_hid(vk: u16, translate: bool) -> Option<u16> {
198329
#[cfg(windows)]
199-
unsafe {
200-
if let Some(&code) = VIRTUALKEY_OVERRIDE.get_by_left(&(code as u8)) {
201-
return Some(code);
202-
}
203-
204-
use winapi::um::winuser::{
205-
GetForegroundWindow, GetKeyboardLayout, GetWindowThreadProcessId, MapVirtualKeyA,
206-
MapVirtualKeyExA,
207-
};
208-
let scancode: u32;
209-
if translate {
210-
let window_handle = GetForegroundWindow();
211-
let thread = GetWindowThreadProcessId(window_handle, 0 as *mut u32);
212-
let layout = GetKeyboardLayout(thread);
213-
scancode = MapVirtualKeyExA(code.into(), 4, layout);
214-
//println!("Window handle: {:?}, thread: {:?}, layout: {:?}, code: {} scancode: {}", window_handle, thread, layout, code, scancode);
330+
if translate {
331+
let scancode: u16;
332+
if let Some(&code) = VIRTUALKEY_OVERRIDE.get_by_left(&(vk as u8)) {
333+
scancode = code;
215334
} else {
216-
scancode = MapVirtualKeyA(code.into(), 0);
217-
}
335+
use winapi::um::winuser::MapVirtualKeyA;
336+
scancode = unsafe { MapVirtualKeyA(vk.into(), 0) as u16 };
218337

219-
if scancode == 0 {
338+
if scancode == 0 {
339+
return None;
340+
}
341+
}
342+
return scancode_to_hid(scancode);
343+
} else {
344+
if let Some(&hid) = HID_TO_VK_MAP_US.get_by_right(&(vk as u8)) {
345+
return Some(hid as u16);
346+
} else {
220347
return None;
221348
}
222-
223-
return Some(scancode as u16);
224349
}
225350

226351
#[cfg(not(windows))]
227352
None
228353
}
229354

230355
#[allow(unused)]
231-
pub fn scancode_to_vk(code: u16, translate: bool) -> Option<u16> {
356+
pub fn hid_to_vk(hid: u16, translate: bool) -> Option<u16> {
232357
#[cfg(windows)]
233-
unsafe {
234-
if let Some(&code) = VIRTUALKEY_OVERRIDE.get_by_right(&code) {
235-
return Some(code as u16);
236-
}
358+
if translate {
359+
if let Some(scancode) = hid_to_scancode(hid) {
360+
if let Some(&hid) = VIRTUALKEY_OVERRIDE.get_by_right(&scancode) {
361+
return Some(hid as u16);
362+
}
363+
364+
use winapi::um::winuser::MapVirtualKeyA;
365+
let vk: u32 = unsafe { MapVirtualKeyA(scancode.into(), 3) };
237366

238-
use winapi::um::winuser::{
239-
GetForegroundWindow, GetKeyboardLayout, GetWindowThreadProcessId, MapVirtualKeyA,
240-
MapVirtualKeyExA,
241-
};
242-
let scancode: u32;
243-
if translate {
244-
let window_handle = GetForegroundWindow();
245-
let thread = GetWindowThreadProcessId(window_handle, 0 as *mut u32);
246-
let layout = GetKeyboardLayout(thread);
247-
scancode = MapVirtualKeyExA(code.into(), 3, layout);
248-
//println!("Window handle: {:?}, thread: {:?}, layout: {:?}, code: {} scancode: {}", window_handle, thread, layout, code, scancode);
367+
if (vk == 0) {
368+
return None;
369+
}
370+
371+
return Some(vk as u16);
249372
} else {
250-
scancode = MapVirtualKeyA(code.into(), 3);
373+
return None;
251374
}
252-
253-
if scancode == 0 {
375+
} else {
376+
if let Some(&vk) = HID_TO_VK_MAP_US.get_by_left(&(hid as u8)) {
377+
return Some(vk as u16);
378+
} else {
254379
return None;
255380
}
256-
257-
return Some(scancode as u16);
258381
}
259382

260383
#[cfg(not(windows))]
@@ -302,8 +425,8 @@ pub fn code_to_hid(code: u16, mode: &KeycodeType) -> Option<u16> {
302425
}
303426
}
304427
KeycodeType::ScanCode1 => scancode_to_hid(code),
305-
KeycodeType::VirtualKey => vk_to_scancode(code, false).and_then(scancode_to_hid),
306-
KeycodeType::VirtualKeyTranslate => vk_to_scancode(code, true).and_then(scancode_to_hid),
428+
KeycodeType::VirtualKey => vk_to_hid(code, false),
429+
KeycodeType::VirtualKeyTranslate => vk_to_hid(code, true),
307430
}
308431
}
309432

@@ -325,12 +448,8 @@ pub fn hid_to_code(code: u16, mode: &KeycodeType) -> Option<u16> {
325448
}
326449
}
327450
KeycodeType::ScanCode1 => hid_to_scancode(code),
328-
KeycodeType::VirtualKey => {
329-
hid_to_scancode(code).and_then(|code| scancode_to_vk(code, false))
330-
}
331-
KeycodeType::VirtualKeyTranslate => {
332-
hid_to_scancode(code).and_then(|code| scancode_to_vk(code, true))
333-
}
451+
KeycodeType::VirtualKey => hid_to_vk(code, false),
452+
KeycodeType::VirtualKeyTranslate => hid_to_vk(code, true),
334453
}
335454
}
336455

0 commit comments

Comments
 (0)