boredos_mirror/src/input/keymap.c
2026-05-12 23:01:43 +02:00

469 lines
No EOL
18 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright (c) 2026 Lluciocc (https://github.com/lluciocc)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "keymap.h"
#define DEAD_NORMAL 0x01
#define DEAD_SHIFT 0x02
#define DEAD_ALTGR 0x04
#define DEAD_SHIFT_ALTGR 0x08
typedef struct {
const char *name;
keymap_entry_t entries[KEY_MAX];
} keyboard_layout_t;
typedef struct {
uint32_t dead;
uint32_t base;
uint32_t result;
} compose_entry_t;
/*
HOW TO ADD A NEW LAYOUT:
1. Add a new entry to the keymap_id_t enum in keymap.h
2. Create a new keyboard_layout_t instance in keymap.c, filling the entries array with the appropriate codepoints for each keycode and modifier combination. Use 0 for unused combinations.
3. Add the new layout to the g_layouts array in keymap.c
4. (Optional) If your layout has dead keys, add the appropriate entries to the g_compose_table array in keymap.c, defining how dead keys combine with base characters to produce composed characters.
5. Add the layout to /src/userland/gui/settings.c in init_settings_widgets() in the *keyboard_opts[] array and increment the count in widget_dropdown_init for drop_keyboard.
*/
// QWERTY LAYOUT US (DEFAULT)
static const keyboard_layout_t layout_qwerty = {
"QWERTY (US)",
.entries = {
// [KEYCODE] = {normal, shift, altgr, shift_altgr, dead_mask, alpha}
[KEY_1] = {'1', '!', 0, 0, 0, false},
[KEY_2] = {'2', '@', 0, 0, 0, false},
[KEY_3] = {'3', '#', 0, 0, 0, false},
[KEY_4] = {'4', '$', 0, 0, 0, false},
[KEY_5] = {'5', '%', 0, 0, 0, false},
[KEY_6] = {'6', '^', 0, 0, 0, false},
[KEY_7] = {'7', '&', 0, 0, 0, false},
[KEY_8] = {'8', '*', 0, 0, 0, false},
[KEY_9] = {'9', '(', 0, 0, 0, false},
[KEY_0] = {'0', ')', 0, 0, 0, false},
[KEY_MINUS] = {'-', '_', 0, 0, 0, false},
[KEY_EQUAL] = {'=', '+', 0, 0, 0, false},
[KEY_Q] = {'q', 'Q', 0, 0, 0, true},
[KEY_W] = {'w', 'W', 0, 0, 0, true},
[KEY_E] = {'e', 'E', 0, 0, 0, true},
[KEY_R] = {'r', 'R', 0, 0, 0, true},
[KEY_T] = {'t', 'T', 0, 0, 0, true},
[KEY_Y] = {'y', 'Y', 0, 0, 0, true},
[KEY_U] = {'u', 'U', 0, 0, 0, true},
[KEY_I] = {'i', 'I', 0, 0, 0, true},
[KEY_O] = {'o', 'O', 0, 0, 0, true},
[KEY_P] = {'p', 'P', 0, 0, 0, true},
[KEY_LBRACKET] = {'[', '{', 0, 0, 0, false},
[KEY_RBRACKET] = {']', '}', 0, 0, 0, false},
[KEY_A] = {'a', 'A', 0, 0, 0, true},
[KEY_S] = {'s', 'S', 0, 0, 0, true},
[KEY_D] = {'d', 'D', 0, 0, 0, true},
[KEY_F] = {'f', 'F', 0, 0, 0, true},
[KEY_G] = {'g', 'G', 0, 0, 0, true},
[KEY_H] = {'h', 'H', 0, 0, 0, true},
[KEY_J] = {'j', 'J', 0, 0, 0, true},
[KEY_K] = {'k', 'K', 0, 0, 0, true},
[KEY_L] = {'l', 'L', 0, 0, 0, true},
[KEY_SEMICOLON] = {';', ':', 0, 0, 0, false},
[KEY_APOSTROPHE] = {'\'', '"', 0, 0, 0, false},
[KEY_GRAVE] = {'`', '~', 0, 0, 0, false},
[KEY_BACKSLASH] = {'\\', '|', 0, 0, 0, false},
[KEY_Z] = {'z', 'Z', 0, 0, 0, true},
[KEY_X] = {'x', 'X', 0, 0, 0, true},
[KEY_C] = {'c', 'C', 0, 0, 0, true},
[KEY_V] = {'v', 'V', 0, 0, 0, true},
[KEY_B] = {'b', 'B', 0, 0, 0, true},
[KEY_N] = {'n', 'N', 0, 0, 0, true},
[KEY_M] = {'m', 'M', 0, 0, 0, true},
[KEY_COMMA] = {',', '<', 0, 0, 0, false},
[KEY_DOT] = {'.', '>', 0, 0, 0, false},
[KEY_SLASH] = {'/', '?', 0, 0, 0, false},
[KEY_SPACE] = {' ', ' ', 0, 0, 0, false},
[KEY_KP_SLASH] = {'/', '/', 0, 0, 0, false},
[KEY_KP_STAR] = {'*', '*', 0, 0, 0, false},
[KEY_KP_MINUS] = {'-', '-', 0, 0, 0, false},
[KEY_KP_PLUS] = {'+', '+', 0, 0, 0, false},
[KEY_KP_DOT] = {'.', '.', 0, 0, 0, false},
[KEY_KP_0] = {'0', '0', 0, 0, 0, false},
[KEY_KP_1] = {'1', '1', 0, 0, 0, false},
[KEY_KP_2] = {'2', '2', 0, 0, 0, false},
[KEY_KP_3] = {'3', '3', 0, 0, 0, false},
[KEY_KP_4] = {'4', '4', 0, 0, 0, false},
[KEY_KP_5] = {'5', '5', 0, 0, 0, false},
[KEY_KP_6] = {'6', '6', 0, 0, 0, false},
[KEY_KP_7] = {'7', '7', 0, 0, 0, false},
[KEY_KP_8] = {'8', '8', 0, 0, 0, false},
[KEY_KP_9] = {'9', '9', 0, 0, 0, false},
}
};
// AZERTY LAYOUT FR
static const keyboard_layout_t layout_azerty = {
"AZERTY (FR)",
.entries = {
[KEY_1] = { '&', '1', 0, 0, 0, false },
[KEY_2] = { 0x00E9, '2', '~', 0, 0, false }, // é / 2 / ~
[KEY_3] = { '"', '3', '#', 0, 0, false },
[KEY_4] = { '\'', '4', '{', 0, 0, false },
[KEY_5] = { '(', '5', '[', 0, 0, false },
[KEY_6] = { '-', '6', '|', 0, 0, false },
[KEY_7] = { 0x00E8, '7', '`', 0, 0, false }, // è / 7 / `
[KEY_8] = { '_', '8', '\\', 0, 0, false },
[KEY_9] = { 0x00E7, '9', '^', 0, 0, false }, // ç / 9 / ^
[KEY_0] = { 0x00E0, '0', '@', 0, 0, false }, // à / 0 / @
[KEY_MINUS] = { ')', 0x00B0, ']', 0, 0, false }, // ) / °
[KEY_EQUAL] = { '=', '+', '}', 0, 0, false },
[KEY_Q] = { 'a', 'A', 0, 0, 0, true },
[KEY_W] = { 'z', 'Z', 0, 0, 0, true },
[KEY_E] = { 'e', 'E', 0x20AC, 0, 0, true }, // €
[KEY_R] = { 'r', 'R', 0, 0, 0, true },
[KEY_T] = { 't', 'T', 0, 0, 0, true },
[KEY_Y] = { 'y', 'Y', 0, 0, 0, true },
[KEY_U] = { 'u', 'U', 0, 0, 0, true },
[KEY_I] = { 'i', 'I', 0, 0, 0, true },
[KEY_O] = { 'o', 'O', 0, 0, 0, true },
[KEY_P] = { 'p', 'P', 0, 0, 0, true },
[KEY_LBRACKET] = { '^', 0x00A8, 0, 0, DEAD_NORMAL | DEAD_SHIFT, false }, // ^ / ¨
[KEY_RBRACKET] = { '$', 0x00A3, 0, 0, 0, false }, // £
[KEY_A] = { 'q', 'Q', 0, 0, 0, true },
[KEY_S] = { 's', 'S', 0, 0, 0, true },
[KEY_D] = { 'd', 'D', 0, 0, 0, true },
[KEY_F] = { 'f', 'F', 0, 0, 0, true },
[KEY_G] = { 'g', 'G', 0, 0, 0, true },
[KEY_H] = { 'h', 'H', 0, 0, 0, true },
[KEY_J] = { 'j', 'J', 0, 0, 0, true },
[KEY_K] = { 'k', 'K', 0, 0, 0, true },
[KEY_L] = { 'l', 'L', 0, 0, 0, true },
[KEY_SEMICOLON] = { 'm', 'M', 0, 0, 0, true },
[KEY_APOSTROPHE] = { 0x00F9, '%', 0, 0, 0, false }, // ù / %
[KEY_GRAVE] = { 0x00B2, 0, 0, 0, 0, false }, // ²
[KEY_BACKSLASH] = { '*', 0x00B5, 0, 0, 0, false }, // * / µ
[KEY_Z] = { 'w', 'W', 0, 0, 0, true },
[KEY_X] = { 'x', 'X', 0, 0, 0, true },
[KEY_C] = { 'c', 'C', 0, 0, 0, true },
[KEY_V] = { 'v', 'V', 0, 0, 0, true },
[KEY_B] = { 'b', 'B', 0, 0, 0, true },
[KEY_N] = { 'n', 'N', 0, 0, 0, true },
[KEY_M] = { ',', '?', 0, 0, 0, false },
[KEY_COMMA] = { ';', '.', 0, 0, 0, false },
[KEY_DOT] = { ':', '/', 0, 0, 0, false },
[KEY_SLASH] = { '!', 0x00A7, 0, 0, 0, false },
[KEY_SPACE] = { ' ', ' ', 0, 0, 0, false },
[KEY_KP_SLASH] = {'/', '/', 0, 0, 0, false},
[KEY_KP_STAR] = {'*', '*', 0, 0, 0, false},
[KEY_KP_MINUS] = {'-', '-', 0, 0, 0, false},
[KEY_KP_PLUS] = {'+', '+', 0, 0, 0, false},
[KEY_KP_DOT] = {'.', '.', 0, 0, 0, false},
[KEY_KP_0] = {'0', '0', 0, 0, 0, false},
[KEY_KP_1] = {'1', '1', 0, 0, 0, false},
[KEY_KP_2] = {'2', '2', 0, 0, 0, false},
[KEY_KP_3] = {'3', '3', 0, 0, 0, false},
[KEY_KP_4] = {'4', '4', 0, 0, 0, false},
[KEY_KP_5] = {'5', '5', 0, 0, 0, false},
[KEY_KP_6] = {'6', '6', 0, 0, 0, false},
[KEY_KP_7] = {'7', '7', 0, 0, 0, false},
[KEY_KP_8] = {'8', '8', 0, 0, 0, false},
[KEY_KP_9] = {'9', '9', 0, 0, 0, false},
}
};
static const keyboard_layout_t layout_qwertz = {
"QWERTZ (DE)",
.entries = {
[KEY_1] = { '1', '!', 0, 0, 0, false },
[KEY_2] = { '2', '"', 0x00B2, 0, 0, false }, // ²
[KEY_3] = { '3', 0x00A7, 0x00B3, 0, 0, false }, // § ³
[KEY_4] = { '4', '$', 0, 0, 0, false },
[KEY_5] = { '5', '%', 0, 0, 0, false },
[KEY_6] = { '6', '&', 0, 0, 0, false },
[KEY_7] = { '7', '/', '{', 0, 0, false },
[KEY_8] = { '8', '(', '[', 0, 0, false },
[KEY_9] = { '9', ')', ']', 0, 0, false },
[KEY_0] = { '0', '=', '}', 0, 0, false },
[KEY_MINUS] = { 0x00DF, '?', '\\', 0, 0, false }, // ß
[KEY_EQUAL] = { 0x00B4, '`', 0, 0, DEAD_NORMAL, false }, // ´ dead
[KEY_Q] = { 'q', 'Q', '@', 0, 0, true },
[KEY_W] = { 'w', 'W', 0, 0, 0, true },
[KEY_E] = { 'e', 'E', 0x20AC, 0, 0, true }, // €
[KEY_R] = { 'r', 'R', 0, 0, 0, true },
[KEY_T] = { 't', 'T', 0, 0, 0, true },
[KEY_Y] = { 'z', 'Z', 0, 0, 0, true },
[KEY_U] = { 'u', 'U', 0, 0, 0, true },
[KEY_I] = { 'i', 'I', 0, 0, 0, true },
[KEY_O] = { 'o', 'O', 0, 0, 0, true },
[KEY_P] = { 'p', 'P', 0, 0, 0, true },
[KEY_LBRACKET] = { 0x00FC, 0x00DC, 0, 0, 0, true }, // ü
[KEY_RBRACKET] = { '+', '*', '~', 0, 0, false },
[KEY_A] = { 'a', 'A', 0, 0, 0, true },
[KEY_S] = { 's', 'S', 0, 0, 0, true },
[KEY_D] = { 'd', 'D', 0, 0, 0, true },
[KEY_F] = { 'f', 'F', 0, 0, 0, true },
[KEY_G] = { 'g', 'G', 0, 0, 0, true },
[KEY_H] = { 'h', 'H', 0, 0, 0, true },
[KEY_J] = { 'j', 'J', 0, 0, 0, true },
[KEY_K] = { 'k', 'K', 0, 0, 0, true },
[KEY_L] = { 'l', 'L', 0, 0, 0, true },
[KEY_SEMICOLON] = { 0x00F6, 0x00D6, 0, 0, 0, true }, // ö
[KEY_APOSTROPHE] = { 0x00E4, 0x00C4, 0, 0, 0, true }, // ä
[KEY_GRAVE] = { '^', 0x00B0, 0, 0, DEAD_NORMAL, false }, // ^ dead
[KEY_BACKSLASH] = { '#', '\'', 0, 0, 0, false },
[KEY_Z] = { 'y', 'Y', 0, 0, 0, true },
[KEY_X] = { 'x', 'X', 0, 0, 0, true },
[KEY_C] = { 'c', 'C', 0, 0, 0, true },
[KEY_V] = { 'v', 'V', 0, 0, 0, true },
[KEY_B] = { 'b', 'B', 0, 0, 0, true },
[KEY_N] = { 'n', 'N', 0, 0, 0, true },
[KEY_M] = { 'm', 'M', 0, 0, 0, true },
[KEY_COMMA] = { ',', ';', 0, 0, 0, false },
[KEY_DOT] = { '.', ':', 0, 0, 0, false },
[KEY_SLASH] = { '-', '_', 0, 0, 0, false },
[KEY_SPACE] = { ' ', ' ', 0, 0, 0, false },
[KEY_KP_SLASH] = {'/', '/', 0, 0, 0, false},
[KEY_KP_STAR] = {'*', '*', 0, 0, 0, false},
[KEY_KP_MINUS] = {'-', '-', 0, 0, 0, false},
[KEY_KP_PLUS] = {'+', '+', 0, 0, 0, false},
[KEY_KP_DOT] = {'.', '.', 0, 0, 0, false},
[KEY_KP_0] = {'0', '0', 0, 0, 0, false},
[KEY_KP_1] = {'1', '1', 0, 0, 0, false},
[KEY_KP_2] = {'2', '2', 0, 0, 0, false},
[KEY_KP_3] = {'3', '3', 0, 0, 0, false},
[KEY_KP_4] = {'4', '4', 0, 0, 0, false},
[KEY_KP_5] = {'5', '5', 0, 0, 0, false},
[KEY_KP_6] = {'6', '6', 0, 0, 0, false},
[KEY_KP_7] = {'7', '7', 0, 0, 0, false},
[KEY_KP_8] = {'8', '8', 0, 0, 0, false},
[KEY_KP_9] = {'9', '9', 0, 0, 0, false},
}
};
static const keyboard_layout_t layout_dvorak = {
"DVORAK",
.entries = {
[KEY_1] = { '1', '!', 0, 0, 0, false },
[KEY_2] = { '2', '@', 0, 0, 0, false },
[KEY_3] = { '3', '#', 0, 0, 0, false },
[KEY_4] = { '4', '$', 0, 0, 0, false },
[KEY_5] = { '5', '%', 0, 0, 0, false },
[KEY_6] = { '6', '^', 0, 0, 0, false },
[KEY_7] = { '7', '&', 0, 0, 0, false },
[KEY_8] = { '8', '*', 0, 0, 0, false },
[KEY_9] = { '9', '(', 0, 0, 0, false },
[KEY_0] = { '0', ')', 0, 0, 0, false },
[KEY_MINUS] = { '[', '{', 0, 0, 0, false },
[KEY_EQUAL] = { ']', '}', 0, 0, 0, false },
[KEY_Q] = { '\'', '"', 0, 0, 0, false },
[KEY_W] = { ',', '<', 0, 0, 0, false },
[KEY_E] = { '.', '>', 0, 0, 0, false },
[KEY_R] = { 'p', 'P', 0, 0, 0, true },
[KEY_T] = { 'y', 'Y', 0, 0, 0, true },
[KEY_Y] = { 'f', 'F', 0, 0, 0, true },
[KEY_U] = { 'g', 'G', 0, 0, 0, true },
[KEY_I] = { 'c', 'C', 0, 0, 0, true },
[KEY_O] = { 'r', 'R', 0, 0, 0, true },
[KEY_P] = { 'l', 'L', 0, 0, 0, true },
[KEY_LBRACKET] = { '/', '?', 0, 0, 0, false },
[KEY_RBRACKET] = { '=', '+', 0, 0, 0, false },
[KEY_A] = { 'a', 'A', 0, 0, 0, true },
[KEY_S] = { 'o', 'O', 0, 0, 0, true },
[KEY_D] = { 'e', 'E', 0, 0, 0, true },
[KEY_F] = { 'u', 'U', 0, 0, 0, true },
[KEY_G] = { 'i', 'I', 0, 0, 0, true },
[KEY_H] = { 'd', 'D', 0, 0, 0, true },
[KEY_J] = { 'h', 'H', 0, 0, 0, true },
[KEY_K] = { 't', 'T', 0, 0, 0, true },
[KEY_L] = { 'n', 'N', 0, 0, 0, true },
[KEY_SEMICOLON] = { 's', 'S', 0, 0, 0, true },
[KEY_APOSTROPHE] = { '-', '_', 0, 0, 0, false },
[KEY_GRAVE] = { '`', '~', 0, 0, 0, false },
[KEY_BACKSLASH] = { '\\', '|', 0, 0, 0, false },
[KEY_Z] = { ';', ':', 0, 0, 0, false },
[KEY_X] = { 'q', 'Q', 0, 0, 0, true },
[KEY_C] = { 'j', 'J', 0, 0, 0, true },
[KEY_V] = { 'k', 'K', 0, 0, 0, true },
[KEY_B] = { 'x', 'X', 0, 0, 0, true },
[KEY_N] = { 'b', 'B', 0, 0, 0, true },
[KEY_M] = { 'm', 'M', 0, 0, 0, true },
[KEY_COMMA] = { 'w', 'W', 0, 0, 0, true },
[KEY_DOT] = { 'v', 'V', 0, 0, 0, true },
[KEY_SLASH] = { 'z', 'Z', 0, 0, 0, true },
[KEY_SPACE] = { ' ', ' ', 0, 0, 0, false },
}
};
static const keyboard_layout_t *g_layouts[] = {
&layout_qwerty,
&layout_azerty,
&layout_qwertz,
&layout_dvorak
};
static keymap_id_t g_current = KEYMAP_QWERTY;
static uint32_t g_active_dead = 0;
static const compose_entry_t g_compose_table[] = {
{ '^', 'a', 0x00E2 }, { '^', 'e', 0x00EA }, { '^', 'i', 0x00EE }, { '^', 'o', 0x00F4 }, { '^', 'u', 0x00FB },
{ '^', 'A', 0x00C2 }, { '^', 'E', 0x00CA }, { '^', 'I', 0x00CE }, { '^', 'O', 0x00D4 }, { '^', 'U', 0x00DB },
{ 0x00A8, 'a', 0x00E4 }, { 0x00A8, 'e', 0x00EB }, { 0x00A8, 'i', 0x00EF }, { 0x00A8, 'o', 0x00F6 }, { 0x00A8, 'u', 0x00FC }, { 0x00A8, 'y', 0x00FF },
{ 0x00A8, 'A', 0x00C4 }, { 0x00A8, 'E', 0x00CB }, { 0x00A8, 'I', 0x00CF }, { 0x00A8, 'O', 0x00D6 }, { 0x00A8, 'U', 0x00DC },
{ 0x00B4, 'a', 0x00E1 }, { 0x00B4, 'e', 0x00E9 }, { 0x00B4, 'i', 0x00ED }, { 0x00B4, 'o', 0x00F3 }, { 0x00B4, 'u', 0x00FA },
{ 0x00B4, 'A', 0x00C1 }, { 0x00B4, 'E', 0x00C9 }, { 0x00B4, 'I', 0x00CD }, { 0x00B4, 'O', 0x00D3 }, { 0x00B4, 'U', 0x00DA },
{ '`', 'a', 0x00E0 }, { '`', 'e', 0x00E8 }, { '`', 'i', 0x00EC }, { '`', 'o', 0x00F2 }, { '`', 'u', 0x00F9 },
{ 0, 0, 0 }
};
void keymap_init(void) {
g_current = KEYMAP_QWERTY;
}
void keymap_set_current(keymap_id_t id) {
if ((int)id < 0 || (int)id >= keymap_get_count()) return;
g_current = id;
}
keymap_id_t keymap_get_current(void) {
return g_current;
}
const char *keymap_get_name(keymap_id_t id) {
if ((int)id < 0 || (int)id >= keymap_get_count()) return "Unknown";
return g_layouts[id]->name;
}
int keymap_get_count(void) {
return (int)(sizeof(g_layouts) / sizeof(g_layouts[0]));
}
static keymap_result_t make_result(uint32_t cp, bool dead) {
keymap_result_t r;
r.codepoint = cp;
r.is_text = (cp != 0);
r.is_dead = dead;
return r;
}
keymap_result_t keymap_translate_keycode(uint16_t keycode, uint32_t mods) {
if (keycode <= 0 || keycode >= KEY_MAX)
return make_result(0, false);
const keymap_entry_t *e = &g_layouts[g_current]->entries[keycode];
if (!e->normal && !e->shift && !e->altgr && !e->shift_altgr)
return make_result(0, false);
bool shift = (mods & KB_MOD_SHIFT) != 0;
bool caps = (mods & KB_MOD_CAPS) != 0;
bool altgr = (mods & KB_MOD_ALTGR) != 0;
uint32_t cp = 0;
uint8_t dead_mask_bit = 0;
if (altgr) {
if (shift) {
cp = e->shift_altgr;
dead_mask_bit = DEAD_SHIFT_ALTGR;
} else {
cp = e->altgr;
dead_mask_bit = DEAD_ALTGR;
}
} else if (e->alpha) {
bool uppercase = shift ^ caps;
cp = uppercase ? e->shift : e->normal;
dead_mask_bit = uppercase ? DEAD_SHIFT : DEAD_NORMAL;
} else {
cp = shift ? e->shift : e->normal;
dead_mask_bit = shift ? DEAD_SHIFT : DEAD_NORMAL;
}
bool is_dead = (e->dead_mask & dead_mask_bit) != 0;
if (is_dead && cp != 0) {
g_active_dead = cp;
return make_result(0, true);
}
if (g_active_dead && cp != 0) {
uint32_t combined = keymap_compose(g_active_dead, cp);
g_active_dead = 0;
if (combined != 0) {
return make_result(combined, false);
}
return make_result(cp, false);
}
return make_result(cp, false);
}
uint32_t keymap_compose(uint32_t dead_codepoint, uint32_t base_codepoint) {
for (int i = 0; g_compose_table[i].dead != 0; i++) {
if (g_compose_table[i].dead == dead_codepoint &&
g_compose_table[i].base == base_codepoint) {
return g_compose_table[i].result;
}
}
return 0;
}
int keymap_legacy_key(uint16_t keycode, uint32_t codepoint) {
if (codepoint != 0 && codepoint < 128) return (int)codepoint;
switch (keycode) {
case KEY_ESC: return 27;
case KEY_BACKSPACE: return '\b';
case KEY_TAB: return '\t';
case KEY_ENTER:
case KEY_KP_ENTER: return '\n';
case KEY_ARROW_UP: return 17;
case KEY_ARROW_DOWN: return 18;
case KEY_ARROW_LEFT: return 19;
case KEY_ARROW_RIGHT: return 20;
case KEY_LEFT_CTRL:
case KEY_RIGHT_CTRL: return 21;
case KEY_LEFT_SHIFT:
case KEY_RIGHT_SHIFT: return 24;
case KEY_LEFT_ALT: return 25;
case KEY_RIGHT_ALT: return 22; // for compat w/ doom
case KEY_CAPS_LOCK: return 23; // same here
case KEY_DELETE: return 127;
case KEY_F1: return 141;
case KEY_F2: return 142;
case KEY_F3: return 143;
case KEY_F4: return 144;
case KEY_F5: return 145;
case KEY_F6: return 146;
case KEY_F7: return 147;
case KEY_F8: return 148;
case KEY_F9: return 149;
case KEY_F10: return 150;
case KEY_F11: return 151;
case KEY_F12: return 152;
default: return 0;
}
}