use hyprcorrect_core::Chord;
mod carbon_mods {
pub const CMD: u32 = 1 << 8; pub const SHIFT: u32 = 1 << 9; pub const OPTION: u32 = 1 << 11; pub const CONTROL: u32 = 1 << 12; }
pub(crate) fn chord_to_carbon(chord: &Chord) -> Option<(u32, u32)> {
let mut mods = 0u32;
if chord.shift {
mods |= carbon_mods::SHIFT;
}
if chord.ctrl {
mods |= carbon_mods::CONTROL;
}
if chord.alt {
mods |= carbon_mods::OPTION;
}
if chord.super_ {
mods |= carbon_mods::CMD;
}
let vkey = key_token_to_vkey(&chord.key)? as u32;
Some((vkey, mods))
}
pub(crate) fn key_token_to_vkey(token: &str) -> Option<u16> {
if token.chars().count() == 1 {
if let Some(vk) = char_to_vkey(token.chars().next().unwrap()) {
return Some(vk);
}
}
Some(match token {
"SPACE" => 0x31,
"ENTER" | "RETURN" => 0x24,
"TAB" => 0x30,
"ESC" | "ESCAPE" => 0x35,
"BACKSPACE" => 0x33,
"DELETE" | "DEL" => 0x75,
"UP" => 0x7E,
"DOWN" => 0x7D,
"LEFT" => 0x7B,
"RIGHT" => 0x7C,
"HOME" => 0x73,
"END" => 0x77,
"PAGEUP" | "PAGE_UP" | "PRIOR" => 0x74,
"PAGEDOWN" | "PAGE_DOWN" | "NEXT" => 0x79,
"F1" => 0x7A,
"F2" => 0x78,
"F3" => 0x63,
"F4" => 0x76,
"F5" => 0x60,
"F6" => 0x61,
"F7" => 0x62,
"F8" => 0x64,
"F9" => 0x65,
"F10" => 0x6D,
"F11" => 0x67,
"F12" => 0x6F,
"F13" => 0x69,
"F14" => 0x6B,
"F15" => 0x71,
"F16" => 0x6A,
"F17" => 0x40,
"F18" => 0x4F,
"F19" => 0x50,
"F20" => 0x5A,
_ => return None,
})
}
fn char_to_vkey(c: char) -> Option<u16> {
Some(match c.to_ascii_lowercase() {
'a' => 0x00,
's' => 0x01,
'd' => 0x02,
'f' => 0x03,
'h' => 0x04,
'g' => 0x05,
'z' => 0x06,
'x' => 0x07,
'c' => 0x08,
'v' => 0x09,
'b' => 0x0B,
'q' => 0x0C,
'w' => 0x0D,
'e' => 0x0E,
'r' => 0x0F,
'y' => 0x10,
't' => 0x11,
'1' => 0x12,
'2' => 0x13,
'3' => 0x14,
'4' => 0x15,
'6' => 0x16,
'5' => 0x17,
'=' => 0x18,
'9' => 0x19,
'7' => 0x1A,
'-' => 0x1B,
'8' => 0x1C,
'0' => 0x1D,
']' => 0x1E,
'o' => 0x1F,
'u' => 0x20,
'[' => 0x21,
'i' => 0x22,
'p' => 0x23,
'l' => 0x25,
'j' => 0x26,
'\'' => 0x27,
'k' => 0x28,
';' => 0x29,
'\\' => 0x2A,
',' => 0x2B,
'/' => 0x2C,
'n' => 0x2D,
'm' => 0x2E,
'.' => 0x2F,
'`' => 0x32,
_ => return None,
})
}
pub(crate) fn vkey_to_token(vkey: u16) -> Option<String> {
let named = match vkey {
0x31 => "SPACE",
0x24 => "RETURN",
0x30 => "TAB",
0x35 => "ESCAPE",
0x33 => "BACKSPACE",
0x75 => "DELETE",
0x7E => "UP",
0x7D => "DOWN",
0x7B => "LEFT",
0x7C => "RIGHT",
0x73 => "HOME",
0x77 => "END",
0x74 => "PAGEUP",
0x79 => "PAGEDOWN",
0x7A => "F1",
0x78 => "F2",
0x63 => "F3",
0x76 => "F4",
0x60 => "F5",
0x61 => "F6",
0x62 => "F7",
0x64 => "F8",
0x65 => "F9",
0x6D => "F10",
0x67 => "F11",
0x6F => "F12",
_ => "",
};
if !named.is_empty() {
return Some(named.to_string());
}
for c in ('a'..='z').chain('0'..='9') {
if char_to_vkey(c) == Some(vkey) {
return Some(c.to_ascii_uppercase().to_string());
}
}
for c in ['-', '=', '[', ']', '\\', ';', '\'', ',', '.', '/', '`'] {
if char_to_vkey(c) == Some(vkey) {
return Some(c.to_string());
}
}
None
}
pub(crate) const VK_BACKSPACE: u16 = 0x33;
pub(crate) const VK_LEFT: u16 = 0x7B;
pub(crate) const VK_RIGHT: u16 = 0x7C;
pub(crate) const VK_E: u16 = 0x0E;