// Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved.
//
// StratoVirt is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan
// PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//         http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.

use std::collections::HashMap;

pub enum DpyMod {
    #[cfg(all(target_env = "ohos", feature = "ohui_srv"))]
    Ohui,
    #[cfg(feature = "gtk")]
    Gtk,
    #[cfg(feature = "vnc")]
    Vnc,
}

#[allow(unused)]
#[derive(Clone, Copy, Debug)]
// Some of KeyCodes are not used on OHOS.
pub enum KeyCode {
    Escape,
    Key1,
    Key2,
    Key3,
    Key4,
    Key5,
    Key6,
    Key7,
    Key8,
    Key9,
    Key0,
    Minus,
    Equal,
    BackSpace,
    Tab,
    Keyq,
    Keyw,
    Keye,
    Keyr,
    Keyt,
    Keyy,
    Keyu,
    Keyi,
    Keyo,
    Keyp,
    BracketLeft,
    BracketRight,
    Return,
    ControlL,
    Keya,
    Keys,
    Keyd,
    Keyf,
    Keyg,
    Keyh,
    Keyj,
    Keyk,
    Keyl,
    Semicolon,
    Apostrophe,
    Grave,
    ShiftL,
    BackSlash,
    Keyz,
    Keyx,
    Keyc,
    Keyv,
    Keyb,
    Keyn,
    Keym,
    Comma,
    Period,
    Slash,
    ShiftR,
    KPMultiply,
    AltL,
    Space,
    CapsLock,
    F1,
    F2,
    F3,
    F4,
    F5,
    F6,
    F7,
    F8,
    F9,
    F10,
    NumLock,
    ScrollLock,
    KPHome,
    KP7,
    KPUp,
    KP8,
    KPPrior,
    KP9,
    KPSubtract,
    KPLeft,
    KP4,
    KPBegin,
    KP5,
    KPRight,
    KP6,
    KPAdd,
    KPEnd,
    KP1,
    KPDown,
    KP2,
    KPNext,
    KP3,
    KPInsert,
    KP0,
    KPDelete,
    KPSeparator,
    KPDecimal,
    Execute,
    Print,
    SysReq,
    F11,
    F12,
    KPEqual,
    HenkanMode,
    Muhenkan,
    KPEnter,
    ControlR,
    KPDivide,
    AltR,
    ISOLevel3Shift,
    ModeSwitch,
    Pause,
    Home,
    Up,
    Prior,
    Left,
    Right,
    End,
    Down,
    Next,
    Insert,
    Delete,
    SuperL,
    SuperR,
    Menu,
    Exclam,
    At,
    Numbersign,
    Dollar,
    Percent,
    Asciicircum,
    Ampersand,
    Asterisk,
    Parenleft,
    Parenright,
    Underscore,
    Plus,
    KeyQ,
    KeyW,
    KeyE,
    KeyR,
    KeyT,
    KeyY,
    KeyU,
    KeyI,
    KeyO,
    KeyP,
    Braceleft,
    Braceright,
    KeyA,
    KeyS,
    KeyD,
    KeyF,
    KeyG,
    KeyH,
    KeyJ,
    KeyK,
    KeyL,
    Colon,
    Quotedbl,
    Asciitilde,
    Bar,
    KeyZ,
    KeyX,
    KeyC,
    KeyV,
    KeyB,
    KeyN,
    KeyM,
    Less,
    Greater,
    Question,
    MetaL,
    MetaR,
    Brokenbar,
}

impl KeyCode {
    fn to_key_num(self) -> u16 {
        match self {
            KeyCode::Escape => 0x0001,
            KeyCode::Key1 => 0x0002,
            KeyCode::Key2 => 0x0003,
            KeyCode::Key3 => 0x0004,
            KeyCode::Key4 => 0x0005,
            KeyCode::Key5 => 0x0006,
            KeyCode::Key6 => 0x0007,
            KeyCode::Key7 => 0x0008,
            KeyCode::Key8 => 0x0009,
            KeyCode::Key9 => 0x000A,
            KeyCode::Key0 => 0x000B,
            KeyCode::Minus => 0x000C,
            KeyCode::Equal => 0x000D,
            KeyCode::BackSpace => 0x000E,
            KeyCode::Tab => 0x000F,
            KeyCode::Keyq => 0x0010,
            KeyCode::Keyw => 0x0011,
            KeyCode::Keye => 0x0012,
            KeyCode::Keyr => 0x0013,
            KeyCode::Keyt => 0x0014,
            KeyCode::Keyy => 0x0015,
            KeyCode::Keyu => 0x0016,
            KeyCode::Keyi => 0x0017,
            KeyCode::Keyo => 0x0018,
            KeyCode::Keyp => 0x0019,
            KeyCode::BracketLeft => 0x001A,
            KeyCode::BracketRight => 0x001B,
            KeyCode::Return => 0x001C,
            KeyCode::ControlL => 0x001D,
            KeyCode::Keya => 0x001E,
            KeyCode::Keys => 0x001F,
            KeyCode::Keyd => 0x0020,
            KeyCode::Keyf => 0x0021,
            KeyCode::Keyg => 0x0022,
            KeyCode::Keyh => 0x0023,
            KeyCode::Keyj => 0x0024,
            KeyCode::Keyk => 0x0025,
            KeyCode::Keyl => 0x0026,
            KeyCode::Semicolon => 0x0027,
            KeyCode::Apostrophe => 0x0028,
            KeyCode::Grave => 0x0029,
            KeyCode::ShiftL => 0x002A,
            KeyCode::BackSlash => 0x002B,
            KeyCode::Keyz => 0x002C,
            KeyCode::Keyx => 0x002D,
            KeyCode::Keyc => 0x002E,
            KeyCode::Keyv => 0x002F,
            KeyCode::Keyb => 0x0030,
            KeyCode::Keyn => 0x0031,
            KeyCode::Keym => 0x0032,
            KeyCode::Comma => 0x0033,
            KeyCode::Period => 0x0034,
            KeyCode::Slash => 0x0035,
            KeyCode::ShiftR => 0x0036,
            KeyCode::KPMultiply => 0x0037,
            KeyCode::AltL => 0x0038,
            KeyCode::Space => 0x0039,
            KeyCode::CapsLock => 0x003A,
            KeyCode::F1 => 0x003B,
            KeyCode::F2 => 0x003C,
            KeyCode::F3 => 0x003D,
            KeyCode::F4 => 0x003E,
            KeyCode::F5 => 0x003F,
            KeyCode::F6 => 0x0040,
            KeyCode::F7 => 0x0041,
            KeyCode::F8 => 0x0042,
            KeyCode::F9 => 0x0043,
            KeyCode::F10 => 0x0044,
            KeyCode::NumLock => 0x0045,
            KeyCode::ScrollLock => 0x0046,
            KeyCode::KPHome => 0x0047,
            KeyCode::KPUp => 0x0048,
            KeyCode::KPPrior => 0x0049,
            KeyCode::KPSubtract => 0x004A,
            KeyCode::KPLeft => 0x004B,
            KeyCode::KPBegin => 0x004C,
            KeyCode::KPRight => 0x004D,
            KeyCode::KPAdd => 0x004E,
            KeyCode::KPEnd => 0x004F,
            KeyCode::KPDown => 0x0050,
            KeyCode::KPNext => 0x0051,
            KeyCode::KPInsert => 0x0052,
            KeyCode::KPDelete => 0x0053,
            KeyCode::KPSeparator => 0x0053,
            KeyCode::KP1 => 0x004F,       // Numlock KPEnd
            KeyCode::KP2 => 0x0050,       // Numlock KPDown
            KeyCode::KP3 => 0x0051,       // Numlock KPNext
            KeyCode::KP4 => 0x004B,       // Numlock KPLeft
            KeyCode::KP5 => 0x004C,       // Numlock KPBegin
            KeyCode::KP6 => 0x004D,       // Numlock KPRight
            KeyCode::KP7 => 0x0047,       // Numlock KPHome
            KeyCode::KP8 => 0x0048,       // Numlock KPUp
            KeyCode::KP9 => 0x0049,       // Numlock KPPrior
            KeyCode::KP0 => 0x0052,       // Numlock KPInsert
            KeyCode::KPDecimal => 0x0053, // Numlock KPDelete
            KeyCode::Execute => 0x0054,
            KeyCode::Print => 0x0054,
            KeyCode::SysReq => 0x0054,
            KeyCode::F11 => 0x0057,
            KeyCode::F12 => 0x0058,
            KeyCode::KPEqual => 0x0059,
            KeyCode::HenkanMode => 0x0079,
            KeyCode::Muhenkan => 0x007B,
            KeyCode::KPEnter => 0x009C,
            KeyCode::ControlR => 0x009D,
            KeyCode::KPDivide => 0x00B5,
            KeyCode::AltR => 0x00B8,
            KeyCode::ISOLevel3Shift => 0x00B8,
            KeyCode::ModeSwitch => 0x00B8,
            KeyCode::Pause => 0x00C6,
            KeyCode::Home => 0x00C7,
            KeyCode::Up => 0x00C8,
            KeyCode::Prior => 0x00C9,
            KeyCode::Left => 0x00CB,
            KeyCode::Right => 0x00CD,
            KeyCode::End => 0x00CF,
            KeyCode::Down => 0x00D0,
            KeyCode::Next => 0x00D1,
            KeyCode::Insert => 0x00D2,
            KeyCode::Delete => 0x00D3,
            KeyCode::SuperL => 0x00DB,
            KeyCode::SuperR => 0x00DC,
            KeyCode::Menu => 0x00DD,
            KeyCode::Exclam => 0x0102,      // Shift 1
            KeyCode::At => 0x0103,          // Shift 2
            KeyCode::Numbersign => 0x0104,  // Shift 3
            KeyCode::Dollar => 0x0105,      // Shift 4
            KeyCode::Percent => 0x0106,     // Shift 5
            KeyCode::Asciicircum => 0x0107, // Shift 6
            KeyCode::Ampersand => 0x0108,   // Shift 7
            KeyCode::Asterisk => 0x0109,    // Shift 8
            KeyCode::Parenleft => 0x010A,   // Shift 9
            KeyCode::Parenright => 0x010B,  // Shift 0
            KeyCode::Underscore => 0x010C,  // Shift Minus
            KeyCode::Plus => 0x010D,        // Shift Equal
            KeyCode::KeyQ => 0x0110,        // Shift q
            KeyCode::KeyW => 0x0111,        // Shift w
            KeyCode::KeyE => 0x0112,        // Shift e
            KeyCode::KeyR => 0x0113,        // Shift r
            KeyCode::KeyT => 0x0114,        // Shift t
            KeyCode::KeyY => 0x0115,        // Shift y
            KeyCode::KeyU => 0x0116,        // Shift u
            KeyCode::KeyI => 0x0117,        // Shift i
            KeyCode::KeyO => 0x0118,        // Shift o
            KeyCode::KeyP => 0x0119,        // Shift p
            KeyCode::Braceleft => 0x011A,   // Shift Bracketleft
            KeyCode::Braceright => 0x011B,  // Shift Bracketright
            KeyCode::KeyA => 0x011E,        // Shift a
            KeyCode::KeyS => 0x011F,        // Shift s
            KeyCode::KeyD => 0x0120,        // Shift d
            KeyCode::KeyF => 0x0121,        // Shift f
            KeyCode::KeyG => 0x0122,        // Shift g
            KeyCode::KeyH => 0x0123,        // Shift h
            KeyCode::KeyJ => 0x0124,        // Shift j
            KeyCode::KeyK => 0x0125,        // Shift k
            KeyCode::KeyL => 0x0126,        // Shift l
            KeyCode::Colon => 0x0127,       // Shift Semicolon
            KeyCode::Quotedbl => 0x0128,    // Shift Apostrophe
            KeyCode::Asciitilde => 0x0129,  // Shift Grave
            KeyCode::Bar => 0x012B,         // Shift Backslash
            KeyCode::KeyZ => 0x012C,        // Shift z
            KeyCode::KeyX => 0x012D,        // Shift x
            KeyCode::KeyC => 0x012E,        // Shift c
            KeyCode::KeyV => 0x012F,        // Shift v
            KeyCode::KeyB => 0x0130,        // Shift b
            KeyCode::KeyN => 0x0131,        // Shift n
            KeyCode::KeyM => 0x0132,        // Shift m
            KeyCode::Less => 0x0133,        // Shift Comma
            KeyCode::Greater => 0x0134,     // Shift Period
            KeyCode::Question => 0x0135,    // Shift Slash
            KeyCode::MetaL => 0x0138,       // Shift AltL
            KeyCode::MetaR => 0x01B8,       // Shift AltR
            KeyCode::Brokenbar => 0x0956,   // Shift Altgr Less
        }
    }

    pub fn keysym_to_qkeycode(mode: DpyMod) -> HashMap<u16, u16> {
        let mut keysym2qkeycode: HashMap<u16, u16> = HashMap::new();
        let keycodes = match mode {
            #[cfg(all(target_env = "ohos", feature = "ohui_srv"))]
            DpyMod::Ohui => KEY_CODE_OH.as_ref(),
            #[cfg(any(feature = "gtk", feature = "vnc"))]
            _ => KEY_CODE_ASCLL.as_ref(),
        };
        // Mapping ASCII to keycode.
        for &(keycode, keysym) in keycodes.iter() {
            let qkeycode = keycode.to_key_num();
            keysym2qkeycode.insert(keysym, qkeycode);
        }
        keysym2qkeycode
    }
}

#[cfg(all(target_env = "ohos", feature = "ohui_srv"))]
const KEY_CODE_OH: [(KeyCode, u16); 105] = [
    (KeyCode::Key0, 0x07D0),
    (KeyCode::Key1, 0x07D1),
    (KeyCode::Key2, 0x07D2),
    (KeyCode::Key3, 0x07D3),
    (KeyCode::Key4, 0x07D4),
    (KeyCode::Key5, 0x07D5),
    (KeyCode::Key6, 0x07D6),
    (KeyCode::Key7, 0x07D7),
    (KeyCode::Key8, 0x07D8),
    (KeyCode::Key9, 0x07D9),
    (KeyCode::Minus, 0x0809),
    (KeyCode::Equal, 0x080A),
    (KeyCode::BackSpace, 0x0807),
    (KeyCode::Tab, 0x0801),
    (KeyCode::Keya, 0x07E1),
    (KeyCode::Keyb, 0x07E2),
    (KeyCode::Keyc, 0x07E3),
    (KeyCode::Keyd, 0x07E4),
    (KeyCode::Keye, 0x07E5),
    (KeyCode::Keyf, 0x07E6),
    (KeyCode::Keyg, 0x07E7),
    (KeyCode::Keyh, 0x07E8),
    (KeyCode::Keyi, 0x07E9),
    (KeyCode::Keyj, 0x07EA),
    (KeyCode::Keyk, 0x07EB),
    (KeyCode::Keyl, 0x07EC),
    (KeyCode::Keym, 0x07ED),
    (KeyCode::Keyn, 0x07EE),
    (KeyCode::Keyo, 0x07EF),
    (KeyCode::Keyp, 0x07F0),
    (KeyCode::Keyq, 0x07F1),
    (KeyCode::Keyr, 0x07F2),
    (KeyCode::Keys, 0x07F3),
    (KeyCode::Keyt, 0x07F4),
    (KeyCode::Keyu, 0x07F5),
    (KeyCode::Keyv, 0x07F6),
    (KeyCode::Keyw, 0x07F7),
    (KeyCode::Keyx, 0x07F8),
    (KeyCode::Keyy, 0x07F9),
    (KeyCode::Keyz, 0x07FA),
    (KeyCode::Space, 0x0802),
    (KeyCode::Comma, 0x07FB),
    (KeyCode::Slash, 0x0810),
    (KeyCode::Down, 0x07DD),
    (KeyCode::Left, 0x07DE),
    (KeyCode::End, 0x0822),
    (KeyCode::Escape, 0x0816),
    (KeyCode::Period, 0x07FC),
    (KeyCode::Up, 0x07DC),
    (KeyCode::Apostrophe, 0x080F),
    (KeyCode::Semicolon, 0x080E),
    (KeyCode::BackSlash, 0x080D),
    (KeyCode::Braceleft, 0x080B),
    (KeyCode::Braceright, 0x080C),
    (KeyCode::AltR, 0x07FE),
    (KeyCode::Return, 0x0806),
    (KeyCode::Grave, 0x0808),
    (KeyCode::Home, 0x0821),
    (KeyCode::SysReq, 0x081F),
    (KeyCode::Right, 0x07DF),
    (KeyCode::Menu, 0x09A2),
    (KeyCode::Prior, 0x0814),
    (KeyCode::Insert, 0x0823),
    (KeyCode::NumLock, 0x0836),
    (KeyCode::Next, 0x0815),
    (KeyCode::KPAdd, 0x0844),
    (KeyCode::KPMultiply, 0x0842),
    (KeyCode::KPEnter, 0x0847),
    (KeyCode::Pause, 0x0820),
    (KeyCode::ScrollLock, 0x081B),
    (KeyCode::SuperL, 0x081C),
    (KeyCode::SuperR, 0x081D),
    (KeyCode::KPDecimal, 0x0845),
    (KeyCode::KPSubtract, 0x0843),
    (KeyCode::KPDivide, 0x0841),
    (KeyCode::KP0, 0x0837),
    (KeyCode::KP1, 0x0838),
    (KeyCode::KP2, 0x0839),
    (KeyCode::KP3, 0x083A),
    (KeyCode::KP4, 0x083B),
    (KeyCode::KP5, 0x083C),
    (KeyCode::KP6, 0x083D),
    (KeyCode::KP7, 0x083E),
    (KeyCode::KP8, 0x083F),
    (KeyCode::KP9, 0x0840),
    (KeyCode::KPEqual, 0x0848),
    (KeyCode::F1, 0x082A),
    (KeyCode::F2, 0x082B),
    (KeyCode::F3, 0x082C),
    (KeyCode::F4, 0x082D),
    (KeyCode::F5, 0x082E),
    (KeyCode::F6, 0x082F),
    (KeyCode::F7, 0x0830),
    (KeyCode::F8, 0x0831),
    (KeyCode::F9, 0x0832),
    (KeyCode::F10, 0x0833),
    (KeyCode::F11, 0x0834),
    (KeyCode::F12, 0x0835),
    (KeyCode::ShiftL, 0x7FF),
    (KeyCode::ShiftR, 0x0800),
    (KeyCode::ControlL, 0x0818),
    (KeyCode::ControlR, 0x0819),
    (KeyCode::CapsLock, 0x081A),
    (KeyCode::AltL, 0x07FD),
    (KeyCode::Delete, 0x0817),
];

#[cfg(any(feature = "gtk", feature = "vnc"))]
const KEY_CODE_ASCLL: [(KeyCode, u16); 173] = [
    (KeyCode::Space, 0x0020),
    (KeyCode::Exclam, 0x0021),
    (KeyCode::Quotedbl, 0x0022),
    (KeyCode::Numbersign, 0x0023),
    (KeyCode::Dollar, 0x0024),
    (KeyCode::Percent, 0x0025),
    (KeyCode::Ampersand, 0x0026),
    (KeyCode::Apostrophe, 0x0027),
    (KeyCode::Parenleft, 0x0028),
    (KeyCode::Parenright, 0x0029),
    (KeyCode::Asterisk, 0x002A),
    (KeyCode::Plus, 0x002B),
    (KeyCode::Comma, 0x002C),
    (KeyCode::Minus, 0x002D),
    (KeyCode::Period, 0x002E),
    (KeyCode::Slash, 0x002F),
    (KeyCode::Key0, 0x0030),
    (KeyCode::Key1, 0x0031),
    (KeyCode::Key2, 0x0032),
    (KeyCode::Key3, 0x0033),
    (KeyCode::Key4, 0x0034),
    (KeyCode::Key5, 0x0035),
    (KeyCode::Key6, 0x0036),
    (KeyCode::Key7, 0x0037),
    (KeyCode::Key8, 0x0038),
    (KeyCode::Key9, 0x0039),
    (KeyCode::Colon, 0x003A),
    (KeyCode::Semicolon, 0x003B),
    (KeyCode::Less, 0x003C),
    (KeyCode::Equal, 0x003D),
    (KeyCode::Greater, 0x003E),
    (KeyCode::Question, 0x003F),
    (KeyCode::At, 0x0040),
    (KeyCode::KeyA, 0x0041),
    (KeyCode::KeyB, 0x0042),
    (KeyCode::KeyC, 0x0043),
    (KeyCode::KeyD, 0x0044),
    (KeyCode::KeyE, 0x0045),
    (KeyCode::KeyF, 0x0046),
    (KeyCode::KeyG, 0x0047),
    (KeyCode::KeyH, 0x0048),
    (KeyCode::KeyI, 0x0049),
    (KeyCode::KeyJ, 0x004A),
    (KeyCode::KeyK, 0x004B),
    (KeyCode::KeyL, 0x004C),
    (KeyCode::KeyM, 0x004D),
    (KeyCode::KeyN, 0x004E),
    (KeyCode::KeyO, 0x004F),
    (KeyCode::KeyP, 0x0050),
    (KeyCode::KeyQ, 0x0051),
    (KeyCode::KeyR, 0x0052),
    (KeyCode::KeyS, 0x0053),
    (KeyCode::KeyT, 0x0054),
    (KeyCode::KeyU, 0x0055),
    (KeyCode::KeyV, 0x0056),
    (KeyCode::KeyW, 0x0057),
    (KeyCode::KeyX, 0x0058),
    (KeyCode::KeyY, 0x0059),
    (KeyCode::KeyZ, 0x005A),
    (KeyCode::BracketLeft, 0x005B),
    (KeyCode::BackSlash, 0x005C),
    (KeyCode::BracketRight, 0x005D),
    (KeyCode::Asciicircum, 0x005E),
    (KeyCode::Underscore, 0x005F),
    (KeyCode::Grave, 0x0060),
    (KeyCode::Keya, 0x0061),
    (KeyCode::Keyb, 0x0062),
    (KeyCode::Keyc, 0x0063),
    (KeyCode::Keyd, 0x0064),
    (KeyCode::Keye, 0x0065),
    (KeyCode::Keyf, 0x0066),
    (KeyCode::Keyg, 0x0067),
    (KeyCode::Keyh, 0x0068),
    (KeyCode::Keyi, 0x0069),
    (KeyCode::Keyj, 0x006A),
    (KeyCode::Keyk, 0x006B),
    (KeyCode::Keyl, 0x006C),
    (KeyCode::Keym, 0x006D),
    (KeyCode::Keyn, 0x006E),
    (KeyCode::Keyo, 0x006F),
    (KeyCode::Keyp, 0x0070),
    (KeyCode::Keyq, 0x0071),
    (KeyCode::Keyr, 0x0072),
    (KeyCode::Keys, 0x0073),
    (KeyCode::Keyt, 0x0074),
    (KeyCode::Keyu, 0x0075),
    (KeyCode::Keyv, 0x0076),
    (KeyCode::Keyw, 0x0077),
    (KeyCode::Keyx, 0x0078),
    (KeyCode::Keyy, 0x0079),
    (KeyCode::Keyz, 0x007A),
    (KeyCode::Braceleft, 0x007B),
    (KeyCode::Bar, 0x007C),
    (KeyCode::Braceright, 0x007D),
    (KeyCode::Asciitilde, 0x007E),
    (KeyCode::Brokenbar, 0x00A6),
    (KeyCode::ISOLevel3Shift, 0xFE03),
    (KeyCode::BackSpace, 0xFF08),
    (KeyCode::Tab, 0xFF09),
    (KeyCode::Return, 0xFF0D),
    (KeyCode::Pause, 0xFF13),
    (KeyCode::ScrollLock, 0xFF14),
    (KeyCode::SysReq, 0xFF15),
    (KeyCode::Escape, 0xFF1B),
    (KeyCode::Muhenkan, 0xFF22),
    (KeyCode::HenkanMode, 0xFF23),
    (KeyCode::Home, 0xFF50),
    (KeyCode::Left, 0xFF51),
    (KeyCode::Up, 0xFF52),
    (KeyCode::Right, 0xFF53),
    (KeyCode::Down, 0xFF54),
    (KeyCode::Prior, 0xFF55),
    (KeyCode::Next, 0xFF56),
    (KeyCode::End, 0xFF57),
    (KeyCode::Print, 0xFF61),
    (KeyCode::Execute, 0xFF62),
    (KeyCode::Insert, 0xFF63),
    (KeyCode::Menu, 0xFF67),
    (KeyCode::ModeSwitch, 0xFF7E),
    (KeyCode::NumLock, 0xFF7F),
    (KeyCode::KPEnter, 0xFF8D),
    (KeyCode::KPHome, 0xFF95),
    (KeyCode::KPLeft, 0xFF96),
    (KeyCode::KPUp, 0xFF97),
    (KeyCode::KPRight, 0xFF98),
    (KeyCode::KPDown, 0xFF99),
    (KeyCode::KPPrior, 0xFF9A),
    (KeyCode::KPNext, 0xFF9B),
    (KeyCode::KPEnd, 0xFF9C),
    (KeyCode::KPBegin, 0xFF9D),
    (KeyCode::KPInsert, 0xFF9E),
    (KeyCode::KPDelete, 0xFF9F),
    (KeyCode::KPMultiply, 0xFFAA),
    (KeyCode::KPAdd, 0xFFAB),
    (KeyCode::KPSeparator, 0xFFAC),
    (KeyCode::KPSubtract, 0xFFAD),
    (KeyCode::KPDecimal, 0xFFAE),
    (KeyCode::KPDivide, 0xFFAF),
    (KeyCode::KP0, 0xFFB0),
    (KeyCode::KP1, 0xFFB1),
    (KeyCode::KP2, 0xFFB2),
    (KeyCode::KP3, 0xFFB3),
    (KeyCode::KP4, 0xFFB4),
    (KeyCode::KP5, 0xFFB5),
    (KeyCode::KP6, 0xFFB6),
    (KeyCode::KP7, 0xFFB7),
    (KeyCode::KP8, 0xFFB8),
    (KeyCode::KP9, 0xFFB9),
    (KeyCode::KPEqual, 0xFFBD),
    (KeyCode::F1, 0xFFBE),
    (KeyCode::F2, 0xFFBF),
    (KeyCode::F3, 0xFFC0),
    (KeyCode::F4, 0xFFC1),
    (KeyCode::F5, 0xFFC2),
    (KeyCode::F6, 0xFFC3),
    (KeyCode::F7, 0xFFC4),
    (KeyCode::F8, 0xFFC5),
    (KeyCode::F9, 0xFFC6),
    (KeyCode::F10, 0xFFC7),
    (KeyCode::F11, 0xFFC8),
    (KeyCode::F12, 0xFFC9),
    (KeyCode::ShiftL, 0xFFE1),
    (KeyCode::ShiftR, 0xFFE2),
    (KeyCode::ControlL, 0xFFE3),
    (KeyCode::ControlR, 0xFFE4),
    (KeyCode::CapsLock, 0xFFE5),
    (KeyCode::MetaL, 0xFFE7),
    (KeyCode::MetaR, 0xFFE8),
    (KeyCode::AltL, 0xFFE9),
    (KeyCode::AltR, 0xFFEA),
    (KeyCode::SuperL, 0xFFEB),
    (KeyCode::SuperR, 0xFFEC),
    (KeyCode::Delete, 0xFFFF),
];