Update the orientation and display modes when the display settings change on Windows Fixes https://github.com/libsdl-org/SDL/issues/1061
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index d57731e..bbe4eab 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 573b6af..276c067 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 3abb5d4..b9a4ac0 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;
}