diff --git a/src/events/SDL_displayevents.c b/src/events/SDL_displayevents.c index cf3694466e..803d24d431 100644 --- a/src/events/SDL_displayevents.c +++ b/src/events/SDL_displayevents.c @@ -53,5 +53,13 @@ int SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent, posted = (SDL_PushEvent(&event) > 0); } + switch (displayevent) { + case SDL_EVENT_DISPLAY_CONNECTED: + SDL_OnDisplayConnected(display); + break; + default: + break; + } + return posted; } diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 5590e941cd..9da28a1c35 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -517,6 +517,7 @@ extern SDL_bool SDL_HasWindows(void); extern void SDL_RelativeToGlobalForWindow(SDL_Window *window, int rel_x, int rel_y, int *abs_x, int *abs_y); extern void SDL_GlobalToRelativeForWindow(SDL_Window *window, int abs_x, int abs_y, int *rel_x, int *rel_y); +extern void SDL_OnDisplayConnected(SDL_VideoDisplay *display); extern void SDL_OnWindowShown(SDL_Window *window); extern void SDL_OnWindowHidden(SDL_Window *window); extern void SDL_OnWindowMoved(SDL_Window *window); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index af6c9194ec..83936dda9a 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -160,6 +160,7 @@ extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window *window); extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window *window, SDL_bool state); #endif +static void SDL_CheckWindowDisplayChanged(SDL_Window *window); static void SDL_CheckWindowDisplayScaleChanged(SDL_Window *window); /* Convenience functions for reading driver flags */ @@ -694,6 +695,16 @@ SDL_DisplayID SDL_AddVideoDisplay(const SDL_VideoDisplay *display, SDL_bool send return id; } +void SDL_OnDisplayConnected(SDL_VideoDisplay *display) +{ + SDL_Window *window; + + /* See if any windows have changed to the new display */ + for (window = _this->windows; window; window = window->next) { + SDL_CheckWindowDisplayChanged(window); + } +} + void SDL_DelVideoDisplay(SDL_DisplayID displayID, SDL_bool send_event) { SDL_VideoDisplay *display; diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c index 79a72daa19..50fa93e0bf 100644 --- a/src/video/windows/SDL_windowsmodes.c +++ b/src/video/windows/SDL_windowsmodes.c @@ -318,7 +318,7 @@ WIN_GetDisplayNameVista_failed: return NULL; } -static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONITORINFOEXW *info, int *display_index, SDL_bool send_event) +static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONITORINFOEXW *info, int *display_index) { int i, index = *display_index; SDL_DisplayID displayID; @@ -356,7 +356,7 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI } driverdata->MonitorHandle = hMonitor; - driverdata->IsValid = SDL_TRUE; + driverdata->state = DisplayUnchanged; if (!_this->setting_display_mode) { SDL_VideoDisplay *existing_display = &_this->displays[i]; @@ -385,7 +385,7 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI } SDL_memcpy(displaydata->DeviceName, info->szDevice, sizeof(displaydata->DeviceName)); displaydata->MonitorHandle = hMonitor; - displaydata->IsValid = SDL_TRUE; + displaydata->state = DisplayAdded; SDL_zero(display); display.name = WIN_GetDisplayNameVista(info->szDevice); @@ -404,8 +404,7 @@ static void WIN_AddDisplay(SDL_VideoDevice *_this, HMONITOR hMonitor, const MONI display.device = _this; display.driverdata = displaydata; WIN_GetDisplayBounds(_this, &display, &displaydata->bounds); - displayID = SDL_AddVideoDisplay(&display, send_event); - SDL_assert(SDL_GetDisplayIndex(displayID) == *display_index); + displayID = SDL_AddVideoDisplay(&display, SDL_FALSE); SDL_free(display.name); done: @@ -416,7 +415,6 @@ typedef struct _WIN_AddDisplaysData { SDL_VideoDevice *video_device; int display_index; - SDL_bool send_event; SDL_bool want_primary; } WIN_AddDisplaysData; @@ -435,7 +433,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->display_index, data->send_event); + WIN_AddDisplay(data->video_device, hMonitor, &info, &data->display_index); } } @@ -443,12 +441,11 @@ static BOOL CALLBACK WIN_AddDisplaysCallback(HMONITOR hMonitor, return TRUE; } -static void WIN_AddDisplays(SDL_VideoDevice *_this, SDL_bool send_event) +static void WIN_AddDisplays(SDL_VideoDevice *_this) { 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; EnumDisplayMonitors(NULL, NULL, WIN_AddDisplaysCallback, (LPARAM)&callback_data); @@ -459,7 +456,7 @@ static void WIN_AddDisplays(SDL_VideoDevice *_this, SDL_bool send_event) int WIN_InitModes(SDL_VideoDevice *_this) { - WIN_AddDisplays(_this, SDL_FALSE); + WIN_AddDisplays(_this); if (_this->num_displays == 0) { return SDL_SetError("No displays available"); @@ -636,22 +633,31 @@ void WIN_RefreshDisplays(SDL_VideoDevice *_this) // entries that have actually been removed for (i = 0; i < _this->num_displays; ++i) { SDL_DisplayData *driverdata = _this->displays[i].driverdata; - driverdata->IsValid = SDL_FALSE; + driverdata->state = DisplayRemoved; } // Enumerate displays to add any new ones and mark still // connected entries as valid - WIN_AddDisplays(_this, SDL_TRUE); + WIN_AddDisplays(_this); // Delete any entries still marked as invalid, iterate // in reverse as each delete takes effect immediately for (i = _this->num_displays - 1; i >= 0; --i) { SDL_VideoDisplay *display = &_this->displays[i]; SDL_DisplayData *driverdata = display->driverdata; - if (driverdata->IsValid == SDL_FALSE) { + if (driverdata->state == DisplayRemoved) { SDL_DelVideoDisplay(display->id, SDL_TRUE); } } + + // Send events for any newly added displays + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + SDL_DisplayData *driverdata = display->driverdata; + if (driverdata->state == DisplayAdded) { + SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_CONNECTED, 0); + } + } } void WIN_QuitModes(SDL_VideoDevice *_this) diff --git a/src/video/windows/SDL_windowsmodes.h b/src/video/windows/SDL_windowsmodes.h index 37ea30426a..31a76026cb 100644 --- a/src/video/windows/SDL_windowsmodes.h +++ b/src/video/windows/SDL_windowsmodes.h @@ -23,11 +23,19 @@ #ifndef SDL_windowsmodes_h_ #define SDL_windowsmodes_h_ +typedef enum +{ + DisplayUnchanged, + DisplayAdded, + DisplayRemoved, + +} WIN_DisplayState; + struct SDL_DisplayData { WCHAR DeviceName[32]; HMONITOR MonitorHandle; - SDL_bool IsValid; + WIN_DisplayState state; SDL_Rect bounds; };