The general code handles restoring video mode/gamma/etc. when the window loses focus. SDL-1.3
authorSam Lantinga <slouken@libsdl.org>
Sun, 09 Jul 2006 18:09:16 +0000
branchSDL-1.3
changeset 1734 f7c667ded87d
parent 1733 0b1070f2f94d
child 1735 8dd28c4ef746
The general code handles restoring video mode/gamma/etc. when the window loses focus. Support for changing fullscreen/windowed mode in progress.
include/SDL_video.h
src/SDL_compat.c
src/events/SDL_windowevents.c
src/video/SDL_gamma.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/win32/SDL_win32events.c
src/video/win32/SDL_win32window.c
--- a/include/SDL_video.h	Sun Jul 09 09:02:26 2006 +0000
+++ b/include/SDL_video.h	Sun Jul 09 18:09:16 2006 +0000
@@ -125,7 +125,7 @@
     SDL_WINDOW_MINIMIZED = 0x00000020,          /**< minimized */
     SDL_WINDOW_MAXIMIZED = 0x00000040,          /**< maximized */
     SDL_WINDOW_INPUT_GRABBED = 0x00000100,      /**< window has grabbed input focus */
-    SDL_WINDOW_KEYBOARD_FOCUS = 0x00000200,     /**< window has keyboard focus */
+    SDL_WINDOW_INPUT_FOCUS = 0x00000200,        /**< window has input focus */
     SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
 } SDL_WindowFlags;
 
@@ -734,7 +734,7 @@
 /**
  * \fn void SDL_RaiseWindow(SDL_WindowID windowID)
  *
- * \brief Raise the window so it's above other windows.
+ * \brief Raise the window above other windows and set the input focus.
  */
 extern DECLSPEC void SDLCALL SDL_RaiseWindow(SDL_WindowID windowID);
 
--- a/src/SDL_compat.c	Sun Jul 09 09:02:26 2006 +0000
+++ b/src/SDL_compat.c	Sun Jul 09 18:09:16 2006 +0000
@@ -699,7 +699,18 @@
 int
 SDL_WM_ToggleFullScreen(SDL_Surface * surface)
 {
-    return 0;
+    if (SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN) {
+        if (SDL_SetWindowFullscreen(SDL_VideoWindow, 0) < 0) {
+            return 0;
+        }
+        SDL_PublicSurface->flags &= ~SDL_FULLSCREEN;
+    } else {
+        if (SDL_SetWindowFullscreen(SDL_VideoWindow, 1) < 0) {
+            return 0;
+        }
+        SDL_PublicSurface->flags |= SDL_FULLSCREEN;
+    }
+    return 1;
 }
 
 SDL_GrabMode
@@ -727,7 +738,7 @@
     if ((flags & SDL_WINDOW_SHOWN) && !(flags & SDL_WINDOW_MINIMIZED)) {
         state |= SDL_APPACTIVE;
     }
