//! Built-in keymap to support libchewing compatibility
//!
//! Original libchewing API accepts C char as input and intepret the char as
//! keycode. Various configured KB types then convert the keycode to corresponding
//! keysyms. Both the original keycode and keysym definition are C char so they
//! were easily confused.
//!
//! It's recommended to use full featured library like xkbcommon to map keycode
//! to keysyms.

use super::KeyState;
use super::KeyboardEvent;
use super::keycode::*;
use super::keysym::*;

macro_rules! keymap {
    ($($k:expr => ($code:expr, $ksym:expr, $state:expr)),* $(,)?) => {{
        [$(($k, KeyboardEvent { code: $code, ksym: Keysym::from_char($ksym), state: $state }),)*]
    }};
}

macro_rules! keypad_map {
    ($($k:expr => ($code:expr, $ksym:expr, $state:expr)),* $(,)?) => {{
        [$(($k, KeyboardEvent { code: $code, ksym: $ksym, state: $state }),)*]
    }};
}

pub type Keymap = [(u8, KeyboardEvent)];

/// Map the ascii to keycode then to a key event
pub fn map_ascii(keymap: &Keymap, ascii: u8) -> KeyboardEvent {
    keymap
        .iter()
        .find(|item| item.0 == ascii)
        .map(|item| item.1)
        .unwrap_or_default()
}

/// Map the keycode to a key event
pub fn map_keycode(keymap: &Keymap, keycode: Keycode, shift: bool) -> KeyboardEvent {
    if let Some(evt) = KEYPAD_MAP
        .iter()
        .find(|item| item.1.code == keycode)
        .map(|item| item.1)
    {
        return evt;
    }
    keymap
        .iter()
        .find(|item| item.1.code == keycode && (shift ^ (item.1.state == 0)))
        .map(|item| item.1)
        .unwrap_or_default()
}

pub static KEYPAD_MAP: [(u8, KeyboardEvent); 16] = keypad_map! {
    b'1' => (KEY_KP1,        SYM_KP1,        KeyState::NumLock as u32),
    b'2' => (KEY_KP2,        SYM_KP2,        KeyState::NumLock as u32),
    b'3' => (KEY_KP3,        SYM_KP3,        KeyState::NumLock as u32),
    b'4' => (KEY_KP4,        SYM_KP4,        KeyState::NumLock as u32),
    b'5' => (KEY_KP5,        SYM_KP5,        KeyState::NumLock as u32),
    b'6' => (KEY_KP6,        SYM_KP6,        KeyState::NumLock as u32),
    b'7' => (KEY_KP7,        SYM_KP7,        KeyState::NumLock as u32),
    b'8' => (KEY_KP8,        SYM_KP8,        KeyState::NumLock as u32),
    b'9' => (KEY_KP9,        SYM_KP9,        KeyState::NumLock as u32),
    b'0' => (KEY_KP0,        SYM_KP0,        KeyState::NumLock as u32),
    b'+' => (KEY_KPPLUS,     SYM_KPADD,      KeyState::NumLock as u32),
    b'-' => (KEY_KPMINUS,    SYM_KPSUBTRACT, KeyState::NumLock as u32),
    b'*' => (KEY_KPASTERISK, SYM_KPMULTIPLY, KeyState::NumLock as u32),
    b'/' => (KEY_KPSLASH,    SYM_KPDIVIDE,   KeyState::NumLock as u32),
    b'.' => (KEY_KPDOT,      SYM_KPDECIMAL,  KeyState::NumLock as u32),
    b'=' => (KEY_KPEQUAL,    SYM_KPEQUAL,    KeyState::NumLock as u32),
};

