/* keymap.c — the single source of truth for keyboard keys. VMCTL_KEYS maps * Linux evdev codes to QEMU QKeyCode names (sorted by evdev for bsearch); * vmctl_evdev_to_qcode is the sole lookup, consumed by the QMP driver. */ #include "keymap.h" #include #include const vmctl_keymap VMCTL_KEYS[] = { { KEY_ESC, "esc" }, { KEY_1, "1" }, { KEY_2, "2" }, { KEY_3, "3" }, { KEY_4, "4" }, { KEY_5, "5" }, { KEY_6, "6" }, { KEY_7, "7" }, { KEY_8, "8" }, { KEY_9, "9" }, { KEY_0, "0" }, { KEY_MINUS, "minus" }, { KEY_EQUAL, "equal" }, { KEY_BACKSPACE, "backspace" }, { KEY_TAB, "tab" }, { KEY_Q, "q" }, { KEY_W, "w" }, { KEY_E, "e" }, { KEY_R, "r" }, { KEY_T, "t" }, { KEY_Y, "y" }, { KEY_U, "u" }, { KEY_I, "i" }, { KEY_O, "o" }, { KEY_P, "p" }, { KEY_LEFTBRACE, "bracket_left" }, { KEY_RIGHTBRACE, "bracket_right" }, { KEY_ENTER, "ret" }, { KEY_LEFTCTRL, "ctrl" }, { KEY_A, "a" }, { KEY_S, "s" }, { KEY_D, "d" }, { KEY_F, "f" }, { KEY_G, "g" }, { KEY_H, "h" }, { KEY_J, "j" }, { KEY_K, "k" }, { KEY_L, "l" }, { KEY_SEMICOLON, "semicolon" }, { KEY_APOSTROPHE, "apostrophe" }, { KEY_GRAVE, "grave_accent" }, { KEY_LEFTSHIFT, "shift" }, { KEY_BACKSLASH, "backslash" }, { KEY_Z, "z" }, { KEY_X, "x" }, { KEY_C, "c" }, { KEY_V, "v" }, { KEY_B, "b" }, { KEY_N, "n" }, { KEY_M, "m" }, { KEY_COMMA, "comma" }, { KEY_DOT, "dot" }, { KEY_SLASH, "slash" }, { KEY_RIGHTSHIFT, "shift_r" }, { KEY_LEFTALT, "alt" }, { KEY_SPACE, "spc" }, { KEY_CAPSLOCK, "caps_lock" }, { KEY_F1, "f1" }, { KEY_F2, "f2" }, { KEY_F3, "f3" }, { KEY_F4, "f4" }, { KEY_F5, "f5" }, { KEY_F6, "f6" }, { KEY_F7, "f7" }, { KEY_F8, "f8" }, { KEY_F9, "f9" }, { KEY_F10, "f10" }, { KEY_NUMLOCK, "num_lock" }, { KEY_SCROLLLOCK, "scroll_lock" }, { KEY_102ND, "less" }, { KEY_F11, "f11" }, { KEY_F12, "f12" }, { KEY_RIGHTCTRL, "ctrl_r" }, { KEY_SYSRQ, "print" }, { KEY_RIGHTALT, "alt_r" }, { KEY_HOME, "home" }, { KEY_UP, "up" }, { KEY_PAGEUP, "pgup" }, { KEY_LEFT, "left" }, { KEY_RIGHT, "right" }, { KEY_END, "end" }, { KEY_DOWN, "down" }, { KEY_PAGEDOWN, "pgdn" }, { KEY_INSERT, "insert" }, { KEY_DELETE, "delete" }, { KEY_POWER, "power" }, { KEY_PAUSE, "pause" }, { KEY_LEFTMETA, "meta_l" }, { KEY_RIGHTMETA, "meta_r" }, { KEY_SLEEP, "sleep" }, { KEY_WAKEUP, "wake" }, }; const int VMCTL_KEYS_LEN = (int)(sizeof VMCTL_KEYS / sizeof VMCTL_KEYS[0]); static int key_cmp(const void* a, const void* b) { return ((const vmctl_keymap*)a)->evdev - ((const vmctl_keymap*)b)->evdev; } const char* vmctl_evdev_to_qcode(int evdev) { vmctl_keymap k = { .evdev = evdev, .qcode = NULL }; const vmctl_keymap* e = bsearch(&k, VMCTL_KEYS, (size_t)VMCTL_KEYS_LEN, sizeof VMCTL_KEYS[0], key_cmp); return e ? e->qcode : NULL; }