SDL: video: Add video device quirk flags and apply them to the video subsystem

From cc9cc2028dd06a43dca0910a66b348dd83e2a6e3 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Sat, 13 Aug 2022 16:43:15 -0400
Subject: [PATCH] video: Add video device quirk flags and apply them to the
 video subsystem

Add quirk flags to the video device struct and add flags to allow video backend drivers to disable mode switching and disable unsetting the fullscreen mode when minimizing a window. As certain platforms can have multiple video backends compiled in at once, #ifdefs, as used by other platforms, aren't suitable as different backends on the same platform may not need the same quirks.

This replaces the formerly dedicated 'disable_display_mode_switching' boolean as additional quirks are needed by the Wayland backend.  Helper functions have also been added to simplify reading the flag states.
---
 src/video/SDL_sysvideo.h             |  8 +++++++-
 src/video/SDL_video.c                | 24 ++++++++++++++++++++----
 src/video/wayland/SDL_waylandvideo.c |  2 +-
 3 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h
index cf0ab8c440b..4ea7705e959 100644
--- a/src/video/SDL_sysvideo.h
+++ b/src/video/SDL_sysvideo.h
@@ -149,6 +149,12 @@ struct SDL_SysWMinfo;
 /* Define the SDL video driver structure */
 #define _THIS   SDL_VideoDevice *_this
 
+/* Video device flags */
+typedef enum {
+    VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING       = 0x01,
+    VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE = 0x02,
+} DeviceQuirkFlags;
+
 struct SDL_VideoDevice
 {
     /* * * */
@@ -347,7 +353,7 @@ struct SDL_VideoDevice
     Uint32 next_object_id;
     char *clipboard_text;
     SDL_bool setting_display_mode;
-    SDL_bool disable_display_mode_switching;
+    Uint32 quirk_flags;
 
     /* * * */
     /* Data used by the GL drivers */
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index 4aeadc07152..21c516265f7 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -166,6 +166,18 @@ extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window);
 extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state);
 #endif
 
+/* Convenience functions for reading driver flags */
+static SDL_bool
+DisableDisplayModeSwitching(_THIS)
+{
+    return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING);
+}
+
+static SDL_bool
+DisableUnsetFullscreenOnMinimize(_THIS)
+{
+    return !!(_this->quirk_flags & VIDEO_DEVICE_QUIRK_DISABLE_UNSET_FULLSCREEN_ON_MINIMIZE);
+}
 
 /* Support for framebuffer emulation using an accelerated renderer */
 
@@ -1419,7 +1431,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen)
                 }
 
                 /* Don't try to change the display mode if the driver doesn't want it. */
-                if (_this->disable_display_mode_switching == SDL_FALSE) {
+                if (DisableDisplayModeSwitching(_this) == SDL_FALSE) {
                     /* only do the mode change if we want exclusive fullscreen */
                     if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
                         if (SDL_SetDisplayModeForDisplay(display, &fullscreen_mode) < 0) {
@@ -2524,7 +2536,9 @@ SDL_MinimizeWindow(SDL_Window * window)
         return;
     }
 
-    SDL_UpdateFullscreenMode(window, SDL_FALSE);
+    if (!DisableUnsetFullscreenOnMinimize(_this)) {
+        SDL_UpdateFullscreenMode(window, SDL_FALSE);
+    }
 
     if (_this->MinimizeWindow) {
         _this->MinimizeWindow(_this, window);
@@ -3072,7 +3086,9 @@ SDL_OnWindowMoved(SDL_Window * window)
 void
 SDL_OnWindowMinimized(SDL_Window * window)
 {
-    SDL_UpdateFullscreenMode(window, SDL_FALSE);
+    if (!DisableUnsetFullscreenOnMinimize(_this)) {
+        SDL_UpdateFullscreenMode(window, SDL_FALSE);
+    }
 }
 
 void
@@ -3153,7 +3169,7 @@ ShouldMinimizeOnFocusLoss(SDL_Window * window)
     hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS);
     if (!hint || !*hint || SDL_strcasecmp(hint, "auto") == 0) {
         if ((window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP ||
-            _this->disable_display_mode_switching == SDL_TRUE) {
+            DisableDisplayModeSwitching(_this) == SDL_TRUE) {
             return SDL_FALSE;
         } else {
             return SDL_TRUE;
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 267812417c1..10186a20ec7 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -279,7 +279,7 @@ Wayland_CreateDevice(void)
 
     device->free = Wayland_DeleteDevice;
 
-    device->disable_display_mode_switching = SDL_TRUE;
+    device->quirk_flags = VIDEO_DEVICE_QUIRK_DISABLE_DISPLAY_MODE_SWITCHING;
 
     return device;
 }