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(window_data->
canvas_id, 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];
488 if (keyEvent->keyCode == 0) {
490 if (
SDL_strncmp(keyEvent->key,
"SoftLeft", 9) == 0) {
493 if (
SDL_strncmp(keyEvent->key,
"SoftRight", 10) == 0) {
500 if (keyEvent->location == DOM_KEY_LOCATION_RIGHT) {
516 else if (keyEvent->location == DOM_KEY_LOCATION_NUMPAD) {
574 is_nav_key = keyEvent->keyCode == 8 ||
575 keyEvent->keyCode == 9 ||
576 keyEvent->keyCode == 37 ||
577 keyEvent->keyCode == 38 ||
578 keyEvent->keyCode == 39 ||
579 keyEvent->keyCode == 40 ;
584 return prevent_default;
588 Emscripten_HandleKeyPress(
int eventType,
const EmscriptenKeyboardEvent *keyEvent,
void *userData)
591 if (Emscripten_ConvertUTF32toUTF8(keyEvent->charCode,
text)) {
598 Emscripten_HandleFullscreenChange(
int eventType,
const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent,
void *userData)
603 if(fullscreenChangeEvent->isFullscreen)
628 Emscripten_HandleResize(
int eventType,
const EmscriptenUiEvent *uiEvent,
void *userData)
635 if (window_data->
pixel_ratio != emscripten_get_device_pixel_ratio()) {
636 window_data->
pixel_ratio = emscripten_get_device_pixel_ratio();
650 emscripten_get_element_css_size(window_data->
canvas_id, &
w, &
h);
657 emscripten_set_element_css_size(window_data->
canvas_id,
w,
h);
682 emscripten_get_element_css_size(window_data->
canvas_id, &css_w, &css_h);
690 Emscripten_HandleVisibilityChange(
int eventType,
const EmscriptenVisibilityChangeEvent *visEvent,
void *userData)
698 Emscripten_HandleBeforeUnload(
int eventType,
const void *reserved,
void *userData)
710 const char *keyElement;
713 emscripten_set_mousemove_callback(
data->canvas_id,
data, 0, Emscripten_HandleMouseMove);
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);
718 emscripten_set_mouseenter_callback(
data->canvas_id,
data, 0, Emscripten_HandleMouseFocus);
719 emscripten_set_mouseleave_callback(
data->canvas_id,
data, 0, Emscripten_HandleMouseFocus);
721 emscripten_set_wheel_callback(
data->canvas_id,
data, 0, Emscripten_HandleWheel);
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);
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);
731 emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
data, 0, Emscripten_HandlePointerLockChange);
735 if (!keyElement) keyElement = EMSCRIPTEN_EVENT_TARGET_WINDOW;
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);
741 emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
data, 0, Emscripten_HandleFullscreenChange);
743 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
data, 0, Emscripten_HandleResize);
745 emscripten_set_visibilitychange_callback(
data, 0, Emscripten_HandleVisibilityChange);
747 emscripten_set_beforeunload_callback(
data, Emscripten_HandleBeforeUnload);
756 emscripten_set_mousemove_callback(
data->canvas_id,
NULL, 0,
NULL);
758 emscripten_set_mousedown_callback(
data->canvas_id,
NULL, 0,
NULL);
759 emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
NULL, 0,
NULL);
761 emscripten_set_mouseenter_callback(
data->canvas_id,
NULL, 0,
NULL);
762 emscripten_set_mouseleave_callback(
data->canvas_id,
NULL, 0,
NULL);
764 emscripten_set_wheel_callback(
data->canvas_id,
NULL, 0,
NULL);
766 emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
NULL, 0,
NULL);
767 emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
NULL, 0,
NULL);
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);
774 emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
NULL, 0,
NULL);
778 target = EMSCRIPTEN_EVENT_TARGET_WINDOW;
785 emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT,
NULL, 0,
NULL);
787 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
NULL, 0,
NULL);
789 emscripten_set_visibilitychange_callback(
NULL, 0,
NULL);
791 emscripten_set_beforeunload_callback(
NULL,
NULL);
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)
SDL_EventType
The types of events that can be delivered.
#define SDL_GetEventState(type)
#define SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT
override the binding element for keyboard inputs for Emscripten builds
void SDL_ResetKeyboard(void)
int SDL_SendKeyboardText(const char *text)
int SDL_SendKeyboardKey(Uint8 state, SDL_Scancode scancode)
int SDL_SendMouseButton(SDL_Window *window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
SDL_Mouse * SDL_GetMouse(void)
void SDL_SetMouseFocus(SDL_Window *window)
int SDL_SendMouseWheel(SDL_Window *window, SDL_MouseID mouseID, float x, float y, SDL_MouseWheelDirection direction)
int SDL_SendMouseMotion(SDL_Window *window, SDL_MouseID mouseID, int relative, int x, int y)
#define SDL_BUTTON_MIDDLE
GLint GLint GLint GLint GLint GLint y
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLint GLint GLint x
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
SDL_Scancode
The SDL keyboard scancode representation.
@ SDL_SCANCODE_RIGHTBRACKET
@ SDL_SCANCODE_NONUSBACKSLASH
@ SDL_SCANCODE_APOSTROPHE
@ SDL_SCANCODE_NUMLOCKCLEAR
@ SDL_SCANCODE_SCROLLLOCK
@ SDL_SCANCODE_LEFTBRACKET
@ SDL_SCANCODE_KP_MULTIPLY
@ SDL_SCANCODE_APPLICATION
@ SDL_SCANCODE_VOLUMEDOWN
@ SDL_SCANCODE_AC_FORWARD
#define SDL_arraysize(array)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
int SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, SDL_bool down, float x, float y, float pressure)
int SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
int SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, SDL_Window *window, float x, float y, float pressure)
@ SDL_TOUCH_DEVICE_DIRECT
@ SDL_WINDOW_ALLOW_HIGHDPI
@ SDL_WINDOWEVENT_FOCUS_LOST
@ SDL_WINDOWEVENT_RESIZED
@ SDL_WINDOWEVENT_FOCUS_GAINED
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)
GLenum GLenum GLuint GLint GLint GLint yscale
GLenum GLenum GLuint GLint GLint xscale
SDL_Window * fullscreen_window
SDL_bool has_pointer_lock
SDL_bool fullscreen_resize
int requested_fullscreen_mode
static char text[MAX_TEXT_LENGTH]