From 6b87d1938fe57a889157beaf48d1626df295bc53 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 3 Mar 2023 11:03:50 -0800
Subject: [PATCH] Added SDL_EVENT_DISPLAY_SCALE_CHANGED
---
include/SDL3/SDL_events.h | 3 ++-
src/events/SDL_displayevents.c | 2 +-
src/events/SDL_events.c | 1 +
src/test/SDL_test_common.c | 11 +++++++++++
src/video/SDL_video.c | 6 ++++++
src/video/windows/SDL_windowsmodes.c | 13 +++++++++----
6 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h
index 4ecd83403754..8e35e283efc0 100644
--- a/include/SDL3/SDL_events.h
+++ b/include/SDL3/SDL_events.h
@@ -93,8 +93,9 @@ typedef enum
SDL_EVENT_DISPLAY_CONNECTED, /**< Display has been added to the system */
SDL_EVENT_DISPLAY_DISCONNECTED, /**< Display has been removed from the system */
SDL_EVENT_DISPLAY_MOVED, /**< Display has changed position */
+ SDL_EVENT_DISPLAY_SCALE_CHANGED, /**< Display has changed desktop display scale */
SDL_EVENT_DISPLAY_FIRST = SDL_EVENT_DISPLAY_ORIENTATION,
- SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_DISCONNECTED,
+ SDL_EVENT_DISPLAY_LAST = SDL_EVENT_DISPLAY_SCALE_CHANGED,
/* Window events */
/* 0x200 was SDL_WINDOWEVENT, reserve the number for sdl2-compat */
diff --git a/src/events/SDL_displayevents.c b/src/events/SDL_displayevents.c
index 10d7bdcce6af..cf3694466ea0 100644
--- a/src/events/SDL_displayevents.c
+++ b/src/events/SDL_displayevents.c
@@ -28,7 +28,7 @@ int SDL_SendDisplayEvent(SDL_VideoDisplay *display, SDL_EventType displayevent,
{
int posted;
- if (display == NULL) {
+ if (display == NULL || display->id == 0) {
return 0;
}
switch (displayevent) {
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index ef5b43f4d889..87152d0e6485 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -223,6 +223,7 @@ static void SDL_LogEvent(const SDL_Event *event)
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_CONNECTED);
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_DISCONNECTED);
SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_MOVED);
+ SDL_DISPLAYEVENT_CASE(SDL_EVENT_DISPLAY_SCALE_CHANGED);
#undef SDL_DISPLAYEVENT_CASE
#define SDL_WINDOWEVENT_CASE(x) \
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index b85d5ede53ad..47cc0bbb731e 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -1511,6 +1511,17 @@ static void SDLTest_PrintEvent(SDL_Event *event)
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " connected",
event->display.displayID);
break;
+ case SDL_EVENT_DISPLAY_SCALE_CHANGED:
+ {
+ float display_scale = 1.0f;
+ const SDL_DisplayMode *mode = SDL_GetDesktopDisplayMode(event->display.displayID);
+ if (mode) {
+ display_scale = mode->display_scale;
+ }
+ SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed scale to %d%%",
+ event->display.displayID, (int)(display_scale * 100.0f));
+ }
+ break;
case SDL_EVENT_DISPLAY_MOVED:
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed position",
event->display.displayID);
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 0d9aaa322279..742b4fc2c759 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -1077,9 +1077,15 @@ const SDL_DisplayMode *SDL_GetClosestFullscreenDisplayMode(SDL_DisplayID display
void SDL_SetDesktopDisplayMode(SDL_VideoDisplay *display, const SDL_DisplayMode *mode)
{
+ float display_scale = display->desktop_mode.display_scale;
+
SDL_memcpy(&display->desktop_mode, mode, sizeof(*mode));
display->desktop_mode.displayID = display->id;
SDL_FinalizeDisplayMode(&display->desktop_mode);
+
+ if (display_scale != display->desktop_mode.display_scale) {
+ SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_SCALE_CHANGED, 0);
+ }
}
const SDL_DisplayMode *SDL_GetDesktopDisplayMode(SDL_DisplayID displayID)
diff --git a/src/video/windows/SDL_windowsmodes.c b/src/video/windows/SDL_windowsmodes.c
index af0962c3a60b..0da179e82ad8 100644
--- a/src/video/windows/SDL_windowsmodes.c
+++ b/src/video/windows/SDL_windowsmodes.c
@@ -324,6 +324,7 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info,
SDL_DisplayData *driverdata = _this->displays[i].driverdata;
if (SDL_wcscmp(driverdata->DeviceName, info->szDevice) == 0) {
SDL_bool moved = (index != i);
+ SDL_bool changed_bounds = SDL_FALSE;
if (moved) {
SDL_VideoDisplay tmp;
@@ -343,10 +344,14 @@ static void WIN_AddDisplay(_THIS, HMONITOR hMonitor, const MONITORINFOEXW *info,
SDL_Rect bounds;
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);
- }
+ SDL_SetDesktopDisplayMode(existing_display, &mode);
+ if (WIN_GetDisplayBounds(_this, existing_display, &bounds) == 0 &&
+ SDL_memcmp(&driverdata->bounds, &bounds, sizeof(bounds)) != 0) {
+ changed_bounds = SDL_TRUE;
+ SDL_copyp(&driverdata->bounds, &bounds);
+ }
+ if (moved || changed_bounds) {
+ SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_MOVED, 0);
}
SDL_SendDisplayEvent(existing_display, SDL_EVENT_DISPLAY_ORIENTATION, orientation);
}