-    if (flags & SDL_WINDOW_KEYBOARD_FOCUS) {
+    if (flags & SDL_WINDOW_INPUT_FOCUS) {
         state |= SDL_APPINPUTFOCUS;
     }
     if (flags & SDL_WINDOW_MOUSE_FOCUS) {
--- a/src/events/SDL_windowevents.c	Sun Jul 09 09:02:26 2006 +0000
+++ b/src/events/SDL_windowevents.c	Sun Jul 09 18:09:16 2006 +0000
@@ -100,17 +100,17 @@
         window->flags &= ~SDL_WINDOW_MOUSE_FOCUS;
         break;
     case SDL_WINDOWEVENT_FOCUS_GAINED:
-        if (window->flags & SDL_WINDOW_KEYBOARD_FOCUS) {
+        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
             return 0;
         }
-        window->flags |= SDL_WINDOW_KEYBOARD_FOCUS;
+        window->flags |= SDL_WINDOW_INPUT_FOCUS;
         SDL_OnWindowFocusGained(window);
         break;
     case SDL_WINDOWEVENT_FOCUS_LOST:
-        if (!(window->flags & SDL_WINDOW_KEYBOARD_FOCUS)) {
+        if (!(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
             return 0;
         }
-        window->flags &= ~SDL_WINDOW_KEYBOARD_FOCUS;
+        window->flags &= ~SDL_WINDOW_INPUT_FOCUS;
         SDL_OnWindowFocusLost(window);
         break;
     }
--- a/src/video/SDL_gamma.c	Sun Jul 09 09:02:26 2006 +0000
+++ b/src/video/SDL_gamma.c	Sun Jul 09 18:09:16 2006 +0000
@@ -152,8 +152,12 @@
     /* Try to set the gamma ramp in the driver */
     succeeded = -1;
     if (_this && _this->SetDisplayGammaRamp) {
-        succeeded =
-            _this->SetDisplayGammaRamp(_this, SDL_CurrentDisplay.gamma);
+        if (SDL_GetFocusWindow()) {
+            succeeded =
+                _this->SetDisplayGammaRamp(_this, SDL_CurrentDisplay.gamma);
+        } else {
+            succeeded = 0;
+        }
     } else {
         SDL_SetError("Gamma ramp manipulation not supported");
     }
--- a/src/video/SDL_sysvideo.h	Sun Jul 09 09:02:26 2006 +0000
+++ b/src/video/SDL_sysvideo.h	Sun Jul 09 18:09:16 2006 +0000
@@ -124,9 +124,9 @@
     void *driverdata;
 };
 #define FULLSCREEN_VISIBLE(W) \
-    ((W->flags & SDL_WINDOW_FULLSCREEN) && \
-     (W->flags & SDL_WINDOW_SHOWN) && \
-     !(W->flags & SDL_WINDOW_MINIMIZED))
+    (((W)->flags & SDL_WINDOW_FULLSCREEN) && \
+     ((W)->flags & SDL_WINDOW_SHOWN) && \
+     !((W)->flags & SDL_WINDOW_MINIMIZED))
 
 /* Define the SDL display structure
    This corresponds to physical monitors attached to the system.
@@ -425,6 +425,7 @@
 extern void SDL_OnWindowHidden(SDL_Window * window);
 extern void SDL_OnWindowFocusGained(SDL_Window * window);
 extern void SDL_OnWindowFocusLost(SDL_Window * window);
+extern SDL_WindowID SDL_GetFocusWindow(void);
 
 #endif /* _SDL_sysvideo_h */
 
--- a/src/video/SDL_video.c	Sun Jul 09 09:02:26 2006 +0000
+++ b/src/video/SDL_video.c	Sun Jul 09 18:09:16 2006 +0000
@@ -712,6 +712,7 @@
                                   SDL_WINDOW_MAXIMIZED |
                                   SDL_WINDOW_MINIMIZED |
                                   SDL_WINDOW_INPUT_GRABBED);
+    SDL_VideoDisplay *display;
     SDL_Window window;
     int num_windows;
     SDL_Window *windows;
@@ -724,14 +725,8 @@
     SDL_zero(window);
     window.id = _this->next_object_id++;
     window.title = title ? SDL_strdup(title) : NULL;
-    if (flags & SDL_WINDOW_FULLSCREEN) {
-        const SDL_DisplayMode *mode = &SDL_CurrentDisplay.current_mode;
-        window.x = (mode->w - w) / 2;
-        window.y = (mode->h - h) / 2;
-    } else {
-        window.x = x;
-        window.y = y;
-    }
+    window.x = x;
+    window.y = y;
     window.w = w;
     window.h = h;
     window.flags = (flags & allowed_flags);
@@ -744,10 +739,10 @@
         return 0;
     }
 
-    num_windows = SDL_CurrentDisplay.num_windows;
+    display = &SDL_CurrentDisplay;
+    num_windows = display->num_windows;
     windows =
-        SDL_realloc(SDL_CurrentDisplay.windows,
-                    (num_windows + 1) * sizeof(*windows));
+        SDL_realloc(display->windows, (num_windows + 1) * sizeof(*windows));
     if (!windows) {
         if (_this->DestroyWindow) {
             _this->DestroyWindow(_this, &window);
@@ -758,8 +753,20 @@
         return 0;
     }
     windows[num_windows] = window;
-    SDL_CurrentDisplay.windows = windows;
-    SDL_CurrentDisplay.num_windows++;
+    display->windows = windows;
+    display->num_windows++;
+
+    if (FULLSCREEN_VISIBLE(&window)) {
+        /* Hide any other fullscreen windows */
+        int i;
+        for (i = 0; i < display->num_windows; ++i) {
+            SDL_Window *other = &display->windows[i];
+            if (other->id != window.id && FULLSCREEN_VISIBLE(other)) {
+                SDL_MinimizeWindow(other->id);
+            }
+        }
+        SDL_SetDisplayMode(display->fullscreen_mode);
+    }
 
     return window.id;
 }
