Commit c0775dd4 authored by Sam Lantinga's avatar Sam Lantinga

* Implemented X11 fullscreen input grab

* Progress towards being able to toggle in and out of fullscreen mode

--HG--
extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%403337
parent 67426e7b
......@@ -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;
}
......
......@@ -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)
......@@ -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);
}
}
......@@ -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;
......@@ -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;
......@@ -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;
}
......@@ -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;
}
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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
......@@ -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);
}
......@@ -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
......@@ -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);
}
}
......@@ -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);
}
}
......
......@@ -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);
}
......@@ -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;
......@@ -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));
}
......@@ -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);
......
......@@ -287,7 +287,7 @@ 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) {
......@@ -295,7 +295,7 @@ X11_CreateWindow(_THIS, SDL_Window * window)
} 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) {
......@@ -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;
......@@ -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;
......@@ -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
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment