23 #include "../../SDL_internal.h"
25 #if SDL_VIDEO_DRIVER_EMSCRIPTEN
27 #include <emscripten/html5.h>
29 #include "../../events/SDL_events_c.h"
30 #include "../../events/SDL_keyboard_c.h"
31 #include "../../events/SDL_touch_c.h"
38 #define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN )
45 static const SDL_Scancode emscripten_scancode_table[] = {
274 Emscripten_ConvertUTF32toUTF8(
Uint32 codepoint,
char *
text)
276 if (codepoint <= 0x7F) {
277 text[0] = (char) codepoint;
279 }
else if (codepoint <= 0x7FF) {
280 text[0] = 0xC0 | (char) ((codepoint >> 6) & 0x1F);
281 text[1] = 0x80 | (char) (codepoint & 0x3F);
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);
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);
301 Emscripten_HandlePointerLockChange(
int eventType,
const EmscriptenPointerlockChangeEvent *changeEvent,
void *userData)
311 Emscripten_HandleMouseMove(
int eventType,
const EmscriptenMouseEvent *mouseEvent,
void *userData)
316 static double residualx = 0, residualy = 0;
320 emscripten_get_element_css_size(window_data->
canvas_id, &client_w, &client_h);
324 if (isPointerLocked) {
325 residualx += mouseEvent->movementX *
xscale;
326 residualy += mouseEvent->movementY *
yscale;
333 mx = mouseEvent->targetX *
xscale;
334 my = mouseEvent->targetY *
yscale;
342 Emscripten_HandleMouseButton(
int eventType,
const EmscriptenMouseEvent *mouseEvent,
void *userData)
346 Uint8 sdl_button_state;
350 switch (mouseEvent->button) {
364 if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) {
366 emscripten_request_pointerlock(
NULL, 0);
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) {
387 Emscripten_HandleMouseFocus(
int eventType,
const EmscriptenMouseEvent *mouseEvent,
void *userData)
391 int mx = mouseEvent->targetX, my = mouseEvent->targetY;
394 if (!isPointerLocked) {
396 double client_w, client_h;
397 emscripten_get_element_css_size(window_data->
canvas_id, &client_w, &client_h);
399 mx = mx * (window_data->
window->
w / client_w);
400 my = my * (window_data->
window->
h / client_h);
409 Emscripten_HandleWheel(
int eventType,
const EmscriptenWheelEvent *wheelEvent,
void *userData)
417 Emscripten_HandleFocus(
int eventType,
const EmscriptenFocusEvent *wheelEvent,
void *userData)
422 if (eventType == EMSCRIPTEN_EVENT_BLUR) {
432 Emscripten_HandleTouch(
int eventType,
const EmscriptenTouchEvent *touchEvent,
void *userData)
436 double client_w, client_h;
437 int preventDefault = 0;
444 emscripten_get_element_css_size(window_data->
canvas_id, &client_w, &client_h);
446 for (
i = 0;
i < touchEvent->numTouches;
i++) {
450 if (!touchEvent->touches[
i].isChanged)
453 id = touchEvent->touches[
i].identifier;
454 x = touchEvent->touches[
i].targetX / client_w;
455 y = touchEvent->touches[
i].targetY / client_h;
457 if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) {
464 }
else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) {
474 return preventDefault;
478 Emscripten_HandleKey(
int eventType,
const EmscriptenKeyboardEvent *keyEvent,
void *userData)
485 if (keyEvent->keyCode <
SDL_arraysize(emscripten_scancode_table)) {
486 scancode = emscripten_scancode_table[keyEvent->keyCode];
490 if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) {
515 is_nav_key = keyEvent->keyCode == 8 ||
516 keyEvent->keyCode == 9 ||
517 keyEvent->keyCode == 37 ||
518 keyEvent->keyCode == 38 ||
519 keyEvent->keyCode == 39 ||
520 keyEvent->keyCode == 40 ;
525 return prevent_default;
529 Emscripten_HandleKeyPress(
int eventType,
const EmscriptenKeyboardEvent *keyEvent,
void *userData)
532 if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode,
text)) {
539 Emscripten_HandleFullscreenChange(
int eventType,
const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent,
void *userData)
544 if(fullscreenChangeEvent->isFullscreen)
569 Emscripten_HandleResize(
int eventType,
const EmscriptenUiEvent *uiEvent,
void *userData)
576 if (window_data->
pixel_ratio != emscripten_get_device_pixel_ratio()) {
577 window_data->
pixel_ratio = emscripten_get_device_pixel_ratio();
591 emscripten_get_element_css_size(window_data->
canvas_id, &
w, &
h);
598 emscripten_set_element_css_size(window_data->
canvas_id,
w,
h);
623 emscripten_get_element_css_size(window_data->
canvas_id, &css_w, &css_h);
631 Emscripten_HandleVisibilityChange(
int eventType,
const EmscriptenVisibilityChangeEvent *visEvent,
void *userData)
641 const char *keyElement;
644 emscripten_set_mousemove_callback(
data->canvas_id,
data, 0, Emscripten_HandleMouseMove);
646 emscripten_set_mousedown_callback(
data->canvas_id,
data, 0, Emscripten_HandleMouseButton);
647 emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
data, 0, Emscripten_HandleMouseButton);
649 emscripten_set_mouseenter_callback(
data->canvas_id,
data, 0, Emscripten_HandleMouseFocus);
650 emscripten_set_mouseleave_callback(
data->canvas_id,
data, 0, Emscripten_HandleMouseFocus);
652 emscripten_set_wheel_callback(
data->canvas_id,
data, 0, Emscripten_HandleWheel);
654 emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
data, 0, Emscripten_HandleFocus);
655 emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
data, 0, Emscripten_HandleFocus);
657 emscripten_set_touchstart_callback(
data->canvas_id,
data, 0, Emscripten_HandleTouch);
658 emscripten_set_touchend_callback(
data->canvas_id,
data, 0, Emscripten_HandleTouch);
659 emscripten_set_touchmove_callback(
data->canvas_id,
data, 0, Emscripten_HandleTouch);
660 emscripten_set_touchcancel_callback(
data->canvas_id,
data, 0, Emscripten_HandleTouch);
662 emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
data, 0, Emscripten_HandlePointerLockChange);
666 if (!keyElement) keyElement = EMSCRIPTEN_EVENT_TARGET_WINDOW;
668 emscripten_set_keydown_callback(keyElement,
data, 0, Emscripten_HandleKey);
669 emscripten_set_keyup_callback(keyElement,
data, 0, Emscripten_HandleKey);
670 emscripten_set_keypress_callback(keyElement,
data, 0, Emscripten_HandleKeyPress);
672 emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
data, 0, Emscripten_HandleFullscreenChange);
674 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
data, 0, Emscripten_HandleResize);
676 emscripten_set_visibilitychange_callback(
data, 0, Emscripten_HandleVisibilityChange);
685 emscripten_set_mousemove_callback(
data->canvas_id,
NULL, 0,
NULL);
687 emscripten_set_mousedown_callback(
data->canvas_id,
NULL, 0,
NULL);
688 emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
NULL, 0,
NULL);
690 emscripten_set_mouseenter_callback(
data->canvas_id,
NULL, 0,
NULL);
691 emscripten_set_mouseleave_callback(
data->canvas_id,
NULL, 0,
NULL);
693 emscripten_set_wheel_callback(
data->canvas_id,
NULL, 0,
NULL);
695 emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
NULL, 0,
NULL);
696 emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
NULL, 0,
NULL);
698 emscripten_set_touchstart_callback(
data->canvas_id,
NULL, 0,
NULL);
699 emscripten_set_touchend_callback(
data->canvas_id,
NULL, 0,
NULL);
700 emscripten_set_touchmove_callback(
data->canvas_id,
NULL, 0,
NULL);
701 emscripten_set_touchcancel_callback(
data->canvas_id,
NULL, 0,
NULL);
703 emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
NULL, 0,
NULL);
707 target = EMSCRIPTEN_EVENT_TARGET_WINDOW;
714 emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
NULL, 0,
NULL);
716 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
NULL, 0,
NULL);
718 emscripten_set_visibilitychange_callback(
NULL, 0,
NULL);