@@ -767,6 +774,7 @@
 SDL_WindowID
 SDL_CreateWindowFrom(const void *data)
 {
+    SDL_VideoDisplay *display;
     SDL_Window window;
     int num_windows;
     SDL_Window *windows;
@@ -785,10 +793,10 @@
         return 0;
     }
 
-    num_windows = SDL_CurrentDisplay.num_windows;
+    display = &SDL_CurrentDisplay;
+    num_windows = display->num_windows;
     windows =
-        SDL_realloc(SDL_CurrentDisplay.windows,
-                    (num_windows + 1) * sizeof(*windows));
+        SDL_realloc(display->windows, (num_windows + 1) * sizeof(*windows));
     if (!windows) {
         if (_this->DestroyWindow) {
             _this->DestroyWindow(_this, &window);
@@ -799,8 +807,8 @@
         return 0;
     }
     windows[num_windows] = window;
-    SDL_CurrentDisplay.windows = windows;
-    SDL_CurrentDisplay.num_windows++;
+    display->windows = windows;
+    display->num_windows++;
 
     return window.id;
 }
@@ -1062,6 +1070,48 @@
     }
 }
 
+int
+SDL_SetWindowFullscreen(SDL_WindowID windowID, int fullscreen)
+{
+    SDL_Window *window = SDL_GetWindowFromID(windowID);
+
+    if (!window) {
+        return -1;
+    }
+
+    if (fullscreen) {
+        fullscreen = SDL_WINDOW_FULLSCREEN;
+    }
+    if ((window->flags & SDL_WINDOW_FULLSCREEN) == fullscreen) {
+        return 0;
+    }
+
+    if (fullscreen) {
+        window->flags |= SDL_WINDOW_FULLSCREEN;
+
+        if (FULLSCREEN_VISIBLE(window)) {
+            SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
+
+            /* Hide any other fullscreen windows */
+            int i;
+            for (i = 0; i < display->num_windows; ++i) {
+                SDL_Window *other = &display->windows[i];
+                if (other->id != windowID && FULLSCREEN_VISIBLE(other)) {
+                    SDL_MinimizeWindow(other->id);
+                }
+            }
+
+            SDL_SetDisplayMode(display->fullscreen_mode);
+        }
+    } else {
+        window->flags &= ~SDL_WINDOW_FULLSCREEN;
+
+        if (FULLSCREEN_VISIBLE(window)) {
+            SDL_SetDisplayMode(NULL);
+        }
+    }
+}
+
 void
 SDL_SetWindowGrab(SDL_WindowID windowID, int mode)
 {
@@ -1077,7 +1127,7 @@
         window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
     }
 
-    if (_this->SetWindowGrab) {
+    if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) {
         _this->SetWindowGrab(_this, window);
     }
 }
@@ -1115,6 +1165,9 @@
     if (display->gamma && _this->SetDisplayGammaRamp) {
         _this->SetDisplayGammaRamp(_this, display->gamma);
     }
+    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && _this->SetWindowGrab) {
+        _this->SetWindowGrab(_this, window);
+    }
 }
 
 void
@@ -1123,12 +1176,36 @@
     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
 
     if (window->flags & SDL_WINDOW_FULLSCREEN) {
+        SDL_MinimizeWindow(window->id);
         SDL_SetDisplayMode(NULL);
-        SDL_MinimizeWindow(window->id);
     }
     if (display->gamma && _this->SetDisplayGammaRamp) {
         _this->SetDisplayGammaRamp(_this, display->saved_gamma);
     }
+    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && _this->SetWindowGrab) {
+        _this->SetWindowGrab(_this, window);
+    }
+}
+
+SDL_WindowID
+SDL_GetFocusWindow(void)
+{
+    SDL_VideoDisplay *display;
+    int i;
+
+    if (!_this) {
+        return 0;
+    }
+
+    display = &SDL_CurrentDisplay;
+    for (i = 0; i < display->num_windows; ++i) {
+        SDL_Window *window = &display->windows[i];
+
+        if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
+            return window->id;
+        }
+    }
+    return 0;
 }
 
 void
