* 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
This commit is contained in:
parent
67426e7b9f
commit
c0775dd47f
4 changed files with 90 additions and 42 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue