diff options
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenvideo.c')
| -rw-r--r-- | contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenvideo.c | 459 |
1 files changed, 459 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenvideo.c b/contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenvideo.c new file mode 100644 index 0000000..1496268 --- /dev/null +++ b/contrib/SDL-3.2.8/src/video/emscripten/SDL_emscriptenvideo.c | |||
| @@ -0,0 +1,459 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 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 | #include "SDL_internal.h" | ||
| 22 | |||
| 23 | #ifdef SDL_VIDEO_DRIVER_EMSCRIPTEN | ||
| 24 | |||
| 25 | #include "../SDL_sysvideo.h" | ||
| 26 | #include "../SDL_pixels_c.h" | ||
| 27 | #include "../../events/SDL_events_c.h" | ||
| 28 | |||
| 29 | #include "SDL_emscriptenvideo.h" | ||
| 30 | #include "SDL_emscriptenopengles.h" | ||
| 31 | #include "SDL_emscriptenframebuffer.h" | ||
| 32 | #include "SDL_emscriptenevents.h" | ||
| 33 | #include "SDL_emscriptenmouse.h" | ||
| 34 | |||
| 35 | #define EMSCRIPTENVID_DRIVER_NAME "emscripten" | ||
| 36 | |||
| 37 | // Initialization/Query functions | ||
| 38 | static bool Emscripten_VideoInit(SDL_VideoDevice *_this); | ||
| 39 | static bool Emscripten_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode); | ||
| 40 | static void Emscripten_VideoQuit(SDL_VideoDevice *_this); | ||
| 41 | static bool Emscripten_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect); | ||
| 42 | |||
| 43 | static bool Emscripten_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props); | ||
| 44 | static void Emscripten_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window); | ||
| 45 | static void Emscripten_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h); | ||
| 46 | static void Emscripten_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window); | ||
| 47 | static SDL_FullscreenResult Emscripten_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen); | ||
| 48 | static void Emscripten_PumpEvents(SDL_VideoDevice *_this); | ||
| 49 | static void Emscripten_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window); | ||
| 50 | |||
| 51 | static bool pumpevents_has_run = false; | ||
| 52 | static int pending_swap_interval = -1; | ||
| 53 | |||
| 54 | |||
| 55 | // Emscripten driver bootstrap functions | ||
| 56 | |||
| 57 | static void Emscripten_DeleteDevice(SDL_VideoDevice *device) | ||
| 58 | { | ||
| 59 | SDL_free(device); | ||
| 60 | } | ||
| 61 | |||
| 62 | static SDL_SystemTheme Emscripten_GetSystemTheme(void) | ||
| 63 | { | ||
| 64 | /* Technically, light theme can mean explicit light theme or no preference. | ||
| 65 | https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme#syntax */ | ||
| 66 | |||
| 67 | int theme_code = EM_ASM_INT({ | ||
| 68 | if (!window.matchMedia) { | ||
| 69 | return -1; | ||
| 70 | } | ||
| 71 | |||
| 72 | if (window.matchMedia('(prefers-color-scheme: light)').matches) { | ||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | if (window.matchMedia('(prefers-color-scheme: dark)').matches) { | ||
| 77 | return 1; | ||
| 78 | } | ||
| 79 | |||
| 80 | return -1; | ||
| 81 | }); | ||
| 82 | |||
| 83 | switch (theme_code) { | ||
| 84 | case 0: | ||
| 85 | return SDL_SYSTEM_THEME_LIGHT; | ||
| 86 | |||
| 87 | case 1: | ||
| 88 | return SDL_SYSTEM_THEME_DARK; | ||
| 89 | |||
| 90 | default: | ||
| 91 | return SDL_SYSTEM_THEME_UNKNOWN; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | static void Emscripten_ListenSystemTheme(void) | ||
| 96 | { | ||
| 97 | MAIN_THREAD_EM_ASM({ | ||
| 98 | if (window.matchMedia) { | ||
| 99 | if (typeof(Module['SDL3']) === 'undefined') { | ||
| 100 | Module['SDL3'] = {}; | ||
| 101 | } | ||
| 102 | |||
| 103 | var SDL3 = Module['SDL3']; | ||
| 104 | |||
| 105 | SDL3.eventHandlerThemeChanged = function(event) { | ||
| 106 | _Emscripten_SendSystemThemeChangedEvent(); | ||
| 107 | }; | ||
| 108 | |||
| 109 | SDL3.themeChangedMatchMedia = window.matchMedia('(prefers-color-scheme: dark)'); | ||
| 110 | SDL3.themeChangedMatchMedia.addEventListener('change', SDL3.eventHandlerThemeChanged); | ||
| 111 | } | ||
| 112 | }); | ||
| 113 | } | ||
| 114 | |||
| 115 | static void Emscripten_UnlistenSystemTheme(void) | ||
| 116 | { | ||
| 117 | MAIN_THREAD_EM_ASM({ | ||
| 118 | if (typeof(Module['SDL3']) !== 'undefined') { | ||
| 119 | var SDL3 = Module['SDL3']; | ||
| 120 | |||
| 121 | SDL3.themeChangedMatchMedia.removeEventListener('change', SDL3.eventHandlerThemeChanged); | ||
| 122 | SDL3.themeChangedMatchMedia = undefined; | ||
| 123 | SDL3.eventHandlerThemeChanged = undefined; | ||
| 124 | } | ||
| 125 | }); | ||
| 126 | } | ||
| 127 | |||
| 128 | EMSCRIPTEN_KEEPALIVE void Emscripten_SendSystemThemeChangedEvent(void) | ||
| 129 | { | ||
| 130 | SDL_SetSystemTheme(Emscripten_GetSystemTheme()); | ||
| 131 | } | ||
| 132 | |||
| 133 | static SDL_VideoDevice *Emscripten_CreateDevice(void) | ||
| 134 | { | ||
| 135 | SDL_VideoDevice *device; | ||
| 136 | |||
| 137 | // Initialize all variables that we clean on shutdown | ||
| 138 | device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); | ||
| 139 | if (!device) { | ||
| 140 | return NULL; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* Firefox sends blur event which would otherwise prevent full screen | ||
| 144 | * when the user clicks to allow full screen. | ||
| 145 | * See https://bugzilla.mozilla.org/show_bug.cgi?id=1144964 | ||
| 146 | */ | ||
| 147 | SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0"); | ||
| 148 | |||
| 149 | // Set the function pointers | ||
| 150 | device->VideoInit = Emscripten_VideoInit; | ||
| 151 | device->VideoQuit = Emscripten_VideoQuit; | ||
| 152 | device->GetDisplayUsableBounds = Emscripten_GetDisplayUsableBounds; | ||
| 153 | device->SetDisplayMode = Emscripten_SetDisplayMode; | ||
| 154 | |||
| 155 | device->PumpEvents = Emscripten_PumpEvents; | ||
| 156 | |||
| 157 | device->CreateSDLWindow = Emscripten_CreateWindow; | ||
| 158 | device->SetWindowTitle = Emscripten_SetWindowTitle; | ||
| 159 | /*device->SetWindowIcon = Emscripten_SetWindowIcon; | ||
| 160 | device->SetWindowPosition = Emscripten_SetWindowPosition;*/ | ||
| 161 | device->SetWindowSize = Emscripten_SetWindowSize; | ||
| 162 | /*device->ShowWindow = Emscripten_ShowWindow; | ||
| 163 | device->HideWindow = Emscripten_HideWindow; | ||
| 164 | device->RaiseWindow = Emscripten_RaiseWindow; | ||
| 165 | device->MaximizeWindow = Emscripten_MaximizeWindow; | ||
| 166 | device->MinimizeWindow = Emscripten_MinimizeWindow; | ||
| 167 | device->RestoreWindow = Emscripten_RestoreWindow; | ||
| 168 | device->SetWindowMouseGrab = Emscripten_SetWindowMouseGrab;*/ | ||
| 169 | device->GetWindowSizeInPixels = Emscripten_GetWindowSizeInPixels; | ||
| 170 | device->DestroyWindow = Emscripten_DestroyWindow; | ||
| 171 | device->SetWindowFullscreen = Emscripten_SetWindowFullscreen; | ||
| 172 | |||
| 173 | device->CreateWindowFramebuffer = Emscripten_CreateWindowFramebuffer; | ||
| 174 | device->UpdateWindowFramebuffer = Emscripten_UpdateWindowFramebuffer; | ||
| 175 | device->DestroyWindowFramebuffer = Emscripten_DestroyWindowFramebuffer; | ||
| 176 | |||
| 177 | device->GL_LoadLibrary = Emscripten_GLES_LoadLibrary; | ||
| 178 | device->GL_GetProcAddress = Emscripten_GLES_GetProcAddress; | ||
| 179 | device->GL_UnloadLibrary = Emscripten_GLES_UnloadLibrary; | ||
| 180 | device->GL_CreateContext = Emscripten_GLES_CreateContext; | ||
| 181 | device->GL_MakeCurrent = Emscripten_GLES_MakeCurrent; | ||
| 182 | device->GL_SetSwapInterval = Emscripten_GLES_SetSwapInterval; | ||
| 183 | device->GL_GetSwapInterval = Emscripten_GLES_GetSwapInterval; | ||
| 184 | device->GL_SwapWindow = Emscripten_GLES_SwapWindow; | ||
| 185 | device->GL_DestroyContext = Emscripten_GLES_DestroyContext; | ||
| 186 | |||
| 187 | device->free = Emscripten_DeleteDevice; | ||
| 188 | |||
| 189 | Emscripten_ListenSystemTheme(); | ||
| 190 | device->system_theme = Emscripten_GetSystemTheme(); | ||
| 191 | |||
| 192 | return device; | ||
| 193 | } | ||
| 194 | |||
| 195 | VideoBootStrap Emscripten_bootstrap = { | ||
| 196 | EMSCRIPTENVID_DRIVER_NAME, "SDL emscripten video driver", | ||
| 197 | Emscripten_CreateDevice, | ||
| 198 | NULL, // no ShowMessageBox implementation | ||
| 199 | false | ||
| 200 | }; | ||
| 201 | |||
| 202 | bool Emscripten_VideoInit(SDL_VideoDevice *_this) | ||
| 203 | { | ||
| 204 | SDL_DisplayMode mode; | ||
| 205 | |||
| 206 | // Use a fake 32-bpp desktop mode | ||
| 207 | SDL_zero(mode); | ||
| 208 | mode.format = SDL_PIXELFORMAT_XRGB8888; | ||
| 209 | emscripten_get_screen_size(&mode.w, &mode.h); | ||
| 210 | mode.pixel_density = emscripten_get_device_pixel_ratio(); | ||
| 211 | |||
| 212 | if (SDL_AddBasicVideoDisplay(&mode) == 0) { | ||
| 213 | return false; | ||
| 214 | } | ||
| 215 | |||
| 216 | Emscripten_InitMouse(); | ||
| 217 | |||
| 218 | // Assume we have a mouse and keyboard | ||
| 219 | SDL_AddKeyboard(SDL_DEFAULT_KEYBOARD_ID, NULL, false); | ||
| 220 | SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL, false); | ||
| 221 | |||
| 222 | // We're done! | ||
| 223 | return true; | ||
| 224 | } | ||
| 225 | |||
| 226 | static bool Emscripten_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode) | ||
| 227 | { | ||
| 228 | // can't do this | ||
| 229 | return true; | ||
| 230 | } | ||
| 231 | |||
| 232 | static void Emscripten_VideoQuit(SDL_VideoDevice *_this) | ||
| 233 | { | ||
| 234 | Emscripten_QuitMouse(); | ||
| 235 | Emscripten_UnlistenSystemTheme(); | ||
| 236 | pumpevents_has_run = false; | ||
| 237 | pending_swap_interval = -1; | ||
| 238 | } | ||
| 239 | |||
| 240 | static bool Emscripten_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect) | ||
| 241 | { | ||
| 242 | if (rect) { | ||
| 243 | rect->x = 0; | ||
| 244 | rect->y = 0; | ||
| 245 | rect->w = MAIN_THREAD_EM_ASM_INT({ | ||
| 246 | return window.innerWidth; | ||
| 247 | }); | ||
| 248 | rect->h = MAIN_THREAD_EM_ASM_INT({ | ||
| 249 | return window.innerHeight; | ||
| 250 | }); | ||
| 251 | } | ||
| 252 | return true; | ||
| 253 | } | ||
| 254 | |||
| 255 | bool Emscripten_ShouldSetSwapInterval(int interval) | ||
| 256 | { | ||
| 257 | if (!pumpevents_has_run) { | ||
| 258 | pending_swap_interval = interval; | ||
| 259 | return false; | ||
| 260 | } | ||
| 261 | return true; | ||
| 262 | } | ||
| 263 | |||
| 264 | static void Emscripten_PumpEvents(SDL_VideoDevice *_this) | ||
| 265 | { | ||
| 266 | if (!pumpevents_has_run) { | ||
| 267 | // we assume you've set a mainloop by the time you've called pumpevents, so we delay initial SetInterval changes until then. | ||
| 268 | // otherwise you'll get a warning on the javascript console. | ||
| 269 | pumpevents_has_run = true; | ||
| 270 | if (pending_swap_interval >= 0) { | ||
| 271 | Emscripten_GLES_SetSwapInterval(_this, pending_swap_interval); | ||
| 272 | pending_swap_interval = -1; | ||
| 273 | } | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | EMSCRIPTEN_KEEPALIVE void requestFullscreenThroughSDL(SDL_Window *window) | ||
| 278 | { | ||
| 279 | SDL_SetWindowFullscreen(window, true); | ||
| 280 | } | ||
| 281 | |||
| 282 | static bool Emscripten_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props) | ||
| 283 | { | ||
| 284 | SDL_WindowData *wdata; | ||
| 285 | double scaled_w, scaled_h; | ||
| 286 | double css_w, css_h; | ||
| 287 | const char *selector; | ||
| 288 | |||
| 289 | // Allocate window internal data | ||
| 290 | wdata = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData)); | ||
| 291 | if (!wdata) { | ||
| 292 | return false; | ||
| 293 | } | ||
| 294 | |||
| 295 | selector = SDL_GetHint(SDL_HINT_EMSCRIPTEN_CANVAS_SELECTOR); | ||
| 296 | if (!selector) { | ||
| 297 | selector = "#canvas"; | ||
| 298 | } | ||
| 299 | |||
| 300 | wdata->canvas_id = SDL_strdup(selector); | ||
| 301 | |||
| 302 | if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { | ||
| 303 | wdata->pixel_ratio = emscripten_get_device_pixel_ratio(); | ||
| 304 | } else { | ||
| 305 | wdata->pixel_ratio = 1.0f; | ||
| 306 | } | ||
| 307 | |||
| 308 | scaled_w = SDL_floor(window->w * wdata->pixel_ratio); | ||
| 309 | scaled_h = SDL_floor(window->h * wdata->pixel_ratio); | ||
| 310 | |||
| 311 | // set a fake size to check if there is any CSS sizing the canvas | ||
| 312 | emscripten_set_canvas_element_size(wdata->canvas_id, 1, 1); | ||
| 313 | emscripten_get_element_css_size(wdata->canvas_id, &css_w, &css_h); | ||
| 314 | |||
| 315 | wdata->external_size = SDL_floor(css_w) != 1 || SDL_floor(css_h) != 1; | ||
| 316 | |||
| 317 | if ((window->flags & SDL_WINDOW_RESIZABLE) && wdata->external_size) { | ||
| 318 | // external css has resized us | ||
| 319 | scaled_w = css_w * wdata->pixel_ratio; | ||
| 320 | scaled_h = css_h * wdata->pixel_ratio; | ||
| 321 | |||
| 322 | SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, SDL_lroundf(css_w), SDL_lroundf(css_h)); | ||
| 323 | } | ||
| 324 | emscripten_set_canvas_element_size(wdata->canvas_id, SDL_lroundf(scaled_w), SDL_lroundf(scaled_h)); | ||
| 325 | |||
| 326 | // if the size is not being controlled by css, we need to scale down for hidpi | ||
| 327 | if (!wdata->external_size) { | ||
| 328 | if (wdata->pixel_ratio != 1.0f) { | ||
| 329 | // scale canvas down | ||
| 330 | emscripten_set_element_css_size(wdata->canvas_id, window->w, window->h); | ||
| 331 | } | ||
| 332 | } | ||
| 333 | |||
| 334 | wdata->window = window; | ||
| 335 | |||
| 336 | // Setup driver data for this window | ||
| 337 | window->internal = wdata; | ||
| 338 | |||
| 339 | // One window, it always has focus | ||
| 340 | SDL_SetMouseFocus(window); | ||
| 341 | SDL_SetKeyboardFocus(window); | ||
| 342 | |||
| 343 | Emscripten_RegisterEventHandlers(wdata); | ||
| 344 | |||
| 345 | // disable the emscripten "fullscreen" button. | ||
| 346 | MAIN_THREAD_EM_ASM({ | ||
| 347 | Module['requestFullscreen'] = function(lockPointer, resizeCanvas) { | ||
| 348 | _requestFullscreenThroughSDL($0); | ||
| 349 | }; | ||
| 350 | }, window); | ||
| 351 | |||
| 352 | // Window has been successfully created | ||
| 353 | return true; | ||
| 354 | } | ||
| 355 | |||
| 356 | static void Emscripten_SetWindowSize(SDL_VideoDevice *_this, SDL_Window *window) | ||
| 357 | { | ||
| 358 | SDL_WindowData *data; | ||
| 359 | |||
| 360 | if (window->internal) { | ||
| 361 | data = window->internal; | ||
| 362 | // update pixel ratio | ||
| 363 | if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { | ||
| 364 | data->pixel_ratio = emscripten_get_device_pixel_ratio(); | ||
| 365 | } | ||
| 366 | emscripten_set_canvas_element_size(data->canvas_id, SDL_lroundf(window->pending.w * data->pixel_ratio), SDL_lroundf(window->pending.h * data->pixel_ratio)); | ||
| 367 | |||
| 368 | // scale canvas down | ||
| 369 | if (!data->external_size && data->pixel_ratio != 1.0f) { | ||
| 370 | emscripten_set_element_css_size(data->canvas_id, window->pending.w, window->pending.h); | ||
| 371 | } | ||
| 372 | |||
| 373 | SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, window->pending.w, window->pending.h); | ||
| 374 | } | ||
| 375 | } | ||
| 376 | |||
| 377 | static void Emscripten_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h) | ||
| 378 | { | ||
| 379 | SDL_WindowData *data; | ||
| 380 | if (window->internal) { | ||
| 381 | data = window->internal; | ||
| 382 | *w = SDL_lroundf(window->w * data->pixel_ratio); | ||
| 383 | *h = SDL_lroundf(window->h * data->pixel_ratio); | ||
| 384 | } | ||
| 385 | } | ||
| 386 | |||
| 387 | static void Emscripten_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window) | ||
| 388 | { | ||
| 389 | SDL_WindowData *data; | ||
| 390 | |||
| 391 | if (window->internal) { | ||
| 392 | data = window->internal; | ||
| 393 | |||
| 394 | Emscripten_UnregisterEventHandlers(data); | ||
| 395 | |||
| 396 | // We can't destroy the canvas, so resize it to zero instead | ||
| 397 | emscripten_set_canvas_element_size(data->canvas_id, 0, 0); | ||
| 398 | SDL_free(data->canvas_id); | ||
| 399 | |||
| 400 | SDL_free(window->internal); | ||
| 401 | window->internal = NULL; | ||
| 402 | } | ||
| 403 | |||
| 404 | // just ignore clicks on the fullscreen button while there's no SDL window. | ||
| 405 | MAIN_THREAD_EM_ASM({ Module['requestFullscreen'] = function(lockPointer, resizeCanvas) {}; }); | ||
| 406 | } | ||
| 407 | |||
| 408 | static SDL_FullscreenResult Emscripten_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen) | ||
| 409 | { | ||
| 410 | SDL_WindowData *data; | ||
| 411 | int res = -1; | ||
| 412 | |||
| 413 | if (window->internal) { | ||
| 414 | data = window->internal; | ||
| 415 | |||
| 416 | if (fullscreen) { | ||
| 417 | EmscriptenFullscreenStrategy strategy; | ||
| 418 | bool is_fullscreen_desktop = !window->fullscreen_exclusive; | ||
| 419 | |||
| 420 | SDL_zero(strategy); | ||
| 421 | strategy.scaleMode = is_fullscreen_desktop ? EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH : EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT; | ||
| 422 | |||
| 423 | if (!is_fullscreen_desktop) { | ||
| 424 | strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE; | ||
| 425 | } else if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { | ||
| 426 | strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF; | ||
| 427 | } else { | ||
| 428 | strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; | ||
| 429 | } | ||
| 430 | |||
| 431 | strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; | ||
| 432 | |||
| 433 | strategy.canvasResizedCallback = Emscripten_HandleCanvasResize; | ||
| 434 | strategy.canvasResizedCallbackUserData = data; | ||
| 435 | |||
| 436 | data->fullscreen_mode_flags = (window->flags & SDL_WINDOW_FULLSCREEN); | ||
| 437 | data->fullscreen_resize = is_fullscreen_desktop; | ||
| 438 | |||
| 439 | res = emscripten_request_fullscreen_strategy(data->canvas_id, 1, &strategy); | ||
| 440 | } else { | ||
| 441 | res = emscripten_exit_fullscreen(); | ||
| 442 | } | ||
| 443 | } | ||
| 444 | |||
| 445 | if (res == EMSCRIPTEN_RESULT_SUCCESS) { | ||
| 446 | return SDL_FULLSCREEN_SUCCEEDED; | ||
| 447 | } else if (res == EMSCRIPTEN_RESULT_DEFERRED) { | ||
| 448 | return SDL_FULLSCREEN_PENDING; | ||
| 449 | } else { | ||
| 450 | return SDL_FULLSCREEN_FAILED; | ||
| 451 | } | ||
| 452 | } | ||
| 453 | |||
| 454 | static void Emscripten_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window) | ||
| 455 | { | ||
| 456 | emscripten_set_window_title(window->title); | ||
| 457 | } | ||
| 458 | |||
| 459 | #endif // SDL_VIDEO_DRIVER_EMSCRIPTEN | ||
