replace hard coded ADB keycode with nice enums.

There are also a couple fixes in the SDL keymap (home key, {, }, keypad numbers)

xdriver isn't updated because I don't care about x.
win32 driver isn't updated pending other win32 keymap patch.
This commit is contained in:
Kelvin Sherlock 2019-02-17 14:15:13 -05:00
parent a76d26a0ad
commit 86285cc43d
4 changed files with 380 additions and 158 deletions

View File

@ -10,6 +10,9 @@
#include "adb.h"
#include "glog.h"
#include "adb_keycodes.h"
int g_fullscreen = 0;
int g_grabmouse = 0;
@ -1655,34 +1658,48 @@ void adb_physical_key_update(int a2code, int is_up) {
/* Now check for special keys (function keys, etc) */
ascii_and_type = a2_key_to_ascii[a2code][1];
special = 0;
if((ascii_and_type & 0xf000) == 0x8000) {
/* special function key */
/* special FKeys? */
if (ascii_and_type & 0x1000) {
special = ascii_and_type & 0xff;
switch(special) {
case 0x01: /* F1 - remap to cmd */
a2code = 0x37;
switch (special) {
case kVK_F1:
/* F1 - remap to cmd */
a2code = kVK_Command;
special = 0;
break;
case 0x02: /* F2 - remap to option */
a2code = 0x3a;
case kVK_F2:
/* F2 - remap to option */
a2code = kVK_Option;
special = 0;
break;
case 0x0c: /* F12 - remap to reset */
a2code = 0x7f;
case kVK_F12:
/* F12 - remap to reset */
a2code = kVK_Reset;
special = 0;
break;
case kVK_F3:
case kVK_F4:
case kVK_F5:
case kVK_F6:
case kVK_F7:
case kVK_F8:
case kVK_F9:
case kVK_F10:
case kVK_F11:
break;
default:
break;
special = 0;
}
}
/* CUA clipboard paste - for those that remember ctrl-insert/shift-insert */
if(is_up == 0 && a2code == 0x72 && SHIFT_DOWN) {
if(is_up == 0 && a2code == kVK_Insert && SHIFT_DOWN) {
clipboard_paste();
}
/* Only process reset requests here */
if(is_up == 0 && a2code == 0x7f && CTRL_DOWN) {
if(is_up == 0 && a2code == kVK_Reset && CTRL_DOWN) {
/* Reset pressed! */
glogf("Reset pressed since CTRL_DOWN: %d", CTRL_DOWN);
do_reset();
@ -1691,10 +1708,10 @@ void adb_physical_key_update(int a2code, int is_up) {
if(special && !is_up) {
switch(special) {
case 0x03: /* F3 - screenshot */
case kVK_F3: /* F3 - screenshot */
g_screenshot_requested = 1;
break;
case 0x04: /* F4 - emulator config panel */
case kVK_F4: /* F4 - emulator config panel */
if (CMD_DOWN) {
glog("Alt-F4 Quit!");
iwm_shut();
@ -1705,7 +1722,7 @@ void adb_physical_key_update(int a2code, int is_up) {
cfg_toggle_config_panel();
}
break;
case 0x05: /* F5 - emulator clipboard paste */
case kVK_F5: /* F5 - emulator clipboard paste */
if (SHIFT_DOWN) {
g_grabmouse = !g_grabmouse;
#ifdef HAVE_SDL
@ -1717,18 +1734,18 @@ void adb_physical_key_update(int a2code, int is_up) {
clipboard_paste();
}
break;
case 0x06: /* F6 - emulator speed */
case kVK_F6: /* F6 - emulator speed */
if(SHIFT_DOWN) {
halt2_printf("Shift-F6 pressed\n");
} else {
adb_increment_speed();
}
break;
case 0x07: /* F7 - fast disk emul */
case kVK_F7: /* F7 - fast disk emul */
g_fast_disk_emul = !g_fast_disk_emul;
glogf("g_fast_disk_emul is now %d", g_fast_disk_emul);
break;
case 0x08: /* F8 - warp pointer */
case kVK_F8: /* F8 - warp pointer */
g_warp_pointer = !g_warp_pointer;
if(g_hide_pointer != g_warp_pointer) {
g_hide_pointer = g_warp_pointer;
@ -1736,7 +1753,7 @@ void adb_physical_key_update(int a2code, int is_up) {
}
glogf("g_warp_pointer is now %d", g_warp_pointer);
break;
case 0x09: /* F9 - swap paddles */
case kVK_F9: /* F9 - swap paddles */
if(SHIFT_DOWN) {
g_swap_paddles = !g_swap_paddles;
glogf("Swap paddles is now: %d", g_swap_paddles);
@ -1745,7 +1762,7 @@ void adb_physical_key_update(int a2code, int is_up) {
glogf("Invert paddles is now: %d", g_invert_paddles);
}
break;
case 0x0a: /* F10 - change a2vid paletter */
case kVK_F10: /* F10 - change a2vid paletter */
if (SHIFT_DOWN) {
#ifdef TOGGLE_STATUS
extern void x_toggle_status_lines();
@ -1758,7 +1775,7 @@ void adb_physical_key_update(int a2code, int is_up) {
change_a2vid_palette((g_a2vid_palette + 1) & 0xf);
}
break;
case 0x0b: /* F11 - full screen */
case kVK_F11: /* F11 - full screen */
g_fullscreen = !g_fullscreen;
x_full_screen(g_fullscreen);
break;
@ -1780,10 +1797,10 @@ void adb_physical_key_update(int a2code, int is_up) {
/* keypress pass on further, except for cmd/opt */
if(ascii == 0x30) {
/* remap '0' to cmd */
a2code = 0x37;
a2code = kVK_Command;
} else if(ascii == 0x2e || ascii == 0x2c) {
/* remap '.' and ',' to option */
a2code = 0x3a;
a2code = kVK_Option;
} else {
/* Just ignore it in this mode */
return;

View File

@ -79,10 +79,10 @@ const int a2_key_to_ascii[][4] = {
{ 0x3c, 0x15, 0x15, -1 }, /* right */
{ 0x3d, 0x0a, 0x0a, -1 }, /* down */
{ 0x3e, 0x0b, 0x0b, -1 }, /* up arrow */
{ 0x3f, -1, -1, -1 },
{ 0x3f, 0x103f, 0x103f, -1 }, /* function key */
{ 0x40, -1, -1, -1 },
{ 0x41, 0x102e, 0x102c, -1 }, /* keypad . */
{ 0x40, 0x1040, 0x1040, -1 }, /* F17 */
{ 0x41, 0x102e, 0x102e, -1 }, /* keypad . */
{ 0x42, -1, -1, -1 },
{ 0x43, 0x102a, 0x102a, -1 }, /* keypad * */
{ 0x44, -1, -1, -1 },
@ -90,16 +90,16 @@ const int a2_key_to_ascii[][4] = {
{ 0x46, -1, -1, -1 },
{ 0x47, 0x1018, 0x1018, -1 }, /* keypad Clear */
{ 0x48, -1, -1, -1 },
{ 0x49, -1, -1, -1 },
{ 0x4a, -1, -1, -1 },
{ 0x48, 0x1048, 0x1048, -1 }, /* volume up */
{ 0x49, 0x1049, 0x1049, -1 }, /* volume down */
{ 0x4a, 0x104a, 0x104a, -1 }, /* mute */
{ 0x4b, 0x102f, 0x102f, -1 }, /* keypad / */
{ 0x4c, 0x100d, 0x100d, -1 }, /* keypad enter */
{ 0x4d, -1, -1, -1 },
{ 0x4e, 0x102d, 0x102d, -1 }, /* keypad - */
{ 0x4f, -1, -1, -1 },
{ 0x4f, 0x104f, 0x104f, -1 }, /* F18 */
{ 0x50, -1, -1, -1 },
{ 0x50, 0x1050, 0x1050, -1 }, /* F19 */
{ 0x51, 0x103d, 0x103d, -1 }, /* keypad = */
{ 0x52, 0x1030, 0x1030, -1 }, /* keypad 0 */
{ 0x53, 0x1031, 0x1031, -1 }, /* keypad 1 */
@ -110,48 +110,46 @@ const int a2_key_to_ascii[][4] = {
{ 0x58, 0x1036, 0x1036, -1 }, /* keypad 6 */
{ 0x59, 0x1037, 0x1037, -1 }, /* keypad 7 */
{ 0x5a, 'a', 'A', 0x01 }, /* probably not necessary */
{ 0x5a, 0x105a, 0x105a, -1 }, /* F20 */
{ 0x5b, 0x1038, 0x1038, -1 }, /* keypad 8 */
{ 0x5c, 0x1039, 0x1039, -1 }, /* keypad 9 */
{ 0x5d, -1, -1, -1 },
{ 0x5e, -1, -1, -1 },
{ 0x5f, -1, -1, -1 },
{ 0x60, 0x8005, 0x1060, -1 }, /* F5 */
{ 0x61, 0x8006, 0x1061, -1 }, /* F6 */
{ 0x62, 0x8007, 0x1062, -1 }, /* F7 */
{ 0x63, 0x8003, 0x1063, -1 }, /* F3 */
{ 0x64, 0x8008, 0x1064, -1 }, /* F8 */
{ 0x65, 0x8009, 0x1065, -1 }, /* F9 */
{ 0x60, 0x1060, 0x1060, -1 }, /* F5 */
{ 0x61, 0x1061, 0x1061, -1 }, /* F6 */
{ 0x62, 0x1062, 0x1062, -1 }, /* F7 */
{ 0x63, 0x1063, 0x1063, -1 }, /* F3 */
{ 0x64, 0x1064, 0x1064, -1 }, /* F8 */
{ 0x65, 0x1065, 0x1065, -1 }, /* F9 */
{ 0x66, -1, -1, -1 },
{ 0x67, 0x800b, 0x1067, -1 }, /* F11 */
{ 0x67, 0x1067, 0x1067, -1 }, /* F11 */
{ 0x68, -1, -1, -1 },
// { 0x69, 0x800d, 0x1069, -1 }, /* F13 */
// OG remap F13 to reset
{ 0x69, 0x800c, 0x1069, -1 }, /* F13 */
{ 0x6a, -1, -1, -1 },
{ 0x6b, 0x800e, 0x106b, -1 }, /* F14 */
{ 0x69, 0x1069, 0x1069, -1 }, /* F13 */
{ 0x6a, 0x106a, 0x106a, -1 }, /* F16 */
{ 0x6b, 0x106b, 0x106b, -1 }, /* F14 */
{ 0x6c, -1, -1, -1 },
{ 0x6d, 0x800a, 0x106d, -1 }, /* F10 */
{ 0x6e, 0x4000, 0x4000, -1 }, /* windows key alias to option */
{ 0x6f, 0x800c, 0x106f, -1 }, /* F12 */
{ 0x6d, 0x106d, 0x106d, -1 }, /* F10 */
{ 0x6e, -1, -1, -1 },
{ 0x6f, 0x106f, 0x106f, -1 }, /* F12 */
{ 0x70, -1, -1, -1 },
{ 0x71, 0x800f, 0x1071, -1 }, /* F15 */
{ 0x71, 0x1071, 0x1071, -1 }, /* F15 */
{ 0x72, 0x1072, 0x1072, -1 }, /* Help, insert */
{ 0x73, 0x1073, 0x1073, -1 }, /* Home */
{ 0x74, 0x1074, 0x1074, -1 }, /* Page up */
{ 0x75, 0x1075, 0x1075, -1 }, /* keypad delete */
{ 0x76, 0x8004, 0x1076, -1 }, /* F4 */
{ 0x76, 0x1076, 0x1076, -1 }, /* F4 */
{ 0x77, 0x1077, 0x1077, -1 }, /* keypad end */
{ 0x78, 0x8002, 0x1078, -1 }, /* F2 */
{ 0x78, 0x1078, 0x1078, -1 }, /* F2 */
{ 0x79, 0x1079, 0x1079, -1 }, /* keypad page down */
{ 0x7a, 0x8001, 0x107a, -1 }, /* F1 */
{ 0x7b, 0x08, 0x08, -1 }, /* left */ /* remapped to 0x3b */
{ 0x7c, 0x15, 0x15, -1 }, /* right */ /* remapped to 0x3c */
{ 0x7d, 0x0a, 0x0a, -1 }, /* down */ /* remapped to 0x3d */
{ 0x7e, 0x0b, 0x0b, -1 }, /* up arrow */ /* remapped to 0x3e */
{ 0x7a, 0x107a, 0x107a, -1 }, /* F1 */
{ 0x7b, 0x0100, 0x0100, -1 }, /* right shift */
{ 0x7c, 0x4000, 0x4000, -1 }, /* right option */
{ 0x7d, 0x0200, 0x0200, -1 }, /* right control */
{ 0x7e, -1, -1, -1 },
{ 0x7f, -1, -1, -1 }, /* Reset */
};

189
src/adb_keycodes.h Normal file
View File

@ -0,0 +1,189 @@
#ifndef adb_keycodes_h
#define adb_keycodes_h
/* Taken from <Carbon/Event.h> */
/*
* Summary:
* Virtual keycodes
*
* Discussion:
* These constants are the virtual keycodes defined originally in
* Inside Mac Volume V, pg. V-191. They identify physical keys on a
* keyboard. Those constants with "ANSI" in the name are labeled
* according to the key position on an ANSI-standard US keyboard.
* For example, kVK_ANSI_A indicates the virtual keycode for the key
* with the letter 'A' in the US keyboard layout. Other keyboard
* layouts may have the 'A' key label on a different physical key;
* in this case, pressing 'A' will generate a different virtual
* keycode.
*/
enum {
kVK_ANSI_A = 0x00,
kVK_ANSI_S = 0x01,
kVK_ANSI_D = 0x02,
kVK_ANSI_F = 0x03,
kVK_ANSI_H = 0x04,
kVK_ANSI_G = 0x05,
kVK_ANSI_Z = 0x06,
kVK_ANSI_X = 0x07,
kVK_ANSI_C = 0x08,
kVK_ANSI_V = 0x09,
kVK_ANSI_B = 0x0B,
kVK_ANSI_Q = 0x0C,
kVK_ANSI_W = 0x0D,
kVK_ANSI_E = 0x0E,
kVK_ANSI_R = 0x0F,
kVK_ANSI_Y = 0x10,
kVK_ANSI_T = 0x11,
kVK_ANSI_1 = 0x12,
kVK_ANSI_2 = 0x13,
kVK_ANSI_3 = 0x14,
kVK_ANSI_4 = 0x15,
kVK_ANSI_6 = 0x16,
kVK_ANSI_5 = 0x17,
kVK_ANSI_Equal = 0x18,
kVK_ANSI_9 = 0x19,
kVK_ANSI_7 = 0x1A,
kVK_ANSI_Minus = 0x1B,
kVK_ANSI_8 = 0x1C,
kVK_ANSI_0 = 0x1D,
kVK_ANSI_RightBracket = 0x1E,
kVK_ANSI_O = 0x1F,
kVK_ANSI_U = 0x20,
kVK_ANSI_LeftBracket = 0x21,
kVK_ANSI_I = 0x22,
kVK_ANSI_P = 0x23,
kVK_ANSI_L = 0x25,
kVK_ANSI_J = 0x26,
kVK_ANSI_Quote = 0x27,
kVK_ANSI_K = 0x28,
kVK_ANSI_Semicolon = 0x29,
kVK_ANSI_Backslash = 0x2A,
kVK_ANSI_Comma = 0x2B,
kVK_ANSI_Slash = 0x2C,
kVK_ANSI_N = 0x2D,
kVK_ANSI_M = 0x2E,
kVK_ANSI_Period = 0x2F,
kVK_ANSI_Grave = 0x32,
kVK_ANSI_KeypadDecimal = 0x41,
kVK_ANSI_KeypadMultiply = 0x43,
kVK_ANSI_KeypadPlus = 0x45,
kVK_ANSI_KeypadClear = 0x47,
kVK_ANSI_KeypadDivide = 0x4B,
kVK_ANSI_KeypadEnter = 0x4C,
kVK_ANSI_KeypadMinus = 0x4E,
kVK_ANSI_KeypadEquals = 0x51,
kVK_ANSI_Keypad0 = 0x52,
kVK_ANSI_Keypad1 = 0x53,
kVK_ANSI_Keypad2 = 0x54,
kVK_ANSI_Keypad3 = 0x55,
kVK_ANSI_Keypad4 = 0x56,
kVK_ANSI_Keypad5 = 0x57,
kVK_ANSI_Keypad6 = 0x58,
kVK_ANSI_Keypad7 = 0x59,
kVK_ANSI_Keypad8 = 0x5B,
kVK_ANSI_Keypad9 = 0x5C
};
/* keycodes for keys that are independent of keyboard layout*/
enum {
kVK_Return = 0x24,
kVK_Tab = 0x30,
kVK_Space = 0x31,
kVK_Delete = 0x33,
kVK_Escape = 0x35,
kVK_Control = 0x36,
kVK_Command = 0x37,
kVK_Shift = 0x38,
kVK_CapsLock = 0x39,
kVK_Option = 0x3A,
kVK_LeftArrow = 0x3B,
kVK_RightArrow = 0x3C,
kVK_DownArrow = 0x3D,
kVK_UpArrow = 0x3E,
kVK_Function = 0x3F,
kVK_F17 = 0x40,
kVK_VolumeUp = 0x48,
kVK_VolumeDown = 0x49,
kVK_Mute = 0x4A,
kVK_F18 = 0x4F,
kVK_F19 = 0x50,
kVK_F20 = 0x5A,
kVK_F5 = 0x60,
kVK_F6 = 0x61,
kVK_F7 = 0x62,
kVK_F3 = 0x63,
kVK_F8 = 0x64,
kVK_F9 = 0x65,
kVK_F11 = 0x67,
kVK_F13 = 0x69,
kVK_F16 = 0x6A,
kVK_F14 = 0x6B,
kVK_F10 = 0x6D,
kVK_F12 = 0x6F,
kVK_F15 = 0x71,
kVK_Help = 0x72,
kVK_Home = 0x73,
kVK_PageUp = 0x74,
kVK_ForwardDelete = 0x75,
kVK_F4 = 0x76,
kVK_End = 0x77,
kVK_F2 = 0x78,
kVK_PageDown = 0x79,
kVK_F1 = 0x7A,
kVK_Reset = 0x7F, /* actually 7F7F */
kVK_Insert = kVK_Help,
#if 0
kVK_RightCommand = 0x37,
kVK_RightShift = 0x7B,
kVK_RightOption = 0x7C,
kVK_RightControl = 0x7D,
#else
kVK_RightCommand = kVK_Command,
kVK_RightShift = kVK_Shift,
kVK_RightOption = kVK_Option,
kVK_RightControl = kVK_Control,
#endif
#if 0
/* Mac OS used a KMAP resource to remap ADB codes:
* Control 36 -> 3B
* Left Arrow 3B -> 7B
* Right Arrow 3C -> 7C
* Down Arrow 3D -> 7D
* Up Arrow 3E -> 7E
* Right Shift 7B* -> 3C
* Right Option 7C* -> 3D
* Right Control 7D* -> 3E
*
* Right shift/option/control only generate unique codes
* when device handler ID in keyboard register 3 has a
* value of $3 (as opposed to $2).
*
* See Guide to the Macintosh Family Hardware, ch 8, page 306-310
*
* KMAP also maps $7e to $36 ... ?
*
*/
kVK_RightCommand = 0x36,
kVK_RightShift = 0x3C,
kVK_RightOption = 0x3D,
kVK_RightControl = 0x3E,
kVK_LeftArrow = 0x7B,
kVK_RightArrow = 0x7C,
kVK_DownArrow = 0x7D,
kVK_UpArrow = 0x7E,
#endif
};
#endif

View File

@ -31,6 +31,8 @@ unsigned int lastTime = 0, currentTime, frames;
#define ControlMask 4
#define LockMask 2
#include "adb_keycodes.h"
int g_use_shmem = 0;
int g_num_check_input_calls = 0;
@ -95,112 +97,128 @@ void handle_sdl_mouse_event(SDL_Event event);
int g_num_a2_keycodes = 0;
int a2_key_to_sdlkeycode[][3] = {
{ 0x35, SDLK_ESCAPE, 0 },
{ 0x7a, SDLK_F1, 0 },
{ 0x78, SDLK_F2, 0 },
{ 0x63, SDLK_F3, 0 },
{ 0x76, SDLK_F4, 0 },
{ 0x60, SDLK_F5, 0 },
{ 0x61, SDLK_F6, 0 },
{ 0x62, SDLK_F7, 0 },
{ 0x64, SDLK_F8, 0 },
{ 0x65, SDLK_F9, 0 },
{ 0x6d, SDLK_F10, 0 },
{ 0x67, SDLK_F11, 0 },
{ 0x6f, SDLK_F12, 0 },
{ 0x69, SDLK_F13, 0 },
{ 0x6b, SDLK_F14, 0 },
{ 0x71, SDLK_F15, 0 },
{ 0x7f, SDLK_PAUSE, 0 },
{ 0x32, SDLK_BACKQUOTE, '~' }, /* Key number 18? */
{ 0x12, SDLK_1, '!' },
{ 0x13, SDLK_2, '@' },
{ 0x14, SDLK_3, '#' },
{ 0x15, SDLK_4, '$' },
{ 0x17, SDLK_5, '%' },
{ 0x16, SDLK_6, '^' },
{ 0x1a, SDLK_7, '&' },
{ 0x1c, SDLK_8, '*' },
{ 0x19, SDLK_9, '(' },
{ 0x1d, SDLK_0, ')' },
{ 0x1b, SDLK_MINUS, SDLK_UNDERSCORE },
{ 0x18, SDLK_EQUALS, SDLK_PLUS },
{ 0x33, SDLK_BACKSPACE, 0 },
{ 0x72, SDLK_INSERT, 0 }, /* Help? XK_Help */
/* { 0x73, XK_Home, 0 }, alias XK_Home to be XK_KP_Equal! */
{ 0x74, SDLK_PAGEUP, 0 },
{ 0x47, SDLK_NUMLOCKCLEAR, 0 }, /* Clear, XK_Clear */
{ 0x51, SDLK_KP_EQUALS, 0 }, /* Note XK_Home alias! XK_Home */
{ 0x4b, SDLK_KP_DIVIDE, 0 },
{ 0x43, SDLK_KP_MULTIPLY, 0 },
{ 0x30, SDLK_TAB, 0 },
{ 0x0c, SDLK_q, 'Q' },
{ 0x0d, SDLK_w, 'W' },
{ 0x0e, SDLK_e, 'E' },
{ 0x0f, SDLK_r, 'R' },
{ 0x11, SDLK_t, 'T' },
{ 0x10, SDLK_y, 'Y' },
{ 0x20, SDLK_u, 'U' },
{ 0x22, SDLK_i, 'I' },
{ 0x1f, SDLK_o, 'O' },
{ 0x23, SDLK_p, 'P' },
{ 0x21, SDLK_RIGHTBRACKET, '{' },
{ 0x1e, SDLK_LEFTBRACKET, '}' },
{ 0x2a, SDLK_BACKSLASH, '|' }, /* backslash, bar */
{ 0x75, SDLK_DELETE, 0 },
{ 0x77, SDLK_END, 0 },
{ 0x79, SDLK_PAGEDOWN, 0 },
{ 0x59, SDLK_KP_7, SDLK_HOME },
{ 0x5b, SDLK_KP_8, SDLK_UP },
{ 0x5c, SDLK_KP_9, SDLK_PAGEUP },
{ 0x4e, SDLK_KP_MINUS, 0 },
{ 0x39, SDLK_CAPSLOCK, 0 },
{ 0x00, SDLK_a, 'A' },
{ 0x01, SDLK_s, 'S' },
{ 0x02, SDLK_d, 'D' },
{ 0x03, SDLK_f, 'F' },
{ 0x05, SDLK_g, 'G' },
{ 0x04, SDLK_h, 'H' },
{ 0x26, SDLK_j, 'J' },
{ 0x28, SDLK_k, 'K' },
{ 0x25, SDLK_l, 'L' },
{ 0x29, SDLK_SEMICOLON, SDLK_COLON },
{ 0x27, SDLK_QUOTE, SDLK_QUOTEDBL },
{ 0x24, SDLK_RETURN, 0 },
{ 0x56, SDLK_KP_4, SDLK_LEFT},
{ 0x57, SDLK_KP_5, 0 },
{ 0x58, SDLK_KP_6, SDLK_RIGHT },
{ 0x45, SDLK_KP_PLUS, 0 },
{ 0x38, SDLK_LSHIFT, SDLK_RSHIFT },
{ 0x06, SDLK_z, 'Z' },
{ 0x07, SDLK_x, 'X' },
{ 0x08, SDLK_c, 'C' },
{ 0x09, SDLK_v, 'V' },
{ 0x0b, SDLK_b, 'B' },
{ 0x2d, SDLK_n, 'N' },
{ 0x2e, SDLK_m, 'M' },
{ 0x2b, SDLK_COMMA, SDLK_LESS },
{ 0x2f, SDLK_PERIOD, SDLK_GREATER },
{ 0x2c, SDLK_SLASH, SDLK_QUESTION },
{ 0x3e, SDLK_UP, 0 },
{ 0x53, SDLK_KP_1, 0 },
{ 0x54, SDLK_KP_2, SDLK_DOWN },
{ 0x55, SDLK_KP_3, SDLK_PAGEDOWN },
{ 0x36, SDLK_RCTRL, SDLK_LCTRL },
{ kVK_Escape, SDLK_ESCAPE, 0 },
{ kVK_F1, SDLK_F1, 0 },
{ kVK_F2, SDLK_F2, 0 },
{ kVK_F3, SDLK_F3, 0 },
{ kVK_F4, SDLK_F4, 0 },
{ kVK_F5, SDLK_F5, 0 },
{ kVK_F6, SDLK_F6, 0 },
{ kVK_F7, SDLK_F7, 0 },
{ kVK_F8, SDLK_F8, 0 },
{ kVK_F9, SDLK_F9, 0 },
{ kVK_F10, SDLK_F10, 0 },
{ kVK_F11, SDLK_F11, 0 },
{ kVK_F12, SDLK_F12, 0 },
{ kVK_F13, SDLK_F13, 0 },
{ kVK_F14, SDLK_F14, 0 },
{ kVK_F15, SDLK_F15, 0 },
{ kVK_F16, SDLK_F16, 0 },
{ kVK_F17, SDLK_F17, 0 },
{ kVK_F18, SDLK_F18, 0 },
{ kVK_F19, SDLK_F19, 0 },
{ kVK_F20, SDLK_F20, 0 },
{ kVK_Reset, SDLK_PAUSE, 0 },
{ kVK_ANSI_Grave, SDLK_BACKQUOTE, '~' },
{ kVK_ANSI_1, SDLK_1, '!' },
{ kVK_ANSI_2, SDLK_2, '@' },
{ kVK_ANSI_3, SDLK_3, '#' },
{ kVK_ANSI_4, SDLK_4, '$' },
{ kVK_ANSI_5, SDLK_5, '%' },
{ kVK_ANSI_6, SDLK_6, '^' },
{ kVK_ANSI_7, SDLK_7, '&' },
{ kVK_ANSI_8, SDLK_8, '*' },
{ kVK_ANSI_9, SDLK_9, '(' },
{ kVK_ANSI_0, SDLK_0, ')' },
{ kVK_ANSI_Minus, SDLK_MINUS, SDLK_UNDERSCORE },
{ kVK_ANSI_Equal, SDLK_EQUALS, SDLK_PLUS },
{ kVK_Delete, SDLK_BACKSPACE, 0 },
{ kVK_Help, SDLK_INSERT, 0 }, /* Help? XK_Help */
{ kVK_Home, SDLK_HOME, 0 },
{ kVK_PageUp, SDLK_PAGEUP, 0 },
{ kVK_Tab, SDLK_TAB, 0 },
{ kVK_ANSI_Q, SDLK_q, 'Q' },
{ kVK_ANSI_W, SDLK_w, 'W' },
{ kVK_ANSI_E, SDLK_e, 'E' },
{ kVK_ANSI_R, SDLK_r, 'R' },
{ kVK_ANSI_T, SDLK_t, 'T' },
{ kVK_ANSI_Y, SDLK_y, 'Y' },
{ kVK_ANSI_U, SDLK_u, 'U' },
{ kVK_ANSI_I, SDLK_i, 'I' },
{ kVK_ANSI_O, SDLK_o, 'O' },
{ kVK_ANSI_P, SDLK_p, 'P' },
{ kVK_ANSI_LeftBracket, SDLK_LEFTBRACKET, '{' },
{ kVK_ANSI_RightBracket, SDLK_RIGHTBRACKET, '}' },
{ kVK_ANSI_Backslash, SDLK_BACKSLASH, '|' }, /* backslash, bar */
{ kVK_ForwardDelete, SDLK_DELETE, 0 },
{ kVK_End, SDLK_END, 0 },
{ kVK_PageDown, SDLK_PAGEDOWN, 0 },
{ kVK_ANSI_A, SDLK_a, 'A' },
{ kVK_ANSI_S, SDLK_s, 'S' },
{ kVK_ANSI_D, SDLK_d, 'D' },
{ kVK_ANSI_F, SDLK_f, 'F' },
{ kVK_ANSI_G, SDLK_g, 'G' },
{ kVK_ANSI_H, SDLK_h, 'H' },
{ kVK_ANSI_J, SDLK_j, 'J' },
{ kVK_ANSI_K, SDLK_k, 'K' },
{ kVK_ANSI_L, SDLK_l, 'L' },
{ kVK_ANSI_Semicolon, SDLK_SEMICOLON, SDLK_COLON },
{ kVK_ANSI_Quote, SDLK_QUOTE, SDLK_QUOTEDBL },
{ kVK_Return, SDLK_RETURN, 0 },
{ kVK_Shift, SDLK_LSHIFT, 0 },
{ kVK_RightShift, SDLK_RSHIFT, 0 },
{ kVK_ANSI_Z, SDLK_z, 'Z' },
{ kVK_ANSI_X, SDLK_x, 'X' },
{ kVK_ANSI_C, SDLK_c, 'C' },
{ kVK_ANSI_V, SDLK_v, 'V' },
{ kVK_ANSI_B, SDLK_b, 'B' },
{ kVK_ANSI_N, SDLK_n, 'N' },
{ kVK_ANSI_M, SDLK_m, 'M' },
{ kVK_ANSI_Comma, SDLK_COMMA, SDLK_LESS },
{ kVK_ANSI_Period, SDLK_PERIOD, SDLK_GREATER },
{ kVK_ANSI_Slash, SDLK_SLASH, SDLK_QUESTION },
{ kVK_CapsLock, SDLK_CAPSLOCK, 0 },
{ kVK_Control, SDLK_LCTRL, 0 },
{ kVK_RightControl, SDLK_RCTRL, 0 },
#if defined(__APPLE__)
{ 0x3a, SDLK_LALT, SDLK_RALT }, /* Option */
{ 0x37, SDLK_LGUI, SDLK_RGUI }, /* Command */
{ kVK_Option, SDLK_LALT, 0 }, /* Option */
{ kVK_RightOption, SDLK_RALT, 0 }, /* Option */
{ kVK_Command, SDLK_LGUI, 0 }, /* Command */
{ kVK_RightCommand, SDLK_RGUI, 0 }, /* Command */
#else
{ 0x3a, SDLK_LGUI, SDLK_RGUI }, /* Command */
{ 0x37, SDLK_LALT, SDLK_RALT }, /* Option */
{ kVK_Option, SDLK_LGUI, 0 }, /* Command */
{ kVK_RightOption, SDLK_RGUI, 0 }, /* Command */
{ kVK_Command, SDLK_LALT, 0 }, /* Option */
{ kVK_RightCommand, SDLK_RALT, 0 }, /* Option */
#endif
{ 0x31, SDLK_SPACE, 0 },
{ 0x3b, SDLK_LEFT, 0 },
{ 0x3d, SDLK_DOWN, 0 },
{ 0x3c, SDLK_RIGHT, 0 },
{ 0x52, SDLK_KP_0, 0 },
{ 0x41, SDLK_KP_PERIOD, 0 },
{ 0x4c, SDLK_KP_ENTER, 0 },
{ kVK_Space, SDLK_SPACE, 0 },
{ kVK_LeftArrow, SDLK_LEFT, 0 },
{ kVK_DownArrow, SDLK_DOWN, 0 },
{ kVK_RightArrow, SDLK_RIGHT, 0 },
{ kVK_UpArrow, SDLK_UP, 0 },
{ kVK_ANSI_Keypad0, SDLK_KP_0, 0 },
{ kVK_ANSI_Keypad1, SDLK_KP_1, 0 },
{ kVK_ANSI_Keypad2, SDLK_KP_2, 0 },
{ kVK_ANSI_Keypad3, SDLK_KP_3, 0 },
{ kVK_ANSI_Keypad4, SDLK_KP_4, 0 },
{ kVK_ANSI_Keypad5, SDLK_KP_5, 0 },
{ kVK_ANSI_Keypad6, SDLK_KP_6, 0 },
{ kVK_ANSI_Keypad7, SDLK_KP_7, 0 },
{ kVK_ANSI_Keypad8, SDLK_KP_8, 0 },
{ kVK_ANSI_Keypad9, SDLK_KP_9, 0 },
{ kVK_ANSI_KeypadMinus, SDLK_KP_MINUS, 0 },
{ kVK_ANSI_KeypadPlus, SDLK_KP_PLUS, 0 },
{ kVK_ANSI_KeypadEquals, SDLK_KP_EQUALS, 0 }, /* Note XK_Home alias! XK_Home */
{ kVK_ANSI_KeypadDivide, SDLK_KP_DIVIDE, 0 },
{ kVK_ANSI_KeypadMultiply,SDLK_KP_MULTIPLY, 0 },
{ kVK_ANSI_KeypadDecimal, SDLK_KP_PERIOD, 0 },
{ kVK_ANSI_KeypadEnter, SDLK_KP_ENTER, 0 },
{ kVK_ANSI_KeypadClear, SDLK_NUMLOCKCLEAR, 0 }, /* Clear, XK_Clear */
{ -1, -1, -1 }
};