Fixed bug 5147 - KMSDRM: SetWindowFullscreen() failing with SDL_WINDOW_FULLSCREEN_DESKTOP

Manuel Alfayate Corchete

This patch is needed so programs that do this work as expected:
1) Start in a different video mode than the mode used by the system and then...
2) Try to go fullscreen with the mode originally used by the system via SetWindowFullScreen() with the SDL_WINDOW_FULLSCREEN_DESKTOP flag.

An example would be pt2-clone in https://github.com/8bitbubsy/pt2-clone.
This program does this:

Starts with:

video.window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED,
    SDL_WINDOWPOS_CENTERED, screenW, screenH, windowFlags);


and then, *IF* the user has configured it in fullscreen mode in its .ini, it tries to go fullscreen with the desktop mode:

SDL_SetWindowFullscreen(video.window, SDL_WINDOW_FULLSCREEN_DESKTOP);


This sequence of operations is currently failing because SDL_SetDisplayModeForDisplay() in SDL_video.c fails because display->desktop_mode is not being initialized with its correct value: SetDisplayMode() in SDL_kmsdrmvideo.c will not be able to set the mode because it detects the mode to have a driverdata of 0x0 ("if (!modedata)") and rightfully returns an error.

So, the included patch fixes this small problem, and programs that first change the video mode and then try to go fullscreen with the system video mode will now work.
The patch simply fixes an small omission, but its really needed now that dynamic video mode changing was implemented on the KMSDRM backend.
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index 608bee5..e00f959 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -601,6 +601,19 @@
     display.desktop_mode.format = drmToSDLPixelFormat(fb->bpp, fb->depth);
     drmModeFreeFB(fb);
 #endif
+
+    /* DRM mode index for the desktop mode is needed to complete desktop mode init NOW,
+       so look for it in the DRM modes array. */
+    for (int i = 0; i < dispdata->conn->count_modes; i++) {
+        if (!SDL_memcmp(dispdata->conn->modes + i, &dispdata->saved_crtc->mode, sizeof(drmModeModeInfo))) {
+            SDL_DisplayModeData *modedata = SDL_calloc(1, sizeof(SDL_DisplayModeData));
+            if (modedata) {
+                modedata->mode_index = i;
+                display.desktop_mode.driverdata = modedata;
+            }   
+        }   
+    }   
+
     display.current_mode = display.desktop_mode;
     display.driverdata = dispdata;
     SDL_AddVideoDisplay(&display);
@@ -760,7 +773,6 @@
 {
     SDL_VideoData *viddata = (SDL_VideoData *)_this->driverdata;
     SDL_WindowData *windata;
-    SDL_VideoDisplay *display;
 
 #if SDL_VIDEO_OPENGL_EGL
     if (!_this->egl_data) {
@@ -778,14 +790,6 @@
         goto error;
     }
 
-    /* Windows have one size for now */
-    display = SDL_GetDisplayForWindow(window);
-    window->w = display->desktop_mode.w;
-    window->h = display->desktop_mode.h;
-
-    /* Maybe you didn't ask for a fullscreen OpenGL window, but that's what you get */
-    window->flags |= (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
-
     /* In case low-latency is wanted, double-buffered video will be used. We take note here */
     windata->double_buffer = SDL_FALSE;