Add event bindings.
authorDavid Thompson <dthompson2@worcester.edu>
Wed, 16 Dec 2015 17:38:38 +0000 (12:38 -0500)
committerDavid Thompson <dthompson2@worcester.edu>
Wed, 16 Dec 2015 17:48:39 +0000 (12:48 -0500)
So far, only window and keyboard events are handled.  More to come in
future patches.

This patch adds a *ton* of constants that I'm not going to mention in
this log because it would be too damn long.

* sdl2/bindings.scm (sdl-poll-event): New procedure.
* sdl2/events.scm: New file.
* Makefile.am (SOURCES): Add it.

Makefile.am
sdl2/bindings.scm
sdl2/events.scm [new file with mode: 0644]

index 543b734..80512fc 100644 (file)
@@ -46,7 +46,8 @@ SOURCES =                                     \
   sdl2/bindings.scm                            \
   sdl2/surface.scm                             \
   sdl2/render.scm                              \
-  sdl2/video.scm
+  sdl2/video.scm                               \
+  sdl2/events.scm
 
 EXTRA_DIST +=                                  \
   pre-inst-env.in                              \
index 64e4313..9bf7913 100644 (file)
@@ -223,6 +223,590 @@ RETURN-TYPE and accept arguments of ARG-TYPES."
 
 \f
 ;;;
