| | |
| | | /* |
| | | Simple DirectMedia Layer |
| | | Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> |
| | | Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org> |
| | | |
| | | This software is provided 'as-is', without any express or implied |
| | | warranty. In no event will the authors be held liable for any damages |
| | |
| | | /* 160 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 161 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 162 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 163 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 163 */ SDL_SCANCODE_KP_HASH, /*KaiOS phone keypad*/ |
| | | /* 164 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 165 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 166 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 167 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 168 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 169 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 170 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 170 */ SDL_SCANCODE_KP_MULTIPLY, /*KaiOS phone keypad*/ |
| | | /* 171 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 172 */ SDL_SCANCODE_UNKNOWN, |
| | | /* 173 */ SDL_SCANCODE_MINUS, /*FX*/ |
| | |
| | | |
| | | /* rescale (in case canvas is being scaled)*/ |
| | | double client_w, client_h, xscale, yscale; |
| | | emscripten_get_element_css_size(NULL, &client_w, &client_h); |
| | | emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h); |
| | | xscale = window_data->window->w / client_w; |
| | | yscale = window_data->window->h / client_h; |
| | | |
| | |
| | | my = residualy; |
| | | residualy -= my; |
| | | } else { |
| | | mx = mouseEvent->canvasX * xscale; |
| | | my = mouseEvent->canvasY * yscale; |
| | | mx = mouseEvent->targetX * xscale; |
| | | my = mouseEvent->targetY * yscale; |
| | | } |
| | | |
| | | SDL_SendMouseMotion(window_data->window, 0, isPointerLocked, mx, my); |
| | |
| | | Uint8 sdl_button; |
| | | Uint8 sdl_button_state; |
| | | SDL_EventType sdl_event_type; |
| | | double css_w, css_h; |
| | | |
| | | switch (mouseEvent->button) { |
| | | case 0: |
| | |
| | | sdl_event_type = SDL_MOUSEBUTTONUP; |
| | | } |
| | | SDL_SendMouseButton(window_data->window, 0, sdl_button_state, sdl_button); |
| | | |
| | | /* Do not consume the event if the mouse is outside of the canvas. */ |
| | | emscripten_get_element_css_size(window_data->canvas_id, &css_w, &css_h); |
| | | if (mouseEvent->targetX < 0 || mouseEvent->targetX >= css_w || |
| | | mouseEvent->targetY < 0 || mouseEvent->targetY >= css_h) { |
| | | return 0; |
| | | } |
| | | |
| | | return SDL_GetEventState(sdl_event_type) == SDL_ENABLE; |
| | | } |
| | | |
| | |
| | | { |
| | | SDL_WindowData *window_data = userData; |
| | | |
| | | int mx = mouseEvent->canvasX, my = mouseEvent->canvasY; |
| | | int mx = mouseEvent->targetX, my = mouseEvent->targetY; |
| | | const int isPointerLocked = window_data->has_pointer_lock; |
| | | |
| | | if (!isPointerLocked) { |
| | | /* rescale (in case canvas is being scaled)*/ |
| | | double client_w, client_h; |
| | | emscripten_get_element_css_size(NULL, &client_w, &client_h); |
| | | emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h); |
| | | |
| | | mx = mx * (window_data->window->w / client_w); |
| | | my = my * (window_data->window->h / client_h); |
| | |
| | | static EM_BOOL |
| | | Emscripten_HandleTouch(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData) |
| | | { |
| | | SDL_WindowData *window_data = userData; |
| | | SDL_WindowData *window_data = (SDL_WindowData *) userData; |
| | | int i; |
| | | double client_w, client_h; |
| | | int preventDefault = 0; |
| | | |
| | | SDL_TouchID deviceId = 1; |
| | | if (SDL_AddTouch(deviceId, "") < 0) { |
| | | if (SDL_AddTouch(deviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) { |
| | | return 0; |
| | | } |
| | | |
| | | emscripten_get_element_css_size(NULL, &client_w, &client_h); |
| | | emscripten_get_element_css_size(window_data->canvas_id, &client_w, &client_h); |
| | | |
| | | for (i = 0; i < touchEvent->numTouches; i++) { |
| | | SDL_FingerID id; |
| | | float x, y; |
| | | int mx, my; |
| | | |
| | | if (!touchEvent->touches[i].isChanged) |
| | | continue; |
| | | |
| | | id = touchEvent->touches[i].identifier; |
| | | x = touchEvent->touches[i].canvasX / client_w; |
| | | y = touchEvent->touches[i].canvasY / client_h; |
| | | |
| | | mx = x * window_data->window->w; |
| | | my = y * window_data->window->h; |
| | | x = touchEvent->touches[i].targetX / client_w; |
| | | y = touchEvent->touches[i].targetY / client_h; |
| | | |
| | | if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) { |
| | | if (!window_data->finger_touching) { |
| | | window_data->finger_touching = SDL_TRUE; |
| | | window_data->first_finger = id; |
| | | SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, mx, my); |
| | | SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT); |
| | | } |
| | | SDL_SendTouch(deviceId, id, SDL_TRUE, x, y, 1.0f); |
| | | SDL_SendTouch(deviceId, id, window_data->window, SDL_TRUE, x, y, 1.0f); |
| | | |
| | | /* disable browser scrolling/pinch-to-zoom if app handles touch events */ |
| | | if (!preventDefault && SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) { |
| | | preventDefault = 1; |
| | | } |
| | | } else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) { |
| | | if ((window_data->finger_touching) && (window_data->first_finger == id)) { |
| | | SDL_SendMouseMotion(window_data->window, SDL_TOUCH_MOUSEID, 0, mx, my); |
| | | } |
| | | SDL_SendTouchMotion(deviceId, id, x, y, 1.0f); |
| | | |
| | | if (!preventDefault && SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) { |
| | | preventDefault = 1; |
| | | } |
| | | SDL_SendTouchMotion(deviceId, id, window_data->window, x, y, 1.0f); |
| | | } else { |
| | | if ((window_data->finger_touching) && (window_data->first_finger == id)) { |
| | | SDL_SendMouseButton(window_data->window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT); |
| | | window_data->finger_touching = SDL_FALSE; |
| | | } |
| | | SDL_SendTouch(deviceId, id, SDL_FALSE, x, y, 1.0f); |
| | | SDL_SendTouch(deviceId, id, window_data->window, SDL_FALSE, x, y, 1.0f); |
| | | |
| | | if (!preventDefault && SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) { |
| | | preventDefault = 1; |
| | | } |
| | | /* block browser's simulated mousedown/mouseup on touchscreen devices */ |
| | | preventDefault = 1; |
| | | } |
| | | } |
| | | |
| | |
| | | Emscripten_HandleFullscreenChange(int eventType, const EmscriptenFullscreenChangeEvent *fullscreenChangeEvent, void *userData) |
| | | { |
| | | SDL_WindowData *window_data = userData; |
| | | SDL_VideoDisplay *display; |
| | | |
| | | if(fullscreenChangeEvent->isFullscreen) |
| | | { |
| | | window_data->window->flags |= window_data->requested_fullscreen_mode; |
| | |
| | | else |
| | | { |
| | | window_data->window->flags &= ~FULLSCREEN_MASK; |
| | | |
| | | /* reset fullscreen window if the browser left fullscreen */ |
| | | display = SDL_GetDisplayForWindow(window_data->window); |
| | | |
| | | if (display->fullscreen_window == window_data->window) { |
| | | display->fullscreen_window = NULL; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | |
| | | Emscripten_HandleResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData) |
| | | { |
| | | SDL_WindowData *window_data = userData; |
| | | SDL_bool force = SDL_FALSE; |
| | | |
| | | /* update pixel ratio */ |
| | | if (window_data->window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { |
| | | window_data->pixel_ratio = emscripten_get_device_pixel_ratio(); |
| | | if (window_data->pixel_ratio != emscripten_get_device_pixel_ratio()) { |
| | | window_data->pixel_ratio = emscripten_get_device_pixel_ratio(); |
| | | force = SDL_TRUE; |
| | | } |
| | | } |
| | | |
| | | if(!(window_data->window->flags & FULLSCREEN_MASK)) |
| | |
| | | double h = window_data->window->h; |
| | | |
| | | if(window_data->external_size) { |
| | | emscripten_get_element_css_size(NULL, &w, &h); |
| | | emscripten_get_element_css_size(window_data->canvas_id, &w, &h); |
| | | } |
| | | |
| | | emscripten_set_canvas_size(w * window_data->pixel_ratio, h * window_data->pixel_ratio); |
| | | emscripten_set_canvas_element_size(window_data->canvas_id, w * window_data->pixel_ratio, h * window_data->pixel_ratio); |
| | | |
| | | /* set_canvas_size unsets this */ |
| | | if (!window_data->external_size && window_data->pixel_ratio != 1.0f) { |
| | | emscripten_set_element_css_size(NULL, w, h); |
| | | emscripten_set_element_css_size(window_data->canvas_id, w, h); |
| | | } |
| | | |
| | | if (force) { |
| | | /* force the event to trigger, so pixel ratio changes can be handled */ |
| | | window_data->window->w = 0; |
| | | window_data->window->h = 0; |
| | | } |
| | | |
| | | SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, w, h); |
| | |
| | | if(window_data->fullscreen_resize) |
| | | { |
| | | double css_w, css_h; |
| | | emscripten_get_element_css_size(NULL, &css_w, &css_h); |
| | | emscripten_get_element_css_size(window_data->canvas_id, &css_w, &css_h); |
| | | SDL_SendWindowEvent(window_data->window, SDL_WINDOWEVENT_RESIZED, css_w, css_h); |
| | | } |
| | | |
| | |
| | | const char *keyElement; |
| | | |
| | | /* There is only one window and that window is the canvas */ |
| | | emscripten_set_mousemove_callback("#canvas", data, 0, Emscripten_HandleMouseMove); |
| | | emscripten_set_mousemove_callback(data->canvas_id, data, 0, Emscripten_HandleMouseMove); |
| | | |
| | | emscripten_set_mousedown_callback("#canvas", data, 0, Emscripten_HandleMouseButton); |
| | | emscripten_set_mouseup_callback("#document", data, 0, Emscripten_HandleMouseButton); |
| | | emscripten_set_mousedown_callback(data->canvas_id, data, 0, Emscripten_HandleMouseButton); |
| | | emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandleMouseButton); |
| | | |
| | | emscripten_set_mouseenter_callback("#canvas", data, 0, Emscripten_HandleMouseFocus); |
| | | emscripten_set_mouseleave_callback("#canvas", data, 0, Emscripten_HandleMouseFocus); |
| | | emscripten_set_mouseenter_callback(data->canvas_id, data, 0, Emscripten_HandleMouseFocus); |
| | | emscripten_set_mouseleave_callback(data->canvas_id, data, 0, Emscripten_HandleMouseFocus); |
| | | |
| | | emscripten_set_wheel_callback("#canvas", data, 0, Emscripten_HandleWheel); |
| | | emscripten_set_wheel_callback(data->canvas_id, data, 0, Emscripten_HandleWheel); |
| | | |
| | | emscripten_set_focus_callback("#window", data, 0, Emscripten_HandleFocus); |
| | | emscripten_set_blur_callback("#window", data, 0, Emscripten_HandleFocus); |
| | | emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleFocus); |
| | | emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleFocus); |
| | | |
| | | emscripten_set_touchstart_callback("#canvas", data, 0, Emscripten_HandleTouch); |
| | | emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch); |
| | | emscripten_set_touchmove_callback("#canvas", data, 0, Emscripten_HandleTouch); |
| | | emscripten_set_touchcancel_callback("#canvas", data, 0, Emscripten_HandleTouch); |
| | | emscripten_set_touchstart_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); |
| | | emscripten_set_touchend_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); |
| | | emscripten_set_touchmove_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); |
| | | emscripten_set_touchcancel_callback(data->canvas_id, data, 0, Emscripten_HandleTouch); |
| | | |
| | | emscripten_set_pointerlockchange_callback("#document", data, 0, Emscripten_HandlePointerLockChange); |
| | | emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandlePointerLockChange); |
| | | |
| | | /* Keyboard events are awkward */ |
| | | keyElement = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT); |
| | | if (!keyElement) keyElement = "#window"; |
| | | if (!keyElement) keyElement = EMSCRIPTEN_EVENT_TARGET_WINDOW; |
| | | |
| | | emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey); |
| | | emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey); |
| | | emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress); |
| | | |
| | | emscripten_set_fullscreenchange_callback("#document", data, 0, Emscripten_HandleFullscreenChange); |
| | | emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, data, 0, Emscripten_HandleFullscreenChange); |
| | | |
| | | emscripten_set_resize_callback("#window", data, 0, Emscripten_HandleResize); |
| | | emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, data, 0, Emscripten_HandleResize); |
| | | |
| | | emscripten_set_visibilitychange_callback(data, 0, Emscripten_HandleVisibilityChange); |
| | | } |
| | |
| | | const char *target; |
| | | |
| | | /* only works due to having one window */ |
| | | emscripten_set_mousemove_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_mousemove_callback(data->canvas_id, NULL, 0, NULL); |
| | | |
| | | emscripten_set_mousedown_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_mouseup_callback("#document", NULL, 0, NULL); |
| | | emscripten_set_mousedown_callback(data->canvas_id, NULL, 0, NULL); |
| | | emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); |
| | | |
| | | emscripten_set_mouseenter_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_mouseleave_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_mouseenter_callback(data->canvas_id, NULL, 0, NULL); |
| | | emscripten_set_mouseleave_callback(data->canvas_id, NULL, 0, NULL); |
| | | |
| | | emscripten_set_wheel_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_wheel_callback(data->canvas_id, NULL, 0, NULL); |
| | | |
| | | emscripten_set_focus_callback("#window", NULL, 0, NULL); |
| | | emscripten_set_blur_callback("#window", NULL, 0, NULL); |
| | | emscripten_set_focus_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL); |
| | | emscripten_set_blur_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL); |
| | | |
| | | emscripten_set_touchstart_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_touchend_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_touchmove_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_touchcancel_callback("#canvas", NULL, 0, NULL); |
| | | emscripten_set_touchstart_callback(data->canvas_id, NULL, 0, NULL); |
| | | emscripten_set_touchend_callback(data->canvas_id, NULL, 0, NULL); |
| | | emscripten_set_touchmove_callback(data->canvas_id, NULL, 0, NULL); |
| | | emscripten_set_touchcancel_callback(data->canvas_id, NULL, 0, NULL); |
| | | |
| | | emscripten_set_pointerlockchange_callback("#document", NULL, 0, NULL); |
| | | emscripten_set_pointerlockchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); |
| | | |
| | | target = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT); |
| | | if (!target) { |
| | | target = "#window"; |
| | | target = EMSCRIPTEN_EVENT_TARGET_WINDOW; |
| | | } |
| | | |
| | | emscripten_set_keydown_callback(target, NULL, 0, NULL); |
| | | emscripten_set_keyup_callback(target, NULL, 0, NULL); |
| | | emscripten_set_keypress_callback(target, NULL, 0, NULL); |
| | | |
| | | emscripten_set_fullscreenchange_callback("#document", NULL, 0, NULL); |
| | | emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, NULL, 0, NULL); |
| | | |
| | | emscripten_set_resize_callback("#window", NULL, 0, NULL); |
| | | emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL); |
| | | |
| | | emscripten_set_visibilitychange_callback(NULL, 0, NULL); |
| | | } |