diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci index feaf0c9b08..40546b9af0 100644 --- a/build-scripts/SDL_migration.cocci +++ b/build-scripts/SDL_migration.cocci @@ -2359,3 +2359,18 @@ SDL_DisplayMode e; - SDL_GetWindowDisplayIndex + SDL_GetDisplayForWindow (...) +@@ +@@ +- SDL_SetWindowDisplayMode ++ SDL_SetWindowFullscreenMode + (...) +@@ +@@ +- SDL_GetWindowDisplayMode ++ SDL_GetWindowFullscreenMode + (...) +@@ +@@ +- SDL_GetClosestDisplayMode ++ SDL_GetClosestFullscreenDisplayMode + (...) diff --git a/docs/README-migration.md b/docs/README-migration.md index 57ea7ede1d..32a7bb3f8a 100644 --- a/docs/README-migration.md +++ b/docs/README-migration.md @@ -962,7 +962,7 @@ Rather than iterating over displays using display index, there is a new function ```c { if (SDL_InitSubSystem(SDL_INIT_VIDEO) == 0) { - int i, num_displays; + int i, num_displays = 0; SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); if (displays) { for (i = 0; i < num_displays; ++i) { @@ -988,6 +988,29 @@ SDL_DisplayMode now includes the pixel size, the screen size and the relationshi The refresh rate in SDL_DisplayMode is now a float. +Rather than iterating over display modes using an index, there is a new function SDL_GetFullscreenDisplayModes() to get the list of available fullscreen modes on a display. +```c +{ + SDL_DisplayID display = SDL_GetPrimaryDisplay(); + int num_modes = 0; + SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(display, &num_modes); + if (modes) { + for (i = 0; i < num_modes; ++i) { + SDL_DisplayMode *mode = modes[i]; + SDL_Log("Display %" SDL_PRIu32 " mode %d: %dx%d@%gHz, %d%% scale\n", + display, i, mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f)); + } + SDL_free(modes); + } +} +``` + +SDL_GetDesktopDisplayMode() and SDL_GetCurrentDisplayMode() return pointers to display modes rather than filling in application memory. + +Windows now have an explicit fullscreen mode that is set, using SDL_SetWindowFullscreenMode(). The fullscreen mode for a window can be queried with SDL_GetWindowFullscreenMode(), which returns a pointer to the mode, or NULL if the window will be fullscreen desktop. SDL_SetWindowFullscreen() just takes a boolean value, setting the correct fullscreen state based on the selected mode. + +SDL_WINDOW_FULLSCREEN has been renamed SDL_WINDOW_FULLSCREEN_EXCLUSIVE, and SDL_WINDOW_FULLSCREEN_DESKTOP no longer includes the old SDL_WINDOW_FULLSCREEN flag. You can use `(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_MASK) != 0` if you want to check for either state. + SDL_SetWindowBrightness and SDL_SetWindowGammaRamp have been removed from the API, because they interact poorly with modern operating systems and aren't able to limit their effects to the SDL window. Programs which have access to shaders can implement more robust versions of those functions using custom shader code rendered as a post-process effect. @@ -1003,18 +1026,22 @@ SDL_GL_GetSwapInterval() takes the interval as an output parameter and returns 0 SDL_GL_GetDrawableSize() has been removed. SDL_GetWindowSizeInPixels() can be used in its place. The following functions have been renamed: +* SDL_GetClosestDisplayMode() => SDL_GetClosestFullscreenDisplayMode() * SDL_GetDisplayDPI() => SDL_GetDisplayPhysicalDPI() * SDL_GetPointDisplayIndex() => SDL_GetDisplayForPoint() * SDL_GetRectDisplayIndex() => SDL_GetDisplayForRect() * SDL_GetWindowDisplayIndex() => SDL_GetDisplayForWindow() +* SDL_GetWindowDisplayMode() => SDL_GetWindowFullscreenMode() +* SDL_SetWindowDisplayMode() => SDL_SetWindowFullscreenMode() The following functions have been removed: +* SDL_GetClosestFullscreenDisplayMode() +* SDL_GetDisplayMode() +* SDL_GetNumDisplayModes() - replaced with SDL_GetFullscreenDisplayModes() * SDL_GetNumVideoDisplays() - replaced with SDL_GetDisplays() SDL_Window id type is named SDL_WindowID -SDL_WINDOW_FULLSCREEN has been renamed SDL_WINDOW_FULLSCREEN_EXCLUSIVE, and SDL_WINDOW_FULLSCREEN_DESKTOP no longer includes the old SDL_WINDOW_FULLSCREEN flag. You can use `(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_MASK) != 0` if you want to check for either state. - The following symbols have been renamed: * SDL_WINDOW_INPUT_GRABBED => SDL_WINDOW_MOUSE_GRABBED diff --git a/docs/README-winrt.md b/docs/README-winrt.md index 7d26fbf5d7..f8c2e812fc 100644 --- a/docs/README-winrt.md +++ b/docs/README-winrt.md @@ -333,17 +333,14 @@ your project, and open the file in Visual C++'s text editor. int main(int argc, char **argv) { - SDL_DisplayMode mode; - SDL_Window * window = NULL; - SDL_Renderer * renderer = NULL; + SDL_Window *window = NULL; + SDL_Renderer *renderer = NULL; SDL_Event evt; SDL_bool keep_going = SDL_TRUE; if (SDL_Init(SDL_INIT_VIDEO) != 0) { return 1; - } else if (SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay(), &mode) != 0) { - return 1; - } else if (SDL_CreateWindowAndRenderer(mode.w, mode.h, SDL_WINDOW_FULLSCREEN_EXCLUSIVE, &window, &renderer) != 0) { + } else if (SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP, &window, &renderer) != 0) { return 1; } diff --git a/include/SDL3/SDL_oldnames.h b/include/SDL3/SDL_oldnames.h index f84b8e0df3..80d73537a3 100644 --- a/include/SDL3/SDL_oldnames.h +++ b/include/SDL3/SDL_oldnames.h @@ -412,10 +412,13 @@ #define SDL_GetTicks64 SDL_GetTicks /* ##SDL_video.h */ +#define SDL_GetClosestDisplayMode SDL_GetClosestFullscreenDisplayMode #define SDL_GetDisplayDPI SDL_GetDisplayPhysicalDPI #define SDL_GetPointDisplayIndex SDL_GetDisplayForPoint #define SDL_GetRectDisplayIndex SDL_GetDisplayForRect #define SDL_GetWindowDisplayIndex SDL_GetDisplayForWindow +#define SDL_GetWindowDisplayMode SDL_GetWindowFullscreenMode +#define SDL_SetWindowDisplayMode SDL_SetWindowFullscreenMode #define SDL_WINDOW_FULLSCREEN SDL_WINDOW_FULLSCREEN_EXCLUSIVE #define SDL_WINDOW_INPUT_GRABBED SDL_WINDOW_MOUSE_GRABBED @@ -795,10 +798,13 @@ #define SDL_GetTicks64 SDL_GetTicks64_renamed_SDL_GetTicks /* ##SDL_video.h */ +#define SDL_GetClosestDisplayMode SDL_GetClosestDisplayMode_renamed_SDL_GetClosestFullscreenDisplayMode #define SDL_GetDisplayDPI SDL_GetDisplayDPI_renamed_SDL_GetDisplayPhysicalDPI #define SDL_GetPointDisplayIndex SDL_GetPointDisplayIndex_renamed_SDL_GetDisplayForPoint #define SDL_GetRectDisplayIndex SDL_GetRectDisplayIndex_renamed_SDL_GetDisplayForRect #define SDL_GetWindowDisplayIndex SDL_GetWindowDisplayIndex_renamed_SDL_GetDisplayForWindow +#define SDL_GetWindowDisplayMode SDL_GetWindowDisplayMode_renamed_SDL_GetWindowFullscreenMode +#define SDL_SetWindowDisplayMode SDL_SetWindowDisplayMode_renamed_SDL_SetWindowFullscreenMode #define SDL_WINDOW_FULLSCREEN SDL_WINDOW_FULLSCREEN_renamed_SDL_WINDOW_FULLSCREEN_EXCLUSIVE #define SDL_WINDOW_INPUT_GRABBED SDL_WINDOW_INPUT_GRABBED_renamed_SDL_WINDOW_MOUSE_GRABBED diff --git a/include/SDL3/SDL_test_common.h b/include/SDL3/SDL_test_common.h index 0dc4df3b70..50a612c34d 100644 --- a/include/SDL3/SDL_test_common.h +++ b/include/SDL3/SDL_test_common.h @@ -61,7 +61,8 @@ typedef struct /* Video info */ const char *videodriver; - int display; + int display_index; + SDL_DisplayID displayID; const char *window_title; const char *window_icon; Uint32 window_flags; @@ -79,6 +80,7 @@ typedef struct float scale; int depth; float refresh_rate; + SDL_DisplayMode fullscreen_mode; int num_windows; SDL_Window **windows; diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h index 05c0c9ae90..fa1c73d6c4 100644 --- a/include/SDL3/SDL_video.h +++ b/include/SDL3/SDL_video.h @@ -43,19 +43,29 @@ extern "C" { typedef Uint32 SDL_DisplayID; typedef Uint32 SDL_WindowID; +/** + * \brief The flags on a display mode + */ +typedef enum +{ + SDL_DISPLAYMODE_DESKTOP = 0x00000001, /**< The display uses this as the desktop mode */ + SDL_DISPLAYMODE_CURRENT = 0x00000002, /**< The display is currently using this mode */ + +} SDL_DisplayModeFlags; + /** * \brief The structure that defines a display mode * - * \sa SDL_GetNumDisplayModes() - * \sa SDL_GetDisplayMode() + * \sa SDL_GetFullscreenDisplayModes() * \sa SDL_GetDesktopDisplayMode() * \sa SDL_GetCurrentDisplayMode() - * \sa SDL_GetClosestDisplayMode() - * \sa SDL_SetWindowDisplayMode() - * \sa SDL_GetWindowDisplayMode() + * \sa SDL_SetWindowFullscreenMode() + * \sa SDL_GetWindowFullscreenMode() */ typedef struct { + SDL_DisplayID displayID; /**< the display this mode is associated with */ + Uint32 flags; /**< whether this mode is the current mode or a desktop mode */ Uint32 format; /**< pixel format */ int pixel_w; /**< width in pixels (used for creating back buffers) */ int pixel_h; /**< height in pixels (used for creating back buffers) */ @@ -422,24 +432,9 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayPhysicalDPI(SDL_DisplayID displayID, f extern DECLSPEC SDL_DisplayOrientation SDLCALL SDL_GetDisplayOrientation(SDL_DisplayID displayID); /** - * Get the number of available display modes. - * - * \param displayID the instance ID of the display to query - * \returns a number >= 1 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetDisplayMode - * \sa SDL_GetDisplays - */ -extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(SDL_DisplayID displayID); - -/** - * Get information about a specific display mode. + * Get a list of fullscreen display modes available on a display. * * The display modes are sorted in this priority: - * * - screen_w -> largest to smallest * - screen_h -> largest to smallest * - pixel_w -> largest to smallest @@ -449,62 +444,16 @@ extern DECLSPEC int SDLCALL SDL_GetNumDisplayModes(SDL_DisplayID displayID); * - refresh rate -> highest to lowest * * \param displayID the instance ID of the display to query - * \param modeIndex the index of the display mode to query - * \param mode an SDL_DisplayMode structure filled in with the mode at - * `modeIndex` - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. + * \param count a pointer filled in with the number of displays returned + * \returns a NULL terminated array of display mode pointers which should be freed + * with SDL_free(), or NULL on error; call SDL_GetError() for more + * details. * * \since This function is available since SDL 3.0.0. * - * \sa SDL_GetNumDisplayModes - */ -extern DECLSPEC int SDLCALL SDL_GetDisplayMode(SDL_DisplayID displayID, int modeIndex, SDL_DisplayMode *mode); - -/** - * Get information about the desktop's display mode. - * - * There's a difference between this function and SDL_GetCurrentDisplayMode() - * when SDL runs fullscreen and has changed the resolution. In that case this - * function will return the previous native display mode, and not the current - * display mode. - * - * \param displayID the instance ID of the display to query - * \param mode an SDL_DisplayMode structure filled in with the current display - * mode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetCurrentDisplayMode - * \sa SDL_GetDisplayMode - * \sa SDL_SetWindowDisplayMode - */ -extern DECLSPEC int SDLCALL SDL_GetDesktopDisplayMode(SDL_DisplayID displayID, SDL_DisplayMode *mode); - -/** - * Get information about the current display mode. - * - * There's a difference between this function and SDL_GetDesktopDisplayMode() - * when SDL runs fullscreen and has changed the resolution. In that case this - * function will return the current display mode, and not the previous native - * display mode. - * - * \param displayID the instance ID of the display to query - * \param mode an SDL_DisplayMode structure filled in with the current display - * mode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. - * - * \since This function is available since SDL 3.0.0. - * - * \sa SDL_GetDesktopDisplayMode - * \sa SDL_GetDisplayMode * \sa SDL_GetDisplays - * \sa SDL_SetWindowDisplayMode */ -extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(SDL_DisplayID displayID, SDL_DisplayMode *mode); +extern DECLSPEC const SDL_DisplayMode **SDLCALL SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, int *count); /** * Get the closest match to the requested display mode. @@ -517,19 +466,57 @@ extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(SDL_DisplayID displayID, S * small, then NULL is returned. * * \param displayID the instance ID of the display to query - * \param mode an SDL_DisplayMode structure containing the desired display - * mode, should be zero initialized - * \param closest an SDL_DisplayMode structure filled in with the closest - * match of the available display modes + * \param w the width in pixels of the desired display mode + * \param h the height in pixels of the desired display mode + * \param refresh_rate the refresh rate of the desired display mode, or 0.0f for the desktop refresh rate + * \returns a pointer to the closest display mode equal to or larger than the desired mode, or NULL on error; call SDL_GetError() for more information. * \returns the passed in value `closest` or NULL if no matching video mode * was available; call SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. * - * \sa SDL_GetDisplayMode - * \sa SDL_GetNumDisplayModes + * \sa SDL_GetDisplays + * \sa SDL_GetFullscreenDisplayModes */ -extern DECLSPEC SDL_DisplayMode *SDLCALL SDL_GetClosestDisplayMode(SDL_DisplayID displayID, const SDL_DisplayMode *mode, SDL_DisplayMode *closest); +extern DECLSPEC const SDL_DisplayMode *SDLCALL SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate); + +/** + * Get information about the desktop's display mode. + * + * There's a difference between this function and SDL_GetCurrentDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the previous native display mode, and not the current + * display mode. + * + * \param displayID the instance ID of the display to query + * \returns a pointer to the desktop display mode or NULL on error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetCurrentDisplayMode + * \sa SDL_GetDisplays + */ +extern DECLSPEC const SDL_DisplayMode *SDLCALL SDL_GetDesktopDisplayMode(SDL_DisplayID displayID); + +/** + * Get information about the current display mode. + * + * There's a difference between this function and SDL_GetDesktopDisplayMode() + * when SDL runs fullscreen and has changed the resolution. In that case this + * function will return the current display mode, and not the previous native + * display mode. + * + * \param displayID the instance ID of the display to query + * \returns a pointer to the desktop display mode or NULL on error; call + * SDL_GetError() for more information. + * + * \since This function is available since SDL 3.0.0. + * + * \sa SDL_GetDesktopDisplayMode + * \sa SDL_GetDisplays + */ +extern DECLSPEC const SDL_DisplayMode *SDLCALL SDL_GetCurrentDisplayMode(SDL_DisplayID displayID); /** * Get the display containing a point @@ -576,41 +563,36 @@ extern DECLSPEC SDL_DisplayID SDLCALL SDL_GetDisplayForRect(const SDL_Rect *rect extern DECLSPEC SDL_DisplayID SDLCALL SDL_GetDisplayForWindow(SDL_Window *window); /** - * Set the display mode to use when a window is visible at fullscreen. + * Set the display mode to use when a window is visible and fullscreen. * * This only affects the display mode used when the window is fullscreen. To * change the window size when the window is not fullscreen, use * SDL_SetWindowSize(). * * \param window the window to affect - * \param mode the SDL_DisplayMode structure representing the mode to use, or - * NULL to use the window's dimensions and the desktop's format - * and refresh rate + * \param mode a pointer to the display mode to use, which can be NULL for desktop mode, or one of the fullscreen modes returned by SDL_GetFullscreenDisplayModes(). * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. * - * \sa SDL_GetWindowDisplayMode + * \sa SDL_GetWindowFullscreenMode * \sa SDL_SetWindowFullscreen */ -extern DECLSPEC int SDLCALL SDL_SetWindowDisplayMode(SDL_Window *window, const SDL_DisplayMode *mode); +extern DECLSPEC int SDLCALL SDL_SetWindowFullscreenMode(SDL_Window *window, const SDL_DisplayMode *mode); /** * Query the display mode to use when a window is visible at fullscreen. * * \param window the window to query - * \param mode an SDL_DisplayMode structure filled in with the fullscreen - * display mode - * \returns 0 on success or a negative error code on failure; call - * SDL_GetError() for more information. + * \returns a pointer to the fullscreen mode to use or NULL for desktop mode * * \since This function is available since SDL 3.0.0. * - * \sa SDL_SetWindowDisplayMode + * \sa SDL_SetWindowFullscreenMode * \sa SDL_SetWindowFullscreen */ -extern DECLSPEC int SDLCALL SDL_GetWindowDisplayMode(SDL_Window *window, SDL_DisplayMode *mode); +extern DECLSPEC const SDL_DisplayMode *SDLCALL SDL_GetWindowFullscreenMode(SDL_Window *window); /** * Get the raw ICC profile data for the screen the window is currently on. @@ -879,8 +861,8 @@ extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window *window, int *x, i * The window size in screen coordinates may differ from the size in pixels if * the window is on a high density display (one with an OS scaling factor). * - * Fullscreen windows automatically match the size of the display mode, and - * you should use SDL_SetWindowDisplayMode() to change their size. + * This only affects the size of the window when not in fullscreen mode. To change + * the fullscreen mode of a window, use SDL_SetWindowFullscreenMode() * * \param window the window to change * \param w the width of the window, must be > 0 @@ -889,7 +871,7 @@ extern DECLSPEC void SDLCALL SDL_GetWindowPosition(SDL_Window *window, int *x, i * \since This function is available since SDL 3.0.0. * * \sa SDL_GetWindowSize - * \sa SDL_SetWindowDisplayMode + * \sa SDL_SetWindowFullscreenMode */ extern DECLSPEC void SDLCALL SDL_SetWindowSize(SDL_Window *window, int w, int h); @@ -1152,22 +1134,20 @@ extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window *window); /** * Set a window's fullscreen state. * - * `flags` may be `SDL_WINDOW_FULLSCREEN_EXCLUSIVE`, for "real" fullscreen - * with a videomode change; `SDL_WINDOW_FULLSCREEN_DESKTOP` for "fake" - * fullscreen that takes the size of the desktop; and 0 for windowed mode. + * By default a window in fullscreen state uses fullscreen desktop mode, + * but a specific display mode can be set using SDL_SetWindowFullscreenMode(). * * \param window the window to change - * \param flags `SDL_WINDOW_FULLSCREEN_EXCLUSIVE`, - * `SDL_WINDOW_FULLSCREEN_DESKTOP` or 0 + * \param fullscreen SDL_TRUE for fullscreen mode, SDL_FALSE for windowed mode * \returns 0 on success or a negative error code on failure; call * SDL_GetError() for more information. * * \since This function is available since SDL 3.0.0. * - * \sa SDL_GetWindowDisplayMode - * \sa SDL_SetWindowDisplayMode + * \sa SDL_GetWindowFullscreenMode + * \sa SDL_SetWindowFullscreenMode */ -extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window *window, Uint32 flags); +extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window *window, SDL_bool fullscreen); /** * Get the SDL surface associated with the window. diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 22bbb40275..8547bde201 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -153,7 +153,6 @@ SDL3_0.0.0 { SDL_GetCPUCacheLineSize; SDL_GetCPUCount; SDL_GetClipboardText; - SDL_GetClosestDisplayMode; SDL_GetCurrentAudioDriver; SDL_GetCurrentDisplayMode; SDL_GetCurrentVideoDriver; @@ -166,7 +165,6 @@ SDL3_0.0.0 { SDL_GetDisplayPhysicalDPI; SDL_GetDisplayForPoint; SDL_GetDisplayForRect; - SDL_GetDisplayMode; SDL_GetDisplayName; SDL_GetDisplayOrientation; SDL_GetDisplayUsableBounds; @@ -260,7 +258,6 @@ SDL3_0.0.0 { SDL_GetNumAllocations; SDL_GetNumAudioDevices; SDL_GetNumAudioDrivers; - SDL_GetNumDisplayModes; SDL_GetNumGamepadMappings; SDL_GetNumJoystickAxes; SDL_GetNumJoystickButtons; @@ -348,7 +345,7 @@ SDL3_0.0.0 { SDL_GetWindowBordersSize; SDL_GetWindowData; SDL_GetDisplayForWindow; - SDL_GetWindowDisplayMode; + SDL_GetWindowFullscreenMode; SDL_GetWindowFlags; SDL_GetWindowFromID; SDL_GetWindowGrab; @@ -613,7 +610,7 @@ SDL3_0.0.0 { SDL_SetWindowAlwaysOnTop; SDL_SetWindowBordered; SDL_SetWindowData; - SDL_SetWindowDisplayMode; + SDL_SetWindowFullscreenMode; SDL_SetWindowFullscreen; SDL_SetWindowGrab; SDL_SetWindowHitTest; @@ -840,6 +837,8 @@ SDL3_0.0.0 { SDL_ConvertAudioSamples; SDL_GetDisplays; SDL_GetPrimaryDisplay; + SDL_GetFullscreenDisplayModes; + SDL_GetClosestFullscreenDisplayMode; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 2f2c0c4663..92d4019f95 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -178,7 +178,6 @@ #define SDL_GetCPUCacheLineSize SDL_GetCPUCacheLineSize_REAL #define SDL_GetCPUCount SDL_GetCPUCount_REAL #define SDL_GetClipboardText SDL_GetClipboardText_REAL -#define SDL_GetClosestDisplayMode SDL_GetClosestDisplayMode_REAL #define SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver_REAL #define SDL_GetCurrentDisplayMode SDL_GetCurrentDisplayMode_REAL #define SDL_GetCurrentVideoDriver SDL_GetCurrentVideoDriver_REAL @@ -191,7 +190,6 @@ #define SDL_GetDisplayPhysicalDPI SDL_GetDisplayPhysicalDPI_REAL #define SDL_GetDisplayForPoint SDL_GetDisplayForPoint_REAL #define SDL_GetDisplayForRect SDL_GetDisplayForRect_REAL -#define SDL_GetDisplayMode SDL_GetDisplayMode_REAL #define SDL_GetDisplayName SDL_GetDisplayName_REAL #define SDL_GetDisplayOrientation SDL_GetDisplayOrientation_REAL #define SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds_REAL @@ -285,7 +283,6 @@ #define SDL_GetNumAllocations SDL_GetNumAllocations_REAL #define SDL_GetNumAudioDevices SDL_GetNumAudioDevices_REAL #define SDL_GetNumAudioDrivers SDL_GetNumAudioDrivers_REAL -#define SDL_GetNumDisplayModes SDL_GetNumDisplayModes_REAL #define SDL_GetNumGamepadMappings SDL_GetNumGamepadMappings_REAL #define SDL_GetNumJoystickAxes SDL_GetNumJoystickAxes_REAL #define SDL_GetNumJoystickButtons SDL_GetNumJoystickButtons_REAL @@ -373,7 +370,7 @@ #define SDL_GetWindowBordersSize SDL_GetWindowBordersSize_REAL #define SDL_GetWindowData SDL_GetWindowData_REAL #define SDL_GetDisplayForWindow SDL_GetDisplayForWindow_REAL -#define SDL_GetWindowDisplayMode SDL_GetWindowDisplayMode_REAL +#define SDL_GetWindowFullscreenMode SDL_GetWindowFullscreenMode_REAL #define SDL_GetWindowFlags SDL_GetWindowFlags_REAL #define SDL_GetWindowFromID SDL_GetWindowFromID_REAL #define SDL_GetWindowGrab SDL_GetWindowGrab_REAL @@ -638,7 +635,7 @@ #define SDL_SetWindowAlwaysOnTop SDL_SetWindowAlwaysOnTop_REAL #define SDL_SetWindowBordered SDL_SetWindowBordered_REAL #define SDL_SetWindowData SDL_SetWindowData_REAL -#define SDL_SetWindowDisplayMode SDL_SetWindowDisplayMode_REAL +#define SDL_SetWindowFullscreenMode SDL_SetWindowFullscreenMode_REAL #define SDL_SetWindowFullscreen SDL_SetWindowFullscreen_REAL #define SDL_SetWindowGrab SDL_SetWindowGrab_REAL #define SDL_SetWindowHitTest SDL_SetWindowHitTest_REAL @@ -867,3 +864,5 @@ #define SDL_ConvertAudioSamples SDL_ConvertAudioSamples_REAL #define SDL_GetDisplays SDL_GetDisplays_REAL #define SDL_GetPrimaryDisplay SDL_GetPrimaryDisplay_REAL +#define SDL_GetFullscreenDisplayModes SDL_GetFullscreenDisplayModes_REAL +#define SDL_GetClosestFullscreenDisplayMode SDL_GetClosestFullscreenDisplayMode_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 74214a85b0..1363f552d6 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -252,20 +252,18 @@ SDL_DYNAPI_PROC(char*,SDL_GetBasePath,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetCPUCacheLineSize,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetCPUCount,(void),(),return) SDL_DYNAPI_PROC(char*,SDL_GetClipboardText,(void),(),return) -SDL_DYNAPI_PROC(SDL_DisplayMode*,SDL_GetClosestDisplayMode,(SDL_DisplayID a, const SDL_DisplayMode *b, SDL_DisplayMode *c),(a,b,c),return) SDL_DYNAPI_PROC(const char*,SDL_GetCurrentAudioDriver,(void),(),return) -SDL_DYNAPI_PROC(int,SDL_GetCurrentDisplayMode,(SDL_DisplayID a, SDL_DisplayMode *b),(a,b),return) +SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetCurrentDisplayMode,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetCurrentVideoDriver,(void),(),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_GetCursor,(void),(),return) SDL_DYNAPI_PROC(SDL_AssertionHandler,SDL_GetDefaultAssertionHandler,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetDefaultAudioInfo,(char **a, SDL_AudioSpec *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(SDL_Cursor*,SDL_GetDefaultCursor,(void),(),return) -SDL_DYNAPI_PROC(int,SDL_GetDesktopDisplayMode,(SDL_DisplayID a, SDL_DisplayMode *b),(a,b),return) +SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetDesktopDisplayMode,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetDisplayBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetDisplayPhysicalDPI,(SDL_DisplayID a, float *b, float *c, float *d),(a,b,c,d),return) SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetDisplayForPoint,(const SDL_Point *a),(a),return) SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetDisplayForRect,(const SDL_Rect *a),(a),return) -SDL_DYNAPI_PROC(int,SDL_GetDisplayMode,(SDL_DisplayID a, int b, SDL_DisplayMode *c),(a,b,c),return) SDL_DYNAPI_PROC(const char*,SDL_GetDisplayName,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(SDL_DisplayOrientation,SDL_GetDisplayOrientation,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetDisplayUsableBounds,(SDL_DisplayID a, SDL_Rect *b),(a,b),return) @@ -359,7 +357,6 @@ SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(float *a, float *b),(a,b),return) SDL_DYNAPI_PROC(int,SDL_GetNumAllocations,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetNumAudioDevices,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumAudioDrivers,(void),(),return) -SDL_DYNAPI_PROC(int,SDL_GetNumDisplayModes,(SDL_DisplayID a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumGamepadMappings,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GetNumJoystickAxes,(SDL_Joystick *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetNumJoystickButtons,(SDL_Joystick *a),(a),return) @@ -445,7 +442,7 @@ SDL_DYNAPI_PROC(const char*,SDL_GetVideoDriver,(int a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetWindowBordersSize,(SDL_Window *a, int *b, int *c, int *d, int *e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(void*,SDL_GetWindowData,(SDL_Window *a, const char *b),(a,b),return) SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetDisplayForWindow,(SDL_Window *a),(a),return) -SDL_DYNAPI_PROC(int,SDL_GetWindowDisplayMode,(SDL_Window *a, SDL_DisplayMode *b),(a,b),return) +SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetWindowFullscreenMode,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(Uint32,SDL_GetWindowFlags,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(SDL_Window*,SDL_GetWindowFromID,(Uint32 a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_GetWindowGrab,(SDL_Window *a),(a),return) @@ -693,8 +690,8 @@ SDL_DYNAPI_PROC(int,SDL_SetThreadPriority,(SDL_ThreadPriority a),(a),return) SDL_DYNAPI_PROC(void,SDL_SetWindowAlwaysOnTop,(SDL_Window *a, SDL_bool b),(a,b),) SDL_DYNAPI_PROC(void,SDL_SetWindowBordered,(SDL_Window *a, SDL_bool b),(a,b),) SDL_DYNAPI_PROC(void*,SDL_SetWindowData,(SDL_Window *a, const char *b, void *c),(a,b,c),return) -SDL_DYNAPI_PROC(int,SDL_SetWindowDisplayMode,(SDL_Window *a, const SDL_DisplayMode *b),(a,b),return) -SDL_DYNAPI_PROC(int,SDL_SetWindowFullscreen,(SDL_Window *a, Uint32 b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_SetWindowFullscreenMode,(SDL_Window *a, const SDL_DisplayMode *b),(a,b),return) +SDL_DYNAPI_PROC(int,SDL_SetWindowFullscreen,(SDL_Window *a, SDL_bool b),(a,b),return) SDL_DYNAPI_PROC(void,SDL_SetWindowGrab,(SDL_Window *a, SDL_bool b),(a,b),) SDL_DYNAPI_PROC(int,SDL_SetWindowHitTest,(SDL_Window *a, SDL_HitTest b, void *c),(a,b,c),return) SDL_DYNAPI_PROC(void,SDL_SetWindowIcon,(SDL_Window *a, SDL_Surface *b),(a,b),) @@ -912,3 +909,5 @@ SDL_DYNAPI_PROC(void,SDL_aligned_free,(void *a),(a),) SDL_DYNAPI_PROC(int,SDL_ConvertAudioSamples,(SDL_AudioFormat a, Uint8 b, int c, int d, Uint8 *e, SDL_AudioFormat f, Uint8 g, int h, int *i, Uint8 **j),(a,b,c,d,e,f,g,h,i,j),return) SDL_DYNAPI_PROC(SDL_DisplayID*,SDL_GetDisplays,(int *a),(a),return) SDL_DYNAPI_PROC(SDL_DisplayID,SDL_GetPrimaryDisplay,(void),(),return) +SDL_DYNAPI_PROC(const SDL_DisplayMode**,SDL_GetFullscreenDisplayModes,(SDL_DisplayID a, int *b),(a,b),return) +SDL_DYNAPI_PROC(const SDL_DisplayMode*,SDL_GetClosestFullscreenDisplayMode,(SDL_DisplayID a, int b, int c, float d),(a,b,c,d),return) diff --git a/src/events/SDL_windowevents.c b/src/events/SDL_windowevents.c index dd5695575d..8753e495db 100644 --- a/src/events/SDL_windowevents.c +++ b/src/events/SDL_windowevents.c @@ -141,10 +141,10 @@ int SDL_SendWindowEvent(SDL_Window *window, SDL_EventType windowevent, window->flags &= ~SDL_WINDOW_INPUT_FOCUS; break; case SDL_EVENT_WINDOW_DISPLAY_CHANGED: - if (data1 == 0 || (SDL_DisplayID)data1 == window->displayID) { + if (data1 == 0 || (SDL_DisplayID)data1 == window->last_displayID) { return 0; } - window->displayID = (SDL_DisplayID)data1; + window->last_displayID = (SDL_DisplayID)data1; break; default: break; diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index f72fa492e7..62df8a6c54 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -916,15 +916,16 @@ static SDL_RenderLineMethod SDL_GetRenderLineMethod() static void SDL_CalculateSimulatedVSyncInterval(SDL_Renderer *renderer, SDL_Window *window) { SDL_DisplayID displayID = SDL_GetDisplayForWindow(window); - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; float refresh_rate; int num, den; if (displayID == 0) { displayID = SDL_GetPrimaryDisplay(); } - if (SDL_GetDesktopDisplayMode(displayID, &mode) == 0 && mode.refresh_rate > 0.0f) { - refresh_rate = mode.refresh_rate; + mode = SDL_GetDesktopDisplayMode(displayID); + if (mode && mode->refresh_rate > 0.0f) { + refresh_rate = mode->refresh_rate; } else { /* Pick a good default refresh rate */ refresh_rate = 60.0f; diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 3ae071b50e..647898fe83 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -289,17 +289,18 @@ static int D3D_ActivateRenderer(SDL_Renderer *renderer) if (data->updateSize) { SDL_Window *window = renderer->window; int w, h; - Uint32 window_flags = SDL_GetWindowFlags(window); + const SDL_DisplayMode *fullscreen_mode = NULL; SDL_GetWindowSizeInPixels(window, &w, &h); data->pparams.BackBufferWidth = w; data->pparams.BackBufferHeight = h; - if ((window_flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { - SDL_DisplayMode fullscreen_mode; - SDL_GetWindowDisplayMode(window, &fullscreen_mode); + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { + fullscreen_mode = SDL_GetWindowFullscreenMode(window); + } + if (fullscreen_mode) { data->pparams.Windowed = FALSE; - data->pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.format); - data->pparams.FullScreen_RefreshRateInHz = (UINT)SDL_ceilf(fullscreen_mode.refresh_rate); + data->pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode->format); + data->pparams.FullScreen_RefreshRateInHz = (UINT)SDL_ceilf(fullscreen_mode->refresh_rate); } else { data->pparams.Windowed = TRUE; data->pparams.BackBufferFormat = D3DFMT_UNKNOWN; @@ -1554,10 +1555,9 @@ D3D_CreateRenderer(SDL_Window *window, Uint32 flags) IDirect3DSwapChain9 *chain; D3DCAPS9 caps; DWORD device_flags; - Uint32 window_flags; int w, h; - SDL_DisplayMode fullscreen_mode; SDL_DisplayID displayID; + const SDL_DisplayMode *fullscreen_mode = NULL; if (SDL_GetWindowWMInfo(window, &windowinfo, SDL_SYSWM_CURRENT_VERSION) < 0 || windowinfo.subsystem != SDL_SYSWM_WINDOWS) { @@ -1612,9 +1612,10 @@ D3D_CreateRenderer(SDL_Window *window, Uint32 flags) renderer->info.flags = (SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); renderer->driverdata = data; - window_flags = SDL_GetWindowFlags(window); SDL_GetWindowSizeInPixels(window, &w, &h); - SDL_GetWindowDisplayMode(window, &fullscreen_mode); + if ((SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { + fullscreen_mode = SDL_GetWindowFullscreenMode(window); + } SDL_zero(pparams); pparams.hDeviceWindow = windowinfo.info.win.window; @@ -1623,10 +1624,10 @@ D3D_CreateRenderer(SDL_Window *window, Uint32 flags) pparams.BackBufferCount = 1; pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; - if ((window_flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { + if (fullscreen_mode) { pparams.Windowed = FALSE; - pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode.format); - pparams.FullScreen_RefreshRateInHz = (UINT)SDL_ceilf(fullscreen_mode.refresh_rate); + pparams.BackBufferFormat = PixelFormatToD3DFMT(fullscreen_mode->format); + pparams.FullScreen_RefreshRateInHz = (UINT)SDL_ceilf(fullscreen_mode->refresh_rate); } else { pparams.Windowed = TRUE; pparams.BackBufferFormat = D3DFMT_UNKNOWN; diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 92435fd36c..49b60391fe 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -218,15 +218,7 @@ int SDLTest_CommonArg(SDLTest_CommonState *state, int index) if (!argv[index]) { return -1; } - state->display = SDL_atoi(argv[index]); - if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) { - state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display); - state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display); - } - if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) { - state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display); - state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display); - } + state->display_index = SDL_atoi(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--metal-window") == 0) { @@ -1036,7 +1028,7 @@ SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state) { int i, j, m, n, w, h; - SDL_DisplayMode fullscreen_mode; + const SDL_DisplayMode *fullscreen_mode; char text[1024]; if (state->flags & SDL_INIT_VIDEO) { @@ -1103,7 +1095,8 @@ SDLTest_CommonInit(SDLTest_CommonState *state) SDL_Rect bounds, usablebounds; float hdpi = 0; float vdpi = 0; - SDL_DisplayMode mode; + const SDL_DisplayMode **modes; + const SDL_DisplayMode *mode; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; #if SDL_VIDEO_DRIVER_WINDOWS @@ -1128,12 +1121,12 @@ SDLTest_CommonInit(SDLTest_CommonState *state) SDL_Log("Usable bounds: %dx%d at %d,%d\n", usablebounds.w, usablebounds.h, usablebounds.x, usablebounds.y); SDL_Log("DPI: %gx%g\n", hdpi, vdpi); - SDL_GetDesktopDisplayMode(displayID, &mode); - SDL_GetMasksForPixelFormatEnum(mode.format, &bpp, &Rmask, &Gmask, + mode = SDL_GetDesktopDisplayMode(displayID); + SDL_GetMasksForPixelFormatEnum(mode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); - SDL_Log(" Current mode: %dx%d@%gHz, %d%% scale, %d bits-per-pixel (%s)\n", - mode.pixel_w, mode.pixel_h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), bpp, - SDL_GetPixelFormatName(mode.format)); + SDL_Log(" Desktop mode: %dx%d@%gHz, %d%% scale, %d bits-per-pixel (%s)\n", + mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f), bpp, + SDL_GetPixelFormatName(mode->format)); if (Rmask || Gmask || Bmask) { SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n", Rmask); SDL_Log(" Green Mask = 0x%.8" SDL_PRIx32 "\n", Gmask); @@ -1144,18 +1137,18 @@ SDLTest_CommonInit(SDLTest_CommonState *state) } /* Print available fullscreen video modes */ - m = SDL_GetNumDisplayModes(displayID); + modes = SDL_GetFullscreenDisplayModes(displayID, &m); if (m == 0) { SDL_Log("No available fullscreen video modes\n"); } else { SDL_Log(" Fullscreen video modes:\n"); for (j = 0; j < m; ++j) { - SDL_GetDisplayMode(displayID, j, &mode); - SDL_GetMasksForPixelFormatEnum(mode.format, &bpp, &Rmask, + mode = modes[j]; + SDL_GetMasksForPixelFormatEnum(mode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); SDL_Log(" Mode %d: %dx%d@%gHz, %d%% scale, %d bits-per-pixel (%s)\n", - j, mode.pixel_w, mode.pixel_h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), bpp, - SDL_GetPixelFormatName(mode.format)); + j, mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f), bpp, + SDL_GetPixelFormatName(mode->format)); if (Rmask || Gmask || Bmask) { SDL_Log(" Red Mask = 0x%.8" SDL_PRIx32 "\n", Rmask); @@ -1169,6 +1162,7 @@ SDLTest_CommonInit(SDLTest_CommonState *state) } } } + SDL_free(modes); #if SDL_VIDEO_DRIVER_WINDOWS && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) /* Print the D3D9 adapter index */ @@ -1195,25 +1189,28 @@ SDLTest_CommonInit(SDLTest_CommonState *state) } } - SDL_zero(fullscreen_mode); - switch (state->depth) { - case 8: - fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8; - break; - case 15: - fullscreen_mode.format = SDL_PIXELFORMAT_RGB555; - break; - case 16: - fullscreen_mode.format = SDL_PIXELFORMAT_RGB565; - break; - case 24: - fullscreen_mode.format = SDL_PIXELFORMAT_RGB24; - break; - default: - fullscreen_mode.format = SDL_PIXELFORMAT_RGB888; - break; + state->displayID = SDL_GetPrimaryDisplay(); + if (state->display_index > 0) { + SDL_DisplayID *displays = SDL_GetDisplays(&n); + if (state->display_index < n) { + state->displayID = displays[state->display_index]; + } + SDL_free(displays); + + if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) { + state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->displayID); + state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->displayID); + } + if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) { + state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->displayID); + state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->displayID); + } + } + + fullscreen_mode = SDL_GetClosestFullscreenDisplayMode(state->displayID, state->window_w, state->window_h, state->refresh_rate); + if (fullscreen_mode) { + SDL_memcpy(&state->fullscreen_mode, fullscreen_mode, sizeof(state->fullscreen_mode)); } - fullscreen_mode.refresh_rate = state->refresh_rate; state->windows = (SDL_Window **)SDL_calloc(state->num_windows, @@ -1239,14 +1236,7 @@ SDLTest_CommonInit(SDLTest_CommonState *state) /* !!! FIXME: hack to make --usable-bounds work for now. */ if ((r.x == -1) && (r.y == -1) && (r.w == -1) && (r.h == -1)) { - int num_displays; - SDL_DisplayID *displays = SDL_GetDisplays(&num_displays); - if (displays && state->display < num_displays) { - SDL_GetDisplayUsableBounds(displays[state->display], &r); - } else { - SDL_GetDisplayUsableBounds(SDL_GetPrimaryDisplay(), &r); - } - SDL_free(displays); + SDL_GetDisplayUsableBounds(state->displayID, &r); } if (state->num_windows > 1) { @@ -1275,10 +1265,13 @@ SDLTest_CommonInit(SDLTest_CommonState *state) state->window_w = w; state->window_h = h; } - if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) { - SDL_Log("Can't set up fullscreen display mode: %s\n", - SDL_GetError()); - return SDL_FALSE; + if ((state->window_flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) { + if ((state->window_flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { + SDL_SetWindowFullscreenMode(state->windows[i], &state->fullscreen_mode); + } else { + SDL_SetWindowFullscreenMode(state->windows[i], NULL); + } + SDL_SetWindowFullscreen(state->windows[i], SDL_TRUE); } /* Add resize/drag areas for windows that are borderless and resizable */ @@ -1728,12 +1721,13 @@ static void SDLTest_ScreenShot(SDL_Renderer *renderer) } } -static void FullscreenTo(int index, int windowId) +static void FullscreenTo(SDLTest_CommonState *state, int index, int windowId) { int num_displays; SDL_DisplayID *displays; SDL_Window *window; Uint32 flags; + const SDL_DisplayMode *mode; struct SDL_Rect rect = { 0, 0, 0, 0 }; displays = SDL_GetDisplays(&num_displays); @@ -1744,12 +1738,27 @@ static void FullscreenTo(int index, int windowId) flags = SDL_GetWindowFlags(window); if ((flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) { - SDL_SetWindowFullscreen(window, 0); + SDL_SetWindowFullscreen(window, SDL_FALSE); SDL_Delay(15); } - SDL_SetWindowPosition(window, rect.x, rect.y); - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_EXCLUSIVE); + mode = SDL_GetWindowFullscreenMode(window); + if (mode) { + /* Try to set the existing mode on the new display */ + SDL_DisplayMode new_mode; + + SDL_memcpy(&new_mode, mode, sizeof(new_mode)); + new_mode.displayID = displays[index]; + if (SDL_SetWindowFullscreenMode(window, &new_mode) < 0) { + /* Try again with a default mode */ + mode = SDL_GetClosestFullscreenDisplayMode(displays[index], state->window_w, state->window_h, state->refresh_rate); + SDL_SetWindowFullscreenMode(window, mode); + } + } + if (!mode) { + SDL_SetWindowPosition(window, rect.x, rect.y); + } + SDL_SetWindowFullscreen(window, SDL_TRUE); } } SDL_free(displays); @@ -2043,9 +2052,9 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done if (window) { Uint32 flags = SDL_GetWindowFlags(window); if ((flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) { - SDL_SetWindowFullscreen(window, 0); + SDL_SetWindowFullscreen(window, SDL_FALSE); } else { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_EXCLUSIVE); + SDL_SetWindowFullscreen(window, SDL_TRUE); } } } else if (withAlt) { @@ -2054,9 +2063,10 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done if (window) { Uint32 flags = SDL_GetWindowFlags(window); if ((flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) { - SDL_SetWindowFullscreen(window, 0); + SDL_SetWindowFullscreen(window, SDL_FALSE); } else { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_SetWindowFullscreenMode(window, NULL); + SDL_SetWindowFullscreen(window, SDL_TRUE); } } } else if (withShift) { @@ -2065,10 +2075,11 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done if (window) { Uint32 flags = SDL_GetWindowFlags(window); if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_EXCLUSIVE); + SDL_SetWindowFullscreenMode(window, &state->fullscreen_mode); } else { - SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + SDL_SetWindowFullscreenMode(window, NULL); } + SDL_SetWindowFullscreen(window, SDL_TRUE); } } @@ -2105,12 +2116,12 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done break; case SDLK_1: if (withControl) { - FullscreenTo(0, event->key.windowID); + FullscreenTo(state, 0, event->key.windowID); } break; case SDLK_2: if (withControl) { - FullscreenTo(1, event->key.windowID); + FullscreenTo(state, 1, event->key.windowID); } break; case SDLK_ESCAPE: @@ -2192,7 +2203,7 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl int x, y, w, h; float fx, fy; SDL_Rect rect; - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; float ddpi, hdpi, vdpi; float scaleX, scaleY; Uint32 flags; @@ -2271,9 +2282,10 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl SDLTest_DrawString(renderer, 0.0f, textY, text); textY += lineHeight; - if (0 == SDL_GetWindowDisplayMode(window, &mode)) { - (void)SDL_snprintf(text, sizeof text, "SDL_GetWindowDisplayMode: %dx%d@%gHz %d%% scale, (%s)", - mode.pixel_w, mode.pixel_h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), SDL_GetPixelFormatName(mode.format)); + mode = SDL_GetWindowFullscreenMode(window); + if (mode) { + (void)SDL_snprintf(text, sizeof text, "SDL_GetWindowFullscreenMode: %dx%d@%gHz %d%% scale, (%s)", + mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f), SDL_GetPixelFormatName(mode->format)); SDLTest_DrawString(renderer, 0.0f, textY, text); textY += lineHeight; } @@ -2301,16 +2313,18 @@ void SDLTest_CommonDrawWindowInfo(SDL_Renderer *renderer, SDL_Window *window, fl textY += lineHeight; } - if (0 == SDL_GetCurrentDisplayMode(windowDisplayID, &mode)) { + mode = SDL_GetCurrentDisplayMode(windowDisplayID); + if (mode) { (void)SDL_snprintf(text, sizeof text, "SDL_GetCurrentDisplayMode: %dx%d@%gHz %d%% scale, (%s)", - mode.pixel_w, mode.pixel_h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), SDL_GetPixelFormatName(mode.format)); + mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f), SDL_GetPixelFormatName(mode->format)); SDLTest_DrawString(renderer, 0.0f, textY, text); textY += lineHeight; } - if (0 == SDL_GetDesktopDisplayMode(windowDisplayID, &mode)) { + mode = SDL_GetDesktopDisplayMode(windowDisplayID); + if (mode) { (void)SDL_snprintf(text, sizeof text, "SDL_GetDesktopDisplayMode: %dx%d@%gHz %d%% scale, (%s)", - mode.pixel_w, mode.pixel_h, mode.refresh_rate, (int)(mode.display_scale * 100.0f), SDL_GetPixelFormatName(mode.format)); + mode->pixel_w, mode->pixel_h, mode->refresh_rate, (int)(mode->display_scale * 100.0f), SDL_GetPixelFormatName(mode->format)); SDLTest_DrawString(renderer, 0.0f, textY, text); textY += lineHeight; } diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index bc21ff6893..11f82a2361 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -107,7 +107,7 @@ struct SDL_Window int last_pixel_w, last_pixel_h; Uint32 flags; Uint32 last_fullscreen_flags; - SDL_DisplayID displayID; + SDL_DisplayID last_displayID; /* Stored position and size for windowed mode */ SDL_Rect windowed; @@ -150,11 +150,10 @@ struct SDL_VideoDisplay { SDL_DisplayID id; char *name; - int max_display_modes; - int num_display_modes; - SDL_DisplayMode *display_modes; + int max_fullscreen_modes; + int num_fullscreen_modes; + SDL_DisplayMode *fullscreen_modes; SDL_DisplayMode desktop_mode; - SDL_DisplayMode current_mode; SDL_DisplayOrientation orientation; SDL_Window *fullscreen_window; @@ -505,11 +504,11 @@ extern SDL_VideoDevice *SDL_GetVideoDevice(void); extern SDL_bool SDL_IsVideoContextExternal(void); extern SDL_DisplayID SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode); extern SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event); -extern void SDL_DelVideoDisplay(SDL_DisplayID display); -extern SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); -extern void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); +extern void SDL_DelVideoDisplay(SDL_DisplayID display, SDL_bool send_event); +extern SDL_bool SDL_AddFullscreenDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); +extern void SDL_ResetFullscreenDisplayModes(SDL_VideoDisplay *display); extern void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); -extern void SDL_ResetDisplayModes(SDL_VideoDisplay *display); +extern void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode); extern SDL_VideoDisplay *SDL_GetVideoDisplay(SDL_DisplayID display); extern SDL_VideoDisplay *SDL_GetVideoDisplayForWindow(SDL_Window *window); extern int SDL_GetDisplayIndex(SDL_DisplayID displayID); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 3606f3ccbf..cfc249c5e4 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -374,9 +374,7 @@ static int SDLCALL cmpmodes(const void *A, const void *B) { const SDL_DisplayMode *a = (const SDL_DisplayMode *)A; const SDL_DisplayMode *b = (const SDL_DisplayMode *)B; - if (a == b) { - return 0; - } else if (a->screen_w != b->screen_w) { + if (a->screen_w != b->screen_w) { return b->screen_w - a->screen_w; } else if (a->screen_h != b->screen_h) { return b->screen_h - a->screen_h; @@ -622,43 +620,40 @@ SDL_DisplayID SDL_AddBasicVideoDisplay(const SDL_DisplayMode *desktop_mode) SDL_zero(display); if (desktop_mode) { - display.desktop_mode = *desktop_mode; - SDL_FinalizeDisplayMode(&display.desktop_mode); + SDL_memcpy(&display.desktop_mode, desktop_mode, sizeof(display.desktop_mode)); } - display.current_mode = display.desktop_mode; - return SDL_AddVideoDisplay(&display, SDL_FALSE); } SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send_event) { - SDL_VideoDisplay *displays; + SDL_VideoDisplay *displays, *new_display; SDL_DisplayID id = 0; - int index; displays = (SDL_VideoDisplay *)SDL_realloc(_this->displays, (_this->num_displays + 1) * sizeof(*displays)); if (displays) { - id = _this->next_object_id++; - index = _this->num_displays++; - displays[index] = *display; - displays[index].id = id; - displays[index].device = _this; _this->displays = displays; + id = _this->next_object_id++; + new_display = &displays[_this->num_displays++]; + SDL_memcpy(new_display, display, sizeof(*new_display)); + new_display->id = id; + new_display->device = _this; if (display->name) { - displays[index].name = SDL_strdup(display->name); + new_display->name = SDL_strdup(display->name); } else { char name[32]; - SDL_itoa(index, name, 10); - displays[index].name = SDL_strdup(name); + SDL_itoa(id, name, 10); + new_display->name = SDL_strdup(name); } - SDL_FinalizeDisplayMode(&displays[index].desktop_mode); - SDL_FinalizeDisplayMode(&displays[index].current_mode); + new_display->desktop_mode.displayID = id; + new_display->desktop_mode.flags = (SDL_DISPLAYMODE_DESKTOP | SDL_DISPLAYMODE_CURRENT); + SDL_FinalizeDisplayMode(&new_display->desktop_mode); if (send_event) { - SDL_SendDisplayEvent(&_this->displays[index], SDL_EVENT_DISPLAY_CONNECTED, 0); + SDL_SendDisplayEvent(new_display, SDL_EVENT_DISPLAY_CONNECTED, 0); } } else { SDL_OutOfMemory(); @@ -666,7 +661,7 @@ SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send return id; } -void SDL_DelVideoDisplay(SDL_DisplayID displayID) +void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event) { SDL_VideoDisplay *display; int display_index = SDL_GetDisplayIndex(displayID); @@ -676,11 +671,17 @@ void SDL_DelVideoDisplay(SDL_DisplayID displayID) display = &_this->displays[display_index]; - SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_DISCONNECTED, 0); - - if (display->driverdata) { - SDL_free(display->driverdata); + if (send_event) { + SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_DISCONNECTED, 0); } + + SDL_free(display->name); + SDL_ResetFullscreenDisplayModes(display); + SDL_free(display->desktop_mode.driverdata); + display->desktop_mode.driverdata = NULL; + SDL_free(display->driverdata); + display->driverdata = NULL; + if (display_index < (_this->num_displays - 1)) { SDL_memmove(&_this->displays[display_index], &_this->displays[display_index + 1], (_this->num_displays - display_index - 1) * sizeof(_this->displays[display_index])); } @@ -781,6 +782,7 @@ const char *SDL_GetDisplayName(SDL_DisplayID displayID) int SDL_GetDisplayBounds(SDL_DisplayID displayID, SDL_Rect *rect) { SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); + const SDL_DisplayMode *mode; CHECK_DISPLAY_MAGIC(display, -1); @@ -802,8 +804,14 @@ int SDL_GetDisplayBounds(SDL_DisplayID displayID, SDL_Rect *rect) SDL_GetDisplayBounds(_this->displays[SDL_GetDisplayIndex(displayID) - 1].id, rect); rect->x += rect->w; } - rect->w = display->current_mode.screen_w; - rect->h = display->current_mode.screen_h; + mode = SDL_GetCurrentDisplayMode(displayID); + if (mode) { + rect->w = mode->screen_w; + rect->h = mode->screen_h; + } else { + rect->w = 0; + rect->h = 0; + } return 0; } @@ -863,314 +871,295 @@ SDL_DisplayOrientation SDL_GetDisplayOrientation(SDL_DisplayID displayID) return display->orientation; } -SDL_bool SDL_AddDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) +static const SDL_DisplayMode *SDL_GetFullscreenModeMatch(const SDL_DisplayMode *mode) +{ + const SDL_DisplayMode **modes; + SDL_DisplayMode fullscreen_mode; + + if (mode->screen_w <= 0 || mode->screen_h <= 0) { + /* Use the desktop mode */ + return NULL; + } + + SDL_memcpy(&fullscreen_mode, mode, sizeof(fullscreen_mode)); + if (fullscreen_mode.displayID == 0) { + fullscreen_mode.displayID = SDL_GetPrimaryDisplay(); + } + SDL_FinalizeDisplayMode(&fullscreen_mode); + + mode = NULL; + + modes = SDL_GetFullscreenDisplayModes(fullscreen_mode.displayID, NULL); + if (modes) { + int i; + + /* Search for an exact match */ + if (!mode) { + for (i = 0; modes[i]; ++i) { + if (SDL_memcmp(&fullscreen_mode, modes[i], sizeof(fullscreen_mode)) == 0) { + mode = modes[i]; + break; + } + } + } + + /* Search for a mode with the same characteristics */ + if (!mode) { + for (i = 0; modes[i]; ++i) { + if (cmpmodes(&fullscreen_mode, modes[i]) == 0) { + mode = modes[i]; + break; + } + } + } + + SDL_free(modes); + } + return mode; +} + +SDL_bool SDL_AddFullscreenDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) { SDL_DisplayMode *modes; + SDL_DisplayMode new_mode; int i, nmodes; + /* Finalize the mode for the display */ + SDL_memcpy(&new_mode, mode, sizeof(new_mode)); + new_mode.displayID = display->id; + SDL_FinalizeDisplayMode(&new_mode); + + if ((new_mode.flags & SDL_DISPLAYMODE_CURRENT) != 0) { + display->desktop_mode.flags &= ~SDL_DISPLAYMODE_CURRENT; + for (i = 0; i < display->num_fullscreen_modes; ++i) { + display->fullscreen_modes[i].flags &= ~SDL_DISPLAYMODE_CURRENT; + } + } + /* Make sure we don't already have the mode in the list */ - modes = display->display_modes; - nmodes = display->num_display_modes; + modes = display->fullscreen_modes; + nmodes = display->num_fullscreen_modes; for (i = 0; i < nmodes; ++i) { - if (cmpmodes(mode, &modes[i]) == 0) { + if (cmpmodes(&new_mode, &modes[i]) == 0) { + /* If the new mode is current, make sure we save that */ + if ((new_mode.flags & SDL_DISPLAYMODE_CURRENT) != 0) { + SDL_memcpy(&modes[i], &new_mode, sizeof(modes[i])); + } return SDL_FALSE; } } /* Go ahead and add the new mode */ - if (nmodes == display->max_display_modes) { - modes = SDL_realloc(modes, (display->max_display_modes + 32) * sizeof(*modes)); + if (nmodes == display->max_fullscreen_modes) { + modes = (SDL_DisplayMode *)SDL_realloc(modes, (display->max_fullscreen_modes + 32) * sizeof(*modes)); if (modes == NULL) { return SDL_FALSE; } - display->display_modes = modes; - display->max_display_modes += 32; + display->fullscreen_modes = modes; + display->max_fullscreen_modes += 32; } - modes[nmodes] = *mode; - SDL_FinalizeDisplayMode(&modes[nmodes]); - display->num_display_modes++; + SDL_memcpy(&modes[display->num_fullscreen_modes++], &new_mode, sizeof(new_mode)); /* Re-sort video modes */ - SDL_qsort(display->display_modes, display->num_display_modes, + SDL_qsort(display->fullscreen_modes, display->num_fullscreen_modes, sizeof(SDL_DisplayMode), cmpmodes); return SDL_TRUE; } -void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) +void SDL_ResetFullscreenDisplayModes(SDL_VideoDisplay *display) { - SDL_memcpy(&display->current_mode, mode, sizeof(*mode)); - SDL_FinalizeDisplayMode(&display->current_mode); + int i; + + for (i = display->num_fullscreen_modes; i--;) { + SDL_free(display->fullscreen_modes[i].driverdata); + display->fullscreen_modes[i].driverdata = NULL; + } + SDL_free(display->fullscreen_modes); + display->fullscreen_modes = NULL; + display->num_fullscreen_modes = 0; + display->max_fullscreen_modes = 0; +} + +const SDL_DisplayMode **SDL_GetFullscreenDisplayModes(SDL_DisplayID displayID, int *count) +{ + int i; + const SDL_DisplayMode **modes; + SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); + + if (count) { + *count = 0; + } + + CHECK_DISPLAY_MAGIC(display, NULL); + + if (display->num_fullscreen_modes == 0 && _this->GetDisplayModes) { + _this->GetDisplayModes(_this, display); + } + + modes = (const SDL_DisplayMode **)SDL_malloc((display->num_fullscreen_modes + 1) * sizeof(*modes)); + if (modes) { + if (count) { + *count = display->num_fullscreen_modes; + } + + for (i = 0; i < display->num_fullscreen_modes; ++i) { + modes[i] = &display->fullscreen_modes[i]; + } + modes[i] = NULL; + } else { + if (count) { + *count = 0; + } + + SDL_OutOfMemory(); + } + return modes; +} + +const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID displayID, int w, int h, float refresh_rate) +{ + const SDL_DisplayMode **modes; + const SDL_DisplayMode *mode, *closest = NULL; + float aspect_ratio; + int i; + + if (h > 0) { + aspect_ratio = (float)w / h; + } else { + aspect_ratio = 1.0f; + } + + if (!refresh_rate) { + mode = SDL_GetDesktopDisplayMode(displayID); + if (mode) { + refresh_rate = mode->refresh_rate; + } + } + + modes = SDL_GetFullscreenDisplayModes(displayID, NULL); + if (modes) { + for (i = 0; modes[i]; ++i) { + mode = modes[i]; + + if (w > mode->pixel_w) { + /* Out of sorted modes large enough here */ + break; + } + if (h > mode->pixel_h) { + /* Wider, but not tall enough, due to a different aspect ratio. + * This mode must be skipped, but closer modes may still follow */ + continue; + } + if (closest) { + float current_aspect_ratio = (float)mode->pixel_w / mode->pixel_h; + float closest_aspect_ratio = (float)closest->pixel_w / closest->pixel_h; + if (SDL_fabsf(aspect_ratio - closest_aspect_ratio) < SDL_fabsf(aspect_ratio - current_aspect_ratio)) { + /* The mode we already found has a better aspect ratio match */ + continue; + } + + if (mode->refresh_rate < refresh_rate) { + /* We already found a mode and the new mode doesn't meet our + * refresh rate target */ + continue; + } + } + + closest = mode; + } + SDL_free(modes); + } + return closest; } void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) { SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode)); + display->desktop_mode.displayID = display->id; + display->desktop_mode.flags = (SDL_DISPLAYMODE_DESKTOP | SDL_DISPLAYMODE_CURRENT); SDL_FinalizeDisplayMode(&display->desktop_mode); } -void SDL_ResetDisplayModes(SDL_VideoDisplay *display) -{ - int i; - - for (i = display->num_display_modes; i--;) { - SDL_free(display->display_modes[i].driverdata); - display->display_modes[i].driverdata = NULL; - } - SDL_free(display->display_modes); - display->display_modes = NULL; - display->num_display_modes = 0; - display->max_display_modes = 0; -} - -static int SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay *display) -{ - if (!display->num_display_modes && _this->GetDisplayModes) { - _this->GetDisplayModes(_this, display); - SDL_qsort(display->display_modes, display->num_display_modes, - sizeof(SDL_DisplayMode), cmpmodes); - } - return display->num_display_modes; -} - -int SDL_GetNumDisplayModes(SDL_DisplayID displayID) -{ - SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); - - CHECK_DISPLAY_MAGIC(display, -1); - - return SDL_GetNumDisplayModesForDisplay(display); -} - -int SDL_GetDisplayMode(SDL_DisplayID displayID, int index, SDL_DisplayMode *mode) -{ - SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); - - CHECK_DISPLAY_MAGIC(display, -1); - - if (index < 0 || index >= SDL_GetNumDisplayModesForDisplay(display)) { - return SDL_SetError("index must be in the range of 0 - %d", SDL_GetNumDisplayModesForDisplay(display) - 1); - } - if (mode) { - *mode = display->display_modes[index]; - } - return 0; -} - -int SDL_GetDesktopDisplayMode(SDL_DisplayID displayID, SDL_DisplayMode *mode) -{ - SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); - - CHECK_DISPLAY_MAGIC(display, -1); - - if (mode) { - *mode = display->desktop_mode; - } - return 0; -} - -int SDL_GetCurrentDisplayMode(SDL_DisplayID displayID, SDL_DisplayMode *mode) -{ - SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); - - CHECK_DISPLAY_MAGIC(display, -1); - - if (mode) { - *mode = display->current_mode; - } - return 0; -} - -static SDL_DisplayMode *SDL_GetClosestDisplayModeForDisplay(SDL_VideoDisplay *display, - const SDL_DisplayMode *mode, - SDL_DisplayMode *closest) -{ - Uint32 target_format; - float target_refresh_rate; - int i; - SDL_DisplayMode requested_mode; - SDL_DisplayMode *current, *match; - - if (mode == NULL || closest == NULL) { - SDL_InvalidParamError("mode/closest"); - return NULL; - } - - /* Make sure all the fields are filled out in the requested mode */ - requested_mode = *mode; - SDL_FinalizeDisplayMode(&requested_mode); - mode = &requested_mode; - - /* Default to the desktop format */ - if (mode->format) { - target_format = mode->format; - } else { - target_format = display->desktop_mode.format; - } - - /* Default to the desktop refresh rate */ - if (mode->refresh_rate > 0.0f) { - target_refresh_rate = mode->refresh_rate; - } else { - target_refresh_rate = display->desktop_mode.refresh_rate; - } - - match = NULL; - for (i = 0; i < SDL_GetNumDisplayModesForDisplay(display); ++i) { - current = &display->display_modes[i]; - - if (current->pixel_w && (current->pixel_w < mode->pixel_w)) { - /* Out of sorted modes large enough here */ - break; - } - if (current->pixel_h && (current->pixel_h < mode->pixel_h)) { - if (current->pixel_w && (current->pixel_w == mode->pixel_w)) { - /* Out of sorted modes large enough here */ - break; - } - /* Wider, but not tall enough, due to a different - aspect ratio. This mode must be skipped, but closer - modes may still follow. */ - continue; - } - if (match == NULL || current->pixel_w < match->pixel_w || current->pixel_h < match->pixel_h) { - match = current; - continue; - } - if (current->format != match->format) { - /* Sorted highest depth to lowest */ - if (current->format == target_format || - (SDL_BITSPERPIXEL(current->format) >= - SDL_BITSPERPIXEL(target_format) && - SDL_PIXELTYPE(current->format) == - SDL_PIXELTYPE(target_format))) { - match = current; - } - continue; - } - if (current->refresh_rate != match->refresh_rate) { - /* Sorted highest refresh to lowest */ - if (current->refresh_rate >= target_refresh_rate) { - match = current; - continue; - } - } - } - - if (match) { - SDL_zerop(closest); - if (match->format) { - closest->format = match->format; - } else { - closest->format = mode->format; - } - if (match->screen_w && match->screen_h) { - closest->screen_w = match->screen_w; - closest->screen_h = match->screen_h; - } else { - closest->screen_w = mode->screen_w; - closest->screen_h = mode->screen_h; - } - if (match->pixel_w && match->pixel_h) { - closest->pixel_w = match->pixel_w; - closest->pixel_h = match->pixel_h; - } else { - closest->pixel_w = mode->pixel_w; - closest->pixel_h = mode->pixel_h; - } - if (match->refresh_rate > 0.0f) { - closest->refresh_rate = match->refresh_rate; - } else { - closest->refresh_rate = mode->refresh_rate; - } - closest->driverdata = match->driverdata; - - /* Pick some reasonable defaults if the app and driver don't care */ - if (!closest->format) { - closest->format = SDL_PIXELFORMAT_RGB888; - } - if (!closest->screen_w) { - closest->screen_w = 640; - } - if (!closest->screen_h) { - closest->screen_h = 480; - } - SDL_FinalizeDisplayMode(closest); - return closest; - } - return NULL; -} - -SDL_DisplayMode *SDL_GetClosestDisplayMode(SDL_DisplayID displayID, const SDL_DisplayMode *mode, SDL_DisplayMode *closest) +const SDL_DisplayMode *SDL_GetDesktopDisplayMode(SDL_DisplayID displayID) { SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); CHECK_DISPLAY_MAGIC(display, NULL); - return SDL_GetClosestDisplayModeForDisplay(display, mode, closest); + return &display->desktop_mode; } -static int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) +void SDL_SetCurrentDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode) { - SDL_DisplayMode display_mode; - SDL_DisplayMode current_mode; - int result; + int i; - /* Mode switching set as emulated via driver quirk flag, nothing to do and cannot fail. */ - if (ModeSwitchingEmulated(_this)) { - return 0; - } - - if (mode) { - display_mode = *mode; - - /* Default to the current mode */ - if (!display_mode.format) { - display_mode.format = display->current_mode.format; - } - if (!display_mode.pixel_w) { - display_mode.pixel_w = display->current_mode.pixel_w; - } - if (!display_mode.pixel_h) { - display_mode.pixel_h = display->current_mode.pixel_h; - } - if (!display_mode.screen_w) { - display_mode.screen_w = display->current_mode.screen_w; - } - if (!display_mode.screen_h) { - display_mode.screen_h = display->current_mode.screen_h; - } - if (display_mode.refresh_rate == 0.0f) { - display_mode.refresh_rate = display->current_mode.refresh_rate; - } - - /* Get a good video mode, the closest one possible */ - if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) { - return SDL_SetError("No video mode large enough for %dx%d (%dx%d)", - display_mode.pixel_w, display_mode.pixel_h, - display_mode.screen_w, display_mode.screen_h); - } + if (mode == &display->desktop_mode) { + display->desktop_mode.flags |= SDL_DISPLAYMODE_CURRENT; } else { - display_mode = display->desktop_mode; + display->desktop_mode.flags &= ~SDL_DISPLAYMODE_CURRENT; } - /* See if there's anything left to do */ - current_mode = display->current_mode; - if (SDL_memcmp(&display_mode, ¤t_mode, sizeof(display_mode)) == 0) { + for (i = 0; i < display->num_fullscreen_modes; ++i) { + if (mode == &display->fullscreen_modes[i]) { + display->fullscreen_modes[i].flags |= SDL_DISPLAYMODE_CURRENT; + } else { + display->fullscreen_modes[i].flags &= ~SDL_DISPLAYMODE_CURRENT; + } + } + SDL_assert((mode->flags & SDL_DISPLAYMODE_CURRENT) != 0); +} + +const SDL_DisplayMode *SDL_GetCurrentDisplayMode(SDL_DisplayID displayID) +{ + SDL_VideoDisplay *display = SDL_GetVideoDisplay(displayID); + const SDL_DisplayMode **modes; + const SDL_DisplayMode *current_mode = NULL; + + CHECK_DISPLAY_MAGIC(display, NULL); + + modes = SDL_GetFullscreenDisplayModes(displayID, NULL); + if (modes) { + int i; + + for (i = 0; modes[i]; ++i) { + if ((modes[i]->flags & SDL_DISPLAYMODE_CURRENT) != 0) { + current_mode = modes[i]; + break; + } + } + SDL_free(modes); + } + if (current_mode == NULL) { + current_mode = &display->desktop_mode; + } + return current_mode; +} + +static int SDL_SetDisplayModeForDisplay(SDL_VideoDisplay *display, SDL_DisplayMode *mode) +{ + if (!mode) { + mode = &display->desktop_mode; + } + + if ((mode->flags & SDL_DISPLAYMODE_CURRENT) != 0) { return 0; } /* Actually change the display mode */ - if (!_this->SetDisplayMode) { - return SDL_SetError("SDL video driver doesn't support changing display mode"); + if (_this->SetDisplayMode) { + int result; + + _this->setting_display_mode = SDL_TRUE; + result = _this->SetDisplayMode(_this, display, mode); + _this->setting_display_mode = SDL_FALSE; + if (result < 0) { + return -1; + } } - _this->setting_display_mode = SDL_TRUE; - result = _this->SetDisplayMode(_this, display, &display_mode); - _this->setting_display_mode = SDL_FALSE; - if (result < 0) { - return -1; - } - SDL_SetCurrentDisplayMode(display, &display_mode); + + SDL_SetCurrentDisplayMode(display, mode); + return 0; } @@ -1273,27 +1262,38 @@ SDL_DisplayID SDL_GetDisplayForWindow(SDL_Window *window) displayID = _this->GetDisplayForWindow(_this, window); } - /* A backend implementation may fail to get a display index for the window + /* A backend implementation may fail to get a display for the window * (for example if the window is off-screen), but other code may expect it * to succeed in that situation, so we fall back to a generic position- * based implementation in that case. */ - if (!displayID) { - displayID = SDL_GetDisplayForWindowCoordinate(window->x); + if (!displayID && (window->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) { + displayID = window->fullscreen_mode.displayID; } if (!displayID) { - displayID = SDL_GetDisplayForWindowCoordinate(window->y); + displayID = SDL_GetDisplayForWindowCoordinate(window->windowed.x); + } + if (!displayID) { + displayID = SDL_GetDisplayForWindowCoordinate(window->windowed.y); } if (!displayID) { - int i, display_index; - displayID = GetDisplayForRect(window->x, window->y, window->w, window->h); if (!displayID) { /* Use the primary display for a window if we can't find it anywhere else */ displayID = SDL_GetPrimaryDisplay(); } - display_index = SDL_GetDisplayIndex(displayID); + } + return displayID; +} - /* Find the display containing the window if fullscreen */ +void SDL_CheckWindowDisplayChanged(SDL_Window *window) +{ + SDL_DisplayID displayID = SDL_GetDisplayForWindow(window); + + if (displayID != window->last_displayID) { + int i, display_index; + + /* Sanity check our fullscreen windows */ + display_index = SDL_GetDisplayIndex(displayID); for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; @@ -1316,90 +1316,14 @@ SDL_DisplayID SDL_GetDisplayForWindow(SDL_Window *window) break; } } - } - return displayID; + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_DISPLAY_CHANGED, (int)displayID, 0); + } } -int SDL_SetWindowDisplayMode(SDL_Window *window, const SDL_DisplayMode *mode) -{ - CHECK_WINDOW_MAGIC(window, -1); - - if (mode) { - window->fullscreen_mode = *mode; - } else { - SDL_zero(window->fullscreen_mode); - } - - if (SDL_WINDOW_FULLSCREEN_VISIBLE(window) && (window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { - SDL_DisplayMode fullscreen_mode; - if (SDL_GetWindowDisplayMode(window, &fullscreen_mode) == 0) { - if (SDL_SetDisplayModeForDisplay(SDL_GetVideoDisplayForWindow(window), &fullscreen_mode) == 0) { -#ifndef __ANDROID__ - /* Android may not resize the window to exactly what our fullscreen mode is, especially on - * windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't - * use fullscreen_mode.screen_w and fullscreen_mode.screen_h, but rather get our current native size. As such, - * Android's SetWindowFullscreen will generate the window event for us with the proper final size. - */ - SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, fullscreen_mode.screen_w, fullscreen_mode.screen_h); -#endif /* !__ANDROID__ */ - } - } - } - return 0; -} - -int SDL_GetWindowDisplayMode(SDL_Window *window, SDL_DisplayMode *mode) -{ - SDL_VideoDisplay *display; - - CHECK_WINDOW_MAGIC(window, -1); - - if (mode == NULL) { - return SDL_InvalidParamError("mode"); - } - - display = SDL_GetVideoDisplayForWindow(window); - - /* if in desktop size mode, just return the size of the desktop */ - if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) { - *mode = display->desktop_mode; - } else { - SDL_DisplayMode fullscreen_mode; - - fullscreen_mode = window->fullscreen_mode; - if (!fullscreen_mode.screen_w) { - fullscreen_mode.screen_w = window->windowed.w; - } - if (!fullscreen_mode.screen_h) { - fullscreen_mode.screen_h = window->windowed.h; - } - if (SDL_GetClosestDisplayModeForDisplay(display, &fullscreen_mode, mode) == NULL) { - SDL_zerop(mode); - return SDL_SetError("Couldn't find display mode match"); - } - } - return 0; -} - -void *SDL_GetWindowICCProfile(SDL_Window *window, size_t *size) -{ - if (!_this->GetWindowICCProfile) { - SDL_Unsupported(); - return NULL; - } - return _this->GetWindowICCProfile(_this, window, size); -} - -Uint32 SDL_GetWindowPixelFormat(SDL_Window *window) -{ - SDL_VideoDisplay *display; - - CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN); - - display = SDL_GetVideoDisplayForWindow(window); - return display->current_mode.format; -} +#if __WINRT__ +extern Uint32 WINRT_DetectWindowFlags(SDL_Window *window); +#endif static void SDL_RestoreMousePosition(SDL_Window *window) { @@ -1411,15 +1335,10 @@ static void SDL_RestoreMousePosition(SDL_Window *window) } } -#if __WINRT__ -extern Uint32 WINRT_DetectWindowFlags(SDL_Window *window); -#endif - static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) { SDL_VideoDisplay *display; - SDL_Window *other; - int retval = 0; + SDL_DisplayMode *mode; CHECK_WINDOW_MAGIC(window, -1); @@ -1428,6 +1347,18 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) return 0; } + display = SDL_GetVideoDisplayForWindow(window); + + mode = NULL; + if (fullscreen && (window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { + mode = (SDL_DisplayMode *)SDL_GetWindowFullscreenMode(window); + if (!mode || mode->displayID != display->id) { + /* Couldn't find a matching mode, pop out of fullscreen mode */ + window->flags &= ~SDL_WINDOW_FULLSCREEN_EXCLUSIVE; + fullscreen = SDL_FALSE; + } + } + #if defined(__MACOS__) && defined(SDL_VIDEO_DRIVER_COCOA) /* if the window is going away and no resolution change is necessary, do nothing, or else we may trigger an ugly double-transition @@ -1488,108 +1419,143 @@ static int SDL_UpdateFullscreenMode(SDL_Window *window, SDL_bool fullscreen) } #endif - display = SDL_GetVideoDisplayForWindow(window); - if (fullscreen) { + int mode_w = 0, mode_h = 0; + SDL_bool resized = SDL_FALSE; + /* Hide any other fullscreen windows */ if (display->fullscreen_window && display->fullscreen_window != window) { SDL_MinimizeWindow(display->fullscreen_window); } - } - /* See if anything needs to be done now */ - if ((display->fullscreen_window == window) == fullscreen) { - if ((window->last_fullscreen_flags & SDL_WINDOW_FULLSCREEN_MASK) == (window->flags & SDL_WINDOW_FULLSCREEN_MASK)) { - return 0; + if (SDL_SetDisplayModeForDisplay(display, mode) < 0) { + return -1; } - } - - /* See if there are any fullscreen windows */ - for (other = _this->windows; other; other = other->next) { - SDL_bool setDisplayMode = SDL_FALSE; - - if (other == window) { - setDisplayMode = fullscreen; - } else if (SDL_WINDOW_FULLSCREEN_VISIBLE(other) && - SDL_GetVideoDisplayForWindow(other) == display) { - setDisplayMode = SDL_TRUE; + if (_this->SetWindowFullscreen) { + _this->SetWindowFullscreen(_this, window, display, SDL_TRUE); } + display->fullscreen_window = window; - if (setDisplayMode) { - SDL_DisplayMode fullscreen_mode; - - SDL_zero(fullscreen_mode); - - if (SDL_GetWindowDisplayMode(other, &fullscreen_mode) == 0) { - SDL_bool resized = SDL_TRUE; - - if (other->w == fullscreen_mode.screen_w && other->h == fullscreen_mode.screen_h) { - resized = SDL_FALSE; - } - - /* only do the mode change if we want exclusive fullscreen */ - if ((window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { - if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) { - return -1; - } - } else { - if (SDL_SetDisplayModeForDisplay(display, NULL) < 0) { - return -1; - } - } - - if (_this->SetWindowFullscreen) { - _this->SetWindowFullscreen(_this, other, display, SDL_TRUE); - } - display->fullscreen_window = other; - - /* Generate a mode change event here */ - if (resized) { -#if !defined(__ANDROID__) && !defined(__WIN32__) - /* Android may not resize the window to exactly what our fullscreen mode is, especially on - * windowed Android environments like the Chromebook or Samsung DeX. Given this, we shouldn't - * use fullscreen_mode.w and fullscreen_mode.h, but rather get our current native size. As such, - * Android's SetWindowFullscreen will generate the window event for us with the proper final size. - */ - - /* This is also unnecessary on Win32 (WIN_SetWindowFullscreen calls SetWindowPos, - * WM_WINDOWPOSCHANGED will send SDL_EVENT_WINDOW_RESIZED). - */ - SDL_SendWindowEvent(other, SDL_EVENT_WINDOW_RESIZED, - fullscreen_mode.screen_w, fullscreen_mode.screen_h); +#if defined(__ANDROID__) + /* Android may not resize the window to exactly what our fullscreen mode is, + * especially on windowed Android environments like the Chromebook or Samsung DeX. + * Given this, we shouldn't use the mode size. As such, Android's SetWindowFullscreen + * will generate the window event for us with the proper final size. + */ +#elif defined(__WIN32__) + /* This is also unnecessary on Win32 (WIN_SetWindowFullscreen calls SetWindowPos, + * WM_WINDOWPOSCHANGED will send SDL_EVENT_WINDOW_RESIZED). + */ +#else + if (mode) { + mode_w = mode->screen_w; + mode_h = mode->screen_h; + } else { + mode_w = display->desktop_mode.screen_w; + mode_h = display->desktop_mode.screen_h; + } + if (window->w != mode_w || window->h != mode_h) { + resized = SDL_TRUE; + } #endif - } else { - SDL_OnWindowResized(other); - } - - SDL_RestoreMousePosition(other); - - window->last_fullscreen_flags = window->flags; - return 0; - } else { - /* Failed to find a matching mode, return an error after restoring windowed mode. */ - retval = -1; - } + if (resized) { + SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, mode_w, mode_h); + } else { + SDL_OnWindowResized(window); } + + /* Restore the cursor position */ + SDL_RestoreMousePosition(window); + + } else { + + if (display->fullscreen_window == window) { + /* Restore the desktop mode */ + SDL_SetDisplayModeForDisplay(display, NULL); + } + + if (_this->SetWindowFullscreen) { + _this->SetWindowFullscreen(_this, window, display, SDL_FALSE); + } + if (display->fullscreen_window == window) { + display->fullscreen_window = NULL; + } + + SDL_OnWindowResized(window); + + /* Restore the cursor position */ + SDL_RestoreMousePosition(window); } - /* Nope, restore the desktop mode */ - SDL_SetDisplayModeForDisplay(display, NULL); - - if (_this->SetWindowFullscreen) { - _this->SetWindowFullscreen(_this, window, display, SDL_FALSE); - } - display->fullscreen_window = NULL; - - /* Generate a mode change event here */ - SDL_OnWindowResized(window); - - /* Restore the cursor position */ - SDL_RestoreMousePosition(window); - window->last_fullscreen_flags = window->flags; - return retval; + + return 0; +} + +int SDL_SetWindowFullscreenMode(SDL_Window *window, const SDL_DisplayMode *mode) +{ + CHECK_WINDOW_MAGIC(window, -1); + + if (mode) { + if (!SDL_GetFullscreenModeMatch(mode)) { + return SDL_SetError("Invalid fullscreen display mode"); + } + + /* Save the mode so we can look up the closest match later */ + SDL_memcpy(&window->fullscreen_mode, mode, sizeof(window->fullscreen_mode)); + + if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) { + window->flags &= ~SDL_WINDOW_FULLSCREEN_DESKTOP; + window->flags |= SDL_WINDOW_FULLSCREEN_EXCLUSIVE; + } + } else { + SDL_zero(window->fullscreen_mode); + + if ((window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { + window->flags &= ~SDL_WINDOW_FULLSCREEN_EXCLUSIVE; + window->flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; + } + } + + if (SDL_WINDOW_FULLSCREEN_VISIBLE(window)) { + SDL_UpdateFullscreenMode(window, SDL_TRUE); + } else { + SDL_CheckWindowDisplayChanged(window); + } + return 0; +} + +const SDL_DisplayMode *SDL_GetWindowFullscreenMode(SDL_Window *window) +{ + CHECK_WINDOW_MAGIC(window, NULL); + + return SDL_GetFullscreenModeMatch(&window->fullscreen_mode); +} + +void *SDL_GetWindowICCProfile(SDL_Window *window, size_t *size) +{ + if (!_this->GetWindowICCProfile) { + SDL_Unsupported(); + return NULL; + } + return _this->GetWindowICCProfile(_this, window, size); +} + +Uint32 SDL_GetWindowPixelFormat(SDL_Window *window) +{ + SDL_DisplayID displayID; + const SDL_DisplayMode *mode; + + CHECK_WINDOW_MAGIC(window, SDL_PIXELFORMAT_UNKNOWN); + + displayID = SDL_GetDisplayForWindow(window); + mode = SDL_GetCurrentDisplayMode(displayID); + if (mode) { + return mode->format; + } else { + return SDL_PIXELFORMAT_UNKNOWN; + } } #define CREATE_FLAGS \ @@ -1759,10 +1725,10 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint } window->magic = &_this->window_magic; window->id = _this->next_object_id++; - window->x = x; - window->y = y; - window->w = w; - window->h = h; + window->windowed.x = window->x = x; + window->windowed.y = window->y = y; + window->windowed.w = window->w = w; + window->windowed.h = window->h = h; if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(x) || SDL_WINDOWPOS_ISCENTERED(y)) { SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); @@ -1770,38 +1736,22 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint SDL_GetDisplayBounds(display->id, &bounds); if (SDL_WINDOWPOS_ISUNDEFINED(x) || SDL_WINDOWPOS_ISCENTERED(x)) { - window->x = bounds.x + (bounds.w - w) / 2; + window->windowed.x = window->x = bounds.x + (bounds.w - w) / 2; } if (SDL_WINDOWPOS_ISUNDEFINED(y) || SDL_WINDOWPOS_ISCENTERED(y)) { - window->y = bounds.y + (bounds.h - h) / 2; + window->windowed.y = window->y = bounds.y + (bounds.h - h) / 2; } } - window->windowed.x = window->x; - window->windowed.y = window->y; - window->windowed.w = window->w; - window->windowed.h = window->h; if (flags & SDL_WINDOW_FULLSCREEN_MASK) { SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); SDL_Rect bounds; - SDL_GetDisplayBounds(display->id, &bounds); + /* Fullscreen at window creation time is always fullscreen desktop */ + flags &= ~SDL_WINDOW_FULLSCREEN_MASK; + flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - /* for real fullscreen we might switch the resolution, so get width and height - * from closest supported mode and use that instead of current resolution - */ - if ((flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0 && (bounds.w != w || bounds.h != h)) { - SDL_DisplayMode fullscreen_mode, closest_mode; - SDL_zero(fullscreen_mode); - fullscreen_mode.screen_w = w; - fullscreen_mode.screen_h = h; - if (SDL_GetClosestDisplayModeForDisplay(display, &fullscreen_mode, &closest_mode) != NULL) { - bounds.w = closest_mode.screen_w; - bounds.h = closest_mode.screen_h; - } - } - window->fullscreen_mode.screen_w = bounds.w; - window->fullscreen_mode.screen_h = bounds.h; + SDL_GetDisplayBounds(display->id, &bounds); window->x = bounds.x; window->y = bounds.y; window->w = bounds.w; @@ -1813,7 +1763,7 @@ SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint window->opacity = 1.0f; window->next = _this->windows; window->is_destroying = SDL_FALSE; - window->displayID = SDL_GetDisplayForWindow(window); + window->last_displayID = SDL_GetDisplayForWindow(window); if (_this->windows) { _this->windows->prev = window; @@ -1919,7 +1869,7 @@ SDL_Window *SDL_CreateWindowFrom(const void *data) return NULL; } - window->displayID = SDL_GetDisplayForWindow(window); + window->last_displayID = SDL_GetDisplayForWindow(window); PrepareDragAndDropSupport(window); return window; @@ -2376,13 +2326,7 @@ void SDL_SetWindowSize(SDL_Window *window, int w, int h) window->windowed.w = w; window->windowed.h = h; - if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) { - if (SDL_WINDOW_FULLSCREEN_VISIBLE(window) && - (window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { - window->last_fullscreen_flags = 0; - SDL_UpdateFullscreenMode(window, SDL_TRUE); - } - } else { + if (!SDL_WINDOW_FULLSCREEN_VISIBLE(window)) { if (_this->SetWindowSize) { _this->SetWindowSize(_this, window); } @@ -2446,21 +2390,26 @@ void SDL_GetWindowSizeInPixels(SDL_Window *window, int *w, int *h) if (_this->GetWindowSizeInPixels) { _this->GetWindowSizeInPixels(_this, window, w, h); } else { - SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); + SDL_DisplayID displayID = SDL_GetDisplayForWindow(window); + const SDL_DisplayMode *mode; SDL_GetWindowSize(window, w, h); - if (display) - { - if (*w == display->current_mode.screen_w) { - *w = display->current_mode.pixel_w; + if ((window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { + mode = SDL_GetCurrentDisplayMode(displayID); + } else { + mode = SDL_GetDesktopDisplayMode(displayID); + } + if (mode) { + if (*w == mode->screen_w) { + *w = mode->pixel_w; } else { - *w = (int)SDL_ceilf(*w * display->current_mode.display_scale); + *w = (int)SDL_ceilf(*w * mode->display_scale); } - if (*h == display->current_mode.screen_h) { - *h = display->current_mode.pixel_h; + if (*h == mode->screen_h) { + *h = mode->pixel_h; } else { - *h = (int)SDL_ceilf(*h * display->current_mode.display_scale); + *h = (int)SDL_ceilf(*h * mode->display_scale); } } } @@ -2648,34 +2597,30 @@ void SDL_RestoreWindow(SDL_Window *window) } } -int SDL_SetWindowFullscreen(SDL_Window *window, Uint32 flags) +int SDL_SetWindowFullscreen(SDL_Window *window, SDL_bool fullscreen) { - Uint32 oldflags; + Uint32 flags; + CHECK_WINDOW_MAGIC(window, -1); - flags &= SDL_WINDOW_FULLSCREEN_MASK; - - /* If both fullscreen exclusive and desktop flags are set, default to desktop */ - if ((flags & SDL_WINDOW_FULLSCREEN_MASK) == SDL_WINDOW_FULLSCREEN_MASK) { - flags = SDL_WINDOW_FULLSCREEN_DESKTOP; + if (fullscreen) { + if (SDL_GetWindowFullscreenMode(window)) { + flags = SDL_WINDOW_FULLSCREEN_EXCLUSIVE; + } else { + flags = SDL_WINDOW_FULLSCREEN_DESKTOP; + } + } else { + flags = 0; } if (flags == (window->flags & SDL_WINDOW_FULLSCREEN_MASK)) { return 0; } - /* clear the previous flags and OR in the new ones */ - oldflags = window->flags & SDL_WINDOW_FULLSCREEN_MASK; - window->flags &= ~SDL_WINDOW_FULLSCREEN_MASK; - window->flags |= flags; + /* Clear the previous flags and OR in the new ones */ + window->flags = (window->flags & ~SDL_WINDOW_FULLSCREEN_MASK) | flags; - if (SDL_UpdateFullscreenMode(window, SDL_WINDOW_FULLSCREEN_VISIBLE(window)) == 0) { - return 0; - } - - window->flags &= ~SDL_WINDOW_FULLSCREEN_MASK; - window->flags |= oldflags; - return -1; + return SDL_UpdateFullscreenMode(window, SDL_WINDOW_FULLSCREEN_VISIBLE(window)); } static SDL_Surface *SDL_CreateWindowFramebuffer(SDL_Window *window) @@ -3028,14 +2973,6 @@ void SDL_OnWindowHidden(SDL_Window *window) SDL_UpdateFullscreenMode(window, SDL_FALSE); } -void SDL_CheckWindowDisplayChanged(SDL_Window *window) -{ - SDL_DisplayID displayID; - - displayID = SDL_GetDisplayForWindow(window); - SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_DISPLAY_CHANGED, (int)displayID, 0); -} - void SDL_OnWindowDisplayChanged(SDL_Window *window) { if ((window->flags & SDL_WINDOW_FULLSCREEN_MASK) != 0) { @@ -3057,19 +2994,16 @@ void SDL_OnWindowDisplayChanged(SDL_Window *window) * emulated mode dimensions since the window is just being scaled. */ if (!ModeSwitchingEmulated(_this) && - SDL_GetDisplayBounds(window->displayID, &rect) == 0) { + SDL_GetDisplayBounds(SDL_GetDisplayForWindow(window), &rect) == 0) { int old_w = window->w; int old_h = window->h; window->x = rect.x; window->y = rect.y; window->w = rect.w; window->h = rect.h; - window->fullscreen_mode.screen_w = rect.w; - window->fullscreen_mode.screen_h = rect.h; if (_this->SetWindowSize) { _this->SetWindowSize(_this, window); } - if (window->w != old_w || window->h != old_h) { SDL_OnWindowResized(window); } @@ -3359,18 +3293,12 @@ void SDL_VideoQuit(void) } _this->VideoQuit(_this); - for (i = 0; i < _this->num_displays; ++i) { + for (i = _this->num_displays; i--; ) { SDL_VideoDisplay *display = &_this->displays[i]; - SDL_ResetDisplayModes(display); - SDL_free(display->desktop_mode.driverdata); - display->desktop_mode.driverdata = NULL; - SDL_free(display->driverdata); - display->driverdata = NULL; + SDL_DelVideoDisplay(display->id, SDL_FALSE); } if (_this->displays) { - for (i = 0; i < _this->num_displays; ++i) { - SDL_free(_this->displays[i].name); - } + SDL_assert(_this->num_displays == 0); SDL_free(_this->displays); _this->displays = NULL; _this->num_displays = 0; diff --git a/src/video/android/SDL_androidvideo.c b/src/video/android/SDL_androidvideo.c index 59bd393738..7cdee3497f 100644 --- a/src/video/android/SDL_androidvideo.c +++ b/src/video/android/SDL_androidvideo.c @@ -193,8 +193,6 @@ int Android_VideoInit(_THIS) display = SDL_GetVideoDisplay(displayID); display->orientation = Android_JNI_GetDisplayOrientation(); - SDL_AddDisplayMode(&_this->displays[0], &mode); - Android_InitTouch(); Android_InitMouse(); @@ -288,22 +286,8 @@ void Android_SendResize(SDL_Window *window) } if (window) { - /* Force the current mode to match the resize otherwise the SDL_EVENT_WINDOW_RESTORED event - * will fall back to the old mode */ - int w, h; - SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); - SDL_DisplayMode current_mode; - SDL_zero(current_mode); - - current_mode.format = Android_ScreenFormat; - current_mode.pixel_w = Android_DeviceWidth; - current_mode.pixel_h = Android_DeviceHeight; - current_mode.display_scale = Android_ScreenDensity; - current_mode.refresh_rate = Android_ScreenRate; - SDL_SetCurrentDisplayMode(display, ¤t_mode); - - w = (int)SDL_floorf(Android_SurfaceWidth / Android_ScreenDensity); - h = (int)SDL_floorf(Android_SurfaceHeight / Android_ScreenDensity); + int w = (int)SDL_floorf(Android_SurfaceWidth / Android_ScreenDensity); + int h = (int)SDL_floorf(Android_SurfaceHeight / Android_ScreenDensity); SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, w, h); } } diff --git a/src/video/cocoa/SDL_cocoamodes.m b/src/video/cocoa/SDL_cocoamodes.m index 27cd9dc3c5..d597fbc791 100644 --- a/src/video/cocoa/SDL_cocoamodes.m +++ b/src/video/cocoa/SDL_cocoamodes.m @@ -236,8 +236,8 @@ static SDL_bool GetDisplayMode(_THIS, CGDisplayModeRef vidmode, SDL_bool vidmode * in case there are duplicate modes with different IO flags or IO * display mode IDs in the future. In that case I think it's better * to try them all in SetDisplayMode than to risk one of them being - * correct but it being filtered out by SDL_AddDisplayMode as being - * a duplicate. + * correct but it being filtered out by SDL_AddFullscreenDisplayMode + * as being a duplicate. */ if (width == otherW && height == otherH && pixelW == otherpixelW && pixelH == otherpixelH && usableForGUI == otherGUI && refreshrate == otherrefresh && format == otherformat) { CFArrayAppendValue(modes, othermode); @@ -352,7 +352,6 @@ void Cocoa_InitModes(_THIS) CGDisplayModeRelease(moderef); display.desktop_mode = mode; - display.current_mode = mode; display.driverdata = displaydata; SDL_AddVideoDisplay(&display, SDL_FALSE); SDL_free(display.name); @@ -478,8 +477,6 @@ void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { SDL_DisplayData *data = display->driverdata; CVDisplayLinkRef link = NULL; - CGDisplayModeRef desktopmoderef; - SDL_DisplayMode desktopmode; CFArrayRef modes; CFDictionaryRef dict = NULL; const CFStringRef dictkeys[] = { kCGDisplayShowDuplicateLowResolutionModes }; @@ -487,23 +484,6 @@ void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay *display) CVDisplayLinkCreateWithCGDisplay(data->display, &link); - desktopmoderef = CGDisplayCopyDisplayMode(data->display); - - /* CopyAllDisplayModes won't always contain the desktop display mode (if - * NULL is passed in) - for example on a retina 15" MBP, System Preferences - * allows choosing 1920x1200 but it's not in the list. AddDisplayMode makes - * sure there are no duplicates so it's safe to always add the desktop mode - * even in cases where it is in the CopyAllDisplayModes list. - */ - if (desktopmoderef && GetDisplayMode(_this, desktopmoderef, SDL_TRUE, NULL, link, &desktopmode)) { - if (!SDL_AddDisplayMode(display, &desktopmode)) { - CFRelease(((SDL_DisplayModeData *)desktopmode.driverdata)->modes); - SDL_free(desktopmode.driverdata); - } - } - - CGDisplayModeRelease(desktopmoderef); - /* By default, CGDisplayCopyAllDisplayModes will only get a subset of the * system's available modes. For example on a 15" 2016 MBP, users can * choose 1920x1080@2x in System Preferences but it won't show up here, @@ -538,7 +518,7 @@ void Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay *display) SDL_DisplayMode mode; if (GetDisplayMode(_this, moderef, SDL_FALSE, modes, link, &mode)) { - if (!SDL_AddDisplayMode(display, &mode)) { + if (!SDL_AddFullscreenDisplayMode(display, &mode)) { CFRelease(((SDL_DisplayModeData *)mode.driverdata)->modes); SDL_free(mode.driverdata); } @@ -642,15 +622,15 @@ void Cocoa_QuitModes(_THIS) SDL_VideoDisplay *display = &_this->displays[i]; SDL_DisplayModeData *mode; - if (display->current_mode.driverdata != display->desktop_mode.driverdata) { + if (SDL_GetCurrentDisplayMode(display->id) != SDL_GetDesktopDisplayMode(display->id)) { Cocoa_SetDisplayMode(_this, display, &display->desktop_mode); } mode = (SDL_DisplayModeData *)display->desktop_mode.driverdata; CFRelease(mode->modes); - for (j = 0; j < display->num_display_modes; j++) { - mode = (SDL_DisplayModeData *)display->display_modes[j].driverdata; + for (j = 0; j < display->num_fullscreen_modes; j++) { + mode = (SDL_DisplayModeData *)display->fullscreen_modes[j].driverdata; CFRelease(mode->modes); } } diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m index ce5eabfaaf..937102d3ae 100644 --- a/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/video/cocoa/SDL_cocoaopengl.m @@ -301,7 +301,7 @@ SDL_GLContext Cocoa_GL_CreateContext(_THIS, SDL_Window *window) attr[i++] = profile; attr[i++] = NSOpenGLPFAColorSize; - attr[i++] = SDL_BYTESPERPIXEL(display->current_mode.format) * 8; + attr[i++] = 32; attr[i++] = NSOpenGLPFADepthSize; attr[i++] = _this->gl_config.depth_size; diff --git a/src/video/dummy/SDL_nullvideo.c b/src/video/dummy/SDL_nullvideo.c index bc3be65a50..f936c8d29e 100644 --- a/src/video/dummy/SDL_nullvideo.c +++ b/src/video/dummy/SDL_nullvideo.c @@ -150,8 +150,6 @@ int DUMMY_VideoInit(_THIS) return -1; } - SDL_AddDisplayMode(&_this->displays[0], &mode); - #if SDL_INPUT_LINUXEV SDL_EVDEV_Init(); #endif diff --git a/src/video/emscripten/SDL_emscriptenvideo.c b/src/video/emscripten/SDL_emscriptenvideo.c index 368483d92e..ca336daf27 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.c +++ b/src/video/emscripten/SDL_emscriptenvideo.c @@ -136,8 +136,6 @@ int Emscripten_VideoInit(_THIS) return -1; } - SDL_AddDisplayMode(&_this->displays[0], &mode); - Emscripten_InitMouse(); /* We're done! */ diff --git a/src/video/haiku/SDL_bmodes.cc b/src/video/haiku/SDL_bmodes.cc index 3694f4a831..b51d959a78 100644 --- a/src/video/haiku/SDL_bmodes.cc +++ b/src/video/haiku/SDL_bmodes.cc @@ -244,7 +244,7 @@ void HAIKU_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { // FIXME: Apparently there are errors with colorspace changes if (bmodes[i].space == this_bmode.space) { _BDisplayModeToSdlDisplayMode(&bmodes[i], &mode); - SDL_AddDisplayMode(display, &mode); + SDL_AddFullscreenDisplayMode(display, &mode); } } free(bmodes); /* This should not be SDL_free() */ diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c index 442e7c8cab..d018dbd077 100644 --- a/src/video/kmsdrm/SDL_kmsdrmvideo.c +++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c @@ -490,27 +490,22 @@ KMSDRM_WaitPageflip(_THIS, SDL_WindowData *windata) available on the DRM connector of the display. We use the SDL mode list (which we filled in KMSDRM_GetDisplayModes) because it's ordered, while the list on the connector is mostly random.*/ -static drmModeModeInfo *KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay *display, - uint32_t width, uint32_t height, uint32_t refresh_rate) +static drmModeModeInfo *KMSDRM_GetClosestDisplayMode(SDL_VideoDisplay *display, int width, int height) { SDL_DisplayData *dispdata = display->driverdata; drmModeConnector *connector = dispdata->connector; - SDL_DisplayMode target, closest; + const SDL_DisplayMode *closest; drmModeModeInfo *drm_mode; - SDL_zero(target); - target.screen_w = (int)width; - target.screen_h = (int)height; - target.refresh_rate = (int)refresh_rate; - - if (!SDL_GetClosestDisplayMode(SDL_atoi(display->name), &target, &closest)) { - return NULL; - } else { - SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)closest.driverdata; + closest = SDL_GetClosestFullscreenDisplayMode(display->id, width, height, 0.0f); + if (closest) { + const SDL_DisplayModeData *modedata = (const SDL_DisplayModeData *)closest->driverdata; drm_mode = &connector->modes[modedata->mode_index]; return drm_mode; + } else { + return NULL; } } @@ -876,7 +871,6 @@ static void KMSDRM_AddDisplay(_THIS, drmModeConnector *connector, drmModeRes *re display.desktop_mode.refresh_rate = CalculateRefreshRate(&dispdata->mode); display.desktop_mode.format = SDL_PIXELFORMAT_ARGB8888; display.desktop_mode.driverdata = modedata; - display.current_mode = display.desktop_mode; /* Add the display to the list of SDL displays. */ if (SDL_AddVideoDisplay(&display, SDL_FALSE) == 0) { @@ -1124,11 +1118,7 @@ static void KMSDRM_GetModeToSet(SDL_Window *window, drmModeModeInfo *out_mode) if ((window->flags & SDL_WINDOW_FULLSCREEN_EXCLUSIVE) != 0) { *out_mode = dispdata->fullscreen_mode; } else { - drmModeModeInfo *mode; - - mode = KMSDRM_GetClosestDisplayMode(display, - window->windowed.w, window->windowed.h, 0); - + drmModeModeInfo *mode = KMSDRM_GetClosestDisplayMode(display, window->windowed.w, window->windowed.h); if (mode) { *out_mode = *mode; } else { @@ -1161,7 +1151,6 @@ int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window) SDL_WindowData *windata = window->driverdata; SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); SDL_DisplayData *dispdata = display->driverdata; - SDL_DisplayMode current_mode; uint32_t surface_fmt = GBM_FORMAT_ARGB8888; uint32_t surface_flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; @@ -1183,15 +1172,20 @@ int KMSDRM_CreateSurfaces(_THIS, SDL_Window *window) /* The KMSDRM backend doesn't always set the mode the higher-level code in SDL_video.c expects. Hulk-smash the display's current_mode to keep the - mode that's set in sync with what SDL_video.c thinks is set */ + mode that's set in sync with what SDL_video.c thinks is set + + FIXME: How do we do that now? Can we get a better idea at the higher level? + */ KMSDRM_GetModeToSet(window, &dispdata->mode); + /* SDL_zero(current_mode); current_mode.pixel_w = dispdata->mode.hdisplay; current_mode.pixel_h = dispdata->mode.vdisplay; current_mode.refresh_rate = CalculateRefreshRate(&dispdata->mode); current_mode.format = SDL_PIXELFORMAT_ARGB8888; SDL_SetCurrentDisplayMode(display, ¤t_mode); + */ windata->gs = KMSDRM_gbm_surface_create(viddata->gbm_dev, dispdata->mode.hdisplay, dispdata->mode.vdisplay, @@ -1308,7 +1302,7 @@ void KMSDRM_GetDisplayModes(_THIS, SDL_VideoDisplay *display) mode.format = SDL_PIXELFORMAT_ARGB8888; mode.driverdata = modedata; - if (!SDL_AddDisplayMode(display, &mode)) { + if (!SDL_AddFullscreenDisplayMode(display, &mode)) { SDL_free(modedata); } } @@ -1508,8 +1502,7 @@ int KMSDRM_CreateWindow(_THIS, SDL_Window *window) are considered "windowed" at this point of their life. If a window is fullscreen, SDL internals will call KMSDRM_SetWindowFullscreen() to reconfigure it if necessary. */ - mode = KMSDRM_GetClosestDisplayMode(display, - window->windowed.w, window->windowed.h, 0); + mode = KMSDRM_GetClosestDisplayMode(display, window->windowed.w, window->windowed.h); if (mode) { dispdata->fullscreen_mode = *mode; diff --git a/src/video/n3ds/SDL_n3dsvideo.c b/src/video/n3ds/SDL_n3dsvideo.c index 0fdbbc294b..a58635c9f9 100644 --- a/src/video/n3ds/SDL_n3dsvideo.c +++ b/src/video/n3ds/SDL_n3dsvideo.c @@ -35,7 +35,6 @@ SDL_FORCE_INLINE void AddN3DSDisplay(gfxScreen_t screen); static int N3DS_VideoInit(_THIS); static void N3DS_VideoQuit(_THIS); -static void N3DS_GetDisplayModes(_THIS, SDL_VideoDisplay *display); static int N3DS_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect); static int N3DS_CreateWindow(_THIS, SDL_Window *window); static void N3DS_DestroyWindow(_THIS, SDL_Window *window); @@ -65,7 +64,6 @@ static SDL_VideoDevice *N3DS_CreateDevice(void) device->VideoInit = N3DS_VideoInit; device->VideoQuit = N3DS_VideoQuit; - device->GetDisplayModes = N3DS_GetDisplayModes; device->GetDisplayBounds = N3DS_GetDisplayBounds; device->CreateSDLWindow = N3DS_CreateWindow; @@ -124,7 +122,6 @@ static void AddN3DSDisplay(gfxScreen_t screen) display.name = (screen == GFX_TOP) ? "N3DS top screen" : "N3DS bottom screen"; display.desktop_mode = mode; - display.current_mode = mode; display.driverdata = display_driver_data; SDL_AddVideoDisplay(&display, SDL_FALSE); @@ -139,23 +136,19 @@ static void N3DS_VideoQuit(_THIS) gfxExit(); } -static void N3DS_GetDisplayModes(_THIS, SDL_VideoDisplay *display) -{ - /* Each display only has a single mode */ - SDL_AddDisplayMode(display, &display->current_mode); -} - static int N3DS_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) { SDL_DisplayData *driver_data = display->driverdata; + const SDL_DisplayMode *mode = SDL_GetCurrentDisplayMode(display->id); + if (driver_data == NULL) { return -1; } + rect->x = 0; rect->y = (driver_data->screen == GFX_TOP) ? 0 : GSP_SCREEN_WIDTH; - rect->w = display->current_mode.screen_w; - rect->h = display->current_mode.screen_h; - + rect->w = mode->screen_w; + rect->h = mode->screen_h; return 0; } diff --git a/src/video/ngage/SDL_ngagevideo.cpp b/src/video/ngage/SDL_ngagevideo.cpp index 0fbe3d7089..d92f6a60a3 100644 --- a/src/video/ngage/SDL_ngagevideo.cpp +++ b/src/video/ngage/SDL_ngagevideo.cpp @@ -48,7 +48,6 @@ extern "C" { /* Initialization/Query functions */ static int NGAGE_VideoInit(_THIS); -static int NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode); static void NGAGE_VideoQuit(_THIS); /* NGAGE driver bootstrap functions */ @@ -121,7 +120,6 @@ static SDL_VideoDevice *NGAGE_CreateDevice(void) /* General video */ device->VideoInit = NGAGE_VideoInit; device->VideoQuit = NGAGE_VideoQuit; - device->SetDisplayMode = NGAGE_SetDisplayMode; device->PumpEvents = NGAGE_PumpEvents; device->CreateWindowFramebuffer = SDL_NGAGE_CreateWindowFramebuffer; device->UpdateWindowFramebuffer = SDL_NGAGE_UpdateWindowFramebuffer; @@ -156,18 +154,10 @@ int NGAGE_VideoInit(_THIS) return -1; } - SDL_zero(mode); - SDL_AddDisplayMode(&_this->displays[0], &mode); - /* We're done! */ return 0; } -static int NGAGE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) -{ - return 0; -} - void NGAGE_VideoQuit(_THIS) { } diff --git a/src/video/offscreen/SDL_offscreenvideo.c b/src/video/offscreen/SDL_offscreenvideo.c index d3b8a54105..47a32656f3 100644 --- a/src/video/offscreen/SDL_offscreenvideo.c +++ b/src/video/offscreen/SDL_offscreenvideo.c @@ -109,8 +109,6 @@ int OFFSCREEN_VideoInit(_THIS) return -1; } - SDL_AddDisplayMode(&_this->displays[0], &mode); - /* We're done! */ return 0; } diff --git a/src/video/psp/SDL_pspvideo.c b/src/video/psp/SDL_pspvideo.c index 8d0fc17e4a..c8712550fd 100644 --- a/src/video/psp/SDL_pspvideo.c +++ b/src/video/psp/SDL_pspvideo.c @@ -133,7 +133,6 @@ VideoBootStrap PSP_bootstrap = { /*****************************************************************************/ int PSP_VideoInit(_THIS) { - SDL_VideoDisplay display; SDL_DisplayMode mode; SDL_zero(mode); @@ -144,17 +143,7 @@ int PSP_VideoInit(_THIS) /* 32 bpp for default */ mode.format = SDL_PIXELFORMAT_ABGR8888; - SDL_zero(display); - display.desktop_mode = mode; - display.current_mode = mode; - - SDL_AddDisplayMode(&display, &mode); - - /* 16 bpp secondary mode */ - mode.format = SDL_PIXELFORMAT_BGR565; - SDL_AddDisplayMode(&display, &mode); - - if (SDL_AddVideoDisplay(&display, SDL_FALSE) == 0) { + if (SDL_AddBasicVideoDisplay(&mode) == 0) { return -1; } return 0; @@ -166,12 +155,27 @@ void PSP_VideoQuit(_THIS) void PSP_GetDisplayModes(_THIS, SDL_VideoDisplay *display) { + SDL_DisplayMode mode; + + SDL_zero(mode); + mode.pixel_w = 480; + mode.pixel_h = 272; + mode.refresh_rate = 60.0f; + + /* 32 bpp for default */ + mode.format = SDL_PIXELFORMAT_ABGR8888; + SDL_AddFullscreenDisplayMode(display, &mode); + + /* 16 bpp secondary mode */ + mode.format = SDL_PIXELFORMAT_BGR565; + SDL_AddFullscreenDisplayMode(display, &mode); } int PSP_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) { return 0; } + #define EGLCHK(stmt) \ do { \ EGLint err; \ diff --git a/src/video/raspberry/SDL_rpivideo.c b/src/video/raspberry/SDL_rpivideo.c index c5bd997a4f..480084c04b 100644 --- a/src/video/raspberry/SDL_rpivideo.c +++ b/src/video/raspberry/SDL_rpivideo.c @@ -102,8 +102,6 @@ static SDL_VideoDevice *RPI_Create() /* Setup all functions which we can handle */ device->VideoInit = RPI_VideoInit; device->VideoQuit = RPI_VideoQuit; - device->GetDisplayModes = RPI_GetDisplayModes; - device->SetDisplayMode = RPI_SetDisplayMode; device->CreateSDLWindow = RPI_CreateWindow; device->CreateSDLWindowFrom = RPI_CreateWindowFrom; device->SetWindowTitle = RPI_SetWindowTitle; @@ -172,7 +170,6 @@ static void AddDispManXDisplay(const int display_id) SDL_zero(display); display.desktop_mode = mode; - display.current_mode = mode; /* Allocate display internal data */ data = (SDL_DisplayData *)SDL_calloc(1, sizeof(SDL_DisplayData)); @@ -214,17 +211,6 @@ void RPI_VideoQuit(_THIS) #endif } -void RPI_GetDisplayModes(_THIS, SDL_VideoDisplay *display) -{ - /* Only one display mode available, the current one */ - SDL_AddDisplayMode(display, &display->current_mode); -} - -int RPI_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) -{ - return 0; -} - static void RPI_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data) { SDL_WindowData *wdata = (SDL_WindowData *)data; diff --git a/src/video/riscos/SDL_riscosframebuffer.c b/src/video/riscos/SDL_riscosframebuffer.c index 46b2b0e018..69c01e7998 100644 --- a/src/video/riscos/SDL_riscosframebuffer.c +++ b/src/video/riscos/SDL_riscosframebuffer.c @@ -37,7 +37,7 @@ int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, vo unsigned int sprite_mode; _kernel_oserror *error; _kernel_swi_regs regs; - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; int size; int w, h; @@ -47,10 +47,10 @@ int RISCOS_CreateWindowFramebuffer(_THIS, SDL_Window *window, Uint32 *format, vo RISCOS_DestroyWindowFramebuffer(_this, window); /* Create a new one */ - SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(window), &mode); - if ((SDL_ISPIXELFORMAT_PACKED(mode.format) || SDL_ISPIXELFORMAT_ARRAY(mode.format))) { - *format = mode.format; - sprite_mode = (unsigned int)mode.driverdata; + mode = SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(window)); + if ((SDL_ISPIXELFORMAT_PACKED(mode->format) || SDL_ISPIXELFORMAT_ARRAY(mode->format))) { + *format = mode->format; + sprite_mode = (unsigned int)mode->driverdata; } else { *format = SDL_PIXELFORMAT_BGR888; sprite_mode = (1 | (90 << 1) | (90 << 14) | (6 << 27)); diff --git a/src/video/riscos/SDL_riscosmodes.c b/src/video/riscos/SDL_riscosmodes.c index f834d60e87..df8d850e8b 100644 --- a/src/video/riscos/SDL_riscosmodes.c +++ b/src/video/riscos/SDL_riscosmodes.c @@ -277,7 +277,7 @@ void RISCOS_GetDisplayModes(_THIS, SDL_VideoDisplay *display) break; } - if (!SDL_AddDisplayMode(display, &mode)) { + if (!SDL_AddFullscreenDisplayMode(display, &mode)) { SDL_free(mode.driverdata); } } diff --git a/src/video/uikit/SDL_uikitmodes.m b/src/video/uikit/SDL_uikitmodes.m index 6d8be3029a..df19891b05 100644 --- a/src/video/uikit/SDL_uikitmodes.m +++ b/src/video/uikit/SDL_uikitmodes.m @@ -275,7 +275,7 @@ static int UIKit_AddSingleDisplayMode(SDL_VideoDisplay *display, int w, int h, mode.refresh_rate = UIKit_GetDisplayModeRefreshRate(uiscreen); mode.format = SDL_PIXELFORMAT_ABGR8888; - if (SDL_AddDisplayMode(display, &mode)) { + if (SDL_AddFullscreenDisplayMode(display, &mode)) { return 0; } else { UIKit_FreeDisplayModeData(&mode); @@ -349,7 +349,6 @@ int UIKit_AddDisplay(UIScreen *uiscreen, SDL_bool send_event) SDL_zero(display); display.desktop_mode = mode; - display.current_mode = mode; /* Allocate the display data */ SDL_DisplayData *data = [[SDL_DisplayData alloc] initWithScreen:uiscreen]; @@ -378,8 +377,8 @@ void UIKit_DelDisplay(UIScreen *uiscreen) if (data && data.uiscreen == uiscreen) { display->driverdata = nil; - SDL_DelVideoDisplay(displays[i]); - return; + SDL_DelVideoDisplay(displays[i], SDL_FALSE); + break; } } SDL_free(displays); @@ -532,8 +531,8 @@ void UIKit_QuitModes(_THIS) SDL_VideoDisplay *display = &_this->displays[i]; UIKit_FreeDisplayModeData(&display->desktop_mode); - for (j = 0; j < display->num_display_modes; j++) { - SDL_DisplayMode *mode = &display->display_modes[j]; + for (j = 0; j < display->num_fullscreen_modes; j++) { + SDL_DisplayMode *mode = &display->fullscreen_modes[j]; UIKit_FreeDisplayModeData(mode); } @@ -551,31 +550,34 @@ void SDL_OnApplicationDidChangeStatusBarOrientation() SDL_VideoDisplay *display = SDL_GetVideoDisplay(SDL_GetPrimaryDisplay()); if (display) { - SDL_DisplayMode *desktopmode = &display->desktop_mode; - SDL_DisplayMode *currentmode = &display->current_mode; + SDL_DisplayMode *mode = &display->desktop_mode; SDL_DisplayOrientation orientation = SDL_ORIENTATION_UNKNOWN; + int i; /* The desktop display mode should be kept in sync with the screen * orientation so that updating a window's fullscreen state to * SDL_WINDOW_FULLSCREEN_DESKTOP keeps the window dimensions in the * correct orientation. */ - if (isLandscape != (desktopmode->pixel_w > desktopmode->pixel_h)) { - int height = desktopmode->pixel_w; - desktopmode->pixel_w = desktopmode->pixel_h; - desktopmode->pixel_h = height; - height = desktopmode->screen_w; - desktopmode->screen_w = desktopmode->screen_h; - desktopmode->screen_h = height; + if (isLandscape != (mode->pixel_w > mode->pixel_h)) { + int height = mode->pixel_w; + mode->pixel_w = mode->pixel_h; + mode->pixel_h = height; + height = mode->screen_w; + mode->screen_w = mode->screen_h; + mode->screen_h = height; } - /* Same deal with the current mode + SDL_GetCurrentDisplayMode. */ - if (isLandscape != (currentmode->pixel_w > currentmode->pixel_h)) { - int height = currentmode->pixel_w; - currentmode->pixel_w = currentmode->pixel_h; - currentmode->pixel_h = height; - height = currentmode->screen_w; - currentmode->screen_w = currentmode->screen_h; - currentmode->screen_h = height; + /* Same deal with the fullscreen modes */ + for (i = 0; i < display->num_fullscreen_modes; ++i) { + mode = &display->fullscreen_modes[i]; + if (isLandscape != (mode->pixel_w > mode->pixel_h)) { + int height = mode->pixel_w; + mode->pixel_w = mode->pixel_h; + mode->pixel_h = height; + height = mode->screen_w; + mode->screen_w = mode->screen_h; + mode->screen_h = height; + } } switch ([UIApplication sharedApplication].statusBarOrientation) { diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index c3b631bdfd..460fc9a048 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -169,19 +169,7 @@ int UIKit_CreateWindow(_THIS, SDL_Window *window) #if !TARGET_OS_TV const CGSize origsize = data.uiscreen.currentMode.size; if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) { - if (display->num_display_modes == 0) { - _this->GetDisplayModes(_this, display); - } - - int i; - const SDL_DisplayMode *bestmode = NULL; - for (i = display->num_display_modes; i >= 0; i--) { - const SDL_DisplayMode *mode = &display->display_modes[i]; - if ((mode->screen_w >= window->w) && (mode->screen_h >= window->h)) { - bestmode = mode; - } - } - + const SDL_DisplayMode *bestmode = SDL_GetClosestFullscreenDisplayMode(display->id, window->w, window->h, 0.0f); if (bestmode) { SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)bestmode->driverdata; [data.uiscreen setCurrentMode:modedata.uiscreenmode]; @@ -189,7 +177,7 @@ int UIKit_CreateWindow(_THIS, SDL_Window *window) /* desktop_mode doesn't change here (the higher level will * use it to set all the screens back to their defaults * upon window destruction, SDL_Quit(), etc. */ - display->current_mode = *bestmode; + SDL_SetCurrentDisplayMode(display, bestmode); } } diff --git a/src/video/vita/SDL_vitavideo.c b/src/video/vita/SDL_vitavideo.c index 84e7c67c16..f71d69ab60 100644 --- a/src/video/vita/SDL_vitavideo.c +++ b/src/video/vita/SDL_vitavideo.c @@ -106,8 +106,6 @@ static SDL_VideoDevice *VITA_Create() /* Setup all functions which we can handle */ device->VideoInit = VITA_VideoInit; device->VideoQuit = VITA_VideoQuit; - device->GetDisplayModes = VITA_GetDisplayModes; - device->SetDisplayMode = VITA_SetDisplayMode; device->CreateSDLWindow = VITA_CreateWindow; device->CreateSDLWindowFrom = VITA_CreateWindowFrom; device->SetWindowTitle = VITA_SetWindowTitle; @@ -208,7 +206,9 @@ int VITA_VideoInit(_THIS) /* 32 bpp for default */ mode.format = SDL_PIXELFORMAT_ABGR8888; - SDL_AddBasicVideoDisplay(&mode); + if (SDL_AddBasicVideoDisplay(&mode) == 0) { + return -1; + } VITA_InitTouch(); VITA_InitKeyboard(); @@ -222,16 +222,6 @@ void VITA_VideoQuit(_THIS) VITA_QuitTouch(); } -void VITA_GetDisplayModes(_THIS, SDL_VideoDisplay *display) -{ - SDL_AddDisplayMode(display, &display->current_mode); -} - -int VITA_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) -{ - return 0; -} - int VITA_CreateWindow(_THIS, SDL_Window *window) { SDL_WindowData *wdata; diff --git a/src/video/vivante/SDL_vivantevideo.c b/src/video/vivante/SDL_vivantevideo.c index 4cf6000363..ccf5b4e6f8 100644 --- a/src/video/vivante/SDL_vivantevideo.c +++ b/src/video/vivante/SDL_vivantevideo.c @@ -74,8 +74,6 @@ static SDL_VideoDevice *VIVANTE_Create() /* Setup all functions which we can handle */ device->VideoInit = VIVANTE_VideoInit; device->VideoQuit = VIVANTE_VideoQuit; - device->GetDisplayModes = VIVANTE_GetDisplayModes; - device->SetDisplayMode = VIVANTE_SetDisplayMode; device->CreateSDLWindow = VIVANTE_CreateWindow; device->SetWindowTitle = VIVANTE_SetWindowTitle; device->SetWindowPosition = VIVANTE_SetWindowPosition; @@ -159,7 +157,6 @@ static int VIVANTE_AddVideoDisplays(_THIS) SDL_zero(display); display.name = VIVANTE_GetDisplayName(_this); display.desktop_mode = mode; - display.current_mode = mode; display.driverdata = data; if (SDL_AddVideoDisplay(&display, SDL_FALSE) == 0) { return -1; @@ -242,17 +239,6 @@ void VIVANTE_VideoQuit(_THIS) #endif } -void VIVANTE_GetDisplayModes(_THIS, SDL_VideoDisplay *display) -{ - /* Only one display mode available, the current one */ - SDL_AddDisplayMode(display, &display->current_mode); -} - -int VIVANTE_SetDisplayMode(_THIS, SDL_VideoDisplay *display, SDL_DisplayMode *mode) -{ - return 0; -} - int VIVANTE_CreateWindow(_THIS, SDL_Window *window) { SDL_VideoData *videodata = _this->driverdata; diff --git a/src/video/wayland/SDL_waylandopengles.c b/src/video/wayland/SDL_waylandopengles.c index 8807b72a4b..0b7f5507b3 100644 --- a/src/video/wayland/SDL_waylandopengles.c +++ b/src/video/wayland/SDL_waylandopengles.c @@ -123,9 +123,8 @@ int Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) if (swap_interval != 0) { SDL_VideoData *videodata = _this->driverdata; struct wl_display *display = videodata->display; - SDL_VideoDisplay *sdldisplay = SDL_GetVideoDisplayForWindow(window); - /* ~10 frames (or 1 sec), so we'll progress even if throttled to zero. */ - const Uint64 max_wait = SDL_GetTicksNS() + (sdldisplay->current_mode.refresh_rate ? ((SDL_NS_PER_SECOND * 10 * 100) / (int)(sdldisplay->current_mode.refresh_rate * 100)) : SDL_NS_PER_SECOND); + /* 1 sec, so we'll progress even if throttled to zero. */ + const Uint64 max_wait = SDL_NS_PER_SECOND; while (SDL_AtomicGet(&data->swap_interval_ready) == 0) { Uint64 now; diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 5002462577..e0bdb344e0 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -413,15 +413,15 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90) int i; SDL_DisplayMode mode; - const int native_width = dpy->display_modes->pixel_w; - const int native_height = dpy->display_modes->pixel_h; + const int native_width = dpy->desktop_mode.pixel_w; + const int native_height = dpy->desktop_mode.pixel_h; for (i = 0; i < SDL_arraysize(mode_list); ++i) { SDL_zero(mode); - mode.format = dpy->display_modes->format; + mode.format = dpy->desktop_mode.format; mode.display_scale = 1.0f; - mode.refresh_rate = dpy->display_modes->refresh_rate; - mode.driverdata = dpy->display_modes->driverdata; + mode.refresh_rate = dpy->desktop_mode.refresh_rate; + mode.driverdata = dpy->desktop_mode.driverdata; if (rot_90) { mode.pixel_w = mode_list[i].h; @@ -435,7 +435,7 @@ static void AddEmulatedModes(SDL_VideoDisplay *dpy, SDL_bool rot_90) if ((mode.pixel_w < native_width && mode.pixel_h < native_height) || (mode.pixel_w < native_width && mode.pixel_h == native_height) || (mode.pixel_w == native_width && mode.pixel_h < native_height)) { - SDL_AddDisplayMode(dpy, &mode); + SDL_AddFullscreenDisplayMode(dpy, &mode); } } } @@ -458,12 +458,12 @@ static void display_handle_geometry(void *data, if (driverdata->wl_output_done_count) { /* Clear the wl_output ref so Reset doesn't free it */ display = SDL_GetVideoDisplay(driverdata->display); - for (i = 0; i < display->num_display_modes; ++i) { - display->display_modes[i].driverdata = NULL; + for (i = 0; i < display->num_fullscreen_modes; ++i) { + display->fullscreen_modes[i].driverdata = NULL; } /* Okay, now it's safe to reset */ - SDL_ResetDisplayModes(display); + SDL_ResetFullscreenDisplayModes(display); /* The display has officially started over. */ driverdata->wl_output_done_count = 0; @@ -609,15 +609,13 @@ static void display_handle_done(void *data, } /* Set the desktop display mode. */ - SDL_AddDisplayMode(dpy, &desktop_mode); - SDL_SetCurrentDisplayMode(dpy, &desktop_mode); - SDL_SetDesktopDisplayMode(dpy, &desktop_mode); + SDL_memcpy(&dpy->desktop_mode, &desktop_mode, sizeof(&dpy->desktop_mode)); /* If the desktop is scaled... */ if (driverdata->scale_factor > 1.0f) { /* ...expose the native resolution if viewports are available... */ if (video->viewporter != NULL) { - SDL_AddDisplayMode(dpy, &native_mode); + SDL_AddFullscreenDisplayMode(dpy, &native_mode); } else { /* ...if not, expose some smaller, integer scaled resolutions. */ int i; @@ -628,7 +626,7 @@ static void display_handle_done(void *data, desktop_mode.pixel_h = base_pixel_h * i; desktop_mode.display_scale = (float)i; - SDL_AddDisplayMode(dpy, &desktop_mode); + SDL_AddFullscreenDisplayMode(dpy, &desktop_mode); } } } @@ -749,7 +747,7 @@ static void Wayland_free_display(SDL_VideoData *d, uint32_t id) } } } - SDL_DelVideoDisplay(displays[i]); + SDL_DelVideoDisplay(displays[i], SDL_FALSE); if (data->xdg_output) { zxdg_output_v1_destroy(data->xdg_output); } @@ -974,10 +972,11 @@ int Wayland_VideoInit(_THIS) static int Wayland_GetDisplayBounds(_THIS, SDL_VideoDisplay *display, SDL_Rect *rect) { SDL_DisplayData *driverdata = display->driverdata; + const SDL_DisplayMode *mode = SDL_GetCurrentDisplayMode(display->id); rect->x = driverdata->x; rect->y = driverdata->y; - rect->w = display->current_mode.screen_w; - rect->h = display->current_mode.screen_h; + rect->w = mode->screen_w; + rect->h = mode->screen_h; return 0; } @@ -1017,11 +1016,11 @@ static void Wayland_VideoCleanup(_THIS) SDL_free(display->driverdata); display->driverdata = NULL; - for (j = display->num_display_modes; j--;) { - display->display_modes[j].driverdata = NULL; + for (j = display->num_fullscreen_modes; j--;) { + display->fullscreen_modes[j].driverdata = NULL; } display->desktop_mode.driverdata = NULL; - SDL_DelVideoDisplay(display->id); + SDL_DelVideoDisplay(display->id, SDL_FALSE); } data->output_list = NULL; diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 9207d03861..c6e16905f9 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -83,17 +83,14 @@ static void GetFullScreenDimensions(SDL_Window *window, int *width, int *height, } } else { /* If a mode was set, use it, otherwise use the native resolution. */ - if (window->fullscreen_mode.pixel_w != 0 && window->fullscreen_mode.pixel_h != 0) { - fs_width = window->fullscreen_mode.screen_w; - fs_height = window->fullscreen_mode.screen_h; - buf_width = window->fullscreen_mode.pixel_w; - buf_height = window->fullscreen_mode.pixel_h; - } else { - fs_width = disp->display_modes[0].screen_w; - fs_height = disp->display_modes[0].screen_h; - buf_width = disp->display_modes[0].pixel_w; - buf_height = disp->display_modes[0].pixel_h; + const SDL_DisplayMode *mode = SDL_GetWindowFullscreenMode(window); + if (!mode) { + mode = &disp->desktop_mode; } + fs_width = mode->screen_w; + fs_height = mode->screen_h; + buf_width = mode->pixel_w; + buf_height = mode->pixel_h; } if (width) { diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 964fea7e8b..7929f338ba 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1241,7 +1241,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) RECT rect; int x, y; int w, h; - SDL_DisplayID displayID = data->window->displayID; + SDL_DisplayID displayID = SDL_GetDisplayForWindow(data->window); if (data->initializing || data->in_border_change) { break; @@ -1294,7 +1294,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Forces a WM_PAINT event */ InvalidateRect(hwnd, NULL, FALSE); - if (data->window->displayID != displayID) { + if (data->window->last_displayID != displayID) { /* Display changed, check ICC profile */ WIN_UpdateWindowICCProfile(data->window, SDL_TRUE); } diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index e52c6dbc39..138d0d1748 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/src/video/windows/SDL_windowsmodes.c @@ -342,9 +342,7 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_VideoDisplay *existing_display = &_this->displays[i]; SDL_Rect bounds; - SDL_ResetDisplayModes(existing_display); - SDL_SetCurrentDisplayMode(existing_display, &mode); - SDL_SetDesktopDisplayMode(existing_display, &mode); + SDL_ResetFullscreenDisplayModes(existing_display); if (WIN_GetDisplayBounds(_this, existing_display, &bounds) == 0) { if (SDL_memcmp(&driverdata->bounds, &bounds, sizeof(bounds)) != 0 || moved) { SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_MOVED, 0); @@ -376,7 +374,6 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, } display.desktop_mode = mode; - display.current_mode = mode; display.orientation = orientation; display.device = _this; display.driverdata = displaydata; @@ -737,7 +734,7 @@ void WIN_GetDisplayModes(_THIS, SDL_VideoDisplay *display) continue; } if (mode.format != SDL_PIXELFORMAT_UNKNOWN) { - if (!SDL_AddDisplayMode(display, &mode)) { + if (!SDL_AddFullscreenDisplayMode(display, &mode)) { SDL_free(mode.driverdata); } } else { @@ -858,7 +855,7 @@ void WIN_RefreshDisplays(_THIS) SDL_VideoDisplay *display = &_this->displays[i]; SDL_DisplayData *driverdata = display->driverdata; if (driverdata->IsValid == SDL_FALSE) { - SDL_DelVideoDisplay(display->id); + SDL_DelVideoDisplay(display->id, SDL_TRUE); } } } diff --git a/src/video/winrt/SDL_winrtvideo.cpp b/src/video/winrt/SDL_winrtvideo.cpp index d74fd1b4cc..5982e242aa 100644 --- a/src/video/winrt/SDL_winrtvideo.cpp +++ b/src/video/winrt/SDL_winrtvideo.cpp @@ -307,17 +307,12 @@ static int WINRT_AddDisplaysForOutput(_THIS, IDXGIAdapter1 *dxgiAdapter1, int ou mode.pixel_h = (dxgiOutputDesc.DesktopCoordinates.bottom - dxgiOutputDesc.DesktopCoordinates.top); mode.format = DXGI_FORMAT_B8G8R8A8_UNORM; display.desktop_mode = mode; - display.current_mode = mode; - if (!SDL_AddDisplayMode(&display, &mode)) { - goto done; - } } else if (FAILED(hr)) { WIN_SetErrorFromHRESULT(__FUNCTION__ ", IDXGIOutput::FindClosestMatchingMode failed", hr); goto done; } else { display.name = WIN_StringToUTF8(dxgiOutputDesc.DeviceName); WINRT_DXGIModeToSDLDisplayMode(&closestMatch, &display.desktop_mode); - display.current_mode = display.desktop_mode; hr = dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL); if (FAILED(hr)) { @@ -343,7 +338,7 @@ static int WINRT_AddDisplaysForOutput(_THIS, IDXGIAdapter1 *dxgiAdapter1, int ou for (UINT i = 0; i < numModes; ++i) { SDL_DisplayMode sdlMode; WINRT_DXGIModeToSDLDisplayMode(&dxgiModes[i], &sdlMode); - SDL_AddDisplayMode(&display, &sdlMode); + SDL_AddFullscreenDisplayMode(&display, &sdlMode); } } @@ -432,9 +427,7 @@ static int WINRT_AddDisplaysForAdapter(_THIS, IDXGIFactory2 *dxgiFactory2, int a mode.format = DXGI_FORMAT_B8G8R8A8_UNORM; display.desktop_mode = mode; - display.current_mode = mode; - bool error = SDL_AddDisplayMode(&display, &mode) < 0 || - SDL_AddVideoDisplay(&display, SDL_FALSE) == 0; + bool error = (SDL_AddVideoDisplay(&display, SDL_FALSE) == 0); if (display.name) { SDL_free(display.name); } diff --git a/src/video/x11/SDL_x11messagebox.c b/src/video/x11/SDL_x11messagebox.c index ac8fedda0c..d7825deee5 100644 --- a/src/video/x11/SDL_x11messagebox.c +++ b/src/video/x11/SDL_x11messagebox.c @@ -470,8 +470,9 @@ static int X11_MessageBoxCreateWindow(SDL_MessageBoxDataX11 *data) if ((dev) && (dev->displays) && (dev->num_displays > 0)) { const SDL_VideoDisplay *dpy = &dev->displays[0]; const SDL_DisplayData *dpydata = dpy->driverdata; - x = dpydata->x + ((dpy->current_mode.pixel_w - data->dialog_width) / 2); - y = dpydata->y + ((dpy->current_mode.pixel_h - data->dialog_height) / 3); + const SDL_DisplayMode *mode = SDL_GetCurrentDisplayMode(dpy->id); + x = dpydata->x + ((mode->pixel_w - data->dialog_width) / 2); + y = dpydata->y + ((mode->pixel_h - data->dialog_height) / 3); } else { /* oh well. This will misposition on a multi-head setup. Init first next time. */ x = (DisplayWidth(display, data->screen) - data->dialog_width) / 2; y = (DisplayHeight(display, data->screen) - data->dialog_height) / 3; diff --git a/src/video/x11/SDL_x11modes.c b/src/video/x11/SDL_x11modes.c index c6ea009311..d52be85047 100644 --- a/src/video/x11/SDL_x11modes.c +++ b/src/video/x11/SDL_x11modes.c @@ -386,7 +386,6 @@ static int X11_AddXRandRDisplay(_THIS, Display *dpy, int screen, RROutput output display.name = display_name; } display.desktop_mode = mode; - display.current_mode = mode; display.driverdata = displaydata; if (SDL_AddVideoDisplay(&display, send_event) == 0) { return -1; @@ -419,7 +418,7 @@ static void X11_HandleXRandROutputChange(_THIS, const XRROutputChangeNotifyEvent if (ev->connection == RR_Disconnected) { /* output is going away */ if (display != NULL) { - SDL_DelVideoDisplay(display->id); + SDL_DelVideoDisplay(display->id, SDL_TRUE); } } else if (ev->connection == RR_Connected) { /* output is coming online */ if (display != NULL) { @@ -629,7 +628,6 @@ static int X11_InitModes_StdXlib(_THIS) SDL_zero(display); display.name = (char *)"Generic X11 Display"; /* this is just copied and thrown away, it's safe to cast to char* here. */ display.desktop_mode = mode; - display.current_mode = mode; display.driverdata = displaydata; if (SDL_AddVideoDisplay(&display, SDL_TRUE) == 0) { return -1; @@ -670,7 +668,7 @@ void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display) * (or support recreating the window with a new visual behind the scenes) */ SDL_zero(mode); - mode.format = sdl_display->current_mode.format; + mode.format = sdl_display->desktop_mode.format; #if SDL_VIDEO_DRIVER_X11_XRANDR if (data->use_xrandr) { @@ -693,7 +691,7 @@ void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display) mode.driverdata = modedata; if (!SetXRandRModeInfo(display, res, output_info->crtc, output_info->modes[i], &mode) || - !SDL_AddDisplayMode(sdl_display, &mode)) { + !SDL_AddFullscreenDisplayMode(sdl_display, &mode)) { SDL_free(modedata); } } @@ -704,20 +702,6 @@ void X11_GetDisplayModes(_THIS, SDL_VideoDisplay *sdl_display) return; } #endif /* SDL_VIDEO_DRIVER_X11_XRANDR */ - - if (!data->use_xrandr) { - SDL_DisplayModeData *modedata; - /* Add the desktop mode */ - mode = sdl_display->desktop_mode; - modedata = (SDL_DisplayModeData *)SDL_calloc(1, sizeof(SDL_DisplayModeData)); - if (modedata) { - *modedata = *(SDL_DisplayModeData *)sdl_display->desktop_mode.driverdata; - } - mode.driverdata = modedata; - if (!SDL_AddDisplayMode(sdl_display, &mode)) { - SDL_free(modedata); - } - } } #if SDL_VIDEO_DRIVER_X11_XRANDR @@ -832,12 +816,12 @@ void X11_QuitModes(_THIS) int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect) { SDL_DisplayData *data = sdl_display->driverdata; + const SDL_DisplayMode *mode = SDL_GetCurrentDisplayMode(sdl_display->id); rect->x = data->x; rect->y = data->y; - rect->w = sdl_display->current_mode.screen_w; - rect->h = sdl_display->current_mode.screen_h; - + rect->w = mode->screen_w; + rect->h = mode->screen_h; return 0; } diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 02465c49b8..ff19d50488 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -125,8 +125,7 @@ static int X11_SafetyNetErrHandler(Display *d, XErrorEvent *e) int i; for (i = 0; i < device->num_displays; i++) { SDL_VideoDisplay *display = &device->displays[i]; - if (SDL_memcmp(&display->current_mode, &display->desktop_mode, - sizeof(SDL_DisplayMode)) != 0) { + if (SDL_GetCurrentDisplayMode(display->id) != SDL_GetDesktopDisplayMode(display->id)) { X11_SetDisplayMode(device, display, &display->desktop_mode); } } diff --git a/test/testautomation_video.c b/test/testautomation_video.c index b09bf8163a..144c2eb064 100644 --- a/test/testautomation_video.c +++ b/test/testautomation_video.c @@ -339,12 +339,13 @@ int video_getWindowFlags(void *arg) } /** - * @brief Tests the functionality of the SDL_GetNumDisplayModes function + * @brief Tests the functionality of the SDL_GetFullscreenDisplayModes function */ -int video_getNumDisplayModes(void *arg) +int video_getFullscreenDisplayModes(void *arg) { SDL_DisplayID *displays; - int result; + const SDL_DisplayMode **modes; + int count; int i; /* Get number of displays */ @@ -354,9 +355,11 @@ int video_getNumDisplayModes(void *arg) /* Make call for each display */ for (i = 0; displays[i]; ++i) { - result = SDL_GetNumDisplayModes(displays[i]); - SDLTest_AssertPass("Call to SDL_GetNumDisplayModes(%d)", i); - SDLTest_AssertCheck(result >= 1, "Validate returned value from function; expected: >=1; got: %d", result); + modes = SDL_GetFullscreenDisplayModes(displays[i], &count); + SDLTest_AssertPass("Call to SDL_GetFullscreenDisplayModes(%" SDL_PRIu32 ")", displays[i]); + SDLTest_AssertCheck(modes != NULL, "Validate returned value from function; expected != NULL; got: %p", modes); + SDLTest_AssertCheck(count >= 0, "Validate number of modes; expected: >= 0; got: %d", count); + SDL_free(modes); } SDL_free(displays); } @@ -365,18 +368,15 @@ int video_getNumDisplayModes(void *arg) } /** - * @brief Tests the functionality of the SDL_GetClosestDisplayMode function against current resolution + * @brief Tests the functionality of the SDL_GetClosestFullscreenDisplayMode function against current resolution */ int video_getClosestDisplayModeCurrentResolution(void *arg) { - int result; SDL_DisplayID *displays; + const SDL_DisplayMode **modes; SDL_DisplayMode current; - SDL_DisplayMode target; - SDL_DisplayMode closest; - SDL_DisplayMode *dResult; - int i; - int variation; + const SDL_DisplayMode *closest; + int i, num_modes; /* Get number of displays */ displays = SDL_GetDisplays(NULL); @@ -388,35 +388,22 @@ int video_getClosestDisplayModeCurrentResolution(void *arg) SDLTest_Log("Testing against display: %" SDL_PRIu32 "", displays[i]); /* Get first display mode to get a sane resolution; this should always work */ - result = SDL_GetDisplayMode(displays[i], 0, ¤t); - SDLTest_AssertPass("Call to SDL_GetDisplayMode()"); - SDLTest_AssertCheck(result == 0, "Verify return value, expected: 0, got: %d", result); - if (result != 0) { - return TEST_ABORTED; - } - - /* Set the desired resolution equals to current resolution */ - SDL_zero(target); - target.pixel_w = current.pixel_w; - target.pixel_h = current.pixel_h; - for (variation = 0; variation < 8; variation++) { - /* Vary constraints on other query parameters */ - target.format = (variation & 1) ? current.format : 0; - target.refresh_rate = (variation & 2) ? current.refresh_rate : 0.0f; - target.driverdata = (variation & 4) ? current.driverdata : 0; + modes = SDL_GetFullscreenDisplayModes(displays[i], &num_modes); + SDLTest_AssertPass("Call to SDL_GetDisplayModes()"); + SDLTest_Assert(modes != NULL, "Verify returned value is not NULL"); + if (num_modes > 0) { + SDL_memcpy(¤t, modes[0], sizeof(current)); /* Make call */ - dResult = SDL_GetClosestDisplayMode(displays[i], &target, &closest); - SDLTest_AssertPass("Call to SDL_GetClosestDisplayMode(target=current/variation%d)", variation); - SDLTest_Assert(dResult != NULL, "Verify returned value is not NULL"); + closest = SDL_GetClosestFullscreenDisplayMode(displays[i], current.pixel_w, current.pixel_h, current.refresh_rate); + SDLTest_AssertPass("Call to SDL_GetClosestFullscreenDisplayMode(target=current)"); + SDLTest_Assert(closest != NULL, "Verify returned value is not NULL"); /* Check that one gets the current resolution back again */ - SDLTest_AssertCheck(closest.pixel_w == current.pixel_w, "Verify returned width matches current width; expected: %d, got: %d", current.pixel_w, closest.pixel_w); - SDLTest_AssertCheck(closest.pixel_h == current.pixel_h, "Verify returned height matches current height; expected: %d, got: %d", current.pixel_h, closest.pixel_h); - /* NOLINTBEGIN(clang-analyzer-core.NullDereference): Checked earlier for NULL */ - SDLTest_AssertCheck(closest.pixel_w == dResult->pixel_w, "Verify return value matches assigned value; expected: %d, got: %d", closest.pixel_w, dResult->pixel_w); - SDLTest_AssertCheck(closest.pixel_h == dResult->pixel_h, "Verify return value matches assigned value; expected: %d, got: %d", closest.pixel_h, dResult->pixel_h); - /* NOLINTEND(clang-analyzer-core.NullDereference) */ + if (closest) { + SDLTest_AssertCheck(closest->pixel_w == current.pixel_w, "Verify returned width matches current width; expected: %d, got: %d", current.pixel_w, closest->pixel_w); + SDLTest_AssertCheck(closest->pixel_h == current.pixel_h, "Verify returned height matches current height; expected: %d, got: %d", current.pixel_h, closest->pixel_h); + } } } SDL_free(displays); @@ -426,13 +413,12 @@ int video_getClosestDisplayModeCurrentResolution(void *arg) } /** - * @brief Tests the functionality of the SDL_GetClosestDisplayMode function against random resolution + * @brief Tests the functionality of the SDL_GetClosestFullscreenDisplayMode function against random resolution */ int video_getClosestDisplayModeRandomResolution(void *arg) { SDL_DisplayID *displays; SDL_DisplayMode target; - SDL_DisplayMode closest; int i; int variation; @@ -451,12 +437,11 @@ int video_getClosestDisplayModeRandomResolution(void *arg) SDL_zero(target); target.pixel_w = (variation & 1) ? SDLTest_RandomIntegerInRange(1, 4096) : 0; target.pixel_h = (variation & 2) ? SDLTest_RandomIntegerInRange(1, 4096) : 0; - target.format = (variation & 4) ? SDLTest_RandomIntegerInRange(1, 10) : 0; target.refresh_rate = (variation & 8) ? (float)SDLTest_RandomIntegerInRange(25, 120) : 0.0f; /* Make call; may or may not find anything, so don't validate any further */ - SDL_GetClosestDisplayMode(displays[i], &target, &closest); - SDLTest_AssertPass("Call to SDL_GetClosestDisplayMode(target=random/variation%d)", variation); + SDL_GetClosestFullscreenDisplayMode(displays[i], target.pixel_w, target.pixel_h, target.refresh_rate); + SDLTest_AssertPass("Call to SDL_GetClosestFullscreenDisplayMode(target=random/variation%d)", variation); } } SDL_free(displays); @@ -466,31 +451,22 @@ int video_getClosestDisplayModeRandomResolution(void *arg) } /** - * @brief Tests call to SDL_GetWindowDisplayMode + * @brief Tests call to SDL_GetWindowFullscreenMode * - * @sa http://wiki.libsdl.org/SDL_GetWindowDisplayMode + * @sa http://wiki.libsdl.org/SDL_GetWindowFullscreenMode */ int video_getWindowDisplayMode(void *arg) { SDL_Window *window; const char *title = "video_getWindowDisplayMode Test Window"; - SDL_DisplayMode mode; - int result; - - /* Invalidate part of the mode content so we can check values later */ - mode.pixel_w = -1; - mode.pixel_h = -1; - mode.refresh_rate = -1.0f; + const SDL_DisplayMode *mode; /* Call against new test window */ window = createVideoSuiteTestWindow(title); if (window != NULL) { - result = SDL_GetWindowDisplayMode(window, &mode); - SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode()"); - SDLTest_AssertCheck(result == 0, "Validate result value; expected: 0, got: %d", result); - SDLTest_AssertCheck(mode.pixel_w > 0, "Validate mode.w content; expected: >0, got: %d", mode.pixel_w); - SDLTest_AssertCheck(mode.pixel_h > 0, "Validate mode.h content; expected: >0, got: %d", mode.pixel_h); - SDLTest_AssertCheck(mode.refresh_rate > 0.0f, "Validate mode.refresh_rate content; expected: >0, got: %g", mode.refresh_rate); + mode = SDL_GetWindowFullscreenMode(window); + SDLTest_AssertPass("Call to SDL_GetWindowFullscreenMode()"); + SDLTest_AssertCheck(mode == NULL, "Validate result value; expected: NULL, got: %p", mode); } /* Clean up */ @@ -519,43 +495,18 @@ static void checkInvalidWindowError() } /** - * @brief Tests call to SDL_GetWindowDisplayMode with invalid input + * @brief Tests call to SDL_GetWindowFullscreenMode with invalid input * - * @sa http://wiki.libsdl.org/SDL_GetWindowDisplayMode + * @sa http://wiki.libsdl.org/SDL_GetWindowFullscreenMode */ int video_getWindowDisplayModeNegative(void *arg) { - const char *expectedError = "Parameter 'mode' is invalid"; - char *lastError; - SDL_Window *window; - const char *title = "video_getWindowDisplayModeNegative Test Window"; - SDL_DisplayMode mode; - int result; - - /* Call against new test window */ - window = createVideoSuiteTestWindow(title); - if (window != NULL) { - result = SDL_GetWindowDisplayMode(window, NULL); - SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode(...,mode=NULL)"); - SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %d", result); - lastError = (char *)SDL_GetError(); - SDLTest_AssertPass("SDL_GetError()"); - SDLTest_AssertCheck(lastError != NULL, "Verify error message is not NULL"); - if (lastError != NULL) { - SDLTest_AssertCheck(SDL_strcmp(lastError, expectedError) == 0, - "SDL_GetError(): expected message '%s', was message: '%s'", - expectedError, - lastError); - } - } - - /* Clean up */ - destroyVideoSuiteTestWindow(window); + const SDL_DisplayMode *mode; /* Call against invalid window */ - result = SDL_GetWindowDisplayMode(NULL, &mode); - SDLTest_AssertPass("Call to SDL_GetWindowDisplayMode(window=NULL,...)"); - SDLTest_AssertCheck(result == -1, "Validate result value; expected: -1, got: %d", result); + mode = SDL_GetWindowFullscreenMode(NULL); + SDLTest_AssertPass("Call to SDL_GetWindowFullscreenMode(window=NULL)"); + SDLTest_AssertCheck(mode == NULL, "Validate result value; expected: NULL, got: %p", mode); checkInvalidWindowError(); return TEST_COMPLETED; @@ -1748,7 +1699,7 @@ int video_setWindowCenteredOnDisplay(void *arg) SDLTest_AssertCheck(currentY == expectedY, "Validate y (current: %d, expected: %d)", currentY, expectedY); /* Enter fullscreen desktop */ - result = SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); + result = SDL_SetWindowFullscreen(window, SDL_TRUE); SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); /* Check we are filling the full display */ @@ -1763,7 +1714,7 @@ int video_setWindowCenteredOnDisplay(void *arg) SDLTest_AssertCheck(currentY == expectedDisplayRect.y, "Validate y (current: %d, expected: %d)", currentY, expectedDisplayRect.y); /* Leave fullscreen desktop */ - result = SDL_SetWindowFullscreen(window, 0); + result = SDL_SetWindowFullscreen(window, SDL_FALSE); SDLTest_AssertCheck(result == 0, "Verify return value; expected: 0, got: %d", result); /* Check window was restored correctly */ @@ -1832,7 +1783,7 @@ static const SDLTest_TestCaseReference videoTest5 = { }; static const SDLTest_TestCaseReference videoTest6 = { - (SDLTest_TestCaseFp)video_getNumDisplayModes, "video_getNumDisplayModes", "Use SDL_GetNumDisplayModes function to get number of display modes", TEST_ENABLED + (SDLTest_TestCaseFp)video_getFullscreenDisplayModes, "video_getFullscreenDisplayModes", "Use SDL_GetFullscreenDisplayModes function to get number of display modes", TEST_ENABLED }; static const SDLTest_TestCaseReference videoTest7 = { diff --git a/test/testdisplayinfo.c b/test/testdisplayinfo.c index 0c77154a6b..c328adbd41 100644 --- a/test/testdisplayinfo.c +++ b/test/testdisplayinfo.c @@ -32,7 +32,8 @@ print_mode(const char *prefix, const SDL_DisplayMode *mode) int main(int argc, char *argv[]) { SDL_DisplayID *displays; - SDL_DisplayMode mode; + const SDL_DisplayMode **modes; + const SDL_DisplayMode *mode; int num_displays, i; /* Enable standard application logging */ @@ -51,13 +52,13 @@ int main(int argc, char *argv[]) for (i = 0; i < num_displays; i++) { SDL_DisplayID dpy = displays[i]; - const int num_modes = SDL_GetNumDisplayModes(dpy); SDL_Rect rect = { 0, 0, 0, 0 }; float ddpi, hdpi, vdpi; - int m; + int m, num_modes = 0; SDL_GetDisplayBounds(dpy, &rect); - SDL_Log("%" SDL_PRIu32 ": \"%s\" (%dx%d, (%d, %d)), %d modes.\n", dpy, SDL_GetDisplayName(dpy), rect.w, rect.h, rect.x, rect.y, num_modes); + modes = SDL_GetFullscreenDisplayModes(dpy, &num_modes); + SDL_Log("%" SDL_PRIu32 ": \"%s\" (%dx%d, (%d, %d)), %d fullscreen modes.\n", dpy, SDL_GetDisplayName(dpy), rect.w, rect.h, rect.x, rect.y, num_modes); if (SDL_GetDisplayPhysicalDPI(dpy, &ddpi, &hdpi, &vdpi) == -1) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " DPI: failed to query (%s)\n", SDL_GetError()); @@ -65,27 +66,26 @@ int main(int argc, char *argv[]) SDL_Log(" DPI: ddpi=%f; hdpi=%f; vdpi=%f\n", ddpi, hdpi, vdpi); } - if (SDL_GetCurrentDisplayMode(dpy, &mode) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " CURRENT: failed to query (%s)\n", SDL_GetError()); + mode = SDL_GetCurrentDisplayMode(dpy); + if (mode) { + print_mode("CURRENT", mode); } else { - print_mode("CURRENT", &mode); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " CURRENT: failed to query (%s)\n", SDL_GetError()); } - if (SDL_GetDesktopDisplayMode(dpy, &mode) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " DESKTOP: failed to query (%s)\n", SDL_GetError()); + mode = SDL_GetDesktopDisplayMode(dpy); + if (mode) { + print_mode("DESKTOP", mode); } else { - print_mode("DESKTOP", &mode); + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " DESKTOP: failed to query (%s)\n", SDL_GetError()); } for (m = 0; m < num_modes; m++) { - if (SDL_GetDisplayMode(dpy, m, &mode) == -1) { - SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, " MODE %d: failed to query (%s)\n", m, SDL_GetError()); - } else { - char prefix[64]; - (void)SDL_snprintf(prefix, sizeof prefix, " MODE %d", m); - print_mode(prefix, &mode); - } + char prefix[64]; + (void)SDL_snprintf(prefix, sizeof prefix, " MODE %d", m); + print_mode(prefix, modes[i]); } + SDL_free(modes); SDL_Log("\n"); } diff --git a/test/testgl.c b/test/testgl.c index 1146dcc7f1..9440231fd9 100644 --- a/test/testgl.c +++ b/test/testgl.c @@ -202,7 +202,7 @@ int main(int argc, char *argv[]) int fsaa, accel; int value; int i, done; - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; SDL_Event event; Uint64 then, now; Uint32 frames; @@ -293,8 +293,10 @@ int main(int argc, char *argv[]) swap_interval = 0; } - SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay(), &mode); - SDL_Log("Screen BPP : %" SDL_PRIu32 "\n", SDL_BITSPERPIXEL(mode.format)); + mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); + if (mode) { + SDL_Log("Screen BPP : %" SDL_PRIu32 "\n", SDL_BITSPERPIXEL(mode->format)); + } ret_interval = SDL_GL_GetSwapInterval(&interval); if (ret_interval < 0) { diff --git a/test/testgles.c b/test/testgles.c index 5df605653b..3a6f958cdd 100644 --- a/test/testgles.c +++ b/test/testgles.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) int fsaa, accel; int value; int i, done; - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; SDL_Event event; Uint32 then, now, frames; int status; @@ -187,9 +187,11 @@ int main(int argc, char *argv[]) SDL_GL_SetSwapInterval(0); } - SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay(), &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); + mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); + if (mode) { + SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode->format)); + SDL_Log("\n"); + } SDL_Log("Vendor : %s\n", glGetString(GL_VENDOR)); SDL_Log("Renderer : %s\n", glGetString(GL_RENDERER)); SDL_Log("Version : %s\n", glGetString(GL_VERSION)); diff --git a/test/testgles2.c b/test/testgles2.c index 9280cc4bc6..ab3eff0599 100644 --- a/test/testgles2.c +++ b/test/testgles2.c @@ -615,7 +615,7 @@ int main(int argc, char *argv[]) int fsaa, accel, threaded; int value; int i; - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; Uint64 then, now; int status; shader_data *data; @@ -714,10 +714,12 @@ int main(int argc, char *argv[]) SDL_GL_SetSwapInterval(0); } - SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay(), &mode); + mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); SDL_Log("Threaded : %s\n", threaded ? "yes" : "no"); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); + if (mode) { + SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode->format)); + SDL_Log("\n"); + } SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); diff --git a/test/testgles2_sdf.c b/test/testgles2_sdf.c index f51dd0b695..49e6917907 100644 --- a/test/testgles2_sdf.c +++ b/test/testgles2_sdf.c @@ -434,7 +434,7 @@ int main(int argc, char *argv[]) int fsaa, accel; int value; int i; - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; Uint64 then, now; int status; shader_data *data; @@ -602,9 +602,11 @@ int main(int argc, char *argv[]) SDL_GL_SetSwapInterval(0); } - SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay(), &mode); - SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode.format)); - SDL_Log("\n"); + mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); + if (mode) { + SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(mode->format)); + SDL_Log("\n"); + } SDL_Log("Vendor : %s\n", ctx.glGetString(GL_VENDOR)); SDL_Log("Renderer : %s\n", ctx.glGetString(GL_RENDERER)); SDL_Log("Version : %s\n", ctx.glGetString(GL_VERSION)); diff --git a/test/testvulkan.c b/test/testvulkan.c index 191b4b5f6a..690f577d28 100644 --- a/test/testvulkan.c +++ b/test/testvulkan.c @@ -1080,7 +1080,7 @@ static SDL_bool render(void) int main(int argc, char **argv) { int done; - SDL_DisplayMode mode; + const SDL_DisplayMode *mode; SDL_Event event; Uint64 then, now; Uint32 frames; @@ -1104,8 +1104,10 @@ int main(int argc, char **argv) return 1; } - SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay(), &mode); - SDL_Log("Screen BPP : %" SDL_PRIu32 "\n", SDL_BITSPERPIXEL(mode.format)); + mode = SDL_GetCurrentDisplayMode(SDL_GetPrimaryDisplay()); + if (mode) { + SDL_Log("Screen BPP : %" SDL_PRIu32 "\n", SDL_BITSPERPIXEL(mode->format)); + } SDL_GetWindowSize(state->windows[0], &dw, &dh); SDL_Log("Window Size : %d,%d\n", dw, dh); SDL_GetWindowSizeInPixels(state->windows[0], &dw, &dh); diff --git a/test/testwm.c b/test/testwm.c index d0642f78de..97d8ad2cf4 100644 --- a/test/testwm.c +++ b/test/testwm.c @@ -54,11 +54,10 @@ quit(int rc) static void draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport) { - SDL_DisplayMode mode; + const SDL_DisplayMode **modes; char text[1024]; const int lineHeight = 10; const SDL_DisplayID displayID = SDL_GetDisplayForWindow(window); - const int num_modes = SDL_GetNumDisplayModes(displayID); int i; int column_chars = 0; int text_length; @@ -83,7 +82,7 @@ draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport) y += lineHeight; - SDL_strlcpy(text, "Click on a mode to set it with SDL_SetWindowDisplayMode", sizeof text); + SDL_strlcpy(text, "Click on a mode to set it with SDL_SetWindowFullscreenMode", sizeof text); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); SDLTest_DrawString(renderer, x, y, text); y += lineHeight; @@ -100,15 +99,13 @@ draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport) highlighted_mode = -1; } - for (i = 0; i < num_modes; ++i) { + modes = SDL_GetFullscreenDisplayModes(displayID, NULL); + for (i = 0; modes[i]; ++i) { SDL_FRect cell_rect; - - if (0 != SDL_GetDisplayMode(displayID, i, &mode)) { - return; - } + const SDL_DisplayMode *mode = modes[i]; (void)SDL_snprintf(text, sizeof text, "%d: %dx%d@%gHz", - i, mode.pixel_w, mode.pixel_h, mode.refresh_rate); + i, mode->pixel_w, mode->pixel_h, mode->refresh_rate); /* Update column width */ text_length = (int)SDL_strlen(text); @@ -141,6 +138,7 @@ draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_FRect viewport) column_chars = 0; } } + SDL_free(modes); } void loop() @@ -208,12 +206,13 @@ void loop() SDL_Window *window = SDL_GetMouseFocus(); if (highlighted_mode != -1 && window != NULL) { SDL_DisplayID displayID = SDL_GetDisplayForWindow(window); - SDL_DisplayMode mode; - if (0 != SDL_GetDisplayMode(displayID, highlighted_mode, &mode)) { - SDL_Log("Couldn't get display mode"); - } else { - SDL_SetWindowDisplayMode(window, &mode); + int num_modes; + const SDL_DisplayMode **modes = SDL_GetFullscreenDisplayModes(displayID, &num_modes); + if (highlighted_mode < num_modes) { + SDL_memcpy(&state->fullscreen_mode, modes[highlighted_mode], sizeof(state->fullscreen_mode)); + SDL_SetWindowFullscreenMode(window, modes[highlighted_mode]); } + SDL_free(modes); } } }