pub static QWERTY_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'-' => (KEY_MINUS,      '-', 0),
    b'=' => (KEY_EQUAL,      '=', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'q' => (KEY_Q,          'q', 0),
    b'w' => (KEY_W,          'w', 0),
    b'e' => (KEY_E,          'e', 0),
    b'r' => (KEY_R,          'r', 0),
    b't' => (KEY_T,          't', 0),
    b'y' => (KEY_Y,          'y', 0),
    b'u' => (KEY_U,          'u', 0),
    b'i' => (KEY_I,          'i', 0),
    b'o' => (KEY_O,          'o', 0),
    b'p' => (KEY_P,          'p', 0),
    b'[' => (KEY_LEFTBRACE,  '[', 0),
    b']' => (KEY_RIGHTBRACE, ']', 0),
    b'a' => (KEY_A,          'a', 0),
    b's' => (KEY_S,          's', 0),
    b'd' => (KEY_D,          'd', 0),
    b'f' => (KEY_F,          'f', 0),
    b'g' => (KEY_G,          'g', 0),
    b'h' => (KEY_H,          'h', 0),
    b'j' => (KEY_J,          'j', 0),
    b'k' => (KEY_K,          'k', 0),
    b'l' => (KEY_L,          'l', 0),
    b';' => (KEY_SEMICOLON,  ';', 0),
    b'\'' => (KEY_APOSTROPHE,'\'', 0),
    b'z' => (KEY_Z,          'z', 0),
    b'x' => (KEY_X,          'x', 0),
    b'c' => (KEY_C,          'c', 0),
    b'v' => (KEY_V,          'v', 0),
    b'b' => (KEY_B,          'b', 0),
    b'n' => (KEY_N,          'n', 0),
    b'm' => (KEY_M,          'm', 0),
    b',' => (KEY_COMMA,      ',', 0),
    b'.' => (KEY_DOT,        '.', 0),
    b'/' => (KEY_SLASH,      '/', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'_' => (KEY_MINUS,      '_', KeyState::Shift as u32),
    b'+' => (KEY_EQUAL,      '+', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'Q' => (KEY_Q,          'Q', KeyState::Shift as u32),
    b'W' => (KEY_W,          'W', KeyState::Shift as u32),
    b'E' => (KEY_E,          'E', KeyState::Shift as u32),
    b'R' => (KEY_R,          'R', KeyState::Shift as u32),
    b'T' => (KEY_T,          'T', KeyState::Shift as u32),
    b'Y' => (KEY_Y,          'Y', KeyState::Shift as u32),
    b'U' => (KEY_U,          'U', KeyState::Shift as u32),
    b'I' => (KEY_I,          'I', KeyState::Shift as u32),
    b'O' => (KEY_O,          'O', KeyState::Shift as u32),
    b'P' => (KEY_P,          'P', KeyState::Shift as u32),
    b'{' => (KEY_LEFTBRACE,  '{', KeyState::Shift as u32),
    b'}' => (KEY_RIGHTBRACE, '}', KeyState::Shift as u32),
    b'A' => (KEY_A,          'A', KeyState::Shift as u32),
    b'S' => (KEY_S,          'S', KeyState::Shift as u32),
    b'D' => (KEY_D,          'D', KeyState::Shift as u32),
    b'F' => (KEY_F,          'F', KeyState::Shift as u32),
    b'G' => (KEY_G,          'G', KeyState::Shift as u32),
    b'H' => (KEY_H,          'H', KeyState::Shift as u32),
    b'J' => (KEY_J,          'J', KeyState::Shift as u32),
    b'K' => (KEY_K,          'K', KeyState::Shift as u32),
    b'L' => (KEY_L,          'L', KeyState::Shift as u32),
    b':' => (KEY_SEMICOLON,  ':', KeyState::Shift as u32),
    b'"' => (KEY_APOSTROPHE, '"', KeyState::Shift as u32),
    b'Z' => (KEY_Z,          'Z', KeyState::Shift as u32),
    b'X' => (KEY_X,          'X', KeyState::Shift as u32),
    b'C' => (KEY_C,          'C', KeyState::Shift as u32),
    b'V' => (KEY_V,          'V', KeyState::Shift as u32),
    b'B' => (KEY_B,          'B', KeyState::Shift as u32),
    b'N' => (KEY_N,          'N', KeyState::Shift as u32),
    b'M' => (KEY_M,          'M', KeyState::Shift as u32),
    b'<' => (KEY_COMMA,      '<', KeyState::Shift as u32),
    b'>' => (KEY_DOT,        '>', KeyState::Shift as u32),
    b'?' => (KEY_SLASH,      '?', KeyState::Shift as u32),
};

pub static DVORAK_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'-' => (KEY_MINUS,      '[', 0),
    b'=' => (KEY_EQUAL,      ']', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'q' => (KEY_Q,          '\'', 0),
    b'w' => (KEY_W,          ',', 0),
    b'e' => (KEY_E,          '.', 0),
    b'r' => (KEY_R,          'p', 0),
    b't' => (KEY_T,          'y', 0),
    b'y' => (KEY_Y,          'f', 0),
    b'u' => (KEY_U,          'g', 0),
    b'i' => (KEY_I,          'c', 0),
    b'o' => (KEY_O,          'r', 0),
    b'p' => (KEY_P,          'l', 0),
    b'[' => (KEY_LEFTBRACE,  '/', 0),
    b']' => (KEY_RIGHTBRACE, '=', 0),
    b'a' => (KEY_A,          'a', 0),
    b's' => (KEY_S,          'o', 0),
    b'd' => (KEY_D,          'e', 0),
    b'f' => (KEY_F,          'u', 0),
    b'g' => (KEY_G,          'i', 0),
    b'h' => (KEY_H,          'd', 0),
    b'j' => (KEY_J,          'h', 0),
    b'k' => (KEY_K,          't', 0),
    b'l' => (KEY_L,          'n', 0),
    b';' => (KEY_SEMICOLON,  's', 0),
    b'\'' => (KEY_APOSTROPHE,'-', 0),
    b'z' => (KEY_Z,          ';', 0),
    b'x' => (KEY_X,          'q', 0),
    b'c' => (KEY_C,          'j', 0),
    b'v' => (KEY_V,          'k', 0),
    b'b' => (KEY_B,          'x', 0),
    b'n' => (KEY_N,          'b', 0),
    b'm' => (KEY_M,          'm', 0),
    b',' => (KEY_COMMA,      'w', 0),
    b'.' => (KEY_DOT,        'v', 0),
    b'/' => (KEY_SLASH,      'z', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'_' => (KEY_MINUS,      '{', KeyState::Shift as u32),
    b'+' => (KEY_EQUAL,      '}', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'Q' => (KEY_Q,          '"', KeyState::Shift as u32),
    b'W' => (KEY_W,          '<', KeyState::Shift as u32),
    b'E' => (KEY_E,          '>', KeyState::Shift as u32),
    b'R' => (KEY_R,          'P', KeyState::Shift as u32),
    b'T' => (KEY_T,          'Y', KeyState::Shift as u32),
    b'Y' => (KEY_Y,          'F', KeyState::Shift as u32),
    b'U' => (KEY_U,          'G', KeyState::Shift as u32),
    b'I' => (KEY_I,          'C', KeyState::Shift as u32),
    b'O' => (KEY_O,          'R', KeyState::Shift as u32),
    b'P' => (KEY_P,          'L', KeyState::Shift as u32),
    b'{' => (KEY_LEFTBRACE,  '?', KeyState::Shift as u32),
    b'}' => (KEY_RIGHTBRACE, '+', KeyState::Shift as u32),
    b'A' => (KEY_A,          'A', KeyState::Shift as u32),
    b'S' => (KEY_S,          'O', KeyState::Shift as u32),
    b'D' => (KEY_D,          'E', KeyState::Shift as u32),
    b'F' => (KEY_F,          'U', KeyState::Shift as u32),
    b'G' => (KEY_G,          'I', KeyState::Shift as u32),
    b'H' => (KEY_H,          'D', KeyState::Shift as u32),
    b'J' => (KEY_J,          'H', KeyState::Shift as u32),
    b'K' => (KEY_K,          'T', KeyState::Shift as u32),
    b'L' => (KEY_L,          'N', KeyState::Shift as u32),
    b':' => (KEY_SEMICOLON,  'S', KeyState::Shift as u32),
    b'"' => (KEY_APOSTROPHE, '_', KeyState::Shift as u32),
    b'Z' => (KEY_Z,          ':', KeyState::Shift as u32),
    b'X' => (KEY_X,          'Q', KeyState::Shift as u32),
    b'C' => (KEY_C,          'J', KeyState::Shift as u32),
    b'V' => (KEY_V,          'K', KeyState::Shift as u32),
    b'B' => (KEY_B,          'X', KeyState::Shift as u32),
    b'N' => (KEY_N,          'B', KeyState::Shift as u32),
    b'M' => (KEY_M,          'M', KeyState::Shift as u32),
    b'<' => (KEY_COMMA,      'W', KeyState::Shift as u32),
    b'>' => (KEY_DOT,        'V', KeyState::Shift as u32),
    b'?' => (KEY_SLASH,      'Z', KeyState::Shift as u32),
};

pub static INVERTED_DVORAK_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'[' => (KEY_MINUS,      '[', 0),
    b']' => (KEY_EQUAL,      ']', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'\'' => (KEY_Q,         '\'', 0),
    b',' => (KEY_W,          ',', 0),
    b'.' => (KEY_E,          '.', 0),
    b'p' => (KEY_R,          'p', 0),
    b'y' => (KEY_T,          'y', 0),
    b'f' => (KEY_Y,          'f', 0),
    b'g' => (KEY_U,          'g', 0),
    b'c' => (KEY_I,          'c', 0),
    b'r' => (KEY_O,          'r', 0),
    b'l' => (KEY_P,          'l', 0),
    b'/' => (KEY_LEFTBRACE,  '/', 0),
    b'=' => (KEY_RIGHTBRACE, '=', 0),
    b'a' => (KEY_A,          'a', 0),
    b'o' => (KEY_S,          'o', 0),
    b'e' => (KEY_D,          'e', 0),
    b'u' => (KEY_F,          'u', 0),
    b'i' => (KEY_G,          'i', 0),
    b'd' => (KEY_H,          'd', 0),
    b'h' => (KEY_J,          'h', 0),
    b't' => (KEY_K,          't', 0),
    b'n' => (KEY_L,          'n', 0),
    b's' => (KEY_SEMICOLON,  's', 0),
    b'-' => (KEY_APOSTROPHE, '-', 0),
    b';' => (KEY_Z,          ';', 0),
    b'q' => (KEY_X,          'q', 0),
    b'j' => (KEY_C,          'j', 0),
    b'k' => (KEY_V,          'k', 0),
    b'x' => (KEY_B,          'x', 0),
    b'b' => (KEY_N,          'b', 0),
    b'm' => (KEY_M,          'm', 0),
    b'w' => (KEY_COMMA,      'w', 0),
    b'v' => (KEY_DOT,        'v', 0),
    b'z' => (KEY_SLASH,      'z', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'{' => (KEY_MINUS,      '{', KeyState::Shift as u32),
    b'}' => (KEY_EQUAL,      '}', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'"' => (KEY_Q,          '"', KeyState::Shift as u32),
    b'<' => (KEY_W,          '<', KeyState::Shift as u32),
    b'>' => (KEY_E,          '>', KeyState::Shift as u32),
    b'P' => (KEY_R,          'P', KeyState::Shift as u32),
    b'Y' => (KEY_T,          'Y', KeyState::Shift as u32),
    b'F' => (KEY_Y,          'F', KeyState::Shift as u32),
    b'G' => (KEY_U,          'G', KeyState::Shift as u32),
    b'C' => (KEY_I,          'C', KeyState::Shift as u32),
    b'R' => (KEY_O,          'R', KeyState::Shift as u32),
    b'L' => (KEY_P,          'L', KeyState::Shift as u32),
    b'?' => (KEY_LEFTBRACE,  '?', KeyState::Shift as u32),
    b'+' => (KEY_RIGHTBRACE, '+', KeyState::Shift as u32),
    b'A' => (KEY_A,          'A', KeyState::Shift as u32),
    b'O' => (KEY_S,          'O', KeyState::Shift as u32),
    b'E' => (KEY_D,          'E', KeyState::Shift as u32),
    b'U' => (KEY_F,          'U', KeyState::Shift as u32),
    b'I' => (KEY_G,          'I', KeyState::Shift as u32),
    b'D' => (KEY_H,          'D', KeyState::Shift as u32),
    b'H' => (KEY_J,          'H', KeyState::Shift as u32),
    b'T' => (KEY_K,          'T', KeyState::Shift as u32),
    b'N' => (KEY_L,          'N', KeyState::Shift as u32),
    b'S' => (KEY_SEMICOLON,  'S', KeyState::Shift as u32),
    b'_' => (KEY_APOSTROPHE, '_', KeyState::Shift as u32),
    b':' => (KEY_Z,          ':', KeyState::Shift as u32),
    b'Q' => (KEY_X,          'Q', KeyState::Shift as u32),
    b'J' => (KEY_C,          'J', KeyState::Shift as u32),
    b'K' => (KEY_V,          'K', KeyState::Shift as u32),
    b'X' => (KEY_B,          'X', KeyState::Shift as u32),
    b'B' => (KEY_N,          'B', KeyState::Shift as u32),
    b'M' => (KEY_M,          'M', KeyState::Shift as u32),
    b'W' => (KEY_COMMA,      'W', KeyState::Shift as u32),
    b'V' => (KEY_DOT,        'V', KeyState::Shift as u32),
    b'Z' => (KEY_SLASH,      'Z', KeyState::Shift as u32),
};

pub static INVERTED_QGMLWY_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'-' => (KEY_MINUS,      '-', 0),
    b'=' => (KEY_EQUAL,      '=', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'q' => (KEY_Q,          'q', 0),
    b'g' => (KEY_W,          'g', 0),
    b'm' => (KEY_E,          'm', 0),
    b'l' => (KEY_R,          'l', 0),
    b'w' => (KEY_T,          'w', 0),
    b'y' => (KEY_Y,          'y', 0),
    b'f' => (KEY_U,          'f', 0),
    b'u' => (KEY_I,          'u', 0),
    b'b' => (KEY_O,          'b', 0),
    b';' => (KEY_P,          ';', 0),
    b'[' => (KEY_LEFTBRACE,  '[', 0),
    b']' => (KEY_RIGHTBRACE, ']', 0),
    b'd' => (KEY_A,          'd', 0),
    b's' => (KEY_S,          's', 0),
    b't' => (KEY_D,          't', 0),
    b'n' => (KEY_F,          'n', 0),
    b'r' => (KEY_G,          'r', 0),
    b'i' => (KEY_H,          'i', 0),
    b'a' => (KEY_J,          'a', 0),
    b'e' => (KEY_K,          'e', 0),
    b'o' => (KEY_L,          'o', 0),
    b'h' => (KEY_SEMICOLON,  'h', 0),
    b'\'' => (KEY_APOSTROPHE,'\'', 0),
    b'z' => (KEY_Z,          'z', 0),
    b'x' => (KEY_X,          'x', 0),
    b'c' => (KEY_C,          'c', 0),
    b'v' => (KEY_V,          'v', 0),
    b'j' => (KEY_B,          'j', 0),
    b'k' => (KEY_N,          'k', 0),
    b'p' => (KEY_M,          'p', 0),
    b',' => (KEY_COMMA,      ',', 0),
    b'.' => (KEY_DOT,        '.', 0),
    b'/' => (KEY_SLASH,      '/', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'_' => (KEY_MINUS,      '_', KeyState::Shift as u32),
    b'+' => (KEY_EQUAL,      '+', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'Q' => (KEY_Q,          'Q', KeyState::Shift as u32),
    b'G' => (KEY_W,          'G', KeyState::Shift as u32),
    b'M' => (KEY_E,          'M', KeyState::Shift as u32),
    b'L' => (KEY_R,          'L', KeyState::Shift as u32),
    b'W' => (KEY_T,          'W', KeyState::Shift as u32),
    b'Y' => (KEY_Y,          'Y', KeyState::Shift as u32),
    b'F' => (KEY_U,          'F', KeyState::Shift as u32),
    b'U' => (KEY_I,          'U', KeyState::Shift as u32),
    b'B' => (KEY_O,          'B', KeyState::Shift as u32),
    b':' => (KEY_P,          ':', KeyState::Shift as u32),
    b'{' => (KEY_LEFTBRACE,  '{', KeyState::Shift as u32),
    b'}' => (KEY_RIGHTBRACE, '}', KeyState::Shift as u32),
    b'D' => (KEY_A,          'D', KeyState::Shift as u32),
    b'S' => (KEY_S,          'S', KeyState::Shift as u32),
    b'T' => (KEY_D,          'T', KeyState::Shift as u32),
    b'N' => (KEY_F,          'N', KeyState::Shift as u32),
    b'R' => (KEY_G,          'R', KeyState::Shift as u32),
    b'I' => (KEY_H,          'I', KeyState::Shift as u32),
    b'A' => (KEY_J,          'A', KeyState::Shift as u32),
    b'E' => (KEY_K,          'E', KeyState::Shift as u32),
    b'O' => (KEY_L,          'O', KeyState::Shift as u32),
    b'H' => (KEY_SEMICOLON,  'H', KeyState::Shift as u32),
    b'"' => (KEY_APOSTROPHE, '"', KeyState::Shift as u32),
    b'Z' => (KEY_Z,          'Z', KeyState::Shift as u32),
    b'X' => (KEY_X,          'X', KeyState::Shift as u32),
    b'C' => (KEY_C,          'C', KeyState::Shift as u32),
    b'V' => (KEY_V,          'V', KeyState::Shift as u32),
    b'J' => (KEY_B,          'J', KeyState::Shift as u32),
    b'K' => (KEY_N,          'K', KeyState::Shift as u32),
    b'P' => (KEY_M,          'P', KeyState::Shift as u32),
    b'<' => (KEY_COMMA,      '<', KeyState::Shift as u32),
    b'>' => (KEY_DOT,        '>', KeyState::Shift as u32),
    b'?' => (KEY_SLASH,      '?', KeyState::Shift as u32),
};

pub static INVERTED_COLEMAK_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'-' => (KEY_MINUS,      '-', 0),
    b'=' => (KEY_EQUAL,      '=', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'q' => (KEY_Q,          'q', 0),
    b'w' => (KEY_W,          'w', 0),
    b'f' => (KEY_E,          'f', 0),
    b'p' => (KEY_R,          'p', 0),
    b'g' => (KEY_T,          'g', 0),
    b'j' => (KEY_Y,          'j', 0),
    b'l' => (KEY_U,          'l', 0),
    b'u' => (KEY_I,          'u', 0),
    b'y' => (KEY_O,          'y', 0),
    b';' => (KEY_P,          ';', 0),
    b'[' => (KEY_LEFTBRACE,  '[', 0),
    b']' => (KEY_RIGHTBRACE, ']', 0),
    b'a' => (KEY_A,          'a', 0),
    b'r' => (KEY_S,          'r', 0),
    b's' => (KEY_D,          's', 0),
    b't' => (KEY_F,          't', 0),
    b'd' => (KEY_G,          'd', 0),
    b'h' => (KEY_H,          'h', 0),
    b'n' => (KEY_J,          'n', 0),
    b'e' => (KEY_K,          'e', 0),
    b'i' => (KEY_L,          'i', 0),
    b'o' => (KEY_SEMICOLON,  'o', 0),
    b'\'' => (KEY_APOSTROPHE,'\'', 0),
    b'z' => (KEY_Z,          'z', 0),
    b'x' => (KEY_X,          'x', 0),
    b'c' => (KEY_C,          'c', 0),
    b'v' => (KEY_V,          'v', 0),
    b'b' => (KEY_B,          'b', 0),
    b'k' => (KEY_N,          'k', 0),
    b'm' => (KEY_M,          'm', 0),
    b',' => (KEY_COMMA,      ',', 0),
    b'.' => (KEY_DOT,        '.', 0),
    b'/' => (KEY_SLASH,      '/', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'_' => (KEY_MINUS,      '_', KeyState::Shift as u32),
    b'+' => (KEY_EQUAL,      '+', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'Q' => (KEY_Q,          'Q', KeyState::Shift as u32),
    b'W' => (KEY_W,          'W', KeyState::Shift as u32),
    b'F' => (KEY_E,          'F', KeyState::Shift as u32),
    b'P' => (KEY_R,          'P', KeyState::Shift as u32),
    b'G' => (KEY_T,          'G', KeyState::Shift as u32),
    b'J' => (KEY_Y,          'J', KeyState::Shift as u32),
    b'L' => (KEY_U,          'L', KeyState::Shift as u32),
    b'U' => (KEY_I,          'U', KeyState::Shift as u32),
    b'Y' => (KEY_O,          'Y', KeyState::Shift as u32),
    b':' => (KEY_P,          ':', KeyState::Shift as u32),
    b'{' => (KEY_LEFTBRACE,  '{', KeyState::Shift as u32),
    b'}' => (KEY_RIGHTBRACE, '}', KeyState::Shift as u32),
    b'A' => (KEY_A,          'A', KeyState::Shift as u32),
    b'R' => (KEY_S,          'R', KeyState::Shift as u32),
    b'S' => (KEY_D,          'S', KeyState::Shift as u32),
    b'T' => (KEY_F,          'T', KeyState::Shift as u32),
    b'D' => (KEY_G,          'D', KeyState::Shift as u32),
    b'H' => (KEY_H,          'H', KeyState::Shift as u32),
    b'N' => (KEY_J,          'N', KeyState::Shift as u32),
    b'E' => (KEY_K,          'E', KeyState::Shift as u32),
    b'I' => (KEY_L,          'I', KeyState::Shift as u32),
    b'O' => (KEY_SEMICOLON,  'O', KeyState::Shift as u32),
    b'"' => (KEY_APOSTROPHE, '"', KeyState::Shift as u32),
    b'Z' => (KEY_Z,          'Z', KeyState::Shift as u32),
    b'X' => (KEY_X,          'X', KeyState::Shift as u32),
    b'C' => (KEY_C,          'C', KeyState::Shift as u32),
    b'V' => (KEY_V,          'V', KeyState::Shift as u32),
    b'B' => (KEY_B,          'B', KeyState::Shift as u32),
    b'K' => (KEY_N,          'K', KeyState::Shift as u32),
    b'M' => (KEY_M,          'M', KeyState::Shift as u32),
    b'<' => (KEY_COMMA,      '<', KeyState::Shift as u32),
    b'>' => (KEY_DOT,        '>', KeyState::Shift as u32),
    b'?' => (KEY_SLASH,      '?', KeyState::Shift as u32),
};

pub static INVERTED_COLEMAK_DH_ANSI_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'-' => (KEY_MINUS,      '-', 0),
    b'=' => (KEY_EQUAL,      '=', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'q' => (KEY_Q,          'q', 0),
    b'w' => (KEY_W,          'w', 0),
    b'f' => (KEY_E,          'f', 0),
    b'p' => (KEY_R,          'p', 0),
    b'b' => (KEY_T,          'b', 0),
    b'j' => (KEY_Y,          'j', 0),
    b'l' => (KEY_U,          'l', 0),
    b'u' => (KEY_I,          'u', 0),
    b'y' => (KEY_O,          'y', 0),
    b';' => (KEY_P,          ';', 0),
    b'[' => (KEY_LEFTBRACE,  '[', 0),
    b']' => (KEY_RIGHTBRACE, ']', 0),
    b'a' => (KEY_A,          'a', 0),
    b'r' => (KEY_S,          'r', 0),
    b's' => (KEY_D,          's', 0),
    b't' => (KEY_F,          't', 0),
    b'g' => (KEY_G,          'g', 0),
    b'm' => (KEY_H,          'm', 0),
    b'n' => (KEY_J,          'n', 0),
    b'e' => (KEY_K,          'e', 0),
    b'i' => (KEY_L,          'i', 0),
    b'o' => (KEY_SEMICOLON,  'o', 0),
    b'\'' => (KEY_APOSTROPHE,'\'', 0),
    b'x' => (KEY_Z,          'x', 0),
    b'c' => (KEY_X,          'c', 0),
    b'd' => (KEY_C,          'd', 0),
    b'v' => (KEY_V,          'v', 0),
    b'z' => (KEY_B,          'z', 0),
    b'k' => (KEY_N,          'k', 0),
    b'h' => (KEY_M,          'h', 0),
    b',' => (KEY_COMMA,      ',', 0),
    b'.' => (KEY_DOT,        '.', 0),
    b'/' => (KEY_SLASH,      '/', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'_' => (KEY_MINUS,      '_', KeyState::Shift as u32),
    b'+' => (KEY_EQUAL,      '+', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'Q' => (KEY_Q,          'Q', KeyState::Shift as u32),
    b'W' => (KEY_W,          'W', KeyState::Shift as u32),
    b'F' => (KEY_E,          'F', KeyState::Shift as u32),
    b'P' => (KEY_R,          'P', KeyState::Shift as u32),
    b'B' => (KEY_T,          'B', KeyState::Shift as u32),
    b'J' => (KEY_Y,          'J', KeyState::Shift as u32),
    b'L' => (KEY_U,          'L', KeyState::Shift as u32),
    b'U' => (KEY_I,          'U', KeyState::Shift as u32),
    b'Y' => (KEY_O,          'Y', KeyState::Shift as u32),
    b':' => (KEY_P,          ':', KeyState::Shift as u32),
    b'{' => (KEY_LEFTBRACE,  '{', KeyState::Shift as u32),
    b'}' => (KEY_RIGHTBRACE, '}', KeyState::Shift as u32),
    b'A' => (KEY_A,          'A', KeyState::Shift as u32),
    b'R' => (KEY_S,          'R', KeyState::Shift as u32),
    b'S' => (KEY_D,          'S', KeyState::Shift as u32),
    b'T' => (KEY_F,          'T', KeyState::Shift as u32),
    b'G' => (KEY_G,          'G', KeyState::Shift as u32),
    b'M' => (KEY_H,          'M', KeyState::Shift as u32),
    b'N' => (KEY_J,          'N', KeyState::Shift as u32),
    b'E' => (KEY_K,          'E', KeyState::Shift as u32),
    b'I' => (KEY_L,          'I', KeyState::Shift as u32),
    b'O' => (KEY_SEMICOLON,  'O', KeyState::Shift as u32),
    b'"' => (KEY_APOSTROPHE, '"', KeyState::Shift as u32),
    b'X' => (KEY_Z,          'X', KeyState::Shift as u32),
    b'C' => (KEY_X,          'C', KeyState::Shift as u32),
    b'D' => (KEY_C,          'D', KeyState::Shift as u32),
    b'V' => (KEY_V,          'V', KeyState::Shift as u32),
    b'Z' => (KEY_B,          'Z', KeyState::Shift as u32),
    b'K' => (KEY_N,          'K', KeyState::Shift as u32),
    b'H' => (KEY_M,          'H', KeyState::Shift as u32),
    b'<' => (KEY_COMMA,      '<', KeyState::Shift as u32),
    b'>' => (KEY_DOT,        '>', KeyState::Shift as u32),
    b'?' => (KEY_SLASH,      '?', KeyState::Shift as u32),
};

pub static INVERTED_COLEMAK_DH_ORTH_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'-' => (KEY_MINUS,      '-', 0),
    b'=' => (KEY_EQUAL,      '=', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'q' => (KEY_Q,          'q', 0),
    b'w' => (KEY_W,          'w', 0),
    b'f' => (KEY_E,          'f', 0),
    b'p' => (KEY_R,          'p', 0),
    b'b' => (KEY_T,          'b', 0),
    b'j' => (KEY_Y,          'j', 0),
    b'l' => (KEY_U,          'l', 0),
    b'u' => (KEY_I,          'u', 0),
    b'y' => (KEY_O,          'y', 0),
    b';' => (KEY_P,          ';', 0),
    b'[' => (KEY_LEFTBRACE,  '[', 0),
    b']' => (KEY_RIGHTBRACE, ']', 0),
    b'a' => (KEY_A,          'a', 0),
    b'r' => (KEY_S,          'r', 0),
    b's' => (KEY_D,          's', 0),
    b't' => (KEY_F,          't', 0),
    b'g' => (KEY_G,          'g', 0),
    b'm' => (KEY_H,          'm', 0),
    b'n' => (KEY_J,          'n', 0),
    b'e' => (KEY_K,          'e', 0),
    b'i' => (KEY_L,          'i', 0),
    b'o' => (KEY_SEMICOLON,  'o', 0),
    b'\'' => (KEY_APOSTROPHE,'\'', 0),
    b'z' => (KEY_Z,          'z', 0),
    b'x' => (KEY_X,          'x', 0),
    b'c' => (KEY_C,          'c', 0),
    b'd' => (KEY_V,          'd', 0),
    b'v' => (KEY_B,          'v', 0),
    b'k' => (KEY_N,          'k', 0),
    b'h' => (KEY_M,          'h', 0),
    b',' => (KEY_COMMA,      ',', 0),
    b'.' => (KEY_DOT,        '.', 0),
    b'/' => (KEY_SLASH,      '/', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'_' => (KEY_MINUS,      '_', KeyState::Shift as u32),
    b'+' => (KEY_EQUAL,      '+', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'Q' => (KEY_Q,          'Q', KeyState::Shift as u32),
    b'W' => (KEY_W,          'W', KeyState::Shift as u32),
    b'F' => (KEY_E,          'F', KeyState::Shift as u32),
    b'P' => (KEY_R,          'P', KeyState::Shift as u32),
    b'B' => (KEY_T,          'B', KeyState::Shift as u32),
    b'J' => (KEY_Y,          'J', KeyState::Shift as u32),
    b'L' => (KEY_U,          'L', KeyState::Shift as u32),
    b'U' => (KEY_I,          'U', KeyState::Shift as u32),
    b'Y' => (KEY_O,          'Y', KeyState::Shift as u32),
    b':' => (KEY_P,          ':', KeyState::Shift as u32),
    b'{' => (KEY_LEFTBRACE,  '{', KeyState::Shift as u32),
    b'}' => (KEY_RIGHTBRACE, '}', KeyState::Shift as u32),
    b'A' => (KEY_A,          'A', KeyState::Shift as u32),
    b'R' => (KEY_S,          'R', KeyState::Shift as u32),
    b'S' => (KEY_D,          'S', KeyState::Shift as u32),
    b'T' => (KEY_F,          'T', KeyState::Shift as u32),
    b'G' => (KEY_G,          'G', KeyState::Shift as u32),
    b'M' => (KEY_H,          'M', KeyState::Shift as u32),
    b'N' => (KEY_J,          'N', KeyState::Shift as u32),
    b'E' => (KEY_K,          'E', KeyState::Shift as u32),
    b'I' => (KEY_L,          'I', KeyState::Shift as u32),
    b'O' => (KEY_SEMICOLON,  'O', KeyState::Shift as u32),
    b'"' => (KEY_APOSTROPHE, '"', KeyState::Shift as u32),
    b'Z' => (KEY_Z,          'Z', KeyState::Shift as u32),
    b'X' => (KEY_X,          'X', KeyState::Shift as u32),
    b'C' => (KEY_C,          'C', KeyState::Shift as u32),
    b'D' => (KEY_V,          'D', KeyState::Shift as u32),
    b'V' => (KEY_B,          'V', KeyState::Shift as u32),
    b'K' => (KEY_N,          'K', KeyState::Shift as u32),
    b'H' => (KEY_M,          'H', KeyState::Shift as u32),
    b'<' => (KEY_COMMA,      '<', KeyState::Shift as u32),
    b'>' => (KEY_DOT,        '>', KeyState::Shift as u32),
    b'?' => (KEY_SLASH,      '?', KeyState::Shift as u32),
};

pub static INVERTED_WORKMAN_MAP: [(u8, KeyboardEvent); 95] = keymap! {
    b'1' => (KEY_1,          '1', 0),
    b'2' => (KEY_2,          '2', 0),
    b'3' => (KEY_3,          '3', 0),
    b'4' => (KEY_4,          '4', 0),
    b'5' => (KEY_5,          '5', 0),
    b'6' => (KEY_6,          '6', 0),
    b'7' => (KEY_7,          '7', 0),
    b'8' => (KEY_8,          '8', 0),
    b'9' => (KEY_9,          '9', 0),
    b'0' => (KEY_0,          '0', 0),
    b'-' => (KEY_MINUS,      '-', 0),
    b'=' => (KEY_EQUAL,      '=', 0),
    b'\\' => (KEY_BACKSLASH, '\\', 0),
    b'`' => (KEY_GRAVE,      '`', 0),
    b'q' => (KEY_Q,          'q', 0),
    b'd' => (KEY_W,          'd', 0),
    b'r' => (KEY_E,          'r', 0),
    b'w' => (KEY_R,          'w', 0),
    b'b' => (KEY_T,          'b', 0),
    b'j' => (KEY_Y,          'j', 0),
    b'f' => (KEY_U,          'f', 0),
    b'u' => (KEY_I,          'u', 0),
    b'p' => (KEY_O,          'p', 0),
    b';' => (KEY_P,          ';', 0),
    b'[' => (KEY_LEFTBRACE,  '[', 0),
    b']' => (KEY_RIGHTBRACE, ']', 0),
    b'a' => (KEY_A,          'a', 0),
    b's' => (KEY_S,          's', 0),
    b'h' => (KEY_D,          'h', 0),
    b't' => (KEY_F,          't', 0),
    b'g' => (KEY_G,          'g', 0),
    b'y' => (KEY_H,          'y', 0),
    b'n' => (KEY_J,          'n', 0),
    b'e' => (KEY_K,          'e', 0),
    b'o' => (KEY_L,          'o', 0),
    b'i' => (KEY_SEMICOLON,  'i', 0),
    b'\'' => (KEY_APOSTROPHE,'\'', 0),
    b'z' => (KEY_Z,          'z', 0),
    b'x' => (KEY_X,          'x', 0),
    b'm' => (KEY_C,          'm', 0),
    b'c' => (KEY_V,          'c', 0),
    b'v' => (KEY_B,          'v', 0),
    b'k' => (KEY_N,          'k', 0),
    b'l' => (KEY_M,          'l', 0),
    b',' => (KEY_COMMA,      ',', 0),
    b'.' => (KEY_DOT,        '.', 0),
    b'/' => (KEY_SLASH,      '/', 0),
    b' ' => (KEY_SPACE,      ' ', 0),
    b'!' => (KEY_1,          '!', KeyState::Shift as u32),
    b'@' => (KEY_2,          '@', KeyState::Shift as u32),
    b'#' => (KEY_3,          '#', KeyState::Shift as u32),
    b'$' => (KEY_4,          '$', KeyState::Shift as u32),
    b'%' => (KEY_5,          '%', KeyState::Shift as u32),
    b'^' => (KEY_6,          '^', KeyState::Shift as u32),
    b'&' => (KEY_7,          '&', KeyState::Shift as u32),
    b'*' => (KEY_8,          '*', KeyState::Shift as u32),
    b'(' => (KEY_9,          '(', KeyState::Shift as u32),
    b')' => (KEY_0,          ')', KeyState::Shift as u32),
    b'_' => (KEY_MINUS,      '_', KeyState::Shift as u32),
    b'+' => (KEY_EQUAL,      '+', KeyState::Shift as u32),
    b'|' => (KEY_BACKSLASH,  '|', KeyState::Shift as u32),
    b'~' => (KEY_GRAVE,      '~', KeyState::Shift as u32),
    b'Q' => (KEY_Q,          'Q', KeyState::Shift as u32),
    b'D' => (KEY_W,          'D', KeyState::Shift as u32),
    b'R' => (KEY_E,          'R', KeyState::Shift as u32),
    b'W' => (KEY_R,          'W', KeyState::Shift as u32),
    b'B' => (KEY_T,          'B', KeyState::Shift as u32),
    b'J' => (KEY_Y,          'J', KeyState::Shift as u32),
    b'F' => (KEY_U,          'F', KeyState::Shift as u32),
    b'U' => (KEY_I,          'U', KeyState::Shift as u32),
    b'P' => (KEY_O,          'P', KeyState::Shift as u32),
    b':' => (KEY_P,          ':', KeyState::Shift as u32),
    b'{' => (KEY_LEFTBRACE,  '{', KeyState::Shift as u32),
    b'}' => (KEY_RIGHTBRACE, '}', KeyState::Shift as u32),
    b'A' => (KEY_A,          'A', KeyState::Shift as u32),
    b'S' => (KEY_S,          'S', KeyState::Shift as u32),
    b'H' => (KEY_D,          'H', KeyState::Shift as u32),
    b'T' => (KEY_F,          'T', KeyState::Shift as u32),
    b'G' => (KEY_G,          'G', KeyState::Shift as u32),
    b'Y' => (KEY_H,          'Y', KeyState::Shift as u32),
    b'N' => (KEY_J,          'N', KeyState::Shift as u32),
    b'E' => (KEY_K,          'E', KeyState::Shift as u32),
    b'O' => (KEY_L,          'O', KeyState::Shift as u32),
    b'I' => (KEY_SEMICOLON,  'I', KeyState::Shift as u32),
    b'"' => (KEY_APOSTROPHE, '"', KeyState::Shift as u32),
    b'Z' => (KEY_Z,          'Z', KeyState::Shift as u32),
    b'X' => (KEY_X,          'X', KeyState::Shift as u32),
    b'M' => (KEY_C,          'M', KeyState::Shift as u32),
    b'C' => (KEY_V,          'C', KeyState::Shift as u32),
    b'V' => (KEY_B,          'V', KeyState::Shift as u32),
    b'K' => (KEY_N,          'K', KeyState::Shift as u32),
    b'L' => (KEY_M,          'L', KeyState::Shift as u32),
    b'<' => (KEY_COMMA,      '<', KeyState::Shift as u32),
    b'>' => (KEY_DOT,        '>', KeyState::Shift as u32),
    b'?' => (KEY_SLASH,      '?', KeyState::Shift as u32),
};
