SDL  2.0
SDL_emscriptenevents.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 
23 #include "../../SDL_internal.h"
24 
25 #if SDL_VIDEO_DRIVER_EMSCRIPTEN
26 
27 #include <emscripten/html5.h>
28 
29 #include "../../events/SDL_events_c.h"
30 #include "../../events/SDL_keyboard_c.h"
31 #include "../../events/SDL_touch_c.h"
32 
33 #include "SDL_emscriptenevents.h"
34 #include "SDL_emscriptenvideo.h"
35 
36 #include "SDL_hints.h"
37 
38 #define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN )
39 
40 /*
41 .keyCode to scancode
42 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent
43 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
44 */
45 static const SDL_Scancode emscripten_scancode_table[] = {
46  /* 0 */ SDL_SCANCODE_UNKNOWN,
47  /* 1 */ SDL_SCANCODE_UNKNOWN,
48  /* 2 */ SDL_SCANCODE_UNKNOWN,
49  /* 3 */ SDL_SCANCODE_CANCEL,
50  /* 4 */ SDL_SCANCODE_UNKNOWN,
51  /* 5 */ SDL_SCANCODE_UNKNOWN,
52  /* 6 */ SDL_SCANCODE_HELP,
53  /* 7 */ SDL_SCANCODE_UNKNOWN,
54  /* 8 */ SDL_SCANCODE_BACKSPACE,
55  /* 9 */ SDL_SCANCODE_TAB,
56  /* 10 */ SDL_SCANCODE_UNKNOWN,
57  /* 11 */ SDL_SCANCODE_UNKNOWN,
58  /* 12 */ SDL_SCANCODE_KP_5,
59  /* 13 */ SDL_SCANCODE_RETURN,
60  /* 14 */ SDL_SCANCODE_UNKNOWN,
61  /* 15 */ SDL_SCANCODE_UNKNOWN,
62  /* 16 */ SDL_SCANCODE_LSHIFT,
63  /* 17 */ SDL_SCANCODE_LCTRL,
64  /* 18 */ SDL_SCANCODE_LALT,
65  /* 19 */ SDL_SCANCODE_PAUSE,
66  /* 20 */ SDL_SCANCODE_CAPSLOCK,
67  /* 21 */ SDL_SCANCODE_UNKNOWN,
68  /* 22 */ SDL_SCANCODE_UNKNOWN,
69  /* 23 */ SDL_SCANCODE_UNKNOWN,
70  /* 24 */ SDL_SCANCODE_UNKNOWN,
71  /* 25 */ SDL_SCANCODE_UNKNOWN,
72  /* 26 */ SDL_SCANCODE_UNKNOWN,
73  /* 27 */ SDL_SCANCODE_ESCAPE,
74  /* 28 */ SDL_SCANCODE_UNKNOWN,
75  /* 29 */ SDL_SCANCODE_UNKNOWN,
76  /* 30 */ SDL_SCANCODE_UNKNOWN,
77  /* 31 */ SDL_SCANCODE_UNKNOWN,
78  /* 32 */ SDL_SCANCODE_SPACE,
79  /* 33 */ SDL_SCANCODE_PAGEUP,
80  /* 34 */ SDL_SCANCODE_PAGEDOWN,
81  /* 35 */ SDL_SCANCODE_END,
82  /* 36 */ SDL_SCANCODE_HOME,
83  /* 37 */ SDL_SCANCODE_LEFT,
84  /* 38 */ SDL_SCANCODE_UP,
85  /* 39 */ SDL_SCANCODE_RIGHT,
86  /* 40 */ SDL_SCANCODE_DOWN,
87  /* 41 */ SDL_SCANCODE_UNKNOWN,
88  /* 42 */ SDL_SCANCODE_UNKNOWN,
89  /* 43 */ SDL_SCANCODE_UNKNOWN,
90  /* 44 */ SDL_SCANCODE_UNKNOWN,
91  /* 45 */ SDL_SCANCODE_INSERT,
92  /* 46 */ SDL_SCANCODE_DELETE,
93  /* 47 */ SDL_SCANCODE_UNKNOWN,
94  /* 48 */ SDL_SCANCODE_0,
95  /* 49 */ SDL_SCANCODE_1,
96  /* 50 */ SDL_SCANCODE_2,
97  /* 51 */ SDL_SCANCODE_3,
98  /* 52 */ SDL_SCANCODE_4,
99  /* 53 */ SDL_SCANCODE_5,
100  /* 54 */ SDL_SCANCODE_6,
101  /* 55 */ SDL_SCANCODE_7,
102  /* 56 */ SDL_SCANCODE_8,
103  /* 57 */ SDL_SCANCODE_9,
104  /* 58 */ SDL_SCANCODE_UNKNOWN,
105  /* 59 */ SDL_SCANCODE_SEMICOLON,
107  /* 61 */ SDL_SCANCODE_EQUALS,
108  /* 62 */ SDL_SCANCODE_UNKNOWN,
109  /* 63 */ SDL_SCANCODE_MINUS,
110  /* 64 */ SDL_SCANCODE_UNKNOWN,
111  /* 65 */ SDL_SCANCODE_A,
112  /* 66 */ SDL_SCANCODE_B,
113  /* 67 */ SDL_SCANCODE_C,
114  /* 68 */ SDL_SCANCODE_D,
115  /* 69 */ SDL_SCANCODE_E,
116  /* 70 */ SDL_SCANCODE_F,
117  /* 71 */ SDL_SCANCODE_G,
118  /* 72 */ SDL_SCANCODE_H,
119  /* 73 */ SDL_SCANCODE_I,
120  /* 74 */ SDL_SCANCODE_J,
121  /* 75 */ SDL_SCANCODE_K,
122  /* 76 */ SDL_SCANCODE_L,
123  /* 77 */ SDL_SCANCODE_M,
124  /* 78 */ SDL_SCANCODE_N,
125  /* 79 */ SDL_SCANCODE_O,
126  /* 80 */ SDL_SCANCODE_P,
127  /* 81 */ SDL_SCANCODE_Q,
128  /* 82 */ SDL_SCANCODE_R,
129  /* 83 */ SDL_SCANCODE_S,
130  /* 84 */ SDL_SCANCODE_T,
131  /* 85 */ SDL_SCANCODE_U,
132  /* 86 */ SDL_SCANCODE_V,
133  /* 87 */ SDL_SCANCODE_W,
134  /* 88 */ SDL_SCANCODE_X,
135  /* 89 */ SDL_SCANCODE_Y,
136  /* 90 */ SDL_SCANCODE_Z,
137  /* 91 */ SDL_SCANCODE_LGUI,
138  /* 92 */ SDL_SCANCODE_UNKNOWN,
139  /* 93 */ SDL_SCANCODE_APPLICATION,
140  /* 94 */ SDL_SCANCODE_UNKNOWN,
141  /* 95 */ SDL_SCANCODE_UNKNOWN,
142  /* 96 */ SDL_SCANCODE_KP_0,
143  /* 97 */ SDL_SCANCODE_KP_1,
144  /* 98 */ SDL_SCANCODE_KP_2,
145  /* 99 */ SDL_SCANCODE_KP_3,
146  /* 100 */ SDL_SCANCODE_KP_4,
147  /* 101 */ SDL_SCANCODE_KP_5,
148  /* 102 */ SDL_SCANCODE_KP_6,
149  /* 103 */ SDL_SCANCODE_KP_7,
150  /* 104 */ SDL_SCANCODE_KP_8,
151  /* 105 */ SDL_SCANCODE_KP_9,
152  /* 106 */ SDL_SCANCODE_KP_MULTIPLY,
153  /* 107 */ SDL_SCANCODE_KP_PLUS,
154  /* 108 */ SDL_SCANCODE_UNKNOWN,
155  /* 109 */ SDL_SCANCODE_KP_MINUS,
156  /* 110 */ SDL_SCANCODE_KP_PERIOD,
157  /* 111 */ SDL_SCANCODE_KP_DIVIDE,
158  /* 112 */ SDL_SCANCODE_F1,
159  /* 113 */ SDL_SCANCODE_F2,
160  /* 114 */ SDL_SCANCODE_F3,
161  /* 115 */ SDL_SCANCODE_F4,
162  /* 116 */ SDL_SCANCODE_F5,
163  /* 117 */ SDL_SCANCODE_F6,
164  /* 118 */ SDL_SCANCODE_F7,
165  /* 119 */ SDL_SCANCODE_F8,
166  /* 120 */ SDL_SCANCODE_F9,
167  /* 121 */ SDL_SCANCODE_F10,
168  /* 122 */ SDL_SCANCODE_F11,
169  /* 123 */ SDL_SCANCODE_F12,
170  /* 124 */ SDL_SCANCODE_F13,
171  /* 125 */ SDL_SCANCODE_F14,
172  /* 126 */ SDL_SCANCODE_F15,
173  /* 127 */ SDL_SCANCODE_F16,
174  /* 128 */ SDL_SCANCODE_F17,
175  /* 129 */ SDL_SCANCODE_F18,
176  /* 130 */ SDL_SCANCODE_F19,
177  /* 131 */ SDL_SCANCODE_F20,
178  /* 132 */ SDL_SCANCODE_F21,
179  /* 133 */ SDL_SCANCODE_F22,
180  /* 134 */ SDL_SCANCODE_F23,
181  /* 135 */ SDL_SCANCODE_F24,
182  /* 136 */ SDL_SCANCODE_UNKNOWN,
183  /* 137 */ SDL_SCANCODE_UNKNOWN,
184  /* 138 */ SDL_SCANCODE_UNKNOWN,
185  /* 139 */ SDL_SCANCODE_UNKNOWN,
186  /* 140 */ SDL_SCANCODE_UNKNOWN,
187  /* 141 */ SDL_SCANCODE_UNKNOWN,
188  /* 142 */ SDL_SCANCODE_UNKNOWN,
189  /* 143 */ SDL_SCANCODE_UNKNOWN,
190  /* 144 */ SDL_SCANCODE_NUMLOCKCLEAR,
191  /* 145 */ SDL_SCANCODE_SCROLLLOCK,
192  /* 146 */ SDL_SCANCODE_UNKNOWN,
193  /* 147 */ SDL_SCANCODE_UNKNOWN,
194  /* 148 */ SDL_SCANCODE_UNKNOWN,
195  /* 149 */ SDL_SCANCODE_UNKNOWN,
196  /* 150 */ SDL_SCANCODE_UNKNOWN,
197  /* 151 */ SDL_SCANCODE_UNKNOWN,
198  /* 152 */ SDL_SCANCODE_UNKNOWN,
199  /* 153 */ SDL_SCANCODE_UNKNOWN,
200  /* 154 */ SDL_SCANCODE_UNKNOWN,
201  /* 155 */ SDL_SCANCODE_UNKNOWN,
202  /* 156 */ SDL_SCANCODE_UNKNOWN,
203  /* 157 */ SDL_SCANCODE_UNKNOWN,
204  /* 158 */ SDL_SCANCODE_UNKNOWN,
205  /* 159 */ SDL_SCANCODE_UNKNOWN,
206  /* 160 */ SDL_SCANCODE_GRAVE,
207  /* 161 */ SDL_SCANCODE_UNKNOWN,
208  /* 162 */ SDL_SCANCODE_UNKNOWN,
209  /* 163 */ SDL_SCANCODE_KP_HASH, /*KaiOS phone keypad*/
210  /* 164 */ SDL_SCANCODE_UNKNOWN,
211  /* 165 */ SDL_SCANCODE_UNKNOWN,
212  /* 166 */ SDL_SCANCODE_UNKNOWN,
213  /* 167 */ SDL_SCANCODE_UNKNOWN,
214  /* 168 */ SDL_SCANCODE_UNKNOWN,
215  /* 169 */ SDL_SCANCODE_UNKNOWN,
216  /* 170 */ SDL_SCANCODE_KP_MULTIPLY, /*KaiOS phone keypad*/
217  /* 171 */ SDL_SCANCODE_RIGHTBRACKET,
218  /* 172 */ SDL_SCANCODE_UNKNOWN,
219  /* 173 */ SDL_SCANCODE_MINUS, /*FX*/
220  /* 174 */ SDL_SCANCODE_VOLUMEDOWN, /*IE, Chrome*/
221  /* 175 */ SDL_SCANCODE_VOLUMEUP, /*IE, Chrome*/
222  /* 176 */ SDL_SCANCODE_AUDIONEXT, /*IE, Chrome*/
223  /* 177 */ SDL_SCANCODE_AUDIOPREV, /*IE, Chrome*/
224  /* 178 */ SDL_SCANCODE_UNKNOWN,
225  /* 179 */ SDL_SCANCODE_AUDIOPLAY, /*IE, Chrome*/
226  /* 180 */ SDL_SCANCODE_UNKNOWN,
227  /* 181 */ SDL_SCANCODE_AUDIOMUTE, /*FX*/
228  /* 182 */ SDL_SCANCODE_VOLUMEDOWN, /*FX*/
229  /* 183 */ SDL_SCANCODE_VOLUMEUP, /*FX*/
230  /* 184 */ SDL_SCANCODE_UNKNOWN,
231  /* 185 */ SDL_SCANCODE_UNKNOWN,
232  /* 186 */ SDL_SCANCODE_SEMICOLON, /*IE, Chrome, D3E legacy*/
233  /* 187 */ SDL_SCANCODE_EQUALS, /*IE, Chrome, D3E legacy*/
234  /* 188 */ SDL_SCANCODE_COMMA,
235  /* 189 */ SDL_SCANCODE_MINUS, /*IE, Chrome, D3E legacy*/
236  /* 190 */ SDL_SCANCODE_PERIOD,
237  /* 191 */ SDL_SCANCODE_SLASH,
238  /* 192 */ SDL_SCANCODE_GRAVE, /*FX, D3E legacy (SDL_SCANCODE_APOSTROPHE in IE/Chrome)*/
239  /* 193 */ SDL_SCANCODE_UNKNOWN,
240  /* 194 */ SDL_SCANCODE_UNKNOWN,
241  /* 195 */ SDL_SCANCODE_UNKNOWN,
242  /* 196 */ SDL_SCANCODE_UNKNOWN,
243  /* 197 */ SDL_SCANCODE_UNKNOWN,
244  /* 198 */ SDL_SCANCODE_UNKNOWN,
245  /* 199 */ SDL_SCANCODE_UNKNOWN,
246  /* 200 */ SDL_SCANCODE_UNKNOWN,
247  /* 201 */ SDL_SCANCODE_UNKNOWN,
248  /* 202 */ SDL_SCANCODE_UNKNOWN,
249  /* 203 */ SDL_SCANCODE_UNKNOWN,
250  /* 204 */ SDL_SCANCODE_UNKNOWN,
251  /* 205 */ SDL_SCANCODE_UNKNOWN,
252  /* 206 */ SDL_SCANCODE_UNKNOWN,
253  /* 207 */ SDL_SCANCODE_UNKNOWN,
254  /* 208 */ SDL_SCANCODE_UNKNOWN,
255  /* 209 */ SDL_SCANCODE_UNKNOWN,
256  /* 210 */ SDL_SCANCODE_UNKNOWN,
257  /* 211 */ SDL_SCANCODE_UNKNOWN,
258  /* 212 */ SDL_SCANCODE_UNKNOWN,
259  /* 213 */ SDL_SCANCODE_UNKNOWN,
260  /* 214 */ SDL_SCANCODE_UNKNOWN,
261  /* 215 */ SDL_SCANCODE_UNKNOWN,
262  /* 216 */ SDL_SCANCODE_UNKNOWN,
263  /* 217 */ SDL_SCANCODE_UNKNOWN,
264  /* 218 */ SDL_SCANCODE_UNKNOWN,
265  /* 219 */ SDL_SCANCODE_LEFTBRACKET,
266  /* 220 */ SDL_SCANCODE_BACKSLASH,
267  /* 221 */ SDL_SCANCODE_RIGHTBRACKET,
268  /* 222 */ SDL_SCANCODE_APOSTROPHE, /*FX, D3E legacy*/
269 };
270 
271 
272 /* "borrowed" from SDL_windowsevents.c */
273 static int
274 Emscripten_ConvertUTF32toUTF8(Uint32 codepoint, char * text)
275 {
276  if (codepoint <= 0x7F) {
277  text[0] = (char) codepoint;
278  text[1] = '\0';
279  } else if (codepoint <= 0x7FF) {
280  text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
281  text[1] = 0x80 | (char) (codepoint & 0x3F);
282  text[2] = '\0';
283  } else if (codepoint <= 0xFFFF) {
284  text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
285  text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
286  text[2] = 0x80 | (char) (codepoint & 0x3F);
287  text[3] = '\0';
288  } else if (codepoint <= 0x10FFFF) {
289  text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
290  text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
291  text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
292  text[3] = 0x80 | (char) (codepoint & 0x3F);
293  text[4] = '\0';
294  } else {
295  return SDL_FALSE;
296  }
297  return SDL_TRUE;
298 }
299 
300 static EM_BOOL
301 Emscripten_HandlePointerLockChange(int eventType, const EmscriptenPointerlockChangeEvent *changeEvent, void *userData)
302 {
303  SDL_WindowData *window_data = (SDL_WindowData *) userData;
304  /* keep track of lock losses, so we can regrab if/when appropriate. */
305  window_data->has_pointer_lock = changeEvent->isActive;
306  return 0;
307 }
308 
309 
310 static EM_BOOL
311 Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
312 {
313  SDL_WindowData *window_data = userData;
314  const int isPointerLocked = window_data->has_pointer_lock;
315  int mx, my;
316  static double residualx = 0, residualy = 0;
317 
318  /* rescale (in case canvas is being scaled)*/
319  double client_w, client_h, xscale, yscale;
320  emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h);
321  xscale = window_data->window->w / client_w;
322  yscale = window_data->window->h / client_h;
323 
324  if (isPointerLocked) {
325  residualx += mouseEvent->movementX * xscale;
326  residualy += mouseEvent->movementY * yscale;
327  /* Let slow sub-pixel motion accumulate. Don't lose it. */
328  mx = residualx;
329  residualx -= mx;
330  my = residualy;
331  residualy -= my;
332  } else {
333  mx = mouseEvent->targetX * xscale;
334  my = mouseEvent->targetY * yscale;
335  }
336 
337  SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
338  return 0;
339 }
340 
341 static EM_BOOL
342 Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
343 {
344  SDL_WindowData *window_data = userData;
345  Uint8 sdl_button;
346  Uint8 sdl_button_state;
347  SDL_EventType sdl_event_type;
348  double css_w, css_h;
349 
350  switch (mouseEvent->button) {
351  case 0:
352  sdl_button = SDL_BUTTON_LEFT;
353  break;
354  case 1:
355  sdl_button = SDL_BUTTON_MIDDLE;
356  break;
357  case 2:
358  sdl_button = SDL_BUTTON_RIGHT;
359  break;
360  default:
361  return 0;
362  }
363 
364  if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) {
365  if (SDL_GetMouse()->relative_mode && !window_data->has_pointer_lock) {
366  emscripten_request_pointerlock(window_data->canvas_id, 0); /* try to regrab lost pointer lock. */
367  }
368  sdl_button_state = SDL_PRESSED;
369  sdl_event_type = SDL_MOUSEBUTTONDOWN;
370  } else {
371  sdl_button_state = SDL_RELEASED;
372  sdl_event_type = SDL_MOUSEBUTTONUP;
373  }
374  SDL_SendMouseButton(window_data->window, 0, sdl_button_state, sdl_button);
375 
376  /* Do not consume the event if the mouse is outside of the canvas. */
377  emscripten_get_element_css_size(window_data->canvas_id, &css_w, &css_h);
378  if (mouseEvent->targetX < 0 || mouseEvent->targetX >= css_w ||
379  mouseEvent->targetY < 0 || mouseEvent->targetY >= css_h) {
380  return 0;
381  }
382 
383  return SDL_GetEventState(sdl_event_type) == SDL_ENABLE;
384 }
385 
386 static EM_BOOL
387 Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
388 {
389  SDL_WindowData *window_data = userData;
390 
391  int mx = mouseEvent->targetX, my = mouseEvent->targetY;
392  const int isPointerLocked = window_data->has_pointer_lock;
393 
394  if (!isPointerLocked) {
395  /* rescale (in case canvas is being scaled)*/
396  double client_w, client_h;
397  emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h);
398 
399  mx = mx * (window_data->window->w / client_w);
400  my = my * (window_data->window->h / client_h);
401  SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my);
402  }
403 
404  SDL_SetMouseFocus(eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? window_data->window : NULL);
406 }
407 
408 static EM_BOOL
409 Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData)
410 {
411  SDL_WindowData *window_data = userData;
412  SDL_SendMouseWheel(window_data->window, 0, (float)wheelEvent->deltaX, (float)-wheelEvent->deltaY, SDL_MOUSEWHEEL_NORMAL);
414 }
415 
416 static EM_BOOL
417 Emscripten_HandleFocus(int eventType, const EmscriptenFocusEvent *wheelEvent, void *userData)
418 {
419  SDL_WindowData *window_data = userData;
420  /* If the user switches away while keys are pressed (such as
421  * via Alt+Tab), key release events won't be received. */
422  if (eventType == EMSCRIPTEN_EVENT_BLUR) {
424  }
425 
426 
427  SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_FOCUS ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
429 }
430 
431 static EM_BOOL
432 Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
433 {
434  SDL_WindowData *window_data = (SDL_WindowData *) userData;
435  int i;
436  double client_w, client_h;
437  int preventDefault = 0;
438 
439  SDL_TouchID deviceId = 1;
440  if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
441  return 0;
442  }
443 
444  emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h);
445 
446  for (i = 0; i < touchEvent->numTouches; i++) {
448  float x, y;
449 
450  if (!touchEvent->touches[i].isChanged)
451  continue;
452 
453  id = touchEvent->touches[i].identifier;
454  x = touchEvent->touches[i].targetX / client_w;
455  y = touchEvent->touches[i].targetY / client_h;
456 
457  if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
458  SDL_SendTouch(deviceId, id, window_data->window, SDL_TRUE, x, y, 1.0f);
459 
460  /* disable browser scrolling/pinch-to-zoom if app handles touch events */
461  if (!preventDefault && SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
462  preventDefault = 1;
463  }
464  } else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) {
465  SDL_SendTouchMotion(deviceId, id, window_data->window, x, y, 1.0f);
466  } else {
467  SDL_SendTouch(deviceId, id, window_data->window, SDL_FALSE, x, y, 1.0f);
468 
469  /* block browser's simulated mousedown/mouseup on touchscreen devices */
470  preventDefault = 1;
471  }
472  }
473 
474  return preventDefault;
475 }
476 
477 static EM_BOOL
478 Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
479 {
480  Uint32 scancode;
481  SDL_bool prevent_default;
482  SDL_bool is_nav_key;
483 
484  /* .keyCode is deprecated, but still the most reliable way to get keys */
485  if (keyEvent->keyCode < SDL_arraysize(emscripten_scancode_table)) {
486  scancode = emscripten_scancode_table[keyEvent->keyCode];
487 
488  if (keyEvent->keyCode == 0) {
489  /* KaiOS Left Soft Key and Right Soft Key, they act as OK/Next/Menu and Cancel/Back/Clear */
490  if (SDL_strncmp(keyEvent->key, "SoftLeft", 9) == 0) {
491  scancode = SDL_SCANCODE_AC_FORWARD;
492  }
493  if (SDL_strncmp(keyEvent->key, "SoftRight", 10) == 0) {
494  scancode = SDL_SCANCODE_AC_BACK;
495  }
496  }
497 
498  if (scancode != SDL_SCANCODE_UNKNOWN) {
499 
500  if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) {
501  switch (scancode) {
502  case SDL_SCANCODE_LSHIFT:
503  scancode = SDL_SCANCODE_RSHIFT;
504  break;
505  case SDL_SCANCODE_LCTRL:
506  scancode = SDL_SCANCODE_RCTRL;
507  break;
508  case SDL_SCANCODE_LALT:
509  scancode = SDL_SCANCODE_RALT;
510  break;
511  case SDL_SCANCODE_LGUI:
512  scancode = SDL_SCANCODE_RGUI;
513  break;
514  }
515  }
516  else if (keyEvent->location == DOM_KEY_LOCATION_NUMPAD) {
517  switch (scancode) {
518  case SDL_SCANCODE_0:
519  case SDL_SCANCODE_INSERT:
520  scancode = SDL_SCANCODE_KP_0;
521  break;
522  case SDL_SCANCODE_1:
523  case SDL_SCANCODE_END:
524  scancode = SDL_SCANCODE_KP_1;
525  break;
526  case SDL_SCANCODE_2:
527  case SDL_SCANCODE_DOWN:
528  scancode = SDL_SCANCODE_KP_2;
529  break;
530  case SDL_SCANCODE_3:
532  scancode = SDL_SCANCODE_KP_3;
533  break;
534  case SDL_SCANCODE_4:
535  case SDL_SCANCODE_LEFT:
536  scancode = SDL_SCANCODE_KP_4;
537  break;
538  case SDL_SCANCODE_5:
539  scancode = SDL_SCANCODE_KP_5;
540  break;
541  case SDL_SCANCODE_6:
542  case SDL_SCANCODE_RIGHT:
543  scancode = SDL_SCANCODE_KP_6;
544  break;
545  case SDL_SCANCODE_7:
546  case SDL_SCANCODE_HOME:
547  scancode = SDL_SCANCODE_KP_7;
548  break;
549  case SDL_SCANCODE_8:
550  case SDL_SCANCODE_UP:
551  scancode = SDL_SCANCODE_KP_8;
552  break;
553  case SDL_SCANCODE_9:
554  case SDL_SCANCODE_PAGEUP:
555  scancode = SDL_SCANCODE_KP_9;
556  break;
557  case SDL_SCANCODE_RETURN:
558  scancode = SDL_SCANCODE_KP_ENTER;
559  break;
560  case SDL_SCANCODE_DELETE:
561  scancode = SDL_SCANCODE_KP_PERIOD;
562  break;
563  }
564  }
565  SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode);
566  }
567  }
568 
569  prevent_default = SDL_GetEventState(eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_KEYDOWN : SDL_KEYUP) == SDL_ENABLE;
570 
571  /* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress
572  * we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX
573  */
574  is_nav_key = keyEvent->keyCode == 8 /* backspace */ ||
575  keyEvent->keyCode == 9 /* tab */ ||
576  keyEvent->keyCode == 37 /* left */ ||
577  keyEvent->keyCode == 38 /* up */ ||
578  keyEvent->keyCode == 39 /* right */ ||
579  keyEvent->keyCode == 40 /* down */;
580 
581  if (eventType == EMSCRIPTEN_EVENT_KEYDOWN && SDL_GetEventState(SDL_TEXTINPUT) == SDL_ENABLE && !is_nav_key)
582  prevent_default = SDL_FALSE;
583 
584  return prevent_default;
585 }
586 
587 static EM_BOOL
588 Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
589 {
590  char text[5];
591  if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text)) {
593  }
595 }
596 
597 static EM_BOOL
598 Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData)
599 {
600  SDL_WindowData *window_data = userData;
601  SDL_VideoDisplay *display;
602 
603  if(fullscreenChangeEvent->isFullscreen)
604  {
605  window_data->window->flags |= window_data->requested_fullscreen_mode;
606 
607  window_data->requested_fullscreen_mode = 0;
608 
609  if(!window_data->requested_fullscreen_mode)
610  window_data->window->flags |= SDL_WINDOW_FULLSCREEN; /*we didn't request fullscreen*/
611  }
612  else
613  {
614  window_data->window->flags &= ~FULLSCREEN_MASK;
615 
616  /* reset fullscreen window if the browser left fullscreen */
617  display = SDL_GetDisplayForWindow(window_data->window);
618 
619  if (display->fullscreen_window == window_data->window) {
620  display->fullscreen_window = NULL;
621  }
622  }
623 
624  return 0;
625 }
626 
627 static EM_BOOL
628 Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
629 {
630  SDL_WindowData *window_data = userData;
631  SDL_bool force = SDL_FALSE;
632 
633  /* update pixel ratio */
634  if (window_data->window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
635  if (window_data->pixel_ratio != emscripten_get_device_pixel_ratio()) {
636  window_data->pixel_ratio = emscripten_get_device_pixel_ratio();
637  force = SDL_TRUE;
638  }
639  }
640 
641  if(!(window_data->window->flags & FULLSCREEN_MASK))
642  {
643  /* this will only work if the canvas size is set through css */
644  if(window_data->window->flags & SDL_WINDOW_RESIZABLE)
645  {
646  double w = window_data->window->w;
647  double h = window_data->window->h;
648 
649  if(window_data->external_size) {
650  emscripten_get_element_css_size(window_data->canvas_id, &w, &h);
651  }
652 
653  emscripten_set_canvas_element_size(window_data->canvas_id, w * window_data->pixel_ratio, h * window_data->pixel_ratio);
654 
655  /* set_canvas_size unsets this */
656  if (!window_data->external_size && window_data->pixel_ratio != 1.0f) {
657  emscripten_set_element_css_size(window_data->canvas_id, w, h);
658  }
659 
660  if (force) {
661  /* force the event to trigger, so pixel ratio changes can be handled */
662  window_data->window->w = 0;
663  window_data->window->h = 0;
664  }
665 
667  }
668  }
669 
670  return 0;
671 }
672 
673 EM_BOOL
674 Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData)
675 {
676  /*this is used during fullscreen changes*/
677  SDL_WindowData *window_data = userData;
678 
679  if(window_data->fullscreen_resize)
680  {
681  double css_w, css_h;
682  emscripten_get_element_css_size(window_data->canvas_id, &css_w, &css_h);
683  SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, css_w, css_h);
684  }
685 
686  return 0;
687 }
688 
689 static EM_BOOL
690 Emscripten_HandleVisibilityChange(int eventType, const EmscriptenVisibilityChangeEvent *visEvent, void *userData)
691 {
692  SDL_WindowData *window_data = userData;
693  SDL_SendWindowEvent(window_data->window, visEvent->hidden ? SDL_WINDOWEVENT_HIDDEN : SDL_WINDOWEVENT_SHOWN, 0, 0);
694  return 0;
695 }
696 
697 static const char*
698 Emscripten_HandleBeforeUnload(int eventType, const void *reserved, void *userData)
699 {
700  /* This event will need to be handled synchronously, e.g. using
701  SDL_AddEventWatch, as the page is being closed *now*. */
702  /* No need to send a SDL_QUIT, the app won't get control again. */
704  return ""; /* don't trigger confirmation dialog */
705 }
706 
707 void
709 {
710  const char *keyElement;
711 
712  /* There is only one window and that window is the canvas */
713  emscripten_set_mousemove_callback(data->canvas_id, data, 0, Emscripten_HandleMouseMove);
714 
715  emscripten_set_mousedown_callback(data->canvas_id, data, 0, Emscripten_HandleMouseButton);
716  emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandleMouseButton);
717 
718  emscripten_set_mouseenter_callback(data->canvas_id, data, 0, Emscripten_HandleMouseFocus);
719  emscripten_set_mouseleave_callback(data->canvas_id, data, 0, Emscripten_HandleMouseFocus);
720 
721  emscripten_set_wheel_callback(data->canvas_id, data, 0, Emscripten_HandleWheel);
722 
723  emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleFocus);
724  emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleFocus);
725 
726  emscripten_set_touchstart_callback(data->canvas_id, data, 0, Emscripten_HandleTouch);
727  emscripten_set_touchend_callback(data->canvas_id, data, 0, Emscripten_HandleTouch);
728  emscripten_set_touchmove_callback(data->canvas_id, data, 0, Emscripten_HandleTouch);
729  emscripten_set_touchcancel_callback(data->canvas_id, data, 0, Emscripten_HandleTouch);
730 
731  emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandlePointerLockChange);
732 
733  /* Keyboard events are awkward */
735  if (!keyElement) keyElement = EMSCRIPTEN_EVENT_TARGET_WINDOW;
736 
737  emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey);
738  emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey);
739  emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress);
740 
741  emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandleFullscreenChange);
742 
743  emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleResize);
744 
745  emscripten_set_visibilitychange_callback(data, 0, Emscripten_HandleVisibilityChange);
746 
747  emscripten_set_beforeunload_callback(data, Emscripten_HandleBeforeUnload);
748 }
749 
750 void
752 {
753  const char *target;
754 
755  /* only works due to having one window */
756  emscripten_set_mousemove_callback(data->canvas_id, NULL, 0, NULL);
757 
758  emscripten_set_mousedown_callback(data->canvas_id, NULL, 0, NULL);
759  emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL);
760 
761  emscripten_set_mouseenter_callback(data->canvas_id, NULL, 0, NULL);
762  emscripten_set_mouseleave_callback(data->canvas_id, NULL, 0, NULL);
763 
764  emscripten_set_wheel_callback(data->canvas_id, NULL, 0, NULL);
765 
766  emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL);
767  emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL);
768 
769  emscripten_set_touchstart_callback(data->canvas_id, NULL, 0, NULL);
770  emscripten_set_touchend_callback(data->canvas_id, NULL, 0, NULL);
771  emscripten_set_touchmove_callback(data->canvas_id, NULL, 0, NULL);
772  emscripten_set_touchcancel_callback(data->canvas_id, NULL, 0, NULL);
773 
774  emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL);
775 
777  if (!target) {
778  target = EMSCRIPTEN_EVENT_TARGET_WINDOW;
779  }
780 
781  emscripten_set_keydown_callback(target, NULL, 0, NULL);
782  emscripten_set_keyup_callback(target, NULL, 0, NULL);
783  emscripten_set_keypress_callback(target, NULL, 0, NULL);
784 
785  emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL);
786 
787  emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL);
788 
789  emscripten_set_visibilitychange_callback(NULL, 0, NULL);
790 
791  emscripten_set_beforeunload_callback(NULL, NULL);
792 }
793 
794 #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
795 
796 /* vi: set ts=4 sw=4 expandtab: */
#define SDL_strncmp
#define SDL_GetHint
void Emscripten_RegisterEventHandlers(SDL_WindowData *data)
EM_BOOL Emscripten_HandleCanvasResize(int eventType, const void *reserved, void *userData)
void Emscripten_UnregisterEventHandlers(SDL_WindowData *data)
int SDL_SendAppEvent(SDL_EventType eventType)
Definition: SDL_events.c:1035
SDL_EventType
The types of events that can be delivered.
Definition: SDL_events.h:56
@ SDL_MOUSEBUTTONUP
Definition: SDL_events.h:109
@ SDL_TEXTINPUT
Definition: SDL_events.h:101
@ SDL_WINDOWEVENT
Definition: SDL_events.h:94
@ SDL_MOUSEWHEEL
Definition: SDL_events.h:110
@ SDL_MOUSEBUTTONDOWN
Definition: SDL_events.h:108
@ SDL_FINGERDOWN
Definition: SDL_events.h:134
@ SDL_APP_TERMINATING
Definition: SDL_events.h:63
@ SDL_KEYDOWN
Definition: SDL_events.h:98
@ SDL_KEYUP
Definition: SDL_events.h:99
#define SDL_GetEventState(type)
Definition: SDL_events.h:808
#define SDL_RELEASED
Definition: SDL_events.h:49
#define SDL_ENABLE
Definition: SDL_events.h:795
#define SDL_PRESSED
Definition: SDL_events.h:50
#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT
override the binding element for keyboard inputs for Emscripten builds
Definition: SDL_hints.h:1110
void SDL_ResetKeyboard(void)
Definition: SDL_keyboard.c:576
int SDL_SendKeyboardText(const char *text)
Definition: SDL_keyboard.c:848
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
Definition: SDL_keyboard.c:806
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
Definition: SDL_mouse.c:599
SDL_Mouse * SDL_GetMouse(void)
Definition: SDL_mouse.c:175
void SDL_SetMouseFocus(SDL_Window *window)
Definition: SDL_mouse.c:208
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
Definition: SDL_mouse.c:605
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
Definition: SDL_mouse.c:298
#define SDL_BUTTON_MIDDLE
Definition: SDL_mouse.h:283
#define SDL_BUTTON_RIGHT
Definition: SDL_mouse.h:284
#define SDL_BUTTON_LEFT
Definition: SDL_mouse.h:282
@ SDL_MOUSEWHEEL_NORMAL
Definition: SDL_mouse.h:68
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLuint id
GLenum target
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
SDL_Scancode
The SDL keyboard scancode representation.
Definition: SDL_scancode.h:44
@ SDL_SCANCODE_E
Definition: SDL_scancode.h:58
@ SDL_SCANCODE_END
Definition: SDL_scancode.h:174
@ SDL_SCANCODE_BACKSLASH
Definition: SDL_scancode.h:102
@ SDL_SCANCODE_ESCAPE
Definition: SDL_scancode.h:93
@ SDL_SCANCODE_F15
Definition: SDL_scancode.h:217
@ SDL_SCANCODE_M
Definition: SDL_scancode.h:66
@ SDL_SCANCODE_F12
Definition: SDL_scancode.h:164
@ SDL_SCANCODE_X
Definition: SDL_scancode.h:77
@ SDL_SCANCODE_W
Definition: SDL_scancode.h:76
@ SDL_SCANCODE_KP_PLUS
Definition: SDL_scancode.h:186
@ SDL_SCANCODE_F4
Definition: SDL_scancode.h:156
@ SDL_SCANCODE_RIGHTBRACKET
Definition: SDL_scancode.h:101
@ SDL_SCANCODE_CAPSLOCK
Definition: SDL_scancode.h:151
@ SDL_SCANCODE_B
Definition: SDL_scancode.h:55
@ SDL_SCANCODE_F2
Definition: SDL_scancode.h:154
@ SDL_SCANCODE_KP_MINUS
Definition: SDL_scancode.h:185
@ SDL_SCANCODE_F6
Definition: SDL_scancode.h:158
@ SDL_SCANCODE_NONUSBACKSLASH
Definition: SDL_scancode.h:200
@ SDL_SCANCODE_KP_0
Definition: SDL_scancode.h:197
@ SDL_SCANCODE_F11
Definition: SDL_scancode.h:163
@ SDL_SCANCODE_CANCEL
Definition: SDL_scancode.h:270
@ SDL_SCANCODE_COMMA
Definition: SDL_scancode.h:147
@ SDL_SCANCODE_KP_PERIOD
Definition: SDL_scancode.h:198
@ SDL_SCANCODE_F24
Definition: SDL_scancode.h:226
@ SDL_SCANCODE_AUDIOMUTE
Definition: SDL_scancode.h:355
@ SDL_SCANCODE_Y
Definition: SDL_scancode.h:78
@ SDL_SCANCODE_APOSTROPHE
Definition: SDL_scancode.h:129
@ SDL_SCANCODE_2
Definition: SDL_scancode.h:82
@ SDL_SCANCODE_O
Definition: SDL_scancode.h:68
@ SDL_SCANCODE_RGUI
Definition: SDL_scancode.h:335
@ SDL_SCANCODE_K
Definition: SDL_scancode.h:64
@ SDL_SCANCODE_F
Definition: SDL_scancode.h:59
@ SDL_SCANCODE_DELETE
Definition: SDL_scancode.h:173
@ SDL_SCANCODE_F10
Definition: SDL_scancode.h:162
@ SDL_SCANCODE_F3
Definition: SDL_scancode.h:155
@ SDL_SCANCODE_5
Definition: SDL_scancode.h:85
@ SDL_SCANCODE_H
Definition: SDL_scancode.h:61
@ SDL_SCANCODE_SLASH
Definition: SDL_scancode.h:149
@ SDL_SCANCODE_F1
Definition: SDL_scancode.h:153
@ SDL_SCANCODE_F21
Definition: SDL_scancode.h:223
@ SDL_SCANCODE_KP_6
Definition: SDL_scancode.h:193
@ SDL_SCANCODE_KP_HASH
Definition: SDL_scancode.h:309
@ SDL_SCANCODE_7
Definition: SDL_scancode.h:87
@ SDL_SCANCODE_9
Definition: SDL_scancode.h:89
@ SDL_SCANCODE_KP_7
Definition: SDL_scancode.h:194
@ SDL_SCANCODE_KP_9
Definition: SDL_scancode.h:196
@ SDL_SCANCODE_VOLUMEUP
Definition: SDL_scancode.h:239
@ SDL_SCANCODE_NUMLOCKCLEAR
Definition: SDL_scancode.h:181
@ SDL_SCANCODE_KP_3
Definition: SDL_scancode.h:190
@ SDL_SCANCODE_SCROLLLOCK
Definition: SDL_scancode.h:167
@ SDL_SCANCODE_AUDIOPREV
Definition: SDL_scancode.h:352
@ SDL_SCANCODE_PAUSE
Definition: SDL_scancode.h:168
@ SDL_SCANCODE_RETURN
Definition: SDL_scancode.h:92
@ SDL_SCANCODE_HELP
Definition: SDL_scancode.h:228
@ SDL_SCANCODE_PAGEDOWN
Definition: SDL_scancode.h:175
@ SDL_SCANCODE_LSHIFT
Definition: SDL_scancode.h:329
@ SDL_SCANCODE_TAB
Definition: SDL_scancode.h:95
@ SDL_SCANCODE_3
Definition: SDL_scancode.h:83
@ SDL_SCANCODE_LCTRL
Definition: SDL_scancode.h:328
@ SDL_SCANCODE_SEMICOLON
Definition: SDL_scancode.h:128
@ SDL_SCANCODE_F16
Definition: SDL_scancode.h:218
@ SDL_SCANCODE_F22
Definition: SDL_scancode.h:224
@ SDL_SCANCODE_UNKNOWN
Definition: SDL_scancode.h:45
@ SDL_SCANCODE_LGUI
Definition: SDL_scancode.h:331
@ SDL_SCANCODE_0
Definition: SDL_scancode.h:90
@ SDL_SCANCODE_LEFTBRACKET
Definition: SDL_scancode.h:100
@ SDL_SCANCODE_F19
Definition: SDL_scancode.h:221
@ SDL_SCANCODE_V
Definition: SDL_scancode.h:75
@ SDL_SCANCODE_GRAVE
Definition: SDL_scancode.h:130
@ SDL_SCANCODE_RALT
Definition: SDL_scancode.h:334
@ SDL_SCANCODE_8
Definition: SDL_scancode.h:88
@ SDL_SCANCODE_I
Definition: SDL_scancode.h:62
@ SDL_SCANCODE_F17
Definition: SDL_scancode.h:219
@ SDL_SCANCODE_6
Definition: SDL_scancode.h:86
@ SDL_SCANCODE_S
Definition: SDL_scancode.h:72
@ SDL_SCANCODE_KP_ENTER
Definition: SDL_scancode.h:187
@ SDL_SCANCODE_AC_BACK
Definition: SDL_scancode.h:363
@ SDL_SCANCODE_PAGEUP
Definition: SDL_scancode.h:172
@ SDL_SCANCODE_Z
Definition: SDL_scancode.h:79
@ SDL_SCANCODE_AUDIOPLAY
Definition: SDL_scancode.h:354
@ SDL_SCANCODE_P
Definition: SDL_scancode.h:69
@ SDL_SCANCODE_D
Definition: SDL_scancode.h:57
@ SDL_SCANCODE_F23
Definition: SDL_scancode.h:225
@ SDL_SCANCODE_PERIOD
Definition: SDL_scancode.h:148
@ SDL_SCANCODE_R
Definition: SDL_scancode.h:71
@ SDL_SCANCODE_KP_1
Definition: SDL_scancode.h:188
@ SDL_SCANCODE_DOWN
Definition: SDL_scancode.h:178
@ SDL_SCANCODE_RIGHT
Definition: SDL_scancode.h:176
@ SDL_SCANCODE_F7
Definition: SDL_scancode.h:159
@ SDL_SCANCODE_MINUS
Definition: SDL_scancode.h:98
@ SDL_SCANCODE_A
Definition: SDL_scancode.h:54
@ SDL_SCANCODE_G
Definition: SDL_scancode.h:60
@ SDL_SCANCODE_KP_2
Definition: SDL_scancode.h:189
@ SDL_SCANCODE_U
Definition: SDL_scancode.h:74
@ SDL_SCANCODE_KP_MULTIPLY
Definition: SDL_scancode.h:184
@ SDL_SCANCODE_4
Definition: SDL_scancode.h:84
@ SDL_SCANCODE_F9
Definition: SDL_scancode.h:161
@ SDL_SCANCODE_F5
Definition: SDL_scancode.h:157
@ SDL_SCANCODE_UP
Definition: SDL_scancode.h:179
@ SDL_SCANCODE_LEFT
Definition: SDL_scancode.h:177
@ SDL_SCANCODE_AUDIONEXT
Definition: SDL_scancode.h:351
@ SDL_SCANCODE_APPLICATION
Definition: SDL_scancode.h:210
@ SDL_SCANCODE_KP_4
Definition: SDL_scancode.h:191
@ SDL_SCANCODE_C
Definition: SDL_scancode.h:56
@ SDL_SCANCODE_HOME
Definition: SDL_scancode.h:171
@ SDL_SCANCODE_F14
Definition: SDL_scancode.h:216
@ SDL_SCANCODE_T
Definition: SDL_scancode.h:73
@ SDL_SCANCODE_F8
Definition: SDL_scancode.h:160
@ SDL_SCANCODE_LALT
Definition: SDL_scancode.h:330
@ SDL_SCANCODE_KP_8
Definition: SDL_scancode.h:195
@ SDL_SCANCODE_RCTRL
Definition: SDL_scancode.h:332
@ SDL_SCANCODE_F20
Definition: SDL_scancode.h:222
@ SDL_SCANCODE_KP_5
Definition: SDL_scancode.h:192
@ SDL_SCANCODE_L
Definition: SDL_scancode.h:65
@ SDL_SCANCODE_VOLUMEDOWN
Definition: SDL_scancode.h:240
@ SDL_SCANCODE_KP_DIVIDE
Definition: SDL_scancode.h:183
@ SDL_SCANCODE_F18
Definition: SDL_scancode.h:220
@ SDL_SCANCODE_F13
Definition: SDL_scancode.h:215
@ SDL_SCANCODE_N
Definition: SDL_scancode.h:67
@ SDL_SCANCODE_BACKSPACE
Definition: SDL_scancode.h:94
@ SDL_SCANCODE_EQUALS
Definition: SDL_scancode.h:99
@ SDL_SCANCODE_SPACE
Definition: SDL_scancode.h:96
@ SDL_SCANCODE_RSHIFT
Definition: SDL_scancode.h:333
@ SDL_SCANCODE_INSERT
Definition: SDL_scancode.h:169
@ SDL_SCANCODE_AC_FORWARD
Definition: SDL_scancode.h:364
@ SDL_SCANCODE_J
Definition: SDL_scancode.h:63
@ SDL_SCANCODE_1
Definition: SDL_scancode.h:81
@ SDL_SCANCODE_Q
Definition: SDL_scancode.h:70
SDL_bool
Definition: SDL_stdinc.h:168
@ SDL_TRUE
Definition: SDL_stdinc.h:170
@ SDL_FALSE
Definition: SDL_stdinc.h:169
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:121
uint8_t Uint8
Definition: SDL_stdinc.h:185
uint32_t Uint32
Definition: SDL_stdinc.h:209
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1130
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure)
Definition: SDL_touch.c:241
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
Definition: SDL_touch.c:154
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure)
Definition: SDL_touch.c:355
Sint64 SDL_FingerID
Definition: SDL_touch.h:42
@ SDL_TOUCH_DEVICE_DIRECT
Definition: SDL_touch.h:47
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
#define FULLSCREEN_MASK
Definition: SDL_video.c:152
@ SDL_WINDOW_ALLOW_HIGHDPI
Definition: SDL_video.h:112
@ SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:104
@ SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:99
@ SDL_WINDOWEVENT_HIDDEN
Definition: SDL_video.h:150
@ SDL_WINDOWEVENT_FOCUS_LOST
Definition: SDL_video.h:166
@ SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:155
@ SDL_WINDOWEVENT_FOCUS_GAINED
Definition: SDL_video.h:165
@ SDL_WINDOWEVENT_SHOWN
Definition: SDL_video.h:149
int SDL_SendWindowEvent(SDL_Window *window, Uint8 windowevent, int data1, int data2)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:163
GLenum GLenum GLuint GLint GLint GLint yscale
Definition: gl2ext.h:2243
GLenum GLenum GLuint GLint GLint xscale
Definition: gl2ext.h:2243
SDL_Window * fullscreen_window
Definition: SDL_sysvideo.h:136
SDL_Window * window
SDL_bool fullscreen_resize
Uint32 flags
Definition: SDL_sysvideo.h:84
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47