use winapi::um::winuser;
use keymap::{Key, Modifiers};
fn translate(c: char) -> Option<(u8, Modifiers)> {
assert!(c as u32 == (c as u16) as u32);
let result: u16 = unsafe { winuser::VkKeyScanW(c as u16) } as u16;
if result == 0xffff {
return None;
}
let keycode: u8 = (result & 0xff) as u8;
let keymods: u8 = (result >> 8) as u8;
let mut modifiers = Modifiers::empty();
if (keymods & 0b0001) != 0 {
modifiers |= Modifiers::SHIFT;
}
if (keymods & 0b0010) != 0 {
modifiers |= Modifiers::CTRL;
}
if (keymods & 0b0100) != 0 {
modifiers |= Modifiers::ALT;
}
Some((keycode, modifiers))
}
pub(super) fn convert(key: Key) -> Option<(u8, Modifiers)> {
if let Some(c) = key.to_char() {
if let Some(t) = translate(c) {
return Some(t);
}
}
let r: Option<(i32, Modifiers)> = match key {
Key::Backspace => Some((winuser::VK_BACK, Modifiers::empty())),
Key::Tab => Some((winuser::VK_TAB, Modifiers::empty())),
Key::Clear => Some((winuser::VK_CLEAR, Modifiers::empty())),
Key::Return => Some((winuser::VK_RETURN, Modifiers::empty())),
Key::Pause => Some((winuser::VK_PAUSE, Modifiers::empty())),
Key::Escape => Some((winuser::VK_ESCAPE, Modifiers::empty())),
Key::Space => Some((winuser::VK_SPACE, Modifiers::empty())),
Key::End => Some((winuser::VK_END, Modifiers::empty())),
Key::Home => Some((winuser::VK_HOME, Modifiers::empty())),
Key::ArrowLeft => Some((winuser::VK_LEFT, Modifiers::empty())),
Key::ArrowUp => Some((winuser::VK_UP, Modifiers::empty())),
Key::ArrowRight => Some((winuser::VK_RIGHT, Modifiers::empty())),
Key::ArrowDown => Some((winuser::VK_DOWN, Modifiers::empty())),
Key::Delete => Some((winuser::VK_DELETE, Modifiers::empty())),
Key::LeftSuper => Some((winuser::VK_LWIN, Modifiers::empty())),
Key::RightSuper => Some((winuser::VK_RWIN, Modifiers::empty())),
Key::Keypad0 => Some((winuser::VK_NUMPAD0, Modifiers::empty())),
Key::Keypad1 => Some((winuser::VK_NUMPAD1, Modifiers::empty())),
Key::Keypad2 => Some((winuser::VK_NUMPAD2, Modifiers::empty())),
Key::Keypad3 => Some((winuser::VK_NUMPAD3, Modifiers::empty())),
Key::Keypad4 => Some((winuser::VK_NUMPAD4, Modifiers::empty())),
Key::Keypad5 => Some((winuser::VK_NUMPAD5, Modifiers::empty())),
Key::Keypad6 => Some((winuser::VK_NUMPAD6, Modifiers::empty())),
Key::Keypad7 => Some((winuser::VK_NUMPAD7, Modifiers::empty())),
Key::Keypad8 => Some((winuser::VK_NUMPAD8, Modifiers::empty())),
Key::Keypad9 => Some((winuser::VK_NUMPAD9, Modifiers::empty())),
Key::F1 => Some((winuser::VK_F1, Modifiers::empty())),
Key::F2 => Some((winuser::VK_F2, Modifiers::empty())),
Key::F3 => Some((winuser::VK_F3, Modifiers::empty())),
Key::F4 => Some((winuser::VK_F4, Modifiers::empty())),
Key::F5 => Some((winuser::VK_F5, Modifiers::empty())),
Key::F6 => Some((winuser::VK_F6, Modifiers::empty())),
Key::F7 => Some((winuser::VK_F7, Modifiers::empty())),
Key::F8 => Some((winuser::VK_F8, Modifiers::empty())),
Key::F9 => Some((winuser::VK_F9, Modifiers::empty())),
Key::F10 => Some((winuser::VK_F10, Modifiers::empty())),
Key::F11 => Some((winuser::VK_F11, Modifiers::empty())),
Key::F12 => Some((winuser::VK_F12, Modifiers::empty())),
Key::F13 => Some((winuser::VK_F13, Modifiers::empty())),
Key::F14 => Some((winuser::VK_F14, Modifiers::empty())),
Key::F15 => Some((winuser::VK_F15, Modifiers::empty())),
Key::F16 => Some((winuser::VK_F16, Modifiers::empty())),
Key::F17 => Some((winuser::VK_F17, Modifiers::empty())),
Key::F18 => Some((winuser::VK_F18, Modifiers::empty())),
Key::F19 => Some((winuser::VK_F19, Modifiers::empty())),
Key::F20 => Some((winuser::VK_F20, Modifiers::empty())),
Key::F21 => Some((winuser::VK_F21, Modifiers::empty())),
Key::F22 => Some((winuser::VK_F22, Modifiers::empty())),
Key::F23 => Some((winuser::VK_F23, Modifiers::empty())),
Key::F24 => Some((winuser::VK_F24, Modifiers::empty())),
Key::NumLock => Some((winuser::VK_NUMLOCK, Modifiers::empty())),
Key::LeftShift => Some((winuser::VK_LSHIFT, Modifiers::empty())),
Key::RightShift => Some((winuser::VK_RSHIFT, Modifiers::empty())),
Key::LeftCtrl => Some((winuser::VK_LCONTROL, Modifiers::empty())),
Key::RightCtrl => Some((winuser::VK_RCONTROL, Modifiers::empty())),
Key::LeftAlt => Some((winuser::VK_MENU, Modifiers::empty())),
Key::VolumeMute => Some((winuser::VK_VOLUME_MUTE, Modifiers::empty())),
Key::VolumeDown => Some((winuser::VK_VOLUME_DOWN, Modifiers::empty())),
Key::VolumeUp => Some((winuser::VK_VOLUME_UP, Modifiers::empty())),
_ => None,
};
r.map(|(a, b)| (a as u8, b))
}