@@ -1140,6 +1217,9 @@
         return;
     }
 
+    /* Restore video mode, etc. */
+    SDL_SendWindowEvent(windowID, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
+
     for (i = 0; i < _this->num_displays; ++i) {
         SDL_VideoDisplay *display = &_this->displays[i];
         for (j = 0; j < display->num_windows; ++j) {
@@ -1147,16 +1227,6 @@
             if (window->id != windowID) {
                 continue;
             }
-            if (window->flags & SDL_WINDOW_FULLSCREEN) {
-                SDL_SetDisplayMode(NULL);
-            }
-            if (display->gamma && _this->SetDisplayGammaRamp) {
-                _this->SetDisplayGammaRamp(_this, display->saved_gamma);
-            }
-            if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
-                window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
-                _this->SetWindowGrab(_this, window);
-            }
             if (window->renderer) {
                 SDL_DestroyRenderer(window->id);
             }
--- a/src/video/win32/SDL_win32events.c	Sun Jul 09 09:02:26 2006 +0000
+++ b/src/video/win32/SDL_win32events.c	Sun Jul 09 18:09:16 2006 +0000
@@ -453,26 +453,11 @@
                 }
                 if (keyboard && keyboard->focus != data->windowID) {
                     SDL_SetKeyboardFocus(index, data->windowID);
-
-                    if (SDL_GetWindowFlags(data->windowID) &
-                        SDL_WINDOW_INPUT_GRABBED) {
-                        RECT rect;
-
-                        GetClientRect(hwnd, &rect);
-                        ClientToScreen(hwnd, (LPPOINT) & rect);
-                        ClientToScreen(hwnd, (LPPOINT) & rect + 1);
-                        ClipCursor(&rect);
-                    }
                 }
                 /* FIXME: Update keyboard state */
             } else {
                 if (keyboard && keyboard->focus == data->windowID) {
                     SDL_SetKeyboardFocus(index, 0);
-
-                    if (SDL_GetWindowFlags(data->windowID) &
-                        SDL_WINDOW_INPUT_GRABBED) {
-                        ClipCursor(NULL);
-                    }
                 }
                 if (minimized) {
                     SDL_SendWindowEvent(data->windowID,
@@ -782,7 +767,7 @@
 
             window_flags = SDL_GetWindowFlags(data->windowID);
             if ((window_flags & SDL_WINDOW_INPUT_GRABBED) &&
-                (window_flags & SDL_WINDOW_KEYBOARD_FOCUS)) {
+                (window_flags & SDL_WINDOW_INPUT_FOCUS)) {
                 ClipCursor(&rect);
             }
 
--- a/src/video/win32/SDL_win32window.c	Sun Jul 09 09:02:26 2006 +0000
+++ b/src/video/win32/SDL_win32window.c	Sun Jul 09 18:09:16 2006 +0000
@@ -109,7 +109,7 @@
     }
     if (GetFocus() == hwnd) {
         int index = data->videodata->keyboard;
-        window->flags |= SDL_WINDOW_KEYBOARD_FOCUS;
+        window->flags |= SDL_WINDOW_INPUT_FOCUS;
         SDL_SetKeyboardFocus(index, data->windowID);
 
         if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
@@ -390,20 +390,15 @@
 {
     HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
 
-    if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
-        if (window->flags & SDL_WINDOW_KEYBOARD_FOCUS) {
-            RECT rect;
-            GetClientRect(hwnd, &rect);
-            ClientToScreen(hwnd, (LPPOINT) & rect);
-            ClientToScreen(hwnd, (LPPOINT) & rect + 1);
-            ClipCursor(&rect);
-        } else {
-            SetFocus(hwnd);
-        }
+    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
+        (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
+        RECT rect;
+        GetClientRect(hwnd, &rect);
+        ClientToScreen(hwnd, (LPPOINT) & rect);
+        ClientToScreen(hwnd, (LPPOINT) & rect + 1);
+        ClipCursor(&rect);
     } else {
-        if (window->flags & SDL_WINDOW_KEYBOARD_FOCUS) {
-            ClipCursor(NULL);
-        }
+        ClipCursor(NULL);
     }
 }