1 /*
2 * ============================================================================
3 * Title: Event Handling Driver for SDL2
4 * Author: J. Zbiciak
5 * ============================================================================
6 * This is the platform-specific driver for SDL 1.x.
7 * ============================================================================
8 */
9
10 #include "config.h"
11 #include "sdl_jzintv.h"
12 #include "event/event_tbl.h"
13 #include "event/event_plat.h"
14 #include "event/event_sdl_pvt.h"
15
16 #define REMAP(x) (((x) & 0x1FF) | ((x) & (1ul << 30) ? 0x200 : 0))
17
18 /* ======================================================================== */
19 /* SDK_KEYMAP -- Maps SDLK values to EVENT values. */
20 /* ======================================================================== */
21 static const event_num_t sdl_keymap[] =
22 {
23 [REMAP(SDLK_UNKNOWN)] = EVENT_UNKNOWN,
24 [REMAP(SDLK_BACKSPACE)] = EVENT_BACKSPACE,
25 [REMAP(SDLK_TAB)] = EVENT_TAB,
26 [REMAP(SDLK_CLEAR)] = EVENT_CLEAR,
27 [REMAP(SDLK_RETURN)] = EVENT_RETURN,
28 [REMAP(SDLK_PAUSE)] = EVENT_PAUSE,
29 [REMAP(SDLK_ESCAPE)] = EVENT_ESCAPE,
30 [REMAP(SDLK_SPACE)] = EVENT_SPACE,
31 [REMAP(SDLK_EXCLAIM)] = EVENT_EXCLAIM,
32 [REMAP(SDLK_QUOTEDBL)] = EVENT_QUOTEDBL,
33 [REMAP(SDLK_HASH)] = EVENT_HASH,
34 [REMAP(SDLK_DOLLAR)] = EVENT_DOLLAR,
35 [REMAP(SDLK_AMPERSAND)] = EVENT_AMPERSAND,
36 [REMAP(SDLK_QUOTE)] = EVENT_QUOTE,
37 [REMAP(SDLK_LEFTPAREN)] = EVENT_LEFTPAREN,
38 [REMAP(SDLK_RIGHTPAREN)] = EVENT_RIGHTPAREN,
39 [REMAP(SDLK_ASTERISK)] = EVENT_ASTERISK,
40 [REMAP(SDLK_PLUS)] = EVENT_PLUS,
41 [REMAP(SDLK_COMMA)] = EVENT_COMMA,
42 [REMAP(SDLK_MINUS)] = EVENT_MINUS,
43 [REMAP(SDLK_PERIOD)] = EVENT_PERIOD,
44 [REMAP(SDLK_SLASH)] = EVENT_SLASH,
45 [REMAP(SDLK_0)] = EVENT_0,
46 [REMAP(SDLK_1)] = EVENT_1,
47 [REMAP(SDLK_2)] = EVENT_2,
48 [REMAP(SDLK_3)] = EVENT_3,
49 [REMAP(SDLK_4)] = EVENT_4,
50 [REMAP(SDLK_5)] = EVENT_5,
51 [REMAP(SDLK_6)] = EVENT_6,
52 [REMAP(SDLK_7)] = EVENT_7,
53 [REMAP(SDLK_8)] = EVENT_8,
54 [REMAP(SDLK_9)] = EVENT_9,
55 [REMAP(SDLK_COLON)] = EVENT_COLON,
56 [REMAP(SDLK_SEMICOLON)] = EVENT_SEMICOLON,
57 [REMAP(SDLK_LESS)] = EVENT_LESS,
58 [REMAP(SDLK_EQUALS)] = EVENT_EQUALS,
59 [REMAP(SDLK_GREATER)] = EVENT_GREATER,
60 [REMAP(SDLK_QUESTION)] = EVENT_QUESTION,
61 [REMAP(SDLK_AT)] = EVENT_AT,
62 [REMAP(SDLK_LEFTBRACKET)] = EVENT_LEFTBRACKET,
63 [REMAP(SDLK_BACKSLASH)] = EVENT_BACKSLASH,
64 [REMAP(SDLK_RIGHTBRACKET)] = EVENT_RIGHTBRACKET,
65 [REMAP(SDLK_CARET)] = EVENT_CARET,
66 [REMAP(SDLK_UNDERSCORE)] = EVENT_UNDERSCORE,
67 [REMAP(SDLK_BACKQUOTE)] = EVENT_BACKQUOTE,
68 [REMAP(SDLK_a)] = EVENT_A,
69 [REMAP(SDLK_b)] = EVENT_B,
70 [REMAP(SDLK_c)] = EVENT_C,
71 [REMAP(SDLK_d)] = EVENT_D,
72 [REMAP(SDLK_e)] = EVENT_E,
73 [REMAP(SDLK_f)] = EVENT_F,
74 [REMAP(SDLK_g)] = EVENT_G,
75 [REMAP(SDLK_h)] = EVENT_H,
76 [REMAP(SDLK_i)] = EVENT_I,
77 [REMAP(SDLK_j)] = EVENT_J,
78 [REMAP(SDLK_k)] = EVENT_K,
79 [REMAP(SDLK_l)] = EVENT_L,
80 [REMAP(SDLK_m)] = EVENT_M,
81 [REMAP(SDLK_n)] = EVENT_N,
82 [REMAP(SDLK_o)] = EVENT_O,
83 [REMAP(SDLK_p)] = EVENT_P,
84 [REMAP(SDLK_q)] = EVENT_Q,
85 [REMAP(SDLK_r)] = EVENT_R,
86 [REMAP(SDLK_s)] = EVENT_S,
87 [REMAP(SDLK_t)] = EVENT_T,
88 [REMAP(SDLK_u)] = EVENT_U,
89 [REMAP(SDLK_v)] = EVENT_V,
90 [REMAP(SDLK_w)] = EVENT_W,
91 [REMAP(SDLK_x)] = EVENT_X,
92 [REMAP(SDLK_y)] = EVENT_Y,
93 [REMAP(SDLK_z)] = EVENT_Z,
94 [REMAP(SDLK_DELETE)] = EVENT_DELETE,
95 [REMAP(SDLK_KP_0)] = EVENT_KP_0,
96 [REMAP(SDLK_KP_1)] = EVENT_KP_1,
97 [REMAP(SDLK_KP_2)] = EVENT_KP_2,
98 [REMAP(SDLK_KP_3)] = EVENT_KP_3,
99 [REMAP(SDLK_KP_4)] = EVENT_KP_4,
100 [REMAP(SDLK_KP_5)] = EVENT_KP_5,
101 [REMAP(SDLK_KP_6)] = EVENT_KP_6,
102 [REMAP(SDLK_KP_7)] = EVENT_KP_7,
103 [REMAP(SDLK_KP_8)] = EVENT_KP_8,
104 [REMAP(SDLK_KP_9)] = EVENT_KP_9,
105 [REMAP(SDLK_KP_PERIOD)] = EVENT_KP_PERIOD,
106 [REMAP(SDLK_KP_DIVIDE)] = EVENT_KP_DIVIDE,
107 [REMAP(SDLK_KP_MULTIPLY)] = EVENT_KP_MULTIPLY,
108 [REMAP(SDLK_KP_MINUS)] = EVENT_KP_MINUS,
109 [REMAP(SDLK_KP_PLUS)] = EVENT_KP_PLUS,
110 [REMAP(SDLK_KP_ENTER)] = EVENT_KP_ENTER,
111 [REMAP(SDLK_KP_EQUALS)] = EVENT_KP_EQUALS,
112 [REMAP(SDLK_UP)] = EVENT_UP,
113 [REMAP(SDLK_DOWN)] = EVENT_DOWN,
114 [REMAP(SDLK_RIGHT)] = EVENT_RIGHT,
115 [REMAP(SDLK_LEFT)] = EVENT_LEFT,
116 [REMAP(SDLK_INSERT)] = EVENT_INSERT,
117 [REMAP(SDLK_HOME)] = EVENT_HOME,
118 [REMAP(SDLK_END)] = EVENT_END,
119 [REMAP(SDLK_PAGEUP)] = EVENT_PAGEUP,
120 [REMAP(SDLK_PAGEDOWN)] = EVENT_PAGEDOWN,
121 [REMAP(SDLK_F1)] = EVENT_F1,
122 [REMAP(SDLK_F2)] = EVENT_F2,
123 [REMAP(SDLK_F3)] = EVENT_F3,
124 [REMAP(SDLK_F4)] = EVENT_F4,
125 [REMAP(SDLK_F5)] = EVENT_F5,
126 [REMAP(SDLK_F6)] = EVENT_F6,
127 [REMAP(SDLK_F7)] = EVENT_F7,
128 [REMAP(SDLK_F8)] = EVENT_F8,
129 [REMAP(SDLK_F9)] = EVENT_F9,
130 [REMAP(SDLK_F10)] = EVENT_F10,
131 [REMAP(SDLK_F11)] = EVENT_F11,
132 [REMAP(SDLK_F12)] = EVENT_F12,
133 [REMAP(SDLK_F13)] = EVENT_F13,
134 [REMAP(SDLK_F14)] = EVENT_F14,
135 [REMAP(SDLK_F15)] = EVENT_F15,
136 [REMAP(SDLK_NUMLOCKCLEAR)] = EVENT_NUMLOCK,
137 [REMAP(SDLK_CAPSLOCK)] = EVENT_CAPSLOCK,
138 [REMAP(SDLK_SCROLLLOCK)] = EVENT_SCROLLOCK,
139 [REMAP(SDLK_RSHIFT)] = EVENT_RSHIFT,
140 [REMAP(SDLK_LSHIFT)] = EVENT_LSHIFT,
141 [REMAP(SDLK_RCTRL)] = EVENT_RCTRL,
142 [REMAP(SDLK_LCTRL)] = EVENT_LCTRL,
143 [REMAP(SDLK_RALT)] = EVENT_RALT,
144 [REMAP(SDLK_LALT)] = EVENT_LALT,
145 [REMAP(SDLK_MODE)] = EVENT_MODE,
146 [REMAP(SDLK_HELP)] = EVENT_HELP,
147 [REMAP(SDLK_PRINTSCREEN)] = EVENT_PRINT,
148 [REMAP(SDLK_SYSREQ)] = EVENT_SYSREQ,
149 [REMAP(SDLK_MENU)] = EVENT_MENU,
150 [REMAP(SDLK_POWER)] = EVENT_POWER,
151 [REMAP(SDLK_UNDO)] = EVENT_UNDO,
152
153 /* New for SDL2 */
154 [REMAP(SDLK_LGUI)] = EVENT_LGUI,
155 [REMAP(SDLK_RGUI)] = EVENT_RGUI,
156 [REMAP(SDLK_F16)] = EVENT_F16,
157 [REMAP(SDLK_F17)] = EVENT_F17,
158 [REMAP(SDLK_F18)] = EVENT_F18,
159 [REMAP(SDLK_F19)] = EVENT_F19,
160 [REMAP(SDLK_F20)] = EVENT_F20,
161 [REMAP(SDLK_F21)] = EVENT_F21,
162 [REMAP(SDLK_F22)] = EVENT_F22,
163 [REMAP(SDLK_F23)] = EVENT_F23,
164 [REMAP(SDLK_F24)] = EVENT_F24,
165 [REMAP(SDLK_SELECT)] = EVENT_SELECT,
166 [REMAP(SDLK_STOP)] = EVENT_STOP,
167 [REMAP(SDLK_AGAIN)] = EVENT_AGAIN,
168 [REMAP(SDLK_CUT)] = EVENT_CUT,
169 [REMAP(SDLK_COPY)] = EVENT_COPY,
170 [REMAP(SDLK_PASTE)] = EVENT_PASTE,
171 [REMAP(SDLK_FIND)] = EVENT_FIND,
172 [REMAP(SDLK_MUTE)] = EVENT_MUTE,
173 [REMAP(SDLK_VOLUMEUP)] = EVENT_VOLUMEUP,
174 [REMAP(SDLK_VOLUMEDOWN)] = EVENT_VOLUMEDOWN,
175 [REMAP(SDLK_KP_COMMA)] = EVENT_KP_COMMA,
176 [REMAP(SDLK_KP_000)] = EVENT_KP_000,
177 [REMAP(SDLK_KP_00)] = EVENT_KP_00,
178 [REMAP(SDLK_KP_EQUALSAS400)] = EVENT_KP_EQUALSAS400,
179 [REMAP(SDLK_CANCEL)] = EVENT_CANCEL,
180 [REMAP(SDLK_PRIOR)] = EVENT_PRIOR,
181 [REMAP(SDLK_SEPARATOR)] = EVENT_SEPARATOR,
182 [REMAP(SDLK_OUT)] = EVENT_OUT,
183 [REMAP(SDLK_OPER)] = EVENT_OPER,
184 [REMAP(SDLK_CLEARAGAIN)] = EVENT_CLEARAGAIN,
185 [REMAP(SDLK_CRSEL)] = EVENT_CRSEL,
186 [REMAP(SDLK_EXSEL)] = EVENT_EXSEL,
187 [REMAP(SDLK_THOUSANDSSEPARATOR)] = EVENT_THOUSANDSSEPARATOR,
188 [REMAP(SDLK_DECIMALSEPARATOR)] = EVENT_DECIMALSEPARATOR,
189 [REMAP(SDLK_CURRENCYUNIT)] = EVENT_CURRENCYUNIT,
190 [REMAP(SDLK_CURRENCYSUBUNIT)] = EVENT_CURRENCYSUBUNIT,
191 [REMAP(SDLK_KP_LEFTPAREN)] = EVENT_KP_LEFTPAREN,
192 [REMAP(SDLK_KP_RIGHTPAREN)] = EVENT_KP_RIGHTPAREN,
193 [REMAP(SDLK_KP_LEFTBRACE)] = EVENT_KP_LEFTBRACE,
194 [REMAP(SDLK_KP_RIGHTBRACE)] = EVENT_KP_RIGHTBRACE,
195 [REMAP(SDLK_KP_TAB)] = EVENT_KP_TAB,
196 [REMAP(SDLK_KP_BACKSPACE)] = EVENT_KP_BACKSPACE,
197 [REMAP(SDLK_KP_A)] = EVENT_KP_A,
198 [REMAP(SDLK_KP_B)] = EVENT_KP_B,
199 [REMAP(SDLK_KP_C)] = EVENT_KP_C,
200 [REMAP(SDLK_KP_D)] = EVENT_KP_D,
201 [REMAP(SDLK_KP_E)] = EVENT_KP_E,
202 [REMAP(SDLK_KP_F)] = EVENT_KP_F,
203 [REMAP(SDLK_KP_XOR)] = EVENT_KP_XOR,
204 [REMAP(SDLK_KP_POWER)] = EVENT_KP_POWER,
205 [REMAP(SDLK_KP_PERCENT)] = EVENT_KP_PERCENT,
206 [REMAP(SDLK_KP_LESS)] = EVENT_KP_LESS,
207 [REMAP(SDLK_KP_GREATER)] = EVENT_KP_GREATER,
208 [REMAP(SDLK_KP_AMPERSAND)] = EVENT_KP_AMPERSAND,
209 [REMAP(SDLK_KP_DBLAMPERSAND)] = EVENT_KP_DBLAMPERSAND,
210 [REMAP(SDLK_KP_VERTICALBAR)] = EVENT_KP_VERTICALBAR,
211 [REMAP(SDLK_KP_DBLVERTICALBAR)] = EVENT_KP_DBLVERTICALBAR,
212 [REMAP(SDLK_KP_COLON)] = EVENT_KP_COLON,
213 [REMAP(SDLK_KP_HASH)] = EVENT_KP_HASH,
214 [REMAP(SDLK_KP_SPACE)] = EVENT_KP_SPACE,
215 [REMAP(SDLK_KP_AT)] = EVENT_KP_AT,
216 [REMAP(SDLK_KP_EXCLAM)] = EVENT_KP_EXCLAIM,
217 [REMAP(SDLK_KP_MEMSTORE)] = EVENT_KP_MEMSTORE,
218 [REMAP(SDLK_KP_MEMRECALL)] = EVENT_KP_MEMRECALL,
219 [REMAP(SDLK_KP_MEMCLEAR)] = EVENT_KP_MEMCLEAR,
220 [REMAP(SDLK_KP_MEMADD)] = EVENT_KP_MEMADD,
221 [REMAP(SDLK_KP_MEMSUBTRACT)] = EVENT_KP_MEMSUBTRACT,
222 [REMAP(SDLK_KP_MEMMULTIPLY)] = EVENT_KP_MEMMULTIPLY,
223 [REMAP(SDLK_KP_MEMDIVIDE)] = EVENT_KP_MEMDIVIDE,
224 [REMAP(SDLK_KP_PLUSMINUS)] = EVENT_KP_PLUSMINUS,
225 [REMAP(SDLK_KP_CLEAR)] = EVENT_KP_CLEAR,
226 [REMAP(SDLK_KP_CLEARENTRY)] = EVENT_KP_CLEARENTRY,
227 [REMAP(SDLK_KP_BINARY)] = EVENT_KP_BINARY,
228 [REMAP(SDLK_KP_OCTAL)] = EVENT_KP_OCTAL,
229 [REMAP(SDLK_KP_DECIMAL)] = EVENT_KP_DECIMAL,
230 [REMAP(SDLK_KP_HEXADECIMAL)] = EVENT_KP_HEXADECIMAL,
231 [REMAP(SDLK_AUDIONEXT)] = EVENT_AUDIONEXT,
232 [REMAP(SDLK_AUDIOPREV)] = EVENT_AUDIOPREV,
233 [REMAP(SDLK_AUDIOSTOP)] = EVENT_AUDIOSTOP,
234 [REMAP(SDLK_AUDIOPLAY)] = EVENT_AUDIOPLAY,
235 [REMAP(SDLK_AUDIOMUTE)] = EVENT_AUDIOMUTE,
236 [REMAP(SDLK_MEDIASELECT)] = EVENT_MEDIASELECT,
237 [REMAP(SDLK_WWW)] = EVENT_WWW,
238 [REMAP(SDLK_MAIL)] = EVENT_MAIL,
239 [REMAP(SDLK_CALCULATOR)] = EVENT_CALCULATOR,
240 [REMAP(SDLK_COMPUTER)] = EVENT_COMPUTER,
241 [REMAP(SDLK_AC_SEARCH)] = EVENT_AC_SEARCH,
242 [REMAP(SDLK_AC_HOME)] = EVENT_AC_HOME,
243 [REMAP(SDLK_AC_BACK)] = EVENT_AC_BACK,
244 [REMAP(SDLK_AC_FORWARD)] = EVENT_AC_FORWARD,
245 [REMAP(SDLK_AC_STOP)] = EVENT_AC_STOP,
246 [REMAP(SDLK_AC_REFRESH)] = EVENT_AC_REFRESH,
247 [REMAP(SDLK_AC_BOOKMARKS)] = EVENT_AC_BOOKMARKS,
248 [REMAP(SDLK_BRIGHTNESSDOWN)] = EVENT_BRIGHTNESSDOWN,
249 [REMAP(SDLK_BRIGHTNESSUP)] = EVENT_BRIGHTNESSUP,
250 [REMAP(SDLK_DISPLAYSWITCH)] = EVENT_DISPLAYSWITCH,
251 [REMAP(SDLK_KBDILLUMTOGGLE)] = EVENT_KBDILLUMTOGGLE,
252 [REMAP(SDLK_KBDILLUMDOWN)] = EVENT_KBDILLUMDOWN,
253 [REMAP(SDLK_KBDILLUMUP)] = EVENT_KBDILLUMUP,
254 [REMAP(SDLK_EJECT)] = EVENT_EJECT,
255 [REMAP(SDLK_SLEEP)] = EVENT_SLEEP,
256 };
257
258 static const int sdl_keymap_size = sizeof(sdl_keymap) / sizeof(sdl_keymap[0]);
259
260 /* ======================================================================== */
261 /* EVENT_SDL_TRANSLATE_KEY -- Translate an SDLKey to event_num_t. */
262 /* ======================================================================== */
event_sdl_translate_key(const SDL_Event * const event)263 event_num_t event_sdl_translate_key(const SDL_Event *const event)
264 {
265 const int remapped_key = REMAP(event->key.keysym.sym);
266 const event_num_t primary =
267 remapped_key < sdl_keymap_size ? sdl_keymap[remapped_key]
268 : EVENT_UNKNOWN;
269 if (primary != EVENT_UNKNOWN)
270 return primary;
271
272 if (event->key.keysym.scancode < 0x200)
273 return EVENT_NUM_OFS(EVENT_SCANCODE_000, event->key.keysym.scancode);
274
275 return EVENT_UNKNOWN;
276 }
277
278 /* ======================================================================== */
279 /* EVENT_SDL_UNHANDLED_EVENT -- Hook for SDL-version specific events. */
280 /* Returns true if the event ended up queuing a COMBO, false otherwise. */
281 /* ======================================================================== */
event_sdl_unhandled_event(evt_pvt_t * const evt_pvt,const SDL_Event * const event)282 bool event_sdl_unhandled_event(evt_pvt_t *const evt_pvt,
283 const SDL_Event *const event)
284 {
285 switch (event->type)
286 {
287 /* ---------------------------------------------------------------- */
288 /* Window events: Only look at whether we're iconified or not, */
289 /* and convert it to an up/down event on EVENT_HIDE. */
290 /* ---------------------------------------------------------------- */
291 case SDL_WINDOWEVENT:
292 {
293 switch (event->window.event)
294 {
295 case SDL_WINDOWEVENT_MINIMIZED:
296 event_enqueue(evt_pvt, EV_DOWN, EVENT_HIDE);
297 break;
298
299 case SDL_WINDOWEVENT_RESTORED:
300 case SDL_WINDOWEVENT_MAXIMIZED:
301 case SDL_WINDOWEVENT_SHOWN:
302 event_enqueue(evt_pvt, EV_UP, EVENT_HIDE);
303 break;
304
305 case SDL_WINDOWEVENT_FOCUS_GAINED:
306 event_enqueue(evt_pvt, EV_DOWN, EVENT_FOCUS_GAINED);
307 event_enqueue(evt_pvt, EV_UP, EVENT_FOCUS_GAINED);
308 break;
309
310 case SDL_WINDOWEVENT_FOCUS_LOST:
311 event_enqueue(evt_pvt, EV_DOWN, EVENT_FOCUS_LOST);
312 event_enqueue(evt_pvt, EV_UP, EVENT_FOCUS_LOST);
313 break;
314
315 default:
316 break;
317 }
318 break;
319 }
320 default:
321 break;
322 }
323 return false;
324 }
325
326 /* ======================================================================== */
327 /* This program is free software; you can redistribute it and/or modify */
328 /* it under the terms of the GNU General Public License as published by */
329 /* the Free Software Foundation; either version 2 of the License, or */
330 /* (at your option) any later version. */
331 /* */
332 /* This program is distributed in the hope that it will be useful, */
333 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
334 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
335 /* General Public License for more details. */
336 /* */
337 /* You should have received a copy of the GNU General Public License along */
338 /* with this program; if not, write to the Free Software Foundation, Inc., */
339 /* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
340 /* ======================================================================== */
341 /* Copyright (c) 2020-+Inf, Joseph Zbiciak */
342 /* ======================================================================== */
343