src/video/emscripten/SDL_emscriptenevents.c
changeset 9277 743c0a496aa8
child 9279 e5e5571d3bed
equal deleted inserted replaced
9276:2b9bf6b04595 9277:743c0a496aa8
       
     1 /*
       
     2   Simple DirectMedia Layer
       
     3   Copyright (C) 1997-2014 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 .which to scancode
       
    42 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Constants
       
    43 */
       
    44 static const SDL_Scancode emscripten_scancode_table[] = {
       
    45     /*  0 */    SDL_SCANCODE_UNKNOWN,
       
    46     /*  1 */    SDL_SCANCODE_UNKNOWN,
       
    47     /*  2 */    SDL_SCANCODE_UNKNOWN,
       
    48     /*  3 */    SDL_SCANCODE_CANCEL,
       
    49     /*  4 */    SDL_SCANCODE_UNKNOWN,
       
    50     /*  5 */    SDL_SCANCODE_UNKNOWN,
       
    51     /*  6 */    SDL_SCANCODE_HELP,
       
    52     /*  7 */    SDL_SCANCODE_UNKNOWN,
       
    53     /*  8 */    SDL_SCANCODE_BACKSPACE,
       
    54     /*  9 */    SDL_SCANCODE_TAB,
       
    55     /*  10 */   SDL_SCANCODE_UNKNOWN,
       
    56     /*  11 */   SDL_SCANCODE_UNKNOWN,
       
    57     /*  12 */   SDL_SCANCODE_UNKNOWN,
       
    58     /*  13 */   SDL_SCANCODE_RETURN,
       
    59     /*  14 */   SDL_SCANCODE_UNKNOWN,
       
    60     /*  15 */   SDL_SCANCODE_UNKNOWN,
       
    61     /*  16 */   SDL_SCANCODE_LSHIFT,
       
    62     /*  17 */   SDL_SCANCODE_LCTRL,
       
    63     /*  18 */   SDL_SCANCODE_LALT,
       
    64     /*  19 */   SDL_SCANCODE_PAUSE,
       
    65     /*  20 */   SDL_SCANCODE_CAPSLOCK,
       
    66     /*  21 */   SDL_SCANCODE_UNKNOWN,
       
    67     /*  22 */   SDL_SCANCODE_UNKNOWN,
       
    68     /*  23 */   SDL_SCANCODE_UNKNOWN,
       
    69     /*  24 */   SDL_SCANCODE_UNKNOWN,
       
    70     /*  25 */   SDL_SCANCODE_UNKNOWN,
       
    71     /*  26 */   SDL_SCANCODE_UNKNOWN,
       
    72     /*  27 */   SDL_SCANCODE_ESCAPE,
       
    73     /*  28 */   SDL_SCANCODE_UNKNOWN,
       
    74     /*  29 */   SDL_SCANCODE_UNKNOWN,
       
    75     /*  30 */   SDL_SCANCODE_UNKNOWN,
       
    76     /*  31 */   SDL_SCANCODE_UNKNOWN,
       
    77     /*  32 */   SDL_SCANCODE_SPACE,
       
    78     /*  33 */   SDL_SCANCODE_PAGEUP,
       
    79     /*  34 */   SDL_SCANCODE_PAGEDOWN,
       
    80     /*  35 */   SDL_SCANCODE_END,
       
    81     /*  36 */   SDL_SCANCODE_HOME,
       
    82     /*  37 */   SDL_SCANCODE_LEFT,
       
    83     /*  38 */   SDL_SCANCODE_UP,
       
    84     /*  39 */   SDL_SCANCODE_RIGHT,
       
    85     /*  40 */   SDL_SCANCODE_DOWN,
       
    86     /*  41 */   SDL_SCANCODE_UNKNOWN,
       
    87     /*  42 */   SDL_SCANCODE_UNKNOWN,
       
    88     /*  43 */   SDL_SCANCODE_UNKNOWN,
       
    89     /*  44 */   SDL_SCANCODE_UNKNOWN,
       
    90     /*  45 */   SDL_SCANCODE_INSERT,
       
    91     /*  46 */   SDL_SCANCODE_DELETE,
       
    92     /*  47 */   SDL_SCANCODE_UNKNOWN,
       
    93     /*  48 */   SDL_SCANCODE_0,
       
    94     /*  49 */   SDL_SCANCODE_1,
       
    95     /*  50 */   SDL_SCANCODE_2,
       
    96     /*  51 */   SDL_SCANCODE_3,
       
    97     /*  52 */   SDL_SCANCODE_4,
       
    98     /*  53 */   SDL_SCANCODE_5,
       
    99     /*  54 */   SDL_SCANCODE_6,
       
   100     /*  55 */   SDL_SCANCODE_7,
       
   101     /*  56 */   SDL_SCANCODE_8,
       
   102     /*  57 */   SDL_SCANCODE_9,
       
   103     /*  58 */   SDL_SCANCODE_UNKNOWN,
       
   104     /*  59 */   SDL_SCANCODE_SEMICOLON,
       
   105     /*  60 */   SDL_SCANCODE_UNKNOWN,
       
   106     /*  61 */   SDL_SCANCODE_EQUALS,
       
   107     /*  62 */   SDL_SCANCODE_UNKNOWN,
       
   108     /*  63 */   SDL_SCANCODE_UNKNOWN,
       
   109     /*  64 */   SDL_SCANCODE_UNKNOWN,
       
   110     /*  65 */   SDL_SCANCODE_A,
       
   111     /*  66 */   SDL_SCANCODE_B,
       
   112     /*  67 */   SDL_SCANCODE_C,
       
   113     /*  68 */   SDL_SCANCODE_D,
       
   114     /*  69 */   SDL_SCANCODE_E,
       
   115     /*  70 */   SDL_SCANCODE_F,
       
   116     /*  71 */   SDL_SCANCODE_G,
       
   117     /*  72 */   SDL_SCANCODE_H,
       
   118     /*  73 */   SDL_SCANCODE_I,
       
   119     /*  74 */   SDL_SCANCODE_J,
       
   120     /*  75 */   SDL_SCANCODE_K,
       
   121     /*  76 */   SDL_SCANCODE_L,
       
   122     /*  77 */   SDL_SCANCODE_M,
       
   123     /*  78 */   SDL_SCANCODE_N,
       
   124     /*  79 */   SDL_SCANCODE_O,
       
   125     /*  80 */   SDL_SCANCODE_P,
       
   126     /*  81 */   SDL_SCANCODE_Q,
       
   127     /*  82 */   SDL_SCANCODE_R,
       
   128     /*  83 */   SDL_SCANCODE_S,
       
   129     /*  84 */   SDL_SCANCODE_T,
       
   130     /*  85 */   SDL_SCANCODE_U,
       
   131     /*  86 */   SDL_SCANCODE_V,
       
   132     /*  87 */   SDL_SCANCODE_W,
       
   133     /*  88 */   SDL_SCANCODE_X,
       
   134     /*  89 */   SDL_SCANCODE_Y,
       
   135     /*  90 */   SDL_SCANCODE_Z,
       
   136     /*  91 */   SDL_SCANCODE_LGUI,
       
   137     /*  92 */   SDL_SCANCODE_UNKNOWN,
       
   138     /*  93 */   SDL_SCANCODE_APPLICATION,
       
   139     /*  94 */   SDL_SCANCODE_UNKNOWN,
       
   140     /*  95 */   SDL_SCANCODE_UNKNOWN,
       
   141     /*  96 */   SDL_SCANCODE_KP_0,
       
   142     /*  97 */   SDL_SCANCODE_KP_1,
       
   143     /*  98 */   SDL_SCANCODE_KP_2,
       
   144     /*  99 */   SDL_SCANCODE_KP_3,
       
   145     /* 100 */   SDL_SCANCODE_KP_4,
       
   146     /* 101 */   SDL_SCANCODE_KP_5,
       
   147     /* 102 */   SDL_SCANCODE_KP_6,
       
   148     /* 103 */   SDL_SCANCODE_KP_7,
       
   149     /* 104 */   SDL_SCANCODE_KP_8,
       
   150     /* 105 */   SDL_SCANCODE_KP_9,
       
   151     /* 106 */   SDL_SCANCODE_KP_MULTIPLY,
       
   152     /* 107 */   SDL_SCANCODE_KP_PLUS,
       
   153     /* 108 */   SDL_SCANCODE_UNKNOWN,
       
   154     /* 109 */   SDL_SCANCODE_KP_MINUS,
       
   155     /* 110 */   SDL_SCANCODE_KP_PERIOD,
       
   156     /* 111 */   SDL_SCANCODE_KP_DIVIDE,
       
   157     /* 112 */   SDL_SCANCODE_F1,
       
   158     /* 113 */   SDL_SCANCODE_F2,
       
   159     /* 114 */   SDL_SCANCODE_F3,
       
   160     /* 115 */   SDL_SCANCODE_F4,
       
   161     /* 116 */   SDL_SCANCODE_F5,
       
   162     /* 117 */   SDL_SCANCODE_F6,
       
   163     /* 118 */   SDL_SCANCODE_F7,
       
   164     /* 119 */   SDL_SCANCODE_F8,
       
   165     /* 120 */   SDL_SCANCODE_F9,
       
   166     /* 121 */   SDL_SCANCODE_F10,
       
   167     /* 122 */   SDL_SCANCODE_F11,
       
   168     /* 123 */   SDL_SCANCODE_F12,
       
   169     /* 124 */   SDL_SCANCODE_F13,
       
   170     /* 125 */   SDL_SCANCODE_F14,
       
   171     /* 126 */   SDL_SCANCODE_F15,
       
   172     /* 127 */   SDL_SCANCODE_F16,
       
   173     /* 128 */   SDL_SCANCODE_F17,
       
   174     /* 129 */   SDL_SCANCODE_F18,
       
   175     /* 130 */   SDL_SCANCODE_F19,
       
   176     /* 131 */   SDL_SCANCODE_F20,
       
   177     /* 132 */   SDL_SCANCODE_F21,
       
   178     /* 133 */   SDL_SCANCODE_F22,
       
   179     /* 134 */   SDL_SCANCODE_F23,
       
   180     /* 135 */   SDL_SCANCODE_F24,
       
   181     /* 136 */   SDL_SCANCODE_UNKNOWN,
       
   182     /* 137 */   SDL_SCANCODE_UNKNOWN,
       
   183     /* 138 */   SDL_SCANCODE_UNKNOWN,
       
   184     /* 139 */   SDL_SCANCODE_UNKNOWN,
       
   185     /* 140 */   SDL_SCANCODE_UNKNOWN,
       
   186     /* 141 */   SDL_SCANCODE_UNKNOWN,
       
   187     /* 142 */   SDL_SCANCODE_UNKNOWN,
       
   188     /* 143 */   SDL_SCANCODE_UNKNOWN,
       
   189     /* 144 */   SDL_SCANCODE_NUMLOCKCLEAR,
       
   190     /* 145 */   SDL_SCANCODE_SCROLLLOCK,
       
   191     /* 146 */   SDL_SCANCODE_UNKNOWN,
       
   192     /* 147 */   SDL_SCANCODE_UNKNOWN,
       
   193     /* 148 */   SDL_SCANCODE_UNKNOWN,
       
   194     /* 149 */   SDL_SCANCODE_UNKNOWN,
       
   195     /* 150 */   SDL_SCANCODE_UNKNOWN,
       
   196     /* 151 */   SDL_SCANCODE_UNKNOWN,
       
   197     /* 152 */   SDL_SCANCODE_UNKNOWN,
       
   198     /* 153 */   SDL_SCANCODE_UNKNOWN,
       
   199     /* 154 */   SDL_SCANCODE_UNKNOWN,
       
   200     /* 155 */   SDL_SCANCODE_UNKNOWN,
       
   201     /* 156 */   SDL_SCANCODE_UNKNOWN,
       
   202     /* 157 */   SDL_SCANCODE_UNKNOWN,
       
   203     /* 158 */   SDL_SCANCODE_UNKNOWN,
       
   204     /* 159 */   SDL_SCANCODE_UNKNOWN,
       
   205     /* 160 */   SDL_SCANCODE_UNKNOWN,
       
   206     /* 161 */   SDL_SCANCODE_UNKNOWN,
       
   207     /* 162 */   SDL_SCANCODE_UNKNOWN,
       
   208     /* 163 */   SDL_SCANCODE_UNKNOWN,
       
   209     /* 164 */   SDL_SCANCODE_UNKNOWN,
       
   210     /* 165 */   SDL_SCANCODE_UNKNOWN,
       
   211     /* 166 */   SDL_SCANCODE_UNKNOWN,
       
   212     /* 167 */   SDL_SCANCODE_UNKNOWN,
       
   213     /* 168 */   SDL_SCANCODE_UNKNOWN,
       
   214     /* 169 */   SDL_SCANCODE_UNKNOWN,
       
   215     /* 170 */   SDL_SCANCODE_UNKNOWN,
       
   216     /* 171 */   SDL_SCANCODE_UNKNOWN,
       
   217     /* 172 */   SDL_SCANCODE_UNKNOWN,
       
   218     /* 173 */   SDL_SCANCODE_MINUS, /*FX*/
       
   219     /* 174 */   SDL_SCANCODE_UNKNOWN,
       
   220     /* 175 */   SDL_SCANCODE_UNKNOWN,
       
   221     /* 176 */   SDL_SCANCODE_UNKNOWN,
       
   222     /* 177 */   SDL_SCANCODE_UNKNOWN,
       
   223     /* 178 */   SDL_SCANCODE_UNKNOWN,
       
   224     /* 179 */   SDL_SCANCODE_UNKNOWN,
       
   225     /* 180 */   SDL_SCANCODE_UNKNOWN,
       
   226     /* 181 */   SDL_SCANCODE_UNKNOWN,
       
   227     /* 182 */   SDL_SCANCODE_UNKNOWN,
       
   228     /* 183 */   SDL_SCANCODE_UNKNOWN,
       
   229     /* 184 */   SDL_SCANCODE_UNKNOWN,
       
   230     /* 185 */   SDL_SCANCODE_UNKNOWN,
       
   231     /* 186 */   SDL_SCANCODE_SEMICOLON, /*IE, Chrome, D3E legacy*/
       
   232     /* 187 */   SDL_SCANCODE_EQUALS, /*IE, Chrome, D3E legacy*/
       
   233     /* 188 */   SDL_SCANCODE_COMMA,
       
   234     /* 189 */   SDL_SCANCODE_MINUS, /*IE, Chrome, D3E legacy*/
       
   235     /* 190 */   SDL_SCANCODE_PERIOD,
       
   236     /* 191 */   SDL_SCANCODE_SLASH,
       
   237     /* 192 */   SDL_SCANCODE_GRAVE, /*FX, D3E legacy (SDL_SCANCODE_APOSTROPHE in IE/Chrome)*/
       
   238     /* 193 */   SDL_SCANCODE_UNKNOWN,
       
   239     /* 194 */   SDL_SCANCODE_UNKNOWN,
       
   240     /* 195 */   SDL_SCANCODE_UNKNOWN,
       
   241     /* 196 */   SDL_SCANCODE_UNKNOWN,
       
   242     /* 197 */   SDL_SCANCODE_UNKNOWN,
       
   243     /* 198 */   SDL_SCANCODE_UNKNOWN,
       
   244     /* 199 */   SDL_SCANCODE_UNKNOWN,
       
   245     /* 200 */   SDL_SCANCODE_UNKNOWN,
       
   246     /* 201 */   SDL_SCANCODE_UNKNOWN,
       
   247     /* 202 */   SDL_SCANCODE_UNKNOWN,
       
   248     /* 203 */   SDL_SCANCODE_UNKNOWN,
       
   249     /* 204 */   SDL_SCANCODE_UNKNOWN,
       
   250     /* 205 */   SDL_SCANCODE_UNKNOWN,
       
   251     /* 206 */   SDL_SCANCODE_UNKNOWN,
       
   252     /* 207 */   SDL_SCANCODE_UNKNOWN,
       
   253     /* 208 */   SDL_SCANCODE_UNKNOWN,
       
   254     /* 209 */   SDL_SCANCODE_UNKNOWN,
       
   255     /* 210 */   SDL_SCANCODE_UNKNOWN,
       
   256     /* 211 */   SDL_SCANCODE_UNKNOWN,
       
   257     /* 212 */   SDL_SCANCODE_UNKNOWN,
       
   258     /* 213 */   SDL_SCANCODE_UNKNOWN,
       
   259     /* 214 */   SDL_SCANCODE_UNKNOWN,
       
   260     /* 215 */   SDL_SCANCODE_UNKNOWN,
       
   261     /* 216 */   SDL_SCANCODE_UNKNOWN,
       
   262     /* 217 */   SDL_SCANCODE_UNKNOWN,
       
   263     /* 218 */   SDL_SCANCODE_UNKNOWN,
       
   264     /* 219 */   SDL_SCANCODE_LEFTBRACKET,
       
   265     /* 220 */   SDL_SCANCODE_BACKSLASH,
       
   266     /* 221 */   SDL_SCANCODE_RIGHTBRACKET,
       
   267     /* 222 */   SDL_SCANCODE_APOSTROPHE, /*FX, D3E legacy*/
       
   268 };
       
   269 
       
   270 
       
   271 /* "borrowed" from SDL_windowsevents.c */
       
   272 int
       
   273 Emscripten_ConvertUTF32toUTF8(Uint32 codepoint, char * text)
       
   274 {
       
   275     if (codepoint <= 0x7F) {
       
   276         text[0] = (char) codepoint;
       
   277         text[1] = '\0';
       
   278     } else if (codepoint <= 0x7FF) {
       
   279         text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
       
   280         text[1] = 0x80 | (char) (codepoint & 0x3F);
       
   281         text[2] = '\0';
       
   282     } else if (codepoint <= 0xFFFF) {
       
   283         text[0] = 0xE0 | (char) ((codepoint >> 12) & 0x0F);
       
   284         text[1] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
       
   285         text[2] = 0x80 | (char) (codepoint & 0x3F);
       
   286         text[3] = '\0';
       
   287     } else if (codepoint <= 0x10FFFF) {
       
   288         text[0] = 0xF0 | (char) ((codepoint >> 18) & 0x0F);
       
   289         text[1] = 0x80 | (char) ((codepoint >> 12) & 0x3F);
       
   290         text[2] = 0x80 | (char) ((codepoint >> 6) & 0x3F);
       
   291         text[3] = 0x80 | (char) (codepoint & 0x3F);
       
   292         text[4] = '\0';
       
   293     } else {
       
   294         return SDL_FALSE;
       
   295     }
       
   296     return SDL_TRUE;
       
   297 }
       
   298 
       
   299 int
       
   300 Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
       
   301 {
       
   302     SDL_WindowData *window_data = userData;
       
   303     int mx = mouseEvent->canvasX, my = mouseEvent->canvasY;
       
   304     EmscriptenPointerlockChangeEvent pointerlock_status;
       
   305 
       
   306     /* check for pointer lock */
       
   307     emscripten_get_pointerlock_status(&pointerlock_status);
       
   308 
       
   309     if (pointerlock_status.isActive) {
       
   310         mx = mouseEvent->movementX;
       
   311         my = mouseEvent->movementY;
       
   312     }
       
   313 
       
   314     /* rescale (in case canvas is being scaled)*/
       
   315     double client_w, client_h;
       
   316     emscripten_get_element_css_size(NULL, &client_w, &client_h);
       
   317 
       
   318     mx = mx * (window_data->window->w / (client_w * window_data->pixel_ratio));
       
   319     my = my * (window_data->window->h / (client_h * window_data->pixel_ratio));
       
   320 
       
   321     SDL_SendMouseMotion(window_data->window, 0, pointerlock_status.isActive, mx, my);
       
   322     return 0;
       
   323 }
       
   324 
       
   325 int
       
   326 Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
       
   327 {
       
   328     SDL_WindowData *window_data = userData;
       
   329     uint32_t sdl_button;
       
   330     switch (mouseEvent->button) {
       
   331         case 0:
       
   332             sdl_button = SDL_BUTTON_LEFT;
       
   333             break;
       
   334         case 1:
       
   335             sdl_button = SDL_BUTTON_MIDDLE;
       
   336             break;
       
   337         case 2:
       
   338             sdl_button = SDL_BUTTON_RIGHT;
       
   339             break;
       
   340         default:
       
   341             return 0;
       
   342     }
       
   343     SDL_SendMouseButton(window_data->window, 0, eventType == EMSCRIPTEN_EVENT_MOUSEDOWN ? SDL_PRESSED : SDL_RELEASED, sdl_button);
       
   344     return 1;
       
   345 }
       
   346 
       
   347 int
       
   348 Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
       
   349 {
       
   350     SDL_WindowData *window_data = userData;
       
   351     SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_MOUSEENTER ? SDL_WINDOWEVENT_ENTER : SDL_WINDOWEVENT_LEAVE, 0, 0);
       
   352     return 1;
       
   353 }
       
   354 
       
   355 int
       
   356 Emscripten_HandleWheel(int eventType, const EmscriptenWheelEvent *wheelEvent, void *userData)
       
   357 {
       
   358     SDL_WindowData *window_data = userData;
       
   359     SDL_SendMouseWheel(window_data->window, 0, wheelEvent->deltaX, -wheelEvent->deltaY);
       
   360     return 1;
       
   361 }
       
   362 
       
   363 int
       
   364 Emscripten_HandleFocus(int eventType, const EmscriptenFocusEvent *wheelEvent, void *userData)
       
   365 {
       
   366     SDL_WindowData *window_data = userData;
       
   367     SDL_SendWindowEvent(window_data->window, eventType == EMSCRIPTEN_EVENT_FOCUS ? SDL_WINDOWEVENT_FOCUS_GAINED : SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
       
   368     return 1;
       
   369 }
       
   370 
       
   371 int
       
   372 Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
       
   373 {
       
   374     /*SDL_WindowData *window_data = userData;*/
       
   375     int i;
       
   376 
       
   377     SDL_TouchID deviceId = 0;
       
   378     if (!SDL_GetTouch(deviceId)) {
       
   379         if (SDL_AddTouch(deviceId, "") < 0) {
       
   380              return 0;
       
   381         }
       
   382     }
       
   383 
       
   384     for (i = 0; i < touchEvent->numTouches; i++) {
       
   385         long x, y, id;
       
   386 
       
   387         if (!touchEvent->touches[i].isChanged)
       
   388             continue;
       
   389 
       
   390         id = touchEvent->touches[i].identifier;
       
   391         x = touchEvent->touches[i].canvasX;
       
   392         y = touchEvent->touches[i].canvasY;
       
   393 
       
   394         if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) {
       
   395             SDL_SendTouchMotion(deviceId, id, x, y, 1.0f);
       
   396         } else if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
       
   397             SDL_SendTouch(deviceId, id, SDL_TRUE, x, y, 1.0f);
       
   398         } else {
       
   399             SDL_SendTouch(deviceId, id, SDL_FALSE, x, y, 1.0f);
       
   400         }
       
   401     }
       
   402 
       
   403 
       
   404     return 1;
       
   405 }
       
   406 
       
   407 int
       
   408 Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
       
   409 {
       
   410     Uint32 scancode;
       
   411 
       
   412     /* .keyCode is deprecated, but still the most reliable way to get keys */
       
   413     if (keyEvent->keyCode < SDL_arraysize(emscripten_scancode_table)) {
       
   414         scancode = emscripten_scancode_table[keyEvent->keyCode];
       
   415 
       
   416         if (scancode != SDL_SCANCODE_UNKNOWN) {
       
   417 
       
   418             if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) {
       
   419                 switch (scancode) {
       
   420                     case SDL_SCANCODE_LSHIFT:
       
   421                         scancode = SDL_SCANCODE_RSHIFT;
       
   422                         break;
       
   423                     case SDL_SCANCODE_LCTRL:
       
   424                         scancode = SDL_SCANCODE_RCTRL;
       
   425                         break;
       
   426                     case SDL_SCANCODE_LALT:
       
   427                         scancode = SDL_SCANCODE_RALT;
       
   428                         break;
       
   429                     case SDL_SCANCODE_LGUI:
       
   430                         scancode = SDL_SCANCODE_RGUI;
       
   431                         break;
       
   432                 }
       
   433             }
       
   434             SDL_SendKeyboardKey(eventType == EMSCRIPTEN_EVENT_KEYDOWN ?
       
   435                                 SDL_PRESSED : SDL_RELEASED, scancode);
       
   436         }
       
   437     }
       
   438 
       
   439     /* if we prevent keydown, we won't get keypress
       
   440      * also we need to ALWAYS prevent backspace and tab otherwise chrome takes action and does bad navigation UX
       
   441      */
       
   442     return SDL_GetEventState(SDL_TEXTINPUT) != SDL_ENABLE || eventType != EMSCRIPTEN_EVENT_KEYDOWN
       
   443             || keyEvent->keyCode == 8 /* backspace */ || keyEvent->keyCode == 9 /* tab */;
       
   444 }
       
   445 
       
   446 int
       
   447 Emscripten_HandleKeyPress(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
       
   448 {
       
   449     char text[5];
       
   450     Emscripten_ConvertUTF32toUTF8(keyEvent->charCode, text);
       
   451     SDL_SendKeyboardText(text);
       
   452     return 1;
       
   453 }
       
   454 
       
   455 int
       
   456 Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData)
       
   457 {
       
   458     /*make sure this is actually our element going fullscreen*/
       
   459     if(SDL_strcmp(fullscreenChangeEvent->id, "SDLFullscreenElement") != 0)
       
   460         return 0;
       
   461 
       
   462     SDL_WindowData *window_data = userData;
       
   463     if(fullscreenChangeEvent->isFullscreen)
       
   464     {
       
   465         SDL_bool is_desktop_fullscreen;
       
   466         window_data->window->flags |= window_data->requested_fullscreen_mode;
       
   467 
       
   468         if(!window_data->requested_fullscreen_mode)
       
   469             window_data->window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; /*we didn't reqest fullscreen*/
       
   470 
       
   471         window_data->requested_fullscreen_mode = 0;
       
   472 
       
   473         is_desktop_fullscreen = (window_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP;
       
   474 
       
   475         /*update size*/
       
   476         if(window_data->window->flags & SDL_WINDOW_RESIZABLE || is_desktop_fullscreen)
       
   477         {
       
   478             emscripten_set_canvas_size(fullscreenChangeEvent->screenWidth, fullscreenChangeEvent->screenHeight);
       
   479             SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, fullscreenChangeEvent->screenWidth, fullscreenChangeEvent->screenHeight);
       
   480         }
       
   481         else
       
   482         {
       
   483             /*preserve ratio*/
       
   484             double w = window_data->window->w;
       
   485             double h = window_data->window->h;
       
   486             double factor = SDL_min(fullscreenChangeEvent->screenWidth / w, fullscreenChangeEvent->screenHeight / h);
       
   487             emscripten_set_element_css_size(NULL, w * factor, h * factor);
       
   488         }
       
   489     }
       
   490     else
       
   491     {
       
   492         EM_ASM({
       
   493             //un-reparent canvas (similar to Module.requestFullscreen)
       
   494             var canvas = Module['canvas'];
       
   495             if(canvas.parentNode.id == "SDLFullscreenElement") {
       
   496                 var canvasContainer = canvas.parentNode;
       
   497                 canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
       
   498                 canvasContainer.parentNode.removeChild(canvasContainer);
       
   499             }
       
   500         });
       
   501         double unscaled_w = window_data->windowed_width / window_data->pixel_ratio;
       
   502         double unscaled_h = window_data->windowed_height / window_data->pixel_ratio;
       
   503         emscripten_set_canvas_size(window_data->windowed_width, window_data->windowed_height);
       
   504 
       
   505         if (!window_data->external_size && window_data->pixel_ratio != 1.0f) {
       
   506             emscripten_set_element_css_size(NULL, unscaled_w, unscaled_h);
       
   507         }
       
   508 
       
   509         SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, unscaled_w, unscaled_h);
       
   510 
       
   511         window_data->window->flags &= ~FULLSCREEN_MASK;
       
   512     }
       
   513 
       
   514     return 0;
       
   515 }
       
   516 
       
   517 int
       
   518 Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
       
   519 {
       
   520     SDL_WindowData *window_data = userData;
       
   521     if(window_data->window->flags & FULLSCREEN_MASK)
       
   522     {
       
   523         SDL_bool is_desktop_fullscreen = (window_data->window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP;
       
   524 
       
   525         if(window_data->window->flags & SDL_WINDOW_RESIZABLE || is_desktop_fullscreen)
       
   526         {
       
   527             emscripten_set_canvas_size(uiEvent->windowInnerWidth * window_data->pixel_ratio, uiEvent->windowInnerHeight * window_data->pixel_ratio);
       
   528             SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, uiEvent->windowInnerWidth, uiEvent->windowInnerHeight);
       
   529         }
       
   530     }
       
   531     else
       
   532     {
       
   533         /* this will only work if the canvas size is set through css */
       
   534         if(window_data->window->flags & SDL_WINDOW_RESIZABLE)
       
   535         {
       
   536             double w = window_data->window->w;
       
   537             double h = window_data->window->h;
       
   538 
       
   539             if(window_data->external_size) {
       
   540                 emscripten_get_element_css_size(NULL, &w, &h);
       
   541             }
       
   542 
       
   543             emscripten_set_canvas_size(w * window_data->pixel_ratio, h * window_data->pixel_ratio);
       
   544 
       
   545             /* set_canvas_size unsets this */
       
   546             if (!window_data->external_size && window_data->pixel_ratio != 1.0f) {
       
   547                 emscripten_set_element_css_size(NULL, w, h);
       
   548             }
       
   549 
       
   550             SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, w, h);
       
   551         }
       
   552     }
       
   553 
       
   554     return 0;
       
   555 }
       
   556 
       
   557 int
       
   558 Emscripten_HandleVisibilityChange(int eventType, const EmscriptenVisibilityChangeEvent *visEvent, void *userData)
       
   559 {
       
   560     SDL_WindowData *window_data = userData;
       
   561     SDL_SendWindowEvent(window_data->window, visEvent->hidden ? SDL_WINDOWEVENT_HIDDEN : SDL_WINDOWEVENT_SHOWN, 0, 0);
       
   562     return 0;
       
   563 }
       
   564 
       
   565 void
       
   566 Emscripten_RegisterEventHandlers(SDL_WindowData *data)
       
   567 {
       
   568     /* There is only one window and that window is the canvas */
       
   569     emscripten_set_mousemove_callback("#canvas", data, 0, Emscripten_HandleMouseMove);
       
   570 
       
   571     emscripten_set_mousedown_callback("#canvas", data, 0, Emscripten_HandleMouseButton);
       
   572     emscripten_set_mouseup_callback("#canvas", data, 0, Emscripten_HandleMouseButton);
       
   573 
       
   574     emscripten_set_mouseenter_callback("#canvas", data, 0, Emscripten_HandleMouseFocus);
       
   575     emscripten_set_mouseleave_callback("#canvas", data, 0, Emscripten_HandleMouseFocus);
       
   576 
       
   577     emscripten_set_wheel_callback("#canvas", data, 0, Emscripten_HandleWheel);
       
   578 
       
   579     emscripten_set_focus_callback("#canvas", data, 0, Emscripten_HandleFocus);
       
   580     emscripten_set_blur_callback("#canvas", data, 0, Emscripten_HandleFocus);
       
   581 
       
   582     emscripten_set_touchstart_callback("#canvas", data, 0, Emscripten_HandleTouch);
       
   583     emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
       
   584     emscripten_set_touchmove_callback("#canvas", data, 0, Emscripten_HandleTouch);
       
   585     emscripten_set_touchcancel_callback("#canvas", data, 0, Emscripten_HandleTouch);
       
   586 
       
   587     /* Keyboard events are awkward */
       
   588     const char *keyElement = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT);
       
   589     if (!keyElement) keyElement = "#window";
       
   590 
       
   591     emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey);
       
   592     emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey);
       
   593     emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress);
       
   594 
       
   595     emscripten_set_fullscreenchange_callback("#document", data, 0, Emscripten_HandleFullscreenChange);
       
   596 
       
   597     emscripten_set_resize_callback("#window", data, 0, Emscripten_HandleResize);
       
   598 
       
   599     emscripten_set_visibilitychange_callback(data, 0, Emscripten_HandleVisibilityChange);
       
   600 }
       
   601 
       
   602 void
       
   603 Emscripten_UnregisterEventHandlers(SDL_WindowData *data)
       
   604 {
       
   605     /* only works due to having one window */
       
   606     emscripten_set_mousemove_callback("#canvas", NULL, 0, NULL);
       
   607 
       
   608     emscripten_set_mousedown_callback("#canvas", NULL, 0, NULL);
       
   609     emscripten_set_mouseup_callback("#canvas", NULL, 0, NULL);
       
   610 
       
   611     emscripten_set_mouseenter_callback("#canvas", NULL, 0, NULL);
       
   612     emscripten_set_mouseleave_callback("#canvas", NULL, 0, NULL);
       
   613 
       
   614     emscripten_set_wheel_callback("#canvas", NULL, 0, NULL);
       
   615 
       
   616     emscripten_set_focus_callback("#canvas", NULL, 0, NULL);
       
   617     emscripten_set_blur_callback("#canvas", NULL, 0, NULL);
       
   618 
       
   619     emscripten_set_touchstart_callback("#canvas", NULL, 0, NULL);
       
   620     emscripten_set_touchend_callback("#canvas", NULL, 0, NULL);
       
   621     emscripten_set_touchmove_callback("#canvas", NULL, 0, NULL);
       
   622     emscripten_set_touchcancel_callback("#canvas", NULL, 0, NULL);
       
   623 
       
   624     emscripten_set_keydown_callback("#window", NULL, 0, NULL);
       
   625     emscripten_set_keyup_callback("#window", NULL, 0, NULL);
       
   626 
       
   627     emscripten_set_keypress_callback("#window", NULL, 0, NULL);
       
   628 
       
   629     emscripten_set_fullscreenchange_callback("#document", NULL, 0, NULL);
       
   630 
       
   631     emscripten_set_resize_callback("#window", NULL, 0, NULL);
       
   632 
       
   633     emscripten_set_visibilitychange_callback(NULL, 0, NULL);
       
   634 }
       
   635 
       
   636 #endif /* SDL_VIDEO_DRIVER_EMSCRIPTEN */
       
   637 
       
   638 /* vi: set ts=4 sw=4 expandtab: */