Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
The general code handles restoring video mode/gamma/etc. when the win…
Browse files Browse the repository at this point in the history
…dow loses focus.

Support for changing fullscreen/windowed mode in progress.
  • Loading branch information
slouken committed Jul 9, 2006
1 parent d8b35a1 commit e7293b1
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 73 deletions.
4 changes: 2 additions & 2 deletions include/SDL_video.h
Expand Up @@ -125,7 +125,7 @@ typedef enum
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;

Expand Down Expand Up @@ -734,7 +734,7 @@ extern DECLSPEC void SDLCALL SDL_HideWindow(SDL_WindowID windowID);
/**
* \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);

Expand Down
15 changes: 13 additions & 2 deletions src/SDL_compat.c
Expand Up @@ -699,7 +699,18 @@ SDL_WM_IconifyWindow(void)
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
Expand Down Expand Up @@ -727,7 +738,7 @@ SDL_GetAppState(void)
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) {
Expand Down
8 changes: 4 additions & 4 deletions src/events/SDL_windowevents.c
Expand Up @@ -100,17 +100,17 @@ SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1,
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;
}
Expand Down
8 changes: 6 additions & 2 deletions src/video/SDL_gamma.c
Expand Up @@ -152,8 +152,12 @@ SDL_SetGammaRamp(const Uint16 * red, const Uint16 * green,
/* 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");
}
Expand Down
7 changes: 4 additions & 3 deletions src/video/SDL_sysvideo.h
Expand Up @@ -124,9 +124,9 @@ struct SDL_Window
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.
Expand Down Expand Up @@ -425,6 +425,7 @@ extern void SDL_OnWindowShown(SDL_Window * window);
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 */

Expand Down
130 changes: 100 additions & 30 deletions src/video/SDL_video.c
Expand Up @@ -712,6 +712,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
SDL_WINDOW_MAXIMIZED |
SDL_WINDOW_MINIMIZED |
SDL_WINDOW_INPUT_GRABBED);
SDL_VideoDisplay *display;
SDL_Window window;
int num_windows;
SDL_Window *windows;
Expand All @@ -724,14 +725,8 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
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);
Expand All @@ -744,10 +739,10 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
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);
Expand All @@ -758,15 +753,28 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
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;
}

SDL_WindowID
SDL_CreateWindowFrom(const void *data)
{
SDL_VideoDisplay *display;
SDL_Window window;
int num_windows;
SDL_Window *windows;
Expand All @@ -785,10 +793,10 @@ SDL_CreateWindowFrom(const void *data)
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);
Expand All @@ -799,8 +807,8 @@ SDL_CreateWindowFrom(const void *data)
return 0;
}
windows[num_windows] = window;
SDL_CurrentDisplay.windows = windows;
SDL_CurrentDisplay.num_windows++;
display->windows = windows;
display->num_windows++;

return window.id;
}
Expand Down Expand Up @@ -1062,6 +1070,48 @@ SDL_RestoreWindow(SDL_WindowID windowID)
}
}

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)
{
Expand All @@ -1077,7 +1127,7 @@ SDL_SetWindowGrab(SDL_WindowID windowID, int mode)
window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
}

if (_this->SetWindowGrab) {
if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) {
_this->SetWindowGrab(_this, window);
}
}
Expand Down Expand Up @@ -1115,6 +1165,9 @@ SDL_OnWindowFocusGained(SDL_Window * window)
if (display->gamma && _this->SetDisplayGammaRamp) {
_this->SetDisplayGammaRamp(_this, display->gamma);
}
if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && _this->SetWindowGrab) {
_this->SetWindowGrab(_this, window);
}
}

void
Expand All @@ -1123,12 +1176,36 @@ SDL_OnWindowFocusLost(SDL_Window * window)
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);

if (window->flags & SDL_WINDOW_FULLSCREEN) {
SDL_SetDisplayMode(NULL);
SDL_MinimizeWindow(window->id);
SDL_SetDisplayMode(NULL);
}
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
Expand All @@ -1140,23 +1217,16 @@ SDL_DestroyWindow(SDL_WindowID windowID)
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) {
SDL_Window *window = &display->windows[j];
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);
}
Expand Down
17 changes: 1 addition & 16 deletions src/video/win32/SDL_win32events.c
Expand Up @@ -453,26 +453,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
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,
Expand Down Expand Up @@ -782,7 +767,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

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);
}

Expand Down

0 comments on commit e7293b1

Please sign in to comment.