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

Commit

Permalink
* Implemented X11 fullscreen input grab
Browse files Browse the repository at this point in the history
* Progress towards being able to toggle in and out of fullscreen mode
  • Loading branch information
slouken committed Dec 17, 2008
1 parent 197e950 commit a9ff673
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 42 deletions.
6 changes: 6 additions & 0 deletions src/events/SDL_windowevents.c
Expand Up @@ -58,6 +58,12 @@ SDL_SendWindowEvent(SDL_WindowID windowID, Uint8 windowevent, int data1,
if (window->flags & SDL_WINDOW_FULLSCREEN) {
return 0;
}
if (data1 == SDL_WINDOWPOS_UNDEFINED) {
data1 = window->x;
}
if (data2 == SDL_WINDOWPOS_UNDEFINED) {
data2 = window->y;
}
if (data1 == window->x && data2 == window->y) {
return 0;
}
Expand Down
58 changes: 29 additions & 29 deletions src/video/SDL_video.c
Expand Up @@ -123,8 +123,7 @@ static VideoBootStrap *bootstrap[] = {
static SDL_VideoDevice *_this = NULL;

/* Various local functions */
int SDL_VideoInit(const char *driver_name, Uint32 flags);
void SDL_VideoQuit(void);
static void SDL_UpdateWindowGrab(SDL_Window *window);

static int
cmpmodes(const void *A, const void *B)
Expand Down Expand Up @@ -635,8 +634,7 @@ SDL_SetDisplayMode(const SDL_DisplayMode * mode)
for (i = 0; i < display->num_windows; ++i) {
SDL_Window *window = &display->windows[i];
if (FULLSCREEN_VISIBLE(window)) {
SDL_SetWindowPosition(window->id, SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED);
SDL_SetWindowPosition(window->id, window->x, window->y);
}
}

Expand Down Expand Up @@ -752,7 +750,8 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
const Uint32 allowed_flags = (SDL_WINDOW_FULLSCREEN |
SDL_WINDOW_OPENGL |
SDL_WINDOW_BORDERLESS |
SDL_WINDOW_RESIZABLE);
SDL_WINDOW_RESIZABLE |
SDL_WINDOW_INPUT_GRABBED);
SDL_VideoDisplay *display;
SDL_Window window;
int num_windows;
Expand All @@ -766,11 +765,6 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
SDL_SetError("No OpenGL support in video driver");
return 0;
}
/* Fullscreen windows don't have any window decorations */
if (flags & SDL_WINDOW_FULLSCREEN) {
flags |= SDL_WINDOW_BORDERLESS;
flags &= ~SDL_WINDOW_RESIZABLE;
}
SDL_zero(window);
window.id = _this->next_object_id++;
window.x = x;
Expand Down Expand Up @@ -809,9 +803,8 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
if (flags & SDL_WINDOW_SHOWN) {
SDL_ShowWindow(window.id);
}
if (flags & SDL_WINDOW_INPUT_GRABBED) {
SDL_SetWindowGrab(window.id, 1);
}
SDL_UpdateWindowGrab(&window);

return window.id;
}

Expand Down Expand Up @@ -889,9 +882,8 @@ SDL_RecreateWindow(SDL_Window * window, Uint32 flags)
if (flags & SDL_WINDOW_SHOWN) {
SDL_ShowWindow(window->id);
}
if (flags & SDL_WINDOW_INPUT_GRABBED) {
SDL_SetWindowGrab(window->id, 1);
}
SDL_UpdateWindowGrab(window);

return 0;
}

Expand Down Expand Up @@ -1004,19 +996,16 @@ SDL_SetWindowPosition(SDL_WindowID windowID, int x, int y)
if (!window) {
return;
}
if (x == SDL_WINDOWPOS_CENTERED) {
window->x = (display->current_mode.w - window->w) / 2;
} else if (x != SDL_WINDOWPOS_UNDEFINED) {
if (x != SDL_WINDOWPOS_UNDEFINED) {
window->x = x;
}
if (y == SDL_WINDOWPOS_CENTERED) {
window->y = (display->current_mode.h - window->h) / 2;
} else if (y != SDL_WINDOWPOS_UNDEFINED) {
if (y != SDL_WINDOWPOS_UNDEFINED) {
window->y = y;
}
if (_this->SetWindowPosition) {
_this->SetWindowPosition(_this, window);
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MOVED, x, y);
}

void
Expand Down Expand Up @@ -1082,11 +1071,11 @@ SDL_ShowWindow(SDL_WindowID windowID)
if (!window || (window->flags & SDL_WINDOW_SHOWN)) {
return;
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_SHOWN, 0, 0);

if (_this->ShowWindow) {
_this->ShowWindow(_this, window);
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_SHOWN, 0, 0);
}

