Added SDL_DISPLAYEVENT_MOVED to detect when display positioning changes
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
diff --git a/WhatsNew.txt b/WhatsNew.txt
index 1f95f05..14c37c1 100644
--- a/WhatsNew.txt
+++ b/WhatsNew.txt
@@ -2,6 +2,14 @@
This is a list of major changes in SDL's version history.
---------------------------------------------------------------------------
+2.28.0:
+---------------------------------------------------------------------------
+
+General:
+* Added a display event SDL_DISPLAYEVENT_MOVED which is sent when the primary monitor changes or displays change position relative to each other
+
+
+---------------------------------------------------------------------------
2.26.0:
---------------------------------------------------------------------------
diff --git a/include/SDL_video.h b/include/SDL_video.h
index b2f1509..25ce98a 100644
--- a/include/SDL_video.h
+++ b/include/SDL_video.h
@@ -187,7 +187,8 @@ typedef enum
SDL_DISPLAYEVENT_NONE, /**< Never used */
SDL_DISPLAYEVENT_ORIENTATION, /**< Display orientation has changed to data1 */
SDL_DISPLAYEVENT_CONNECTED, /**< Display has been added to the system */
- SDL_DISPLAYEVENT_DISCONNECTED /**< Display has been removed from the system */
+ SDL_DISPLAYEVENT_DISCONNECTED, /**< Display has been removed from the system */
+ SDL_DISPLAYEVENT_MOVED /**< Display has changed position */
} SDL_DisplayEventID;
/**
diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c
index 8250232..8748f26 100644
--- a/src/video/windows/SDL_windowsmodes.c
+++ b/src/video/windows/SDL_windowsmodes.c
@@ -294,9 +294,9 @@ WIN_GetDisplayNameVista_failed:
return NULL;
}
-static SDL_bool WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, SDL_bool send_event)
+static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info, int *display_index, SDL_bool send_event)
{
- int i;
+ int i, index = *display_index;
SDL_VideoDisplay display;
SDL_DisplayData *displaydata;
SDL_DisplayMode mode;
@@ -307,7 +307,7 @@ static SDL_bool WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *i
#endif
if (!WIN_GetDisplayMode(_this, info->szDevice, ENUM_CURRENT_SETTINGS, &mode, &orientation)) {
- return SDL_FALSE;
+ return;
}
// Prevent adding duplicate displays. Do this after we know the display is
@@ -316,22 +316,41 @@ static SDL_bool WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *i
for (i = 0; i < _this->num_displays; ++i) {
SDL_DisplayData *driverdata = (SDL_DisplayData *)_this->displays[i].driverdata;
if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) {
+ SDL_bool moved = (index != i);
+
+ if (moved) {
+ SDL_VideoDisplay tmp;
+
+ SDL_assert(index < _this->num_displays);
+ SDL_memcpy(&tmp, &_this->displays[index], sizeof(tmp));
+ SDL_memcpy(&_this->displays[index], &_this->displays[i], sizeof(tmp));
+ SDL_memcpy(&_this->displays[i], &tmp, sizeof(tmp));
+ i = index;
+ }
+
driverdata->MonitorHandle = hMonitor;
driverdata->IsValid = SDL_TRUE;
if (!_this->setting_display_mode) {
+ SDL_Rect bounds;
+
SDL_ResetDisplayModes(i);
SDL_SetCurrentDisplayMode(&_this->displays[i], &mode);
SDL_SetDesktopDisplayMode(&_this->displays[i], &mode);
+ if (WIN_GetDisplayBounds(_this, &_this->displays[i], &bounds) == 0) {
+ if (SDL_memcmp(&driverdata->bounds, &bounds, sizeof(bounds)) != 0 || moved) {
+ SDL_SendDisplayEvent(&_this->displays[i], SDL_DISPLAYEVENT_MOVED, 0);
+ }
+ }
SDL_SendDisplayEvent(&_this->displays[i], SDL_DISPLAYEVENT_ORIENTATION, orientation);
}
- return SDL_FALSE;
+ goto done;
}
}
displaydata = (SDL_DisplayData *)SDL_calloc(1, sizeof(*displaydata));
if (displaydata == NULL) {
- return SDL_FALSE;
+ return;
}
SDL_memcpy(displaydata->DeviceName, info->szDevice, sizeof(displaydata->DeviceName));
displaydata->MonitorHandle = hMonitor;
@@ -351,15 +370,21 @@ static SDL_bool WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *i
display.desktop_mode = mode;
display.current_mode = mode;
display.orientation = orientation;
+ display.device = _this;
display.driverdata = displaydata;
- SDL_AddVideoDisplay(&display, send_event);
+ WIN_GetDisplayBounds(_this, &display, &displaydata->bounds);
+ index = SDL_AddVideoDisplay(&display, send_event);
+ SDL_assert(index == *display_index);
SDL_free(display.name);
- return SDL_TRUE;
+
+done:
+ *display_index += 1;
}
typedef struct _WIN_AddDisplaysData
{
SDL_VideoDevice *video_device;
+ int display_index;
SDL_bool send_event;
SDL_bool want_primary;
} WIN_AddDisplaysData;
@@ -379,7 +404,7 @@ static BOOL CALLBACK WIN_AddDisplaysCallback(HMONITOR hMonitor,
const SDL_bool is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY);
if (is_primary == data->want_primary) {
- WIN_AddDisplay(data->video_device, hMonitor, &info, data->send_event);
+ WIN_AddDisplay(data->video_device, hMonitor, &info, &data->display_index, data->send_event);
}
}
@@ -391,6 +416,7 @@ static void WIN_AddDisplays(_THIS, SDL_bool send_event)
{
WIN_AddDisplaysData callback_data;
callback_data.video_device = _this;
+ callback_data.display_index = 0;
callback_data.send_event = send_event;
callback_data.want_primary = SDL_TRUE;
diff --git a/src/video/windows/SDL_windowsmodes.h b/src/video/windows/SDL_windowsmodes.h
index fd586ed..c687fc9 100644
--- a/src/video/windows/SDL_windowsmodes.h
+++ b/src/video/windows/SDL_windowsmodes.h
@@ -28,6 +28,7 @@ typedef struct
WCHAR DeviceName[32];
HMONITOR MonitorHandle;
SDL_bool IsValid;
+ SDL_Rect bounds;
} SDL_DisplayData;
typedef struct