src/video/emscripten/SDL_emscriptenevents.c
author Boris Gjenero <boris.gjenero@gmail.com>
Tue, 13 Sep 2016 00:03:45 -0700
changeset 10325 743e0f5e8ace
parent 10324 efa3b17582ce
child 10326 b7059a6e0de7
permissions -rw-r--r--
Accumulate subpixel mouse motion so motion is not lost.

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