void
Expand All @@ -1097,11 +1086,11 @@ SDL_HideWindow(SDL_WindowID windowID)
if (!window || !(window->flags & SDL_WINDOW_SHOWN)) {
return;
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_HIDDEN, 0, 0);

if (_this->HideWindow) {
_this->HideWindow(_this, window);
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_HIDDEN, 0, 0);
}

void
Expand All @@ -1125,11 +1114,11 @@ SDL_MaximizeWindow(SDL_WindowID windowID)
if (!window || (window->flags & SDL_WINDOW_MAXIMIZED)) {
return;
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);

if (_this->MaximizeWindow) {
_this->MaximizeWindow(_this, window);
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
}

void
Expand All @@ -1140,11 +1129,11 @@ SDL_MinimizeWindow(SDL_WindowID windowID)
if (!window || (window->flags & SDL_WINDOW_MINIMIZED)) {
return;
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MINIMIZED, 0, 0);

if (_this->MinimizeWindow) {
_this->MinimizeWindow(_this, window);
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
}

void
Expand All @@ -1156,11 +1145,11 @@ SDL_RestoreWindow(SDL_WindowID windowID)
|| (window->flags & (SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED))) {
return;
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_RESTORED, 0, 0);

if (_this->RestoreWindow) {
_this->RestoreWindow(_this, window);
}
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_RESTORED, 0, 0);
}

int
Expand Down Expand Up @@ -1217,7 +1206,12 @@ SDL_SetWindowGrab(SDL_WindowID windowID, int mode)
} else {
window->flags &= ~SDL_WINDOW_INPUT_GRABBED;
}
SDL_UpdateWindowGrab(window);
}

static void
SDL_UpdateWindowGrab(SDL_Window *window)
{
if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) {
_this->SetWindowGrab(_this, window);
}
Expand All @@ -1237,11 +1231,17 @@ SDL_GetWindowGrab(SDL_WindowID windowID)
void
SDL_OnWindowShown(SDL_Window * window)
{
if (window->flags & SDL_WINDOW_FULLSCREEN) {
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
}
}

void
SDL_OnWindowHidden(SDL_Window * window)
{
if (window->flags & SDL_WINDOW_FULLSCREEN) {
SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
}
}

void
Expand All @@ -1265,7 +1265,7 @@ SDL_OnWindowFocusGained(SDL_Window * window)
if (display->gamma && _this->SetDisplayGammaRamp) {
_this->SetDisplayGammaRamp(_this, display->gamma);
}
if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && _this->SetWindowGrab) {
if ((window->flags & (SDL_WINDOW_INPUT_GRABBED|SDL_WINDOW_FULLSCREEN)) && _this->SetWindowGrab) {
_this->SetWindowGrab(_this, window);
}
}
Expand All @@ -1282,7 +1282,7 @@ SDL_OnWindowFocusLost(SDL_Window * window)
if (display->gamma && _this->SetDisplayGammaRamp) {
_this->SetDisplayGammaRamp(_this, display->saved_gamma);
}
if ((window->flags & SDL_WINDOW_INPUT_GRABBED) && _this->SetWindowGrab) {
if ((window->flags & (SDL_WINDOW_INPUT_GRABBED|SDL_WINDOW_FULLSCREEN)) && _this->SetWindowGrab) {
_this->SetWindowGrab(_this, window);
}
}
Expand Down
23 changes: 16 additions & 7 deletions src/video/win32/SDL_win32window.c
Expand Up @@ -159,12 +159,12 @@ WIN_CreateWindow(_THIS, SDL_Window * window)
int x, y;
int w, h;

if (window->flags & SDL_WINDOW_BORDERLESS) {
if (window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN)) {
style |= WS_POPUP;
} else {
style |= (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
}
if (window->flags & SDL_WINDOW_RESIZABLE) {
if ((window->flags & SDL_WINDOW_RESIZABLE) && !(window->flags & SDL_WINDOW_FULLSCREEN)) {
style |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
}

Expand All @@ -182,14 +182,14 @@ WIN_CreateWindow(_THIS, SDL_Window * window)
w = (rect.right - rect.left);
h = (rect.bottom - rect.top);

if (window->x == SDL_WINDOWPOS_CENTERED) {
if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) {
x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
} else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
x = CW_USEDEFAULT;
} else {
x = window->x + rect.left;
}
if (window->y == SDL_WINDOWPOS_CENTERED) {
if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) {
y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
} else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
y = CW_USEDEFAULT;
Expand Down Expand Up @@ -331,8 +331,17 @@ WIN_SetWindowPosition(_THIS, SDL_Window * window)
AdjustWindowRectEx(&rect, style,
(style & WS_CHILDWINDOW) ? FALSE : (GetMenu(hwnd) !=
NULL), 0);
x = window->x + rect.left;
y = window->y + rect.top;

if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) {
x = (GetSystemMetrics(SM_CXSCREEN) - window->w) / 2;
} else {
x = window->x + rect.left;
}
if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) {
y = (GetSystemMetrics(SM_CYSCREEN) - window->h) / 2;
} else {
y = window->y + rect.top;
}

