From fed857787af1120765a95a352c89f1c9b4206011 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 10 Nov 2021 08:47:39 -0800 Subject: [PATCH] Update the orientation and display modes when the display settings change on Windows Fixes https://github.com/libsdl-org/SDL/issues/1061 --- src/video/SDL_sysvideo.h | 4 +++ src/video/SDL_video.c | 50 ++++++++++++++++++++++------ src/video/windows/SDL_windowsmodes.c | 10 +++++- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index d57731eda..bbe4eab17 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -341,6 +341,7 @@ struct SDL_VideoDevice Uint8 window_magic; Uint32 next_object_id; char *clipboard_text; + SDL_bool setting_display_mode; /* * * */ /* Data used by the GL drivers */ @@ -459,6 +460,9 @@ extern int SDL_AddBasicVideoDisplay(const SDL_DisplayMode * desktop_mode); extern int SDL_AddVideoDisplay(const SDL_VideoDisplay * display, SDL_bool send_event); extern void SDL_DelVideoDisplay(int index); 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_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode * mode); +extern void SDL_ResetDisplayModes(int displayIndex); extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display); extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex); extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 573b6afbf..276c0674b 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -796,7 +796,7 @@ SDL_GetDisplayOrientation(int displayIndex) } SDL_bool -SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) { SDL_DisplayMode *modes; int i, nmodes; @@ -831,6 +831,18 @@ SDL_AddDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) return SDL_TRUE; } +void +SDL_SetCurrentDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +{ + SDL_memcpy(&display->current_mode, mode, sizeof(*mode)); +} + +void +SDL_SetDesktopDisplayMode(SDL_VideoDisplay * display, const SDL_DisplayMode * mode) +{ + SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode)); +} + static int SDL_GetNumDisplayModesForDisplay(SDL_VideoDisplay * display) { @@ -850,6 +862,25 @@ SDL_GetNumDisplayModes(int displayIndex) return SDL_GetNumDisplayModesForDisplay(&_this->displays[displayIndex]); } +void +SDL_ResetDisplayModes(int displayIndex) +{ + SDL_VideoDisplay *display; + int i; + + CHECK_DISPLAY_INDEX(displayIndex,); + + display = &_this->displays[displayIndex]; + 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; +} + int SDL_GetDisplayMode(int displayIndex, int index, SDL_DisplayMode * mode) { @@ -1021,6 +1052,7 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * { SDL_DisplayMode display_mode; SDL_DisplayMode current_mode; + int result; if (mode) { display_mode = *mode; @@ -1058,10 +1090,13 @@ SDL_SetDisplayModeForDisplay(SDL_VideoDisplay * display, const SDL_DisplayMode * if (!_this->SetDisplayMode) { return SDL_SetError("SDL video driver doesn't support changing display mode"); } - if (_this->SetDisplayMode(_this, display, &display_mode) < 0) { + _this->setting_display_mode = SDL_TRUE; + result = _this->SetDisplayMode(_this, display, &display_mode); + _this->setting_display_mode = SDL_FALSE; + if (result < 0) { return -1; } - display->current_mode = display_mode; + SDL_SetCurrentDisplayMode(display, &display_mode); return 0; } @@ -3157,7 +3192,7 @@ SDL_DisableScreenSaver() void SDL_VideoQuit(void) { - int i, j; + int i; if (!_this) { return; @@ -3179,12 +3214,7 @@ SDL_VideoQuit(void) for (i = 0; i < _this->num_displays; ++i) { SDL_VideoDisplay *display = &_this->displays[i]; - for (j = display->num_display_modes; j--;) { - SDL_free(display->display_modes[j].driverdata); - display->display_modes[j].driverdata = NULL; - } - SDL_free(display->display_modes); - display->display_modes = NULL; + SDL_ResetDisplayModes(i); SDL_free(display->desktop_mode.driverdata); display->desktop_mode.driverdata = NULL; SDL_free(display->driverdata); diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index 3abb5d42c..b9a4ac06f 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/src/video/windows/SDL_windowsmodes.c @@ -23,6 +23,7 @@ #if SDL_VIDEO_DRIVER_WINDOWS #include "SDL_windowsvideo.h" +#include "../../events/SDL_displayevents_c.h" /* Windows CE compatibility */ #ifndef CDS_FULLSCREEN @@ -211,6 +212,13 @@ WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool se if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) { driverdata->MonitorHandle = hMonitor; driverdata->IsValid = SDL_TRUE; + + if (!_this->setting_display_mode) { + SDL_ResetDisplayModes(i); + SDL_SetCurrentDisplayMode(&_this->displays[i], &mode); + SDL_SetDesktopDisplayMode(&_this->displays[i], &mode); + SDL_SendDisplayEvent(&_this->displays[i], SDL_DISPLAYEVENT_ORIENTATION, orientation); + } return SDL_FALSE; } } @@ -405,7 +413,7 @@ WIN_GetDisplayModes(_THIS, SDL_VideoDisplay * display) DWORD i; SDL_DisplayMode mode; - for (i = 0;; ++i) { + for (i = 0; ; ++i) { if (!WIN_GetDisplayMode(_this, data->DeviceName, i, &mode, NULL)) { break; }