+;;; Events
+;;;
+
+(define-public SDL_QUIT #x100)
+(define-public SDL_APP_TERMINATING #x101)
+(define-public SDL_APP_LOWMEMORY #x102)
+(define-public SDL_APP_WILLENTERBACKGROUND #x103)
+(define-public SDL_APP_DIDENTERBACKGROUND #x104)
+(define-public SDL_APP_WILLENTERFOREGROUND #x105)
+(define-public SDL_APP_DIDENTERFOREGROUND #x106)
+(define-public SDL_WINDOWEVENT #x200)
+(define-public SDL_SYSWMEVENT #x201)
+(define-public SDL_KEYDOWN #x300)
+(define-public SDL_KEYUP #x301)
+(define-public SDL_TEXTEDITING #x302)
+(define-public SDL_TEXTINPUT #x303)
+(define-public SDL_MOUSEMOTION #x400)
+(define-public SDL_MOUSEBUTTONDOWN #x401)
+(define-public SDL_MOUSEBUTTONUP #x402)
+(define-public SDL_MOUSEWHEEL #x403)
+(define-public SDL_JOYAXISMOTION #x600)
+(define-public SDL_JOYBALLMOTION #x601)
+(define-public SDL_JOYHATMOTION #x602)
+(define-public SDL_JOYBUTTONDOWN #x603)
+(define-public SDL_JOYBUTTONUP #x604)
+(define-public SDL_JOYDEVICEADDED #x605)
+(define-public SDL_JOYDEVICEREMOVED #x606)
+(define-public SDL_CONTROLLERAXISMOTION #x650)
+(define-public SDL_CONTROLLERBUTTONDOWN #x651)
+(define-public SDL_CONTROLLERBUTTONUP #x652)
+(define-public SDL_CONTROLLERDEVICEADDED #x653)
+(define-public SDL_CONTROLLERDEVICEREMOVED #x654)
+(define-public SDL_CONTROLLERDEVICEREMAPPED #x655)
+(define-public SDL_FINGERDOWN #x700)
+(define-public SDL_FINGERUP #x701)
+(define-public SDL_FINGERMOTION #x702)
+(define-public SDL_DOLLARGESTURE #x800)
+(define-public SDL_DOLLARRECORD #x801)
+(define-public SDL_MULTIGESTURE #x802)
+(define-public SDL_CLIPBOARDUPDATE #x900)
+(define-public SDL_DROPFILE #x1000)
+(define-public SDL_RENDER_TARGETS_RESET #x2000)
+(define-public SDL_USEREVENT #x8000)
+
+(define-public SDL_RELEASED 0)
+(define-public SDL_PRESSED  1)
+
+(define-public SDL_WINDOWEVENT_NONE         0)
+(define-public SDL_WINDOWEVENT_SHOWN        1)
+(define-public SDL_WINDOWEVENT_HIDDEN       2)
+(define-public SDL_WINDOWEVENT_EXPOSED      3)
+(define-public SDL_WINDOWEVENT_MOVED        4)
+(define-public SDL_WINDOWEVENT_RESIZED      5)
+(define-public SDL_WINDOWEVENT_SIZE_CHANGED 6)
+(define-public SDL_WINDOWEVENT_MINIMIZED    7)
+(define-public SDL_WINDOWEVENT_MAXIMIZED    8)
+(define-public SDL_WINDOWEVENT_RESTORED     9)
+(define-public SDL_WINDOWEVENT_ENTER        10)
+(define-public SDL_WINDOWEVENT_LEAVE        11)
+(define-public SDL_WINDOWEVENT_FOCUS_GAINED 12)
+(define-public SDL_WINDOWEVENT_FOCUS_LOST   13)
+(define-public SDL_WINDOWEVENT_CLOSE        14)
+
+(define-foreign sdl-poll-event
+  int "SDL_PollEvent" '(*))
+
+\f
+;;;
+;;; Keycodes and scancodes
+;;;
+
+(define-public KMOD_NONE #x0000)
+(define-public KMOD_LSHIFT #x0001)
+(define-public KMOD_RSHIFT #x0002)
+(define-public KMOD_LCTRL #x0040)
+(define-public KMOD_RCTRL #x0080)
+(define-public KMOD_LALT #x0100)
+(define-public KMOD_RALT #x0200)
+(define-public KMOD_LGUI #x0400)
+(define-public KMOD_RGUI #x0800)
+(define-public KMOD_NUM #x1000)
+(define-public KMOD_CAPS #x2000)
+(define-public KMOD_MODE #x4000)
+
+(define-public SDLK_SCANCODE_MASK (ash 1 30))
+
+(define-public (scancode->keycode scancode)
+  (logior scancode SDLK_SCANCODE_MASK))
+
+(define-public SDL_SCANCODE_UNKNOWN 0)
+(define-public SDL_SCANCODE_A 4)
+(define-public SDL_SCANCODE_B 5)
+(define-public SDL_SCANCODE_C 6)
+(define-public SDL_SCANCODE_D 7)
+(define-public SDL_SCANCODE_E 8)
+(define-public SDL_SCANCODE_F 9)
+(define-public SDL_SCANCODE_G 10)
+(define-public SDL_SCANCODE_H 11)
+(define-public SDL_SCANCODE_I 12)
+(define-public SDL_SCANCODE_J 13)
+(define-public SDL_SCANCODE_K 14)
+(define-public SDL_SCANCODE_L 15)
+(define-public SDL_SCANCODE_M 16)
+(define-public SDL_SCANCODE_N 17)
+(define-public SDL_SCANCODE_O 18)
+(define-public SDL_SCANCODE_P 19)
+(define-public SDL_SCANCODE_Q 20)
+(define-public SDL_SCANCODE_R 21)
+(define-public SDL_SCANCODE_S 22)
+(define-public SDL_SCANCODE_T 23)
+(define-public SDL_SCANCODE_U 24)
+(define-public SDL_SCANCODE_V 25)
+(define-public SDL_SCANCODE_W 26)
+(define-public SDL_SCANCODE_X 27)
+(define-public SDL_SCANCODE_Y 28)
+(define-public SDL_SCANCODE_Z 29)
+(define-public SDL_SCANCODE_1 30)
+(define-public SDL_SCANCODE_2 31)
+(define-public SDL_SCANCODE_3 32)
+(define-public SDL_SCANCODE_4 33)
+(define-public SDL_SCANCODE_5 34)
+(define-public SDL_SCANCODE_6 35)
+(define-public SDL_SCANCODE_7 36)
+(define-public SDL_SCANCODE_8 37)
+(define-public SDL_SCANCODE_9 38)
+(define-public SDL_SCANCODE_0 39)
+(define-public SDL_SCANCODE_RETURN 40)
+(define-public SDL_SCANCODE_ESCAPE 41)
+(define-public SDL_SCANCODE_BACKSPACE 42)
+(define-public SDL_SCANCODE_TAB 43)
+(define-public SDL_SCANCODE_SPACE 44)
+(define-public SDL_SCANCODE_MINUS 45)
+(define-public SDL_SCANCODE_EQUALS 46)
+(define-public SDL_SCANCODE_LEFTBRACKET 47)
+(define-public SDL_SCANCODE_RIGHTBRACKET 48)
+(define-public SDL_SCANCODE_BACKSLASH 49)
+(define-public SDL_SCANCODE_NONUSHASH 50)
+(define-public SDL_SCANCODE_SEMICOLON 51)
+(define-public SDL_SCANCODE_APOSTROPHE 52)
+(define-public SDL_SCANCODE_GRAVE 53)
+(define-public SDL_SCANCODE_COMMA 54)
+(define-public SDL_SCANCODE_PERIOD 55)
+(define-public SDL_SCANCODE_SLASH 56)
+(define-public SDL_SCANCODE_CAPSLOCK 57)
+(define-public SDL_SCANCODE_F1 58)
+(define-public SDL_SCANCODE_F2 59)
+(define-public SDL_SCANCODE_F3 60)
+(define-public SDL_SCANCODE_F4 61)
+(define-public SDL_SCANCODE_F5 62)
+(define-public SDL_SCANCODE_F6 63)
+(define-public SDL_SCANCODE_F7 64)
+(define-public SDL_SCANCODE_F8 65)
+(define-public SDL_SCANCODE_F9 66)
+(define-public SDL_SCANCODE_F10 67)
+(define-public SDL_SCANCODE_F11 68)
+(define-public SDL_SCANCODE_F12 69)
+(define-public SDL_SCANCODE_PRINTSCREEN 70)
+(define-public SDL_SCANCODE_SCROLLLOCK 71)
+(define-public SDL_SCANCODE_PAUSE 72)
+(define-public SDL_SCANCODE_INSERT 73)
+(define-public SDL_SCANCODE_HOME 74)
+(define-public SDL_SCANCODE_PAGEUP 75)
+(define-public SDL_SCANCODE_DELETE 76)
+(define-public SDL_SCANCODE_END 77)
+(define-public SDL_SCANCODE_PAGEDOWN 78)
+(define-public SDL_SCANCODE_RIGHT 79)
+(define-public SDL_SCANCODE_LEFT 80)
+(define-public SDL_SCANCODE_DOWN 81)
+(define-public SDL_SCANCODE_UP 82)
+(define-public SDL_SCANCODE_NUMLOCKCLEAR 83)
+(define-public SDL_SCANCODE_KP_DIVIDE 84)
+(define-public SDL_SCANCODE_KP_MULTIPLY 85)
+(define-public SDL_SCANCODE_KP_MINUS 86)
+(define-public SDL_SCANCODE_KP_PLUS 87)
+(define-public SDL_SCANCODE_KP_ENTER 88)
+(define-public SDL_SCANCODE_KP_1 89)
+(define-public SDL_SCANCODE_KP_2 90)
+(define-public SDL_SCANCODE_KP_3 91)
+(define-public SDL_SCANCODE_KP_4 92)
+(define-public SDL_SCANCODE_KP_5 93)
+(define-public SDL_SCANCODE_KP_6 94)
+(define-public SDL_SCANCODE_KP_7 95)
+(define-public SDL_SCANCODE_KP_8 96)
+(define-public SDL_SCANCODE_KP_9 97)
+(define-public SDL_SCANCODE_KP_0 98)
+(define-public SDL_SCANCODE_KP_PERIOD 99)
+(define-public SDL_SCANCODE_NONUSBACKSLASH 100)
+(define-public SDL_SCANCODE_APPLICATION 101)
+(define-public SDL_SCANCODE_POWER 102)
+(define-public SDL_SCANCODE_KP_EQUALS 103)
+(define-public SDL_SCANCODE_F13 104)
+(define-public SDL_SCANCODE_F14 105)
+(define-public SDL_SCANCODE_F15 106)
+(define-public SDL_SCANCODE_F16 107)
+(define-public SDL_SCANCODE_F17 108)
+(define-public SDL_SCANCODE_F18 109)
+(define-public SDL_SCANCODE_F19 110)
+(define-public SDL_SCANCODE_F20 111)
+(define-public SDL_SCANCODE_F21 112)
+(define-public SDL_SCANCODE_F22 113)
+(define-public SDL_SCANCODE_F23 114)
+(define-public SDL_SCANCODE_F24 115)
+(define-public SDL_SCANCODE_EXECUTE 116)
+(define-public SDL_SCANCODE_HELP 117)
+(define-public SDL_SCANCODE_MENU 118)
+(define-public SDL_SCANCODE_SELECT 119)
+(define-public SDL_SCANCODE_STOP 120)
+(define-public SDL_SCANCODE_AGAIN 121)
+(define-public SDL_SCANCODE_UNDO 122)
+(define-public SDL_SCANCODE_CUT 123)
+(define-public SDL_SCANCODE_COPY 124)
+(define-public SDL_SCANCODE_PASTE 125)
+(define-public SDL_SCANCODE_FIND 126)
+(define-public SDL_SCANCODE_MUTE 127)
+(define-public SDL_SCANCODE_VOLUMEUP 128)
+(define-public SDL_SCANCODE_VOLUMEDOWN 129)
+(define-public SDL_SCANCODE_KP_COMMA 133)
+(define-public SDL_SCANCODE_KP_EQUALSAS400 134)
+(define-public SDL_SCANCODE_INTERNATIONAL1 135)
+(define-public SDL_SCANCODE_INTERNATIONAL2 136)
+(define-public SDL_SCANCODE_INTERNATIONAL3 137)
+(define-public SDL_SCANCODE_INTERNATIONAL4 138)
+(define-public SDL_SCANCODE_INTERNATIONAL5 139)
+(define-public SDL_SCANCODE_INTERNATIONAL6 140)
+(define-public SDL_SCANCODE_INTERNATIONAL7 141)
+(define-public SDL_SCANCODE_INTERNATIONAL8 142)
+(define-public SDL_SCANCODE_INTERNATIONAL9 143)
+(define-public SDL_SCANCODE_LANG1 144)
+(define-public SDL_SCANCODE_LANG2 145)
+(define-public SDL_SCANCODE_LANG3 146)
+(define-public SDL_SCANCODE_LANG4 147)
+(define-public SDL_SCANCODE_LANG5 148)
+(define-public SDL_SCANCODE_LANG6 149)
+(define-public SDL_SCANCODE_LANG7 150)
+(define-public SDL_SCANCODE_LANG8 151)
+(define-public SDL_SCANCODE_LANG9 152)
+(define-public SDL_SCANCODE_ALTERASE 153)
+(define-public SDL_SCANCODE_SYSREQ 154)
+(define-public SDL_SCANCODE_CANCEL 155)
+(define-public SDL_SCANCODE_CLEAR 156)
+(define-public SDL_SCANCODE_PRIOR 157)
+(define-public SDL_SCANCODE_RETURN2 158)
+(define-public SDL_SCANCODE_SEPARATOR 159)
+(define-public SDL_SCANCODE_OUT 160)
+(define-public SDL_SCANCODE_OPER 161)
+(define-public SDL_SCANCODE_CLEARAGAIN 162)
+(define-public SDL_SCANCODE_CRSEL 163)
+(define-public SDL_SCANCODE_EXSEL 164)
+(define-public SDL_SCANCODE_KP_00 176)
+(define-public SDL_SCANCODE_KP_000 177)
+(define-public SDL_SCANCODE_THOUSANDSSEPARATOR 178)
+(define-public SDL_SCANCODE_DECIMALSEPARATOR 179)
+(define-public SDL_SCANCODE_CURRENCYUNIT 180)
+(define-public SDL_SCANCODE_CURRENCYSUBUNIT 181)
+(define-public SDL_SCANCODE_KP_LEFTPAREN 182)
+(define-public SDL_SCANCODE_KP_RIGHTPAREN 183)
+(define-public SDL_SCANCODE_KP_LEFTBRACE 184)
+(define-public SDL_SCANCODE_KP_RIGHTBRACE 185)
+(define-public SDL_SCANCODE_KP_TAB 186)
+(define-public SDL_SCANCODE_KP_BACKSPACE 187)
+(define-public SDL_SCANCODE_KP_A 188)
+(define-public SDL_SCANCODE_KP_B 189)
+(define-public SDL_SCANCODE_KP_C 190)
+(define-public SDL_SCANCODE_KP_D 191)
+(define-public SDL_SCANCODE_KP_E 192)
+(define-public SDL_SCANCODE_KP_F 193)
+(define-public SDL_SCANCODE_KP_XOR 194)
+(define-public SDL_SCANCODE_KP_POWER 195)
+(define-public SDL_SCANCODE_KP_PERCENT 196)
+(define-public SDL_SCANCODE_KP_LESS 197)
+(define-public SDL_SCANCODE_KP_GREATER 198)
+(define-public SDL_SCANCODE_KP_AMPERSAND 199)
+(define-public SDL_SCANCODE_KP_DBLAMPERSAND 200)
+(define-public SDL_SCANCODE_KP_VERTICALBAR 201)
+(define-public SDL_SCANCODE_KP_DBLVERTICALBAR 202)
+(define-public SDL_SCANCODE_KP_COLON 203)
+(define-public SDL_SCANCODE_KP_HASH 204)
+(define-public SDL_SCANCODE_KP_SPACE 205)
+(define-public SDL_SCANCODE_KP_AT 206)
+(define-public SDL_SCANCODE_KP_EXCLAM 207)
+(define-public SDL_SCANCODE_KP_MEMSTORE 208)
+(define-public SDL_SCANCODE_KP_MEMRECALL 209)
+(define-public SDL_SCANCODE_KP_MEMCLEAR 210)
+(define-public SDL_SCANCODE_KP_MEMADD 211)
+(define-public SDL_SCANCODE_KP_MEMSUBTRACT 212)
+(define-public SDL_SCANCODE_KP_MEMMULTIPLY 213)
+(define-public SDL_SCANCODE_KP_MEMDIVIDE 214)
+(define-public SDL_SCANCODE_KP_PLUSMINUS 215)
+(define-public SDL_SCANCODE_KP_CLEAR 216)
+(define-public SDL_SCANCODE_KP_CLEARENTRY 217)
+(define-public SDL_SCANCODE_KP_BINARY 218)
+(define-public SDL_SCANCODE_KP_OCTAL 219)
+(define-public SDL_SCANCODE_KP_DECIMAL 220)
+(define-public SDL_SCANCODE_KP_HEXADECIMAL 221)
+(define-public SDL_SCANCODE_LCTRL 224)
+(define-public SDL_SCANCODE_LSHIFT 225)
+(define-public SDL_SCANCODE_LALT 226)
+(define-public SDL_SCANCODE_LGUI 227)
+(define-public SDL_SCANCODE_RCTRL 228)
+(define-public SDL_SCANCODE_RSHIFT 229)
+(define-public SDL_SCANCODE_RALT 230)
+(define-public SDL_SCANCODE_RGUI 231)
+(define-public SDL_SCANCODE_MODE 257)
+(define-public SDL_SCANCODE_AUDIONEXT 258)
+(define-public SDL_SCANCODE_AUDIOPREV 259)
+(define-public SDL_SCANCODE_AUDIOSTOP 260)
+(define-public SDL_SCANCODE_AUDIOPLAY 261)
+(define-public SDL_SCANCODE_AUDIOMUTE 262)
+(define-public SDL_SCANCODE_MEDIASELECT 263)
+(define-public SDL_SCANCODE_WWW 264)
+(define-public SDL_SCANCODE_MAIL 265)
+(define-public SDL_SCANCODE_CALCULATOR 266)
+(define-public SDL_SCANCODE_COMPUTER 267)
+(define-public SDL_SCANCODE_AC_SEARCH 268)
+(define-public SDL_SCANCODE_AC_HOME 269)
+(define-public SDL_SCANCODE_AC_BACK 270)
+(define-public SDL_SCANCODE_AC_FORWARD 271)
+(define-public SDL_SCANCODE_AC_STOP 272)
+(define-public SDL_SCANCODE_AC_REFRESH 273)
+(define-public SDL_SCANCODE_AC_BOOKMARKS 274)
+(define-public SDL_SCANCODE_BRIGHTNESSDOWN 275)
+(define-public SDL_SCANCODE_BRIGHTNESSUP 276)
+(define-public SDL_SCANCODE_DISPLAYSWITCH 277)
+(define-public SDL_SCANCODE_KBDILLUMTOGGLE 278)
+(define-public SDL_SCANCODE_KBDILLUMDOWN 279)
+(define-public SDL_SCANCODE_KBDILLUMUP 280)
+(define-public SDL_SCANCODE_EJECT 281)
+(define-public SDL_SCANCODE_SLEEP 282)
+(define-public SDL_SCANCODE_APP1 283)
+(define-public SDL_SCANCODE_APP2 284)
+(define-public SDL_NUM_SCANCODES 512)
+
+(define-public SDLK_UNKNOWN 0)
+(define-public SDLK_RETURN 13)
+(define-public SDLK_ESCAPE 27)
+(define-public SDLK_BACKSPACE 8)
+(define-public SDLK_TAB 9)
+(define-public SDLK_SPACE 32)
+(define-public SDLK_EXCLAIM 33)
+(define-public SDLK_QUOTEDBL 34)
+(define-public SDLK_HASH 35)
+(define-public SDLK_PERCENT 37)
+(define-public SDLK_DOLLAR 36)
+(define-public SDLK_AMPERSAND 38)
+(define-public SDLK_QUOTE 39)
+(define-public SDLK_LEFTPAREN 40)
+(define-public SDLK_RIGHTPAREN 41)
+(define-public SDLK_ASTERISK 42)
+(define-public SDLK_PLUS 43)
+(define-public SDLK_COMMA 44)
+(define-public SDLK_MINUS 45)
+(define-public SDLK_PERIOD 46)
+(define-public SDLK_SLASH 47)
+(define-public SDLK_0 48)
+(define-public SDLK_1 49)
+(define-public SDLK_2 50)
+(define-public SDLK_3 51)
+(define-public SDLK_4 52)
+(define-public SDLK_5 53)
+(define-public SDLK_6 54)
+(define-public SDLK_7 55)
+(define-public SDLK_8 56)
+(define-public SDLK_9 57)
+(define-public SDLK_COLON 58)
+(define-public SDLK_SEMICOLON 59)
+(define-public SDLK_LESS 60)
+(define-public SDLK_EQUALS 61)
+(define-public SDLK_GREATER 62)
+(define-public SDLK_QUESTION 63)
+(define-public SDLK_AT 64)
+(define-public SDLK_LEFTBRACKET 91)
+(define-public SDLK_BACKSLASH 92)
+(define-public SDLK_RIGHTBRACKET 93)
+(define-public SDLK_CARET 94)
+(define-public SDLK_UNDERSCORE 95)
+(define-public SDLK_BACKQUOTE 96)
+(define-public SDLK_a 97)
+(define-public SDLK_b 98)
+(define-public SDLK_c 99)
+(define-public SDLK_d 100)
+(define-public SDLK_e 101)
+(define-public SDLK_f 102)
+(define-public SDLK_g 103)
+(define-public SDLK_h 104)
+(define-public SDLK_i 105)
+(define-public SDLK_j 106)
+(define-public SDLK_k 107)
+(define-public SDLK_l 108)
+(define-public SDLK_m 109)
+(define-public SDLK_n 110)
+(define-public SDLK_o 111)
+(define-public SDLK_p 112)
+(define-public SDLK_q 113)
+(define-public SDLK_r 114)
+(define-public SDLK_s 115)
+(define-public SDLK_t 116)
+(define-public SDLK_u 117)
+(define-public SDLK_v 118)
+(define-public SDLK_w 119)
+(define-public SDLK_x 120)
+(define-public SDLK_y 121)
+(define-public SDLK_z 122)
+(define-public SDLK_CAPSLOCK (scancode->keycode SDL_SCANCODE_CAPSLOCK))
+(define-public SDLK_F1 (scancode->keycode SDL_SCANCODE_F1))
+(define-public SDLK_F2 (scancode->keycode SDL_SCANCODE_F2))
+(define-public SDLK_F3 (scancode->keycode SDL_SCANCODE_F3))
+(define-public SDLK_F4 (scancode->keycode SDL_SCANCODE_F4))
+(define-public SDLK_F5 (scancode->keycode SDL_SCANCODE_F5))
+(define-public SDLK_F6 (scancode->keycode SDL_SCANCODE_F6))
+(define-public SDLK_F7 (scancode->keycode SDL_SCANCODE_F7))
+(define-public SDLK_F8 (scancode->keycode SDL_SCANCODE_F8))
+(define-public SDLK_F9 (scancode->keycode SDL_SCANCODE_F9))
+(define-public SDLK_F10 (scancode->keycode SDL_SCANCODE_F10))
+(define-public SDLK_F11 (scancode->keycode SDL_SCANCODE_F11))
+(define-public SDLK_F12 (scancode->keycode SDL_SCANCODE_F12))
+(define-public SDLK_PRINTSCREEN (scancode->keycode SDL_SCANCODE_PRINTSCREEN))
+(define-public SDLK_SCROLLLOCK (scancode->keycode SDL_SCANCODE_SCROLLLOCK))
+(define-public SDLK_PAUSE (scancode->keycode SDL_SCANCODE_PAUSE))
+(define-public SDLK_INSERT (scancode->keycode SDL_SCANCODE_INSERT))
+(define-public SDLK_HOME (scancode->keycode SDL_SCANCODE_HOME))
+(define-public SDLK_PAGEUP (scancode->keycode SDL_SCANCODE_PAGEUP))
+(define-public SDLK_DELETE 127)
+(define-public SDLK_END (scancode->keycode SDL_SCANCODE_END))
+(define-public SDLK_PAGEDOWN (scancode->keycode SDL_SCANCODE_PAGEDOWN))
+(define-public SDLK_RIGHT (scancode->keycode SDL_SCANCODE_RIGHT))
+(define-public SDLK_LEFT (scancode->keycode SDL_SCANCODE_LEFT))
+(define-public SDLK_DOWN (scancode->keycode SDL_SCANCODE_DOWN))
+(define-public SDLK_UP (scancode->keycode SDL_SCANCODE_UP))
+(define-public SDLK_NUMLOCKCLEAR (scancode->keycode SDL_SCANCODE_NUMLOCKCLEAR))
+(define-public SDLK_KP_DIVIDE (scancode->keycode SDL_SCANCODE_KP_DIVIDE))
+(define-public SDLK_KP_MULTIPLY (scancode->keycode SDL_SCANCODE_KP_MULTIPLY))
+(define-public SDLK_KP_MINUS (scancode->keycode SDL_SCANCODE_KP_MINUS))
+(define-public SDLK_KP_PLUS (scancode->keycode SDL_SCANCODE_KP_PLUS))
+(define-public SDLK_KP_ENTER (scancode->keycode SDL_SCANCODE_KP_ENTER))
+(define-public SDLK_KP_1 (scancode->keycode SDL_SCANCODE_KP_1))
+(define-public SDLK_KP_2 (scancode->keycode SDL_SCANCODE_KP_2))
+(define-public SDLK_KP_3 (scancode->keycode SDL_SCANCODE_KP_3))
+(define-public SDLK_KP_4 (scancode->keycode SDL_SCANCODE_KP_4))
+(define-public SDLK_KP_5 (scancode->keycode SDL_SCANCODE_KP_5))
+(define-public SDLK_KP_6 (scancode->keycode SDL_SCANCODE_KP_6))
+(define-public SDLK_KP_7 (scancode->keycode SDL_SCANCODE_KP_7))
+(define-public SDLK_KP_8 (scancode->keycode SDL_SCANCODE_KP_8))
+(define-public SDLK_KP_9 (scancode->keycode SDL_SCANCODE_KP_9))
+(define-public SDLK_KP_0 (scancode->keycode SDL_SCANCODE_KP_0))
+(define-public SDLK_KP_PERIOD (scancode->keycode SDL_SCANCODE_KP_PERIOD))
+(define-public SDLK_APPLICATION (scancode->keycode SDL_SCANCODE_APPLICATION))
+(define-public SDLK_POWER (scancode->keycode SDL_SCANCODE_POWER))
+(define-public SDLK_KP_EQUALS (scancode->keycode SDL_SCANCODE_KP_EQUALS))
+(define-public SDLK_F13 (scancode->keycode SDL_SCANCODE_F13))
+(define-public SDLK_F14 (scancode->keycode SDL_SCANCODE_F14))
+(define-public SDLK_F15 (scancode->keycode SDL_SCANCODE_F15))
+(define-public SDLK_F16 (scancode->keycode SDL_SCANCODE_F16))
+(define-public SDLK_F17 (scancode->keycode SDL_SCANCODE_F17))
+(define-public SDLK_F18 (scancode->keycode SDL_SCANCODE_F18))
+(define-public SDLK_F19 (scancode->keycode SDL_SCANCODE_F19))
+(define-public SDLK_F20 (scancode->keycode SDL_SCANCODE_F20))
+(define-public SDLK_F21 (scancode->keycode SDL_SCANCODE_F21))
+(define-public SDLK_F22 (scancode->keycode SDL_SCANCODE_F22))
+(define-public SDLK_F23 (scancode->keycode SDL_SCANCODE_F23))
+(define-public SDLK_F24 (scancode->keycode SDL_SCANCODE_F24))
+(define-public SDLK_EXECUTE (scancode->keycode SDL_SCANCODE_EXECUTE))
+(define-public SDLK_HELP (scancode->keycode SDL_SCANCODE_HELP))
+(define-public SDLK_MENU (scancode->keycode SDL_SCANCODE_MENU))
+(define-public SDLK_SELECT (scancode->keycode SDL_SCANCODE_SELECT))
+(define-public SDLK_STOP (scancode->keycode SDL_SCANCODE_STOP))
+(define-public SDLK_AGAIN (scancode->keycode SDL_SCANCODE_AGAIN))
+(define-public SDLK_UNDO (scancode->keycode SDL_SCANCODE_UNDO))
+(define-public SDLK_CUT (scancode->keycode SDL_SCANCODE_CUT))
+(define-public SDLK_COPY (scancode->keycode SDL_SCANCODE_COPY))
+(define-public SDLK_PASTE (scancode->keycode SDL_SCANCODE_PASTE))
+(define-public SDLK_FIND (scancode->keycode SDL_SCANCODE_FIND))
+(define-public SDLK_MUTE (scancode->keycode SDL_SCANCODE_MUTE))
+(define-public SDLK_VOLUMEUP (scancode->keycode SDL_SCANCODE_VOLUMEUP))
+(define-public SDLK_VOLUMEDOWN (scancode->keycode SDL_SCANCODE_VOLUMEDOWN))
+(define-public SDLK_KP_COMMA (scancode->keycode SDL_SCANCODE_KP_COMMA))
+(define-public SDLK_KP_EQUALSAS400
+  (scancode->keycode SDL_SCANCODE_KP_EQUALSAS400))
+(define-public SDLK_ALTERASE (scancode->keycode SDL_SCANCODE_ALTERASE))
+(define-public SDLK_SYSREQ (scancode->keycode SDL_SCANCODE_SYSREQ))
+(define-public SDLK_CANCEL (scancode->keycode SDL_SCANCODE_CANCEL))
+(define-public SDLK_CLEAR (scancode->keycode SDL_SCANCODE_CLEAR))
+(define-public SDLK_PRIOR (scancode->keycode SDL_SCANCODE_PRIOR))
+(define-public SDLK_RETURN2 (scancode->keycode SDL_SCANCODE_RETURN2))
+(define-public SDLK_SEPARATOR (scancode->keycode SDL_SCANCODE_SEPARATOR))
+(define-public SDLK_OUT (scancode->keycode SDL_SCANCODE_OUT))
+(define-public SDLK_OPER (scancode->keycode SDL_SCANCODE_OPER))
+(define-public SDLK_CLEARAGAIN (scancode->keycode SDL_SCANCODE_CLEARAGAIN))
+(define-public SDLK_CRSEL (scancode->keycode SDL_SCANCODE_CRSEL))
+(define-public SDLK_EXSEL (scancode->keycode SDL_SCANCODE_EXSEL))
+(define-public SDLK_KP_00 (scancode->keycode SDL_SCANCODE_KP_00))
+(define-public SDLK_KP_000 (scancode->keycode SDL_SCANCODE_KP_000))
+(define-public SDLK_THOUSANDSSEPARATOR
+  (scancode->keycode SDL_SCANCODE_THOUSANDSSEPARATOR))
+(define-public SDLK_DECIMALSEPARATOR
+  (scancode->keycode SDL_SCANCODE_DECIMALSEPARATOR))
+(define-public SDLK_CURRENCYUNIT (scancode->keycode SDL_SCANCODE_CURRENCYUNIT))
+(define-public SDLK_CURRENCYSUBUNIT
+  (scancode->keycode SDL_SCANCODE_CURRENCYSUBUNIT))
+(define-public SDLK_KP_LEFTPAREN (scancode->keycode SDL_SCANCODE_KP_LEFTPAREN))
+(define-public SDLK_KP_RIGHTPAREN
+  (scancode->keycode SDL_SCANCODE_KP_RIGHTPAREN))
+(define-public SDLK_KP_LEFTBRACE (scancode->keycode SDL_SCANCODE_KP_LEFTBRACE))
+(define-public SDLK_KP_RIGHTBRACE (scancode->keycode SDL_SCANCODE_KP_RIGHTBRACE))
+(define-public SDLK_KP_TAB (scancode->keycode SDL_SCANCODE_KP_TAB))
+(define-public SDLK_KP_BACKSPACE (scancode->keycode SDL_SCANCODE_KP_BACKSPACE))
+(define-public SDLK_KP_A (scancode->keycode SDL_SCANCODE_KP_A))
+(define-public SDLK_KP_B (scancode->keycode SDL_SCANCODE_KP_B))
+(define-public SDLK_KP_C (scancode->keycode SDL_SCANCODE_KP_C))
+(define-public SDLK_KP_D (scancode->keycode SDL_SCANCODE_KP_D))
+(define-public SDLK_KP_E (scancode->keycode SDL_SCANCODE_KP_E))
+(define-public SDLK_KP_F (scancode->keycode SDL_SCANCODE_KP_F))
+(define-public SDLK_KP_XOR (scancode->keycode SDL_SCANCODE_KP_XOR))
+(define-public SDLK_KP_POWER (scancode->keycode SDL_SCANCODE_KP_POWER))
+(define-public SDLK_KP_PERCENT (scancode->keycode SDL_SCANCODE_KP_PERCENT))
+(define-public SDLK_KP_LESS (scancode->keycode SDL_SCANCODE_KP_LESS))
+(define-public SDLK_KP_GREATER (scancode->keycode SDL_SCANCODE_KP_GREATER))
+(define-public SDLK_KP_AMPERSAND (scancode->keycode SDL_SCANCODE_KP_AMPERSAND))
+(define-public SDLK_KP_DBLAMPERSAND
+  (scancode->keycode SDL_SCANCODE_KP_DBLAMPERSAND))
+(define-public SDLK_KP_VERTICALBAR
+  (scancode->keycode SDL_SCANCODE_KP_VERTICALBAR))
+(define-public SDLK_KP_DBLVERTICALBAR
+  (scancode->keycode SDL_SCANCODE_KP_DBLVERTICALBAR))
+(define-public SDLK_KP_COLON (scancode->keycode SDL_SCANCODE_KP_COLON))
+(define-public SDLK_KP_HASH (scancode->keycode SDL_SCANCODE_KP_HASH))
+(define-public SDLK_KP_SPACE (scancode->keycode SDL_SCANCODE_KP_SPACE))
+(define-public SDLK_KP_AT (scancode->keycode SDL_SCANCODE_KP_AT))
+(define-public SDLK_KP_EXCLAM (scancode->keycode SDL_SCANCODE_KP_EXCLAM))
+(define-public SDLK_KP_MEMSTORE (scancode->keycode SDL_SCANCODE_KP_MEMSTORE))
+(define-public SDLK_KP_MEMRECALL (scancode->keycode SDL_SCANCODE_KP_MEMRECALL))
+(define-public SDLK_KP_MEMCLEAR (scancode->keycode SDL_SCANCODE_KP_MEMCLEAR))
+(define-public SDLK_KP_MEMADD (scancode->keycode SDL_SCANCODE_KP_MEMADD))
+(define-public SDLK_KP_MEMSUBTRACT
+  (scancode->keycode SDL_SCANCODE_KP_MEMSUBTRACT))
+(define-public SDLK_KP_MEMMULTIPLY
+  (scancode->keycode SDL_SCANCODE_KP_MEMMULTIPLY))
+(define-public SDLK_KP_MEMDIVIDE (scancode->keycode SDL_SCANCODE_KP_MEMDIVIDE))
+(define-public SDLK_KP_PLUSMINUS (scancode->keycode SDL_SCANCODE_KP_PLUSMINUS))
+(define-public SDLK_KP_CLEAR (scancode->keycode SDL_SCANCODE_KP_CLEAR))
+(define-public SDLK_KP_CLEARENTRY (scancode->keycode SDL_SCANCODE_KP_CLEARENTRY))
+(define-public SDLK_KP_BINARY (scancode->keycode SDL_SCANCODE_KP_BINARY))
+(define-public SDLK_KP_OCTAL (scancode->keycode SDL_SCANCODE_KP_OCTAL))
+(define-public SDLK_KP_DECIMAL (scancode->keycode SDL_SCANCODE_KP_DECIMAL))
+(define-public SDLK_KP_HEXADECIMAL
+  (scancode->keycode SDL_SCANCODE_KP_HEXADECIMAL))
+(define-public SDLK_LCTRL (scancode->keycode SDL_SCANCODE_LCTRL))
+(define-public SDLK_LSHIFT (scancode->keycode SDL_SCANCODE_LSHIFT))
+(define-public SDLK_LALT (scancode->keycode SDL_SCANCODE_LALT))
+(define-public SDLK_LGUI (scancode->keycode SDL_SCANCODE_LGUI))
+(define-public SDLK_RCTRL (scancode->keycode SDL_SCANCODE_RCTRL))
+(define-public SDLK_RSHIFT (scancode->keycode SDL_SCANCODE_RSHIFT))
+(define-public SDLK_RALT (scancode->keycode SDL_SCANCODE_RALT))
+(define-public SDLK_RGUI (scancode->keycode SDL_SCANCODE_RGUI))
+(define-public SDLK_MODE (scancode->keycode SDL_SCANCODE_MODE))
+(define-public SDLK_AUDIONEXT (scancode->keycode SDL_SCANCODE_AUDIONEXT))
+(define-public SDLK_AUDIOPREV (scancode->keycode SDL_SCANCODE_AUDIOPREV))
+(define-public SDLK_AUDIOSTOP (scancode->keycode SDL_SCANCODE_AUDIOSTOP))
+(define-public SDLK_AUDIOPLAY (scancode->keycode SDL_SCANCODE_AUDIOPLAY))
+(define-public SDLK_AUDIOMUTE (scancode->keycode SDL_SCANCODE_AUDIOMUTE))
+(define-public SDLK_MEDIASELECT (scancode->keycode SDL_SCANCODE_MEDIASELECT))
+(define-public SDLK_WWW (scancode->keycode SDL_SCANCODE_WWW))
+(define-public SDLK_MAIL (scancode->keycode SDL_SCANCODE_MAIL))
+(define-public SDLK_CALCULATOR (scancode->keycode SDL_SCANCODE_CALCULATOR))
+(define-public SDLK_COMPUTER (scancode->keycode SDL_SCANCODE_COMPUTER))
+(define-public SDLK_AC_SEARCH (scancode->keycode SDL_SCANCODE_AC_SEARCH))
+(define-public SDLK_AC_HOME (scancode->keycode SDL_SCANCODE_AC_HOME))
+(define-public SDLK_AC_BACK (scancode->keycode SDL_SCANCODE_AC_BACK))
+(define-public SDLK_AC_FORWARD (scancode->keycode SDL_SCANCODE_AC_FORWARD))
+(define-public SDLK_AC_STOP (scancode->keycode SDL_SCANCODE_AC_STOP))
+(define-public SDLK_AC_REFRESH (scancode->keycode SDL_SCANCODE_AC_REFRESH))
+(define-public SDLK_AC_BOOKMARKS (scancode->keycode SDL_SCANCODE_AC_BOOKMARKS))
+(define-public SDLK_BRIGHTNESSDOWN
+  (scancode->keycode SDL_SCANCODE_BRIGHTNESSDOWN))
+(define-public SDLK_BRIGHTNESSUP (scancode->keycode SDL_SCANCODE_BRIGHTNESSUP))
+(define-public SDLK_DISPLAYSWITCH (scancode->keycode SDL_SCANCODE_DISPLAYSWITCH))
+(define-public SDLK_KBDILLUMTOGGLE
+  (scancode->keycode SDL_SCANCODE_KBDILLUMTOGGLE))
+(define-public SDLK_KBDILLUMDOWN (scancode->keycode SDL_SCANCODE_KBDILLUMDOWN))
+(define-public SDLK_KBDILLUMUP (scancode->keycode SDL_SCANCODE_KBDILLUMUP))
+(define-public SDLK_EJECT (scancode->keycode SDL_SCANCODE_EJECT))
+(define-public SDLK_SLEEP (scancode->keycode SDL_SCANCODE_SLEEP))
+
+\f
+;;;
 ;;; Timer
 ;;;
 
diff --git a/sdl2/events.scm b/sdl2/events.scm
new file mode 100644 (file)
index 0000000..ad798a8
--- /dev/null
@@ -0,0 +1,673 @@
+;;; guile-sdl2 --- FFI bindings for SDL2
+;;; Copyright © 2015 David Thompson <davet@gnu.org>
+;;;
+;;; This file is part of guile-sdl2.
+;;;
+;;; Guile-sdl2 is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU Lesser General Public License as
+;;; published by the Free Software Foundation; either version 3 of the
+;;; License, or (at your option) any later version.
+;;;
+;;; Guile-sdl2 is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;;; General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU Lesser General Public
+;;; License along with guile-sdl2.  If not, see
+;;; <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; SDL event handling.
+;;
+;;; Code:
+
+(define-module (sdl2 events)
+  #:use-module (ice-9 hash-table)
+  #:use-module (ice-9 match)
+  #:use-module (rnrs bytevectors)
+  #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-4)
+  #:use-module (srfi srfi-9)
+  #:use-module (system foreign)
+  #:use-module ((sdl2 bindings) #:prefix ffi:)
+  #:use-module (sdl2)
+  #:export (make-window-event
+            window-event?
+            window-event-timestamp
+            window-event-window-id
+            window-event-type
+            window-event-vector
+
+            make-keyboard-event
+            keyboard-event?
+            keyboard-event-timestamp
+            keyboard-event-window-id
+            keyboard-event-pressed?
+            keyboard-event-repeat
+            keyboard-event-keysym
+
+            poll-event))
+
+(define (make-sdl-event)
+  (make-u8vector 56 0)) ; sizeof(SDL_Event) is 56
+
+(define (sdl-event-type event)
+  (u32vector-ref event 0))
+
+\f
+;;;
+;;; Window
+;;;
+
+(define-record-type <window-event>
+  (make-window-event timestamp window-id type vector)
+  window-event?
+  (timestamp window-event timestamp)
+  (window-id window-event-window-id)
+  (type window-event-type)
+  (vector window-event-vector))
+
+(define (parse-window-event ptr)
+  (define (type-symbol n)
+    (list-ref '(none
+                shown
+                hidden
+                exposed
+                moved
+                resized
+                size-changed
+                minimized
+                maximized
+                restored
+                enter
+                leave
+                focus-gained
+                focus-lost
+                close)
+              n))
+
+  (define types
+    (list uint32  ; type
+          uint32  ; timestamp
+          uint32  ; windowID
+          uint8   ; event
+          uint8   ; padding1
+          uint8   ; padding2
+          uint8   ; padding3
+          int32   ; data1
+          int32)) ; data2
+
+  (match (parse-c-struct ptr types)
+    ((_ timestamp id event _ _ _ data1 data2)
+     (make-window-event timestamp id (type-symbol event) (cons data1 data2)))))
+
+\f
+;;;
+;;; Keyboard
+;;;
+
+(define-record-type <keyboard-event>
+  (make-keyboard-event timestamp window-id pressed? repeat
+                       key scancode modifiers)
+  keyboard-event?
+  (timestamp keyboard-event-timestamp)
+  (window-id keyboard-event-window-id)
+  (pressed? keyboard-event-pressed?)
+  (repeat keyboard-event-repeat)
+  (key keyboard-event-key)
+  (scancode keyboard-event-scancode)
+  (modifiers keyboard-event-modifiers))
+
+(define keycode-map
+  (alist->hash-table
+   `((,ffi:SDLK_UNKNOWN . unknown)
+     (,ffi:SDLK_RETURN . return)
+     (,ffi:SDLK_ESCAPE . escape)
+     (,ffi:SDLK_BACKSPACE . backspace)
+     (,ffi:SDLK_TAB . tab)
+     (,ffi:SDLK_SPACE . space)
+     (,ffi:SDLK_EXCLAIM . exclaim)
+     (,ffi:SDLK_QUOTEDBL . double-quote)
+     (,ffi:SDLK_HASH . hash)
+     (,ffi:SDLK_PERCENT . percent)
+     (,ffi:SDLK_DOLLAR . dollar)
+     (,ffi:SDLK_AMPERSAND . ampersand)
+     (,ffi:SDLK_QUOTE . quote)
+     (,ffi:SDLK_LEFTPAREN . left-paren)
+     (,ffi:SDLK_RIGHTPAREN . right-paren)
+     (,ffi:SDLK_ASTERISK . asterisk)
+     (,ffi:SDLK_PLUS . plus)
+     (,ffi:SDLK_COMMA . comma)
+     (,ffi:SDLK_MINUS . minus)
+     (,ffi:SDLK_PERIOD . period)
+     (,ffi:SDLK_SLASH . slash)
+     (,ffi:SDLK_0 . 0)
+     (,ffi:SDLK_1 . 1)
+     (,ffi:SDLK_2 . 2)
+     (,ffi:SDLK_3 . 3)
+     (,ffi:SDLK_4 . 4)
+     (,ffi:SDLK_5 . 5)
+     (,ffi:SDLK_6 . 6)
+     (,ffi:SDLK_7 . 7)
+     (,ffi:SDLK_8 . 8)
+     (,ffi:SDLK_9 . 9)
+     (,ffi:SDLK_COLON . colon)
+     (,ffi:SDLK_SEMICOLON . semicolon)
+     (,ffi:SDLK_LESS . less)
+     (,ffi:SDLK_EQUALS . equals)
+     (,ffi:SDLK_GREATER . greater)
+     (,ffi:SDLK_QUESTION . question)
+     (,ffi:SDLK_AT . at)
+     (,ffi:SDLK_LEFTBRACKET . left-bracket)
+     (,ffi:SDLK_BACKSLASH . backslash)
+     (,ffi:SDLK_RIGHTBRACKET . right-bracket)
+     (,ffi:SDLK_CARET . caret)
+     (,ffi:SDLK_UNDERSCORE . underscore)
+     (,ffi:SDLK_BACKQUOTE . backquote)
+     (,ffi:SDLK_a . a)
+     (,ffi:SDLK_b . b)
+     (,ffi:SDLK_c . c)
+     (,ffi:SDLK_d . d)
+     (,ffi:SDLK_e . e)
+     (,ffi:SDLK_f . f)
+     (,ffi:SDLK_g . g)
+     (,ffi:SDLK_h . h)
+     (,ffi:SDLK_i . i)
+     (,ffi:SDLK_j . j)
+     (,ffi:SDLK_k . k)
+     (,ffi:SDLK_l . l)
+     (,ffi:SDLK_m . m)
+     (,ffi:SDLK_n . n)
+     (,ffi:SDLK_o . o)
+     (,ffi:SDLK_p . p)
+     (,ffi:SDLK_q . q)
+     (,ffi:SDLK_r . r)
+     (,ffi:SDLK_s . s)
+     (,ffi:SDLK_t . t)
+     (,ffi:SDLK_u . u)
+     (,ffi:SDLK_v . v)
+     (,ffi:SDLK_w . w)
+     (,ffi:SDLK_x . x)
+     (,ffi:SDLK_y . y)
+     (,ffi:SDLK_z . z)
+     (,ffi:SDLK_CAPSLOCK . caps-lock)
+     (,ffi:SDLK_F1 . f1)
+     (,ffi:SDLK_F2 . f2)
+     (,ffi:SDLK_F3 . f3)
+     (,ffi:SDLK_F4 . f4)
+     (,ffi:SDLK_F5 . f5)
+     (,ffi:SDLK_F6 . f6)
+     (,ffi:SDLK_F7 . f7)
+     (,ffi:SDLK_F8 . f8)
+     (,ffi:SDLK_F9 . f9)
+     (,ffi:SDLK_F10 . f10)
+     (,ffi:SDLK_F11 . f11)
+     (,ffi:SDLK_F12 . f12)
+     (,ffi:SDLK_PRINTSCREEN . print-screen)
+     (,ffi:SDLK_SCROLLLOCK . scroll-lock)
+     (,ffi:SDLK_PAUSE . pause)
+     (,ffi:SDLK_INSERT . insert)
+     (,ffi:SDLK_HOME . home)
+     (,ffi:SDLK_PAGEUP . page-up)
+     (,ffi:SDLK_DELETE . delete)
+     (,ffi:SDLK_END . end)
+     (,ffi:SDLK_PAGEDOWN . page-down)
+     (,ffi:SDLK_RIGHT . right)
+     (,ffi:SDLK_LEFT . left)
+     (,ffi:SDLK_DOWN . down)
+     (,ffi:SDLK_UP . up)
+     (,ffi:SDLK_NUMLOCKCLEAR . num-lock-clear)
+     (,ffi:SDLK_KP_DIVIDE . keypad-divide)
+     (,ffi:SDLK_KP_MULTIPLY . keypad-multiply)
+     (,ffi:SDLK_KP_MINUS . keypad-minus)
+     (,ffi:SDLK_KP_PLUS . keypad-plus)
+     (,ffi:SDLK_KP_ENTER . keypad-enter)
+     (,ffi:SDLK_KP_1 . keypad-1)
+     (,ffi:SDLK_KP_2 . keypad-2)
+     (,ffi:SDLK_KP_3 . keypad-3)
+     (,ffi:SDLK_KP_4 . keypad-4)
+     (,ffi:SDLK_KP_5 . keypad-5)
+     (,ffi:SDLK_KP_6 . keypad-6)
+     (,ffi:SDLK_KP_7 . keypad-7)
+     (,ffi:SDLK_KP_8 . keypad-8)
+     (,ffi:SDLK_KP_9 . keypad-9)
+     (,ffi:SDLK_KP_0 . keypad-0)
+     (,ffi:SDLK_KP_PERIOD . keypad-period)
+     (,ffi:SDLK_APPLICATION . application)
+     (,ffi:SDLK_POWER . power)
+     (,ffi:SDLK_KP_EQUALS . keypad-equals)
+     (,ffi:SDLK_F13 . f13)
+     (,ffi:SDLK_F14 . f14)
+     (,ffi:SDLK_F15 . f15)
+     (,ffi:SDLK_F16 . f16)
+     (,ffi:SDLK_F17 . f17)
+     (,ffi:SDLK_F18 . f18)
+     (,ffi:SDLK_F19 . f19)
+     (,ffi:SDLK_F20 . f20)
+     (,ffi:SDLK_F21 . f21)
+     (,ffi:SDLK_F22 . f22)
+     (,ffi:SDLK_F23 . f23)
+     (,ffi:SDLK_F24 . f24)
+     (,ffi:SDLK_EXECUTE . execute)
+     (,ffi:SDLK_HELP . help)
+     (,ffi:SDLK_MENU . menu)
+     (,ffi:SDLK_SELECT . select)
+     (,ffi:SDLK_STOP . stop)
+     (,ffi:SDLK_AGAIN . again)
+     (,ffi:SDLK_UNDO . undo)
+     (,ffi:SDLK_CUT . cut)
+     (,ffi:SDLK_COPY . copy)
+     (,ffi:SDLK_PASTE . paste)
+     (,ffi:SDLK_FIND . find)
+     (,ffi:SDLK_MUTE . mute)
+     (,ffi:SDLK_VOLUMEUP . volume-up)
+     (,ffi:SDLK_VOLUMEDOWN . volume-down)
+     (,ffi:SDLK_KP_COMMA . keypad-comma)
+     (,ffi:SDLK_KP_EQUALSAS400 . keypad-equalsas400)
+     (,ffi:SDLK_ALTERASE . alt-erase)
+     (,ffi:SDLK_SYSREQ . sysreq)
+     (,ffi:SDLK_CANCEL . cancel)
+     (,ffi:SDLK_CLEAR . clear)
+     (,ffi:SDLK_PRIOR . prior)
+     (,ffi:SDLK_RETURN2 . return-2)
+     (,ffi:SDLK_SEPARATOR . separator)
+     (,ffi:SDLK_OUT . out)
+     (,ffi:SDLK_OPER . oper)
+     (,ffi:SDLK_CLEARAGAIN . clear-again)
+     (,ffi:SDLK_CRSEL . crsel)
+     (,ffi:SDLK_EXSEL . exsel)
+     (,ffi:SDLK_KP_00 . keypad-00)
+     (,ffi:SDLK_KP_000 . keypad-000)
+     (,ffi:SDLK_THOUSANDSSEPARATOR . thousands-separator)
+     (,ffi:SDLK_DECIMALSEPARATOR . decimal-separator)
+     (,ffi:SDLK_CURRENCYUNIT . currency-unit)
+     (,ffi:SDLK_CURRENCYSUBUNIT . currency-subunit)
+     (,ffi:SDLK_KP_LEFTPAREN . keypad-left-paren)
+     (,ffi:SDLK_KP_RIGHTPAREN . keypad-right-paren)
+     (,ffi:SDLK_KP_LEFTBRACE . keypad-left-brace)
+     (,ffi:SDLK_KP_RIGHTBRACE . keypad-right-brace)
+     (,ffi:SDLK_KP_TAB . keypad-tab)
+     (,ffi:SDLK_KP_BACKSPACE . keypad-backspace)
+     (,ffi:SDLK_KP_A . keypad-a)
+     (,ffi:SDLK_KP_B . keypad-b)
+     (,ffi:SDLK_KP_C . keypad-c)
+     (,ffi:SDLK_KP_D . keypad-d)
+     (,ffi:SDLK_KP_E . keypad-e)
+     (,ffi:SDLK_KP_F . keypad-f)
+     (,ffi:SDLK_KP_XOR . keypad-xor)
+     (,ffi:SDLK_KP_POWER . keypad-power)
+     (,ffi:SDLK_KP_PERCENT . keypad-percent)
+     (,ffi:SDLK_KP_LESS . keypad-less)
+     (,ffi:SDLK_KP_GREATER . keypad-greater)
+     (,ffi:SDLK_KP_AMPERSAND . keypad-ampersand)
+     (,ffi:SDLK_KP_DBLAMPERSAND . keypad-double-ampersand)
+     (,ffi:SDLK_KP_VERTICALBAR . keypad-vertical-bar)
+     (,ffi:SDLK_KP_DBLVERTICALBAR . keypad-double-vertical-bar)
+     (,ffi:SDLK_KP_COLON . keypad-colon)
+     (,ffi:SDLK_KP_HASH . keypad-hash)
+     (,ffi:SDLK_KP_SPACE . keypad-space)
+     (,ffi:SDLK_KP_AT . keypad-at)
+     (,ffi:SDLK_KP_EXCLAM . keypad-exclam)
+     (,ffi:SDLK_KP_MEMSTORE . keypad-mem-store)
+     (,ffi:SDLK_KP_MEMRECALL . keypad-mem-recall)
+     (,ffi:SDLK_KP_MEMCLEAR . keypad-mem-clear)
+     (,ffi:SDLK_KP_MEMADD . keypad-mem-add)
+     (,ffi:SDLK_KP_MEMSUBTRACT . keypad-mem-subtract)
+     (,ffi:SDLK_KP_MEMMULTIPLY . keypad-mem-multiply)
+     (,ffi:SDLK_KP_MEMDIVIDE . keypad-mem-divide)
+     (,ffi:SDLK_KP_PLUSMINUS . keypad-plus-minus)
+     (,ffi:SDLK_KP_CLEAR . keypad-clear)
+     (,ffi:SDLK_KP_CLEARENTRY . keypad-clear-entry)
+     (,ffi:SDLK_KP_BINARY . keypad-binary)
+     (,ffi:SDLK_KP_OCTAL . keypad-octal)
+     (,ffi:SDLK_KP_DECIMAL . keypad-decimal)
+     (,ffi:SDLK_KP_HEXADECIMAL . keypad-hexadecimal)
+     (,ffi:SDLK_LCTRL . left-control)
+     (,ffi:SDLK_LSHIFT . left-shift)
+     (,ffi:SDLK_LALT . left-alt)
+     (,ffi:SDLK_LGUI . left-gui)
+     (,ffi:SDLK_RCTRL . right-control)
+     (,ffi:SDLK_RSHIFT . right-shift)
+     (,ffi:SDLK_RALT . right-alt)
+     (,ffi:SDLK_RGUI . right-gui)
+     (,ffi:SDLK_MODE . mode)
+     (,ffi:SDLK_AUDIONEXT . audio-next)
+     (,ffi:SDLK_AUDIOPREV . audio-prev)
+     (,ffi:SDLK_AUDIOSTOP . audio-stop)
+     (,ffi:SDLK_AUDIOPLAY . audio-play)
+     (,ffi:SDLK_AUDIOMUTE . audio-mute)
+     (,ffi:SDLK_MEDIASELECT . media-select)
+     (,ffi:SDLK_WWW . www)
+     (,ffi:SDLK_MAIL . mail)
+     (,ffi:SDLK_CALCULATOR . calculator)
+     (,ffi:SDLK_COMPUTER . computer)
+     (,ffi:SDLK_AC_SEARCH . ac-search)
+     (,ffi:SDLK_AC_HOME . ac-home)
+     (,ffi:SDLK_AC_BACK . ac-back)
+     (,ffi:SDLK_AC_FORWARD . ac-forward)
+     (,ffi:SDLK_AC_STOP . ac-stop)
+     (,ffi:SDLK_AC_REFRESH . ac-refresh)
+     (,ffi:SDLK_AC_BOOKMARKS . ac-bookmarks)
+     (,ffi:SDLK_BRIGHTNESSDOWN . brightness-down)
+     (,ffi:SDLK_BRIGHTNESSUP . brightness-up)
+     (,ffi:SDLK_DISPLAYSWITCH . display-switch)
+     (,ffi:SDLK_KBDILLUMTOGGLE . keyboard-illum-toggle)
+     (,ffi:SDLK_KBDILLUMDOWN . keyboard-illum-down)
+     (,ffi:SDLK_KBDILLUMUP . keyboard-illum-up)
+     (,ffi:SDLK_EJECT . eject)
+     (,ffi:SDLK_SLEEP . sleep))))
+
+(define scancode-map
+  (alist->hash-table
+   `((,ffi:SDL_SCANCODE_UNKNOWN . unknown)
+     (,ffi:SDL_SCANCODE_A . a)
+     (,ffi:SDL_SCANCODE_B . b)
+     (,ffi:SDL_SCANCODE_C . c)
+     (,ffi:SDL_SCANCODE_D . d)
+     (,ffi:SDL_SCANCODE_E . e)
+     (,ffi:SDL_SCANCODE_F . f)
+     (,ffi:SDL_SCANCODE_G . g)
+     (,ffi:SDL_SCANCODE_H . h)
+     (,ffi:SDL_SCANCODE_I . i)
+     (,ffi:SDL_SCANCODE_J . j)
+     (,ffi:SDL_SCANCODE_K . k)
+     (,ffi:SDL_SCANCODE_L . l)
+     (,ffi:SDL_SCANCODE_M . m)
+     (,ffi:SDL_SCANCODE_N . n)
+     (,ffi:SDL_SCANCODE_O . o)
+     (,ffi:SDL_SCANCODE_P . p)
+     (,ffi:SDL_SCANCODE_Q . q)
+     (,ffi:SDL_SCANCODE_R . r)
+     (,ffi:SDL_SCANCODE_S . s)
+     (,ffi:SDL_SCANCODE_T . t)
+     (,ffi:SDL_SCANCODE_U . u)
+     (,ffi:SDL_SCANCODE_V . v)
+     (,ffi:SDL_SCANCODE_W . w)
+     (,ffi:SDL_SCANCODE_X . x)
+     (,ffi:SDL_SCANCODE_Y . y)
+     (,ffi:SDL_SCANCODE_Z . z)
+     (,ffi:SDL_SCANCODE_1 . 1)
+     (,ffi:SDL_SCANCODE_2 . 2)
+     (,ffi:SDL_SCANCODE_3 . 3)
+     (,ffi:SDL_SCANCODE_4 . 4)
+     (,ffi:SDL_SCANCODE_5 . 5)
+     (,ffi:SDL_SCANCODE_6 . 6)
+     (,ffi:SDL_SCANCODE_7 . 7)
+     (,ffi:SDL_SCANCODE_8 . 8)
+     (,ffi:SDL_SCANCODE_9 . 9)
+     (,ffi:SDL_SCANCODE_0 . 0)
+     (,ffi:SDL_SCANCODE_RETURN . return)
+     (,ffi:SDL_SCANCODE_ESCAPE . escape)
+     (,ffi:SDL_SCANCODE_BACKSPACE . backspace)
+     (,ffi:SDL_SCANCODE_TAB . tab)
+     (,ffi:SDL_SCANCODE_SPACE . space)
+     (,ffi:SDL_SCANCODE_MINUS . minus)
+     (,ffi:SDL_SCANCODE_EQUALS . equals)
+     (,ffi:SDL_SCANCODE_LEFTBRACKET . left-bracket)
+     (,ffi:SDL_SCANCODE_RIGHTBRACKET . right-bracket)
+     (,ffi:SDL_SCANCODE_BACKSLASH . backslash)
+     (,ffi:SDL_SCANCODE_NONUSHASH . nonushash)
+     (,ffi:SDL_SCANCODE_SEMICOLON . semicolon)
+     (,ffi:SDL_SCANCODE_APOSTROPHE . apostrophe)
+     (,ffi:SDL_SCANCODE_GRAVE . grave)
+     (,ffi:SDL_SCANCODE_COMMA . comma)
+     (,ffi:SDL_SCANCODE_PERIOD . period)
+     (,ffi:SDL_SCANCODE_SLASH . slash)
+     (,ffi:SDL_SCANCODE_CAPSLOCK . caps-lock)
+     (,ffi:SDL_SCANCODE_F1 . f1)
+     (,ffi:SDL_SCANCODE_F2 . f2)
+     (,ffi:SDL_SCANCODE_F3 . f3)
+     (,ffi:SDL_SCANCODE_F4 . f4)
+     (,ffi:SDL_SCANCODE_F5 . f5)
+     (,ffi:SDL_SCANCODE_F6 . f6)
+     (,ffi:SDL_SCANCODE_F7 . f7)
+     (,ffi:SDL_SCANCODE_F8 . f8)
+     (,ffi:SDL_SCANCODE_F9 . f9)
+     (,ffi:SDL_SCANCODE_F10 . f10)
+     (,ffi:SDL_SCANCODE_F11 . f11)
+     (,ffi:SDL_SCANCODE_F12 . f12)
+     (,ffi:SDL_SCANCODE_PRINTSCREEN . print-screen)
+     (,ffi:SDL_SCANCODE_SCROLLLOCK . scroll-lock)
+     (,ffi:SDL_SCANCODE_PAUSE . pause)
+     (,ffi:SDL_SCANCODE_INSERT . insert)
+     (,ffi:SDL_SCANCODE_HOME . home)
+     (,ffi:SDL_SCANCODE_PAGEUP . page-up)
+     (,ffi:SDL_SCANCODE_DELETE . delete)
+     (,ffi:SDL_SCANCODE_END . end)
+     (,ffi:SDL_SCANCODE_PAGEDOWN . page-down)
+     (,ffi:SDL_SCANCODE_RIGHT . right)
+     (,ffi:SDL_SCANCODE_LEFT . left)
+     (,ffi:SDL_SCANCODE_DOWN . down)
+     (,ffi:SDL_SCANCODE_UP . up)
+     (,ffi:SDL_SCANCODE_NUMLOCKCLEAR . num-lock-clear)
+     (,ffi:SDL_SCANCODE_KP_DIVIDE . keypad-divide)
+     (,ffi:SDL_SCANCODE_KP_MULTIPLY . keypad-multiply)
+     (,ffi:SDL_SCANCODE_KP_MINUS . keypad-minus)
+     (,ffi:SDL_SCANCODE_KP_PLUS . keypad-plus)
+     (,ffi:SDL_SCANCODE_KP_ENTER . keypad-enter)
+     (,ffi:SDL_SCANCODE_KP_1 . keypad-1)
+     (,ffi:SDL_SCANCODE_KP_2 . keypad-2)
+     (,ffi:SDL_SCANCODE_KP_3 . keypad-3)
+     (,ffi:SDL_SCANCODE_KP_4 . keypad-4)
+     (,ffi:SDL_SCANCODE_KP_5 . keypad-5)
+     (,ffi:SDL_SCANCODE_KP_6 . keypad-6)
+     (,ffi:SDL_SCANCODE_KP_7 . keypad-7)
+     (,ffi:SDL_SCANCODE_KP_8 . keypad-8)
+     (,ffi:SDL_SCANCODE_KP_9 . keypad-9)
+     (,ffi:SDL_SCANCODE_KP_0 . keypad-0)
+     (,ffi:SDL_SCANCODE_KP_PERIOD . keypad-period)
+     (,ffi:SDL_SCANCODE_NONUSBACKSLASH . nonusbackslash)
+     (,ffi:SDL_SCANCODE_APPLICATION . application)
+     (,ffi:SDL_SCANCODE_POWER . power)
+     (,ffi:SDL_SCANCODE_KP_EQUALS . keypad-equals)
+     (,ffi:SDL_SCANCODE_F13 . f13)
+     (,ffi:SDL_SCANCODE_F14 . f14)
+     (,ffi:SDL_SCANCODE_F15 . f15)
+     (,ffi:SDL_SCANCODE_F16 . f16)
+     (,ffi:SDL_SCANCODE_F17 . f17)
+     (,ffi:SDL_SCANCODE_F18 . f18)
+     (,ffi:SDL_SCANCODE_F19 . f19)
+     (,ffi:SDL_SCANCODE_F20 . f20)
+     (,ffi:SDL_SCANCODE_F21 . f21)
+     (,ffi:SDL_SCANCODE_F22 . f22)
+     (,ffi:SDL_SCANCODE_F23 . f23)
+     (,ffi:SDL_SCANCODE_F24 . f24)
+     (,ffi:SDL_SCANCODE_EXECUTE . execute)
+     (,ffi:SDL_SCANCODE_HELP . help)
+     (,ffi:SDL_SCANCODE_MENU . menu)
+     (,ffi:SDL_SCANCODE_SELECT . select)
+     (,ffi:SDL_SCANCODE_STOP . stop)
+     (,ffi:SDL_SCANCODE_AGAIN . again)
+     (,ffi:SDL_SCANCODE_UNDO . undo)
+     (,ffi:SDL_SCANCODE_CUT . cut)
+     (,ffi:SDL_SCANCODE_COPY . copy)
+     (,ffi:SDL_SCANCODE_PASTE . paste)
+     (,ffi:SDL_SCANCODE_FIND . find)
+     (,ffi:SDL_SCANCODE_MUTE . mute)
+     (,ffi:SDL_SCANCODE_VOLUMEUP . volume-up)
+     (,ffi:SDL_SCANCODE_VOLUMEDOWN . volume-down)
+     (,ffi:SDL_SCANCODE_KP_COMMA . keypad-comma)
+     (,ffi:SDL_SCANCODE_KP_EQUALSAS400 . keypad-equalsas400)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL1 . international-1)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL2 . international-2)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL3 . international-3)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL4 . international-4)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL5 . international-5)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL6 . international-6)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL7 . international-7)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL8 . international-8)
+     (,ffi:SDL_SCANCODE_INTERNATIONAL9 . international-9)
+     (,ffi:SDL_SCANCODE_LANG1 . lang-1)
+     (,ffi:SDL_SCANCODE_LANG2 . lang-2)
+     (,ffi:SDL_SCANCODE_LANG3 . lang-3)
+     (,ffi:SDL_SCANCODE_LANG4 . lang-4)
+     (,ffi:SDL_SCANCODE_LANG5 . lang-5)
+     (,ffi:SDL_SCANCODE_LANG6 . lang-6)
+     (,ffi:SDL_SCANCODE_LANG7 . lang-7)
+     (,ffi:SDL_SCANCODE_LANG8 . lang-8)
+     (,ffi:SDL_SCANCODE_LANG9 . lang-9)
+     (,ffi:SDL_SCANCODE_ALTERASE . alt-erase)
+     (,ffi:SDL_SCANCODE_SYSREQ . sysreq)
+     (,ffi:SDL_SCANCODE_CANCEL . cancel)
+     (,ffi:SDL_SCANCODE_CLEAR . clear)
+     (,ffi:SDL_SCANCODE_PRIOR . prior)
+     (,ffi:SDL_SCANCODE_RETURN2 . return-2)
+     (,ffi:SDL_SCANCODE_SEPARATOR . separator)
+     (,ffi:SDL_SCANCODE_OUT . out)
+     (,ffi:SDL_SCANCODE_OPER . oper)
+     (,ffi:SDL_SCANCODE_CLEARAGAIN . clear-again)
+     (,ffi:SDL_SCANCODE_CRSEL . crsel)
+     (,ffi:SDL_SCANCODE_EXSEL . exsel)
+     (,ffi:SDL_SCANCODE_KP_00 . keypad-00)
+     (,ffi:SDL_SCANCODE_KP_000 . keypad-000)
+     (,ffi:SDL_SCANCODE_THOUSANDSSEPARATOR . thousands-separator)
+     (,ffi:SDL_SCANCODE_DECIMALSEPARATOR . decimal-separator)
+     (,ffi:SDL_SCANCODE_CURRENCYUNIT . currency-unit)
+     (,ffi:SDL_SCANCODE_CURRENCYSUBUNIT . current-subunit)
+     (,ffi:SDL_SCANCODE_KP_LEFTPAREN . keypad-left-paren)
+     (,ffi:SDL_SCANCODE_KP_RIGHTPAREN . keypad-right-paren)
+     (,ffi:SDL_SCANCODE_KP_LEFTBRACE . keypad-left-brace)
+     (,ffi:SDL_SCANCODE_KP_RIGHTBRACE . keypad-right-brace)
+     (,ffi:SDL_SCANCODE_KP_TAB . keypad-tab)
+     (,ffi:SDL_SCANCODE_KP_BACKSPACE . keypad-backspace)
+     (,ffi:SDL_SCANCODE_KP_A . keypad-a)
+     (,ffi:SDL_SCANCODE_KP_B . keypad-b)
+     (,ffi:SDL_SCANCODE_KP_C . keypad-c)
+     (,ffi:SDL_SCANCODE_KP_D . keypad-d)
+     (,ffi:SDL_SCANCODE_KP_E . keypad-e)
+     (,ffi:SDL_SCANCODE_KP_F . keypad-f)
+     (,ffi:SDL_SCANCODE_KP_XOR . keypad-xor)
+     (,ffi:SDL_SCANCODE_KP_POWER . keypad-power)
+     (,ffi:SDL_SCANCODE_KP_PERCENT . keypad-percent)
+     (,ffi:SDL_SCANCODE_KP_LESS . keypad-less)
+     (,ffi:SDL_SCANCODE_KP_GREATER . keypad-greater)
+     (,ffi:SDL_SCANCODE_KP_AMPERSAND . keypad-ampersand)
+     (,ffi:SDL_SCANCODE_KP_DBLAMPERSAND . keypad-double-ampersand)
+     (,ffi:SDL_SCANCODE_KP_VERTICALBAR . keypad-vertical-bar)
+     (,ffi:SDL_SCANCODE_KP_DBLVERTICALBAR . keypad-double-vertical-bar)
+     (,ffi:SDL_SCANCODE_KP_COLON . keypad-colon)
+     (,ffi:SDL_SCANCODE_KP_HASH . keypad-hash)
+     (,ffi:SDL_SCANCODE_KP_SPACE . keypad-space)
+     (,ffi:SDL_SCANCODE_KP_AT . keypad-at)
+     (,ffi:SDL_SCANCODE_KP_EXCLAM . keypad-exclam)
+     (,ffi:SDL_SCANCODE_KP_MEMSTORE . keypad-mem-store)
+     (,ffi:SDL_SCANCODE_KP_MEMRECALL . keypad-mem-recall)
+     (,ffi:SDL_SCANCODE_KP_MEMCLEAR . keypad-mem-clear)
+     (,ffi:SDL_SCANCODE_KP_MEMADD . keypad-mem-add)
+     (,ffi:SDL_SCANCODE_KP_MEMSUBTRACT . keypadd-mem-subtract)
+     (,ffi:SDL_SCANCODE_KP_MEMMULTIPLY . keypad-mem-multiply)
+     (,ffi:SDL_SCANCODE_KP_MEMDIVIDE . keypad-mem-divide)
+     (,ffi:SDL_SCANCODE_KP_PLUSMINUS . keypad-plus-minus)
+     (,ffi:SDL_SCANCODE_KP_CLEAR . keypad-clear)
+     (,ffi:SDL_SCANCODE_KP_CLEARENTRY . keypad-clear-entry)
+     (,ffi:SDL_SCANCODE_KP_BINARY . keypad-binary)
+     (,ffi:SDL_SCANCODE_KP_OCTAL . keypad-octal)
+     (,ffi:SDL_SCANCODE_KP_DECIMAL . keypad-decimal)
+     (,ffi:SDL_SCANCODE_KP_HEXADECIMAL . keypad-hexadecimal)
+     (,ffi:SDL_SCANCODE_LCTRL . left-control)
+     (,ffi:SDL_SCANCODE_LSHIFT . left-shift)
+     (,ffi:SDL_SCANCODE_LALT . left-alt)
+     (,ffi:SDL_SCANCODE_LGUI . left-gui)
+     (,ffi:SDL_SCANCODE_RCTRL . right-control)
+     (,ffi:SDL_SCANCODE_RSHIFT . right-shift)
+     (,ffi:SDL_SCANCODE_RALT . right-alt)
+     (,ffi:SDL_SCANCODE_RGUI . right-cui)
+     (,ffi:SDL_SCANCODE_MODE . mode)
+     (,ffi:SDL_SCANCODE_AUDIONEXT . audio-next)
+     (,ffi:SDL_SCANCODE_AUDIOPREV . audio-prev)
+     (,ffi:SDL_SCANCODE_AUDIOSTOP . audio-stop)
+     (,ffi:SDL_SCANCODE_AUDIOPLAY . audio-play)
+     (,ffi:SDL_SCANCODE_AUDIOMUTE . audio-mute)
+     (,ffi:SDL_SCANCODE_MEDIASELECT . media-select)
+     (,ffi:SDL_SCANCODE_WWW . www)
+     (,ffi:SDL_SCANCODE_MAIL . mail)
+     (,ffi:SDL_SCANCODE_CALCULATOR . calculator)
+     (,ffi:SDL_SCANCODE_COMPUTER . computer)
+     (,ffi:SDL_SCANCODE_AC_SEARCH . ac-search)
+     (,ffi:SDL_SCANCODE_AC_HOME . ac-home)
+     (,ffi:SDL_SCANCODE_AC_BACK . ac-back)
+     (,ffi:SDL_SCANCODE_AC_FORWARD . ac-forward)
+     (,ffi:SDL_SCANCODE_AC_STOP . ac-stop)
+     (,ffi:SDL_SCANCODE_AC_REFRESH . ac-refresh)
+     (,ffi:SDL_SCANCODE_AC_BOOKMARKS . ac-bookmarks)
+     (,ffi:SDL_SCANCODE_BRIGHTNESSDOWN . brightness-down)
+     (,ffi:SDL_SCANCODE_BRIGHTNESSUP . brightness-up)
+     (,ffi:SDL_SCANCODE_DISPLAYSWITCH . display-switch)
+     (,ffi:SDL_SCANCODE_KBDILLUMTOGGLE . keyboard-illum-toggle)
+     (,ffi:SDL_SCANCODE_KBDILLUMDOWN . keyboard-illum-down)
+     (,ffi:SDL_SCANCODE_KBDILLUMUP . keyboard-illum-up)
+     (,ffi:SDL_SCANCODE_EJECT . eject)
+     (,ffi:SDL_SCANCODE_SLEEP . sleep)
+     (,ffi:SDL_SCANCODE_APP1 . app-1)
+     (,ffi:SDL_SCANCODE_APP2 . app-2))))
+
+(define (parse-keyboard-event ptr)
+  (define types
+    (list uint32  ; type
+          uint32  ; timestamp
+          uint32  ; windowID
+          uint8   ; state
+          uint8   ; repeat
+          uint8   ; padding2
+          uint8   ; padding3
+          (list int       ; scancode
+                int       ; sym
+                uint16    ; mod
+                uint32))) ; unused
+
+  (define (mod->list mod)
+    (fold (lambda (pair prev)
+            (match pair
+              ((sym . bit)
+               (if (zero? (logand mod bit))
+                   prev
+                   (cons sym prev)))))
+          '()
+          `((left-shift    . ,ffi:KMOD_LSHIFT)
+            (right-shift   . ,ffi:KMOD_RSHIFT)
+            (left-control  . ,ffi:KMOD_LCTRL)
+            (right-control . ,ffi:KMOD_RCTRL)
+            (left-alt      . ,ffi:KMOD_LALT)
+            (right-alt     . ,ffi:KMOD_RALT)
+            (left-gui      . ,ffi:KMOD_LGUI)
+            (right-gui     . ,ffi:KMOD_RGUI)
+            (num-lock      . ,ffi:KMOD_NUM)
+            (caps-lock     . ,ffi:KMOD_CAPS)
+            (alt-gr        . ,ffi:KMOD_MODE))))
+
+  (define (keycode->symbol keycode)
+    (hash-ref keycode-map keycode))
+
+  (define (scancode->symbol scancode)
+    (hash-ref scancode-map scancode))
+
+  (match (parse-c-struct ptr types)
+    ((_ timestamp window-id state repeat _ _ (scancode sym mod _))
+     (make-keyboard-event timestamp
+                          window-id
+                          (= state ffi:SDL_PRESSED)
+                          repeat
+                          (keycode->symbol sym)
+                          (scancode->symbol scancode)
+                          (mod->list mod)))))
+
+\f
+;;;
+;;; Event management
+;;;
+
+(define (poll-event)
+  (let* ((e (make-sdl-event))
+         (ptr (bytevector->pointer e))
+         (result (ffi:sdl-poll-event ptr)))
+    (and (= result 1)
+         (let ((type (sdl-event-type e)))
+           (cond
+            ((= type ffi:SDL_WINDOWEVENT)
+             (parse-window-event ptr))
+            ((or (= type ffi:SDL_KEYDOWN)
+                 (= type ffi:SDL_KEYUP))
+             (parse-keyboard-event ptr))
+            (else 'fixme:unsupported-event))))))