SetWindowPos(hwnd, top, x, y, 0, 0, (SWP_NOCOPYBITS | SWP_NOSIZE));
}
Expand Down Expand Up @@ -425,7 +434,7 @@ WIN_SetWindowGrab(_THIS, SDL_Window * window)
{
HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;

if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
if ((window->flags & (SDL_WINDOW_INPUT_GRABBED|SDL_WINDOW_FULLSCREEN)) &&
(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
RECT rect;
GetClientRect(hwnd, &rect);
Expand Down
45 changes: 39 additions & 6 deletions src/video/x11/SDL_x11window.c
Expand Up @@ -287,15 +287,15 @@ X11_CreateWindow(_THIS, SDL_Window * window)
visual, AllocNone);
}

if (window->x == SDL_WINDOWPOS_CENTERED) {
if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) {
x = (DisplayWidth(data->display, displaydata->screen) -
window->w) / 2;
} else if (window->x == SDL_WINDOWPOS_UNDEFINED) {
x = 0;
} else {
x = window->x;
}
if (window->y == SDL_WINDOWPOS_CENTERED) {
if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) {
y = (DisplayHeight(data->display, displaydata->screen) -
window->h) / 2;
} else if (window->y == SDL_WINDOWPOS_UNDEFINED) {
Expand All @@ -321,7 +321,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)

sizehints = XAllocSizeHints();
if (sizehints) {
if (window->flags & SDL_WINDOW_RESIZABLE) {
if ((window->flags & SDL_WINDOW_RESIZABLE) && !(window->flags & SDL_WINDOW_FULLSCREEN)) {
sizehints->min_width = 32;
sizehints->min_height = 32;
sizehints->max_height = 4096;
Expand All @@ -342,7 +342,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
XFree(sizehints);
}

if (window->flags & SDL_WINDOW_BORDERLESS) {
if (window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN)) {
SDL_bool set;
Atom WM_HINTS;

Expand Down Expand Up @@ -601,8 +601,19 @@ X11_SetWindowPosition(_THIS, SDL_Window * window)
SDL_DisplayData *displaydata =
(SDL_DisplayData *) SDL_GetDisplayFromWindow(window)->driverdata;
Display *display = data->videodata->display;
int x, y;

XMoveWindow(display, data->window, window->x, window->y);
if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->x == SDL_WINDOWPOS_CENTERED) {
x = (DisplayWidth(display, displaydata->screen) - window->w) / 2;
} else {
x = window->x;
}
if ((window->flags & SDL_WINDOW_FULLSCREEN) || window->y == SDL_WINDOWPOS_CENTERED) {
y = (DisplayHeight(display, displaydata->screen) - window->h) / 2;
} else {
y = window->y;
}
XMoveWindow(display, data->window, x, y);
}

void
Expand Down Expand Up @@ -662,7 +673,29 @@ X11_RestoreWindow(_THIS, SDL_Window * window)
void
X11_SetWindowGrab(_THIS, SDL_Window * window)
{
/* FIXME */
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
Display *display = data->videodata->display;

if ((window->flags & (SDL_WINDOW_INPUT_GRABBED|SDL_WINDOW_FULLSCREEN)) &&
(window->flags & SDL_WINDOW_INPUT_FOCUS)) {
/* Try to grab the mouse */
for ( ; ; ) {
int result = XGrabPointer(display, data->window, True, 0, GrabModeAsync, GrabModeAsync, data->window, None, CurrentTime);
if ( result == GrabSuccess ) {
break;
}
SDL_Delay(100);
}

/* Raise the window if we grab the mouse */
XRaiseWindow(display, data->window);

/* Now grab the keyboard */
XGrabKeyboard(display, data->window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
} else {
XUngrabPointer(display, CurrentTime);
XUngrabKeyboard(display, CurrentTime);
}
}

void
Expand Down

0 comments on commit a9ff673

Please sign in to comment.