diff options
Diffstat (limited to '3rdparty/SDL2/src/video/x11/SDL_x11window.c')
-rw-r--r-- | 3rdparty/SDL2/src/video/x11/SDL_x11window.c | 1583 |
1 files changed, 0 insertions, 1583 deletions
diff --git a/3rdparty/SDL2/src/video/x11/SDL_x11window.c b/3rdparty/SDL2/src/video/x11/SDL_x11window.c deleted file mode 100644 index 668bce2257b..00000000000 --- a/3rdparty/SDL2/src/video/x11/SDL_x11window.c +++ /dev/null @@ -1,1583 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ -#include "../../SDL_internal.h" - -#if SDL_VIDEO_DRIVER_X11 - -#include "SDL_assert.h" -#include "SDL_hints.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_keyboard_c.h" -#include "../../events/SDL_mouse_c.h" - -#include "SDL_x11video.h" -#include "SDL_x11mouse.h" -#include "SDL_x11shape.h" -#include "SDL_x11xinput2.h" - -#if SDL_VIDEO_OPENGL_EGL -#include "SDL_x11opengles.h" -#endif - -#include "SDL_timer.h" -#include "SDL_syswm.h" -#include "SDL_assert.h" - -#define _NET_WM_STATE_REMOVE 0l -#define _NET_WM_STATE_ADD 1l -#define _NET_WM_STATE_TOGGLE 2l - -static Bool isMapNotify(Display *dpy, XEvent *ev, XPointer win) -{ - return ev->type == MapNotify && ev->xmap.window == *((Window*)win); -} -static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win) -{ - return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win); -} - -/* -static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win) -{ - return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win); -} -static Bool -X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS) -{ - Uint32 start = SDL_GetTicks(); - - while (!X11_XCheckIfEvent(display, event_return, predicate, arg)) { - if (SDL_TICKS_PASSED(SDL_GetTicks(), start + timeoutMS)) { - return False; - } - } - return True; -} -*/ - -static SDL_bool -X11_IsWindowLegacyFullscreen(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - return (data->fswindow != 0); -} - -static SDL_bool -X11_IsWindowMapped(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - XWindowAttributes attr; - - X11_XGetWindowAttributes(videodata->display, data->xwindow, &attr); - if (attr.map_state != IsUnmapped) { - return SDL_TRUE; - } else { - return SDL_FALSE; - } -} - -#if 0 -static SDL_bool -X11_IsActionAllowed(SDL_Window *window, Atom action) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS; - Atom type; - Display *display = data->videodata->display; - int form; - unsigned long remain; - unsigned long len, i; - Atom *list; - SDL_bool ret = SDL_FALSE; - - if (X11_XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success) - { - for (i=0; i<len; ++i) - { - if (list[i] == action) { - ret = SDL_TRUE; - break; - } - } - X11_XFree(list); - } - return ret; -} -#endif /* 0 */ - -void -X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - Display *display = videodata->display; - /* !!! FIXME: just dereference videodata below instead of copying to locals. */ - Atom _NET_WM_STATE = videodata->_NET_WM_STATE; - /* Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; */ - Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED; - Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT; - Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ; - Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN; - Atom _NET_WM_STATE_ABOVE = videodata->_NET_WM_STATE_ABOVE; - Atom _NET_WM_STATE_SKIP_TASKBAR = videodata->_NET_WM_STATE_SKIP_TASKBAR; - Atom _NET_WM_STATE_SKIP_PAGER = videodata->_NET_WM_STATE_SKIP_PAGER; - Atom atoms[16]; - int count = 0; - - /* The window manager sets this property, we shouldn't set it. - If we did, this would indicate to the window manager that we don't - actually want to be mapped during X11_XMapRaised(), which would be bad. - * - if (flags & SDL_WINDOW_HIDDEN) { - atoms[count++] = _NET_WM_STATE_HIDDEN; - } - */ - - if (flags & SDL_WINDOW_ALWAYS_ON_TOP) { - atoms[count++] = _NET_WM_STATE_ABOVE; - } - if (flags & SDL_WINDOW_SKIP_TASKBAR) { - atoms[count++] = _NET_WM_STATE_SKIP_TASKBAR; - atoms[count++] = _NET_WM_STATE_SKIP_PAGER; - } - if (flags & SDL_WINDOW_INPUT_FOCUS) { - atoms[count++] = _NET_WM_STATE_FOCUSED; - } - if (flags & SDL_WINDOW_MAXIMIZED) { - atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT; - atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ; - } - if (flags & SDL_WINDOW_FULLSCREEN) { - atoms[count++] = _NET_WM_STATE_FULLSCREEN; - } - - SDL_assert(count <= SDL_arraysize(atoms)); - - if (count > 0) { - X11_XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32, - PropModeReplace, (unsigned char *)atoms, count); - } else { - X11_XDeleteProperty(display, xwindow, _NET_WM_STATE); - } -} - -Uint32 -X11_GetNetWMState(_THIS, Window xwindow) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - Display *display = videodata->display; - Atom _NET_WM_STATE = videodata->_NET_WM_STATE; - Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; - Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED; - Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT; - Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ; - Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN; - Atom actualType; - int actualFormat; - unsigned long i, numItems, bytesAfter; - unsigned char *propertyValue = NULL; - long maxLength = 1024; - Uint32 flags = 0; - - if (X11_XGetWindowProperty(display, xwindow, _NET_WM_STATE, - 0l, maxLength, False, XA_ATOM, &actualType, - &actualFormat, &numItems, &bytesAfter, - &propertyValue) == Success) { - Atom *atoms = (Atom *) propertyValue; - int maximized = 0; - int fullscreen = 0; - - for (i = 0; i < numItems; ++i) { - if (atoms[i] == _NET_WM_STATE_HIDDEN) { - flags |= SDL_WINDOW_HIDDEN; - } else if (atoms[i] == _NET_WM_STATE_FOCUSED) { - flags |= SDL_WINDOW_INPUT_FOCUS; - } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) { - maximized |= 1; - } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) { - maximized |= 2; - } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) { - fullscreen = 1; - } - } - if (maximized == 3) { - flags |= SDL_WINDOW_MAXIMIZED; - } - - if (fullscreen == 1) { - flags |= SDL_WINDOW_FULLSCREEN; - } - X11_XFree(propertyValue); - } - - /* FIXME, check the size hints for resizable */ - /* flags |= SDL_WINDOW_RESIZABLE; */ - - return flags; -} - -static int -SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created) -{ - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_WindowData *data; - int numwindows = videodata->numwindows; - int windowlistlength = videodata->windowlistlength; - SDL_WindowData **windowlist = videodata->windowlist; - - /* Allocate the window data */ - data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data)); - if (!data) { - return SDL_OutOfMemory(); - } - data->window = window; - data->xwindow = w; -#ifdef X_HAVE_UTF8_STRING - if (SDL_X11_HAVE_UTF8 && videodata->im) { - data->ic = - X11_XCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w, - XNInputStyle, XIMPreeditNothing | XIMStatusNothing, - NULL); - } -#endif - data->created = created; - data->videodata = videodata; - - /* Associate the data with the window */ - - if (numwindows < windowlistlength) { - windowlist[numwindows] = data; - videodata->numwindows++; - } else { - windowlist = - (SDL_WindowData **) SDL_realloc(windowlist, - (numwindows + - 1) * sizeof(*windowlist)); - if (!windowlist) { - SDL_free(data); - return SDL_OutOfMemory(); - } - windowlist[numwindows] = data; - videodata->numwindows++; - videodata->windowlistlength++; - videodata->windowlist = windowlist; - } - - /* Fill in the SDL window with the window data */ - { - XWindowAttributes attrib; - - X11_XGetWindowAttributes(data->videodata->display, w, &attrib); - window->x = attrib.x; - window->y = attrib.y; - window->w = attrib.width; - window->h = attrib.height; - if (attrib.map_state != IsUnmapped) { - window->flags |= SDL_WINDOW_SHOWN; - } else { - window->flags &= ~SDL_WINDOW_SHOWN; - } - data->visual = attrib.visual; - data->colormap = attrib.colormap; - } - - window->flags |= X11_GetNetWMState(_this, w); - - { - Window FocalWindow; - int RevertTo=0; - X11_XGetInputFocus(data->videodata->display, &FocalWindow, &RevertTo); - if (FocalWindow==w) - { - window->flags |= SDL_WINDOW_INPUT_FOCUS; - } - - if (window->flags & SDL_WINDOW_INPUT_FOCUS) { - SDL_SetKeyboardFocus(data->window); - } - - if (window->flags & SDL_WINDOW_INPUT_GRABBED) { - /* Tell x11 to clip mouse */ - } - } - - /* All done! */ - window->driverdata = data; - return 0; -} - -static void -SetWindowBordered(Display *display, int screen, Window window, SDL_bool border) -{ - /* - * this code used to check for KWM_WIN_DECORATION, but KDE hasn't - * supported it for years and years. It now respects _MOTIF_WM_HINTS. - * Gnome is similar: just use the Motif atom. - */ - - Atom WM_HINTS = X11_XInternAtom(display, "_MOTIF_WM_HINTS", True); - if (WM_HINTS != None) { - /* Hints used by Motif compliant window managers */ - struct - { - unsigned long flags; - unsigned long functions; - unsigned long decorations; - long input_mode; - unsigned long status; - } MWMHints = { - (1L << 1), 0, border ? 1 : 0, 0, 0 - }; - - X11_XChangeProperty(display, window, WM_HINTS, WM_HINTS, 32, - PropModeReplace, (unsigned char *) &MWMHints, - sizeof(MWMHints) / sizeof(long)); - } else { /* set the transient hints instead, if necessary */ - X11_XSetTransientForHint(display, window, RootWindow(display, screen)); - } -} - -int -X11_CreateWindow(_THIS, SDL_Window * window) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - SDL_WindowData *windowdata; - Display *display = data->display; - int screen = displaydata->screen; - Visual *visual; - int depth; - XSetWindowAttributes xattr; - Window w; - XSizeHints *sizehints; - XWMHints *wmhints; - XClassHint *classhints; - Atom _NET_WM_BYPASS_COMPOSITOR; - Atom _NET_WM_WINDOW_TYPE; - Atom wintype; - const char *wintype_name = NULL; - int compositor = 1; - Atom _NET_WM_PID; - Atom XdndAware, xdnd_version = 5; - long fevent = 0; - -#if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_EGL - if ((window->flags & SDL_WINDOW_OPENGL) && - !SDL_getenv("SDL_VIDEO_X11_VISUALID")) { - XVisualInfo *vinfo = NULL; - -#if SDL_VIDEO_OPENGL_EGL - if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES -#if SDL_VIDEO_OPENGL_GLX - && ( !_this->gl_data || ! _this->gl_data->HAS_GLX_EXT_create_context_es2_profile ) -#endif - ) { - vinfo = X11_GLES_GetVisual(_this, display, screen); - } else -#endif - { -#if SDL_VIDEO_OPENGL_GLX - vinfo = X11_GL_GetVisual(_this, display, screen); -#endif - } - - if (!vinfo) { - return -1; - } - visual = vinfo->visual; - depth = vinfo->depth; - X11_XFree(vinfo); - } else -#endif - { - visual = displaydata->visual; - depth = displaydata->depth; - } - - xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU)) ? True : False; - xattr.background_pixmap = None; - xattr.border_pixel = 0; - - if (visual->class == DirectColor) { - XColor *colorcells; - int i; - int ncolors; - int rmax, gmax, bmax; - int rmask, gmask, bmask; - int rshift, gshift, bshift; - - xattr.colormap = - X11_XCreateColormap(display, RootWindow(display, screen), - visual, AllocAll); - - /* If we can't create a colormap, then we must die */ - if (!xattr.colormap) { - return SDL_SetError("Could not create writable colormap"); - } - - /* OK, we got a colormap, now fill it in as best as we can */ - colorcells = SDL_malloc(visual->map_entries * sizeof(XColor)); - if (!colorcells) { - return SDL_OutOfMemory(); - } - ncolors = visual->map_entries; - rmax = 0xffff; - gmax = 0xffff; - bmax = 0xffff; - - rshift = 0; - rmask = visual->red_mask; - while (0 == (rmask & 1)) { - rshift++; - rmask >>= 1; - } - - gshift = 0; - gmask = visual->green_mask; - while (0 == (gmask & 1)) { - gshift++; - gmask >>= 1; - } - - bshift = 0; - bmask = visual->blue_mask; - while (0 == (bmask & 1)) { - bshift++; - bmask >>= 1; - } - - /* build the color table pixel values */ - for (i = 0; i < ncolors; i++) { - Uint32 red = (rmax * i) / (ncolors - 1); - Uint32 green = (gmax * i) / (ncolors - 1); - Uint32 blue = (bmax * i) / (ncolors - 1); - - Uint32 rbits = (rmask * i) / (ncolors - 1); - Uint32 gbits = (gmask * i) / (ncolors - 1); - Uint32 bbits = (bmask * i) / (ncolors - 1); - - Uint32 pix = - (rbits << rshift) | (gbits << gshift) | (bbits << bshift); - - colorcells[i].pixel = pix; - - colorcells[i].red = red; - colorcells[i].green = green; - colorcells[i].blue = blue; - - colorcells[i].flags = DoRed | DoGreen | DoBlue; - } - - X11_XStoreColors(display, xattr.colormap, colorcells, ncolors); - - SDL_free(colorcells); - } else { - xattr.colormap = - X11_XCreateColormap(display, RootWindow(display, screen), - visual, AllocNone); - } - - w = X11_XCreateWindow(display, RootWindow(display, screen), - window->x, window->y, window->w, window->h, - 0, depth, InputOutput, visual, - (CWOverrideRedirect | CWBackPixmap | CWBorderPixel | - CWColormap), &xattr); - if (!w) { - return SDL_SetError("Couldn't create window"); - } - - SetWindowBordered(display, screen, w, - (window->flags & SDL_WINDOW_BORDERLESS) == 0); - - sizehints = X11_XAllocSizeHints(); - /* Setup the normal size hints */ - sizehints->flags = 0; - if (!(window->flags & SDL_WINDOW_RESIZABLE)) { - sizehints->min_width = sizehints->max_width = window->w; - sizehints->min_height = sizehints->max_height = window->h; - sizehints->flags |= (PMaxSize | PMinSize); - } - sizehints->x = window->x; - sizehints->y = window->y; - sizehints->flags |= USPosition; - - /* Setup the input hints so we get keyboard input */ - wmhints = X11_XAllocWMHints(); - wmhints->input = True; - wmhints->window_group = data->window_group; - wmhints->flags = InputHint | WindowGroupHint; - - /* Setup the class hints so we can get an icon (AfterStep) */ - classhints = X11_XAllocClassHint(); - classhints->res_name = data->classname; - classhints->res_class = data->classname; - - /* Set the size, input and class hints, and define WM_CLIENT_MACHINE and WM_LOCALE_NAME */ - X11_XSetWMProperties(display, w, NULL, NULL, NULL, 0, sizehints, wmhints, classhints); - - X11_XFree(sizehints); - X11_XFree(wmhints); - X11_XFree(classhints); - /* Set the PID related to the window for the given hostname, if possible */ - if (data->pid > 0) { - long pid = (long) data->pid; - _NET_WM_PID = X11_XInternAtom(display, "_NET_WM_PID", False); - X11_XChangeProperty(display, w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, - (unsigned char *) &pid, 1); - } - - /* Set the window manager state */ - X11_SetNetWMState(_this, w, window->flags); - - compositor = 2; /* don't disable compositing except for "normal" windows */ - - if (window->flags & SDL_WINDOW_UTILITY) { - wintype_name = "_NET_WM_WINDOW_TYPE_UTILITY"; - } else if (window->flags & SDL_WINDOW_TOOLTIP) { - wintype_name = "_NET_WM_WINDOW_TYPE_TOOLTIP"; - } else if (window->flags & SDL_WINDOW_POPUP_MENU) { - wintype_name = "_NET_WM_WINDOW_TYPE_POPUP_MENU"; - } else { - wintype_name = "_NET_WM_WINDOW_TYPE_NORMAL"; - compositor = 1; /* disable compositing for "normal" windows */ - } - - /* Let the window manager know what type of window we are. */ - _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); - wintype = X11_XInternAtom(display, wintype_name, False); - X11_XChangeProperty(display, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, - PropModeReplace, (unsigned char *)&wintype, 1); - - _NET_WM_BYPASS_COMPOSITOR = X11_XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False); - X11_XChangeProperty(display, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, - PropModeReplace, - (unsigned char *)&compositor, 1); - - { - Atom protocols[3]; - int proto_count = 0; - - protocols[proto_count++] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */ - protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */ - - /* Default to using ping if there is no hint */ - if (SDL_GetHintBoolean(SDL_HINT_VIDEO_X11_NET_WM_PING, SDL_TRUE)) { - protocols[proto_count++] = data->_NET_WM_PING; /* Respond so WM knows we're alive */ - } - - SDL_assert(proto_count <= sizeof(protocols) / sizeof(protocols[0])); - - X11_XSetWMProtocols(display, w, protocols, proto_count); - } - - if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) { - X11_XDestroyWindow(display, w); - return -1; - } - windowdata = (SDL_WindowData *) window->driverdata; - -#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - if ((window->flags & SDL_WINDOW_OPENGL) && - _this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES -#if SDL_VIDEO_OPENGL_GLX - && ( !_this->gl_data || ! _this->gl_data->HAS_GLX_EXT_create_context_es2_profile ) -#endif - ) { -#if SDL_VIDEO_OPENGL_EGL - if (!_this->egl_data) { - X11_XDestroyWindow(display, w); - return -1; - } - - /* Create the GLES window surface */ - windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) w); - - if (windowdata->egl_surface == EGL_NO_SURFACE) { - X11_XDestroyWindow(display, w); - return SDL_SetError("Could not create GLES window surface"); - } -#else - return SDL_SetError("Could not create GLES window surface (no EGL support available)"); -#endif /* SDL_VIDEO_OPENGL_EGL */ - } -#endif - - -#ifdef X_HAVE_UTF8_STRING - if (SDL_X11_HAVE_UTF8 && windowdata->ic) { - X11_XGetICValues(windowdata->ic, XNFilterEvents, &fevent, NULL); - } -#endif - - X11_Xinput2SelectTouch(_this, window); - - X11_XSelectInput(display, w, - (FocusChangeMask | EnterWindowMask | LeaveWindowMask | - ExposureMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | KeyPressMask | KeyReleaseMask | - PropertyChangeMask | StructureNotifyMask | - KeymapStateMask | fevent)); - - XdndAware = X11_XInternAtom(display, "XdndAware", False); - X11_XChangeProperty(display, w, XdndAware, XA_ATOM, 32, - PropModeReplace, - (unsigned char*)&xdnd_version, 1); - - X11_XFlush(display); - - return 0; -} - -int -X11_CreateWindowFrom(_THIS, SDL_Window * window, const void *data) -{ - Window w = (Window) data; - - window->title = X11_GetWindowTitle(_this, w); - - if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) { - return -1; - } - return 0; -} - -char * -X11_GetWindowTitle(_THIS, Window xwindow) -{ - SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; - Display *display = data->display; - int status, real_format; - Atom real_type; - unsigned long items_read, items_left; - unsigned char *propdata; - char *title = NULL; - - status = X11_XGetWindowProperty(display, xwindow, data->_NET_WM_NAME, - 0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format, - &items_read, &items_left, &propdata); - if (status == Success && propdata) { - title = SDL_strdup(SDL_static_cast(char*, propdata)); - X11_XFree(propdata); - } else { - status = X11_XGetWindowProperty(display, xwindow, XA_WM_NAME, - 0L, 8192L, False, XA_STRING, &real_type, &real_format, - &items_read, &items_left, &propdata); - if (status == Success && propdata) { - title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1); - X11_XFree(propdata); - } else { - title = SDL_strdup(""); - } - } - return title; -} - -void -X11_SetWindowTitle(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - XTextProperty titleprop; - Status status; - const char *title = window->title ? window->title : ""; - char *title_locale = NULL; - -#ifdef X_HAVE_UTF8_STRING - Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME; -#endif - - title_locale = SDL_iconv_utf8_locale(title); - if (!title_locale) { - SDL_OutOfMemory(); - return; - } - - status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop); - SDL_free(title_locale); - if (status) { - X11_XSetTextProperty(display, data->xwindow, &titleprop, XA_WM_NAME); - X11_XFree(titleprop.value); - } -#ifdef X_HAVE_UTF8_STRING - if (SDL_X11_HAVE_UTF8) { - status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1, - XUTF8StringStyle, &titleprop); - if (status == Success) { - X11_XSetTextProperty(display, data->xwindow, &titleprop, - _NET_WM_NAME); - X11_XFree(titleprop.value); - } - } -#endif - - X11_XFlush(display); -} - -void -X11_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON; - - if (icon) { - int propsize; - long *propdata; - - /* Set the _NET_WM_ICON property */ - SDL_assert(icon->format->format == SDL_PIXELFORMAT_ARGB8888); - propsize = 2 + (icon->w * icon->h); - propdata = SDL_malloc(propsize * sizeof(long)); - if (propdata) { - int x, y; - Uint32 *src; - long *dst; - - propdata[0] = icon->w; - propdata[1] = icon->h; - dst = &propdata[2]; - for (y = 0; y < icon->h; ++y) { - src = (Uint32*)((Uint8*)icon->pixels + y * icon->pitch); - for (x = 0; x < icon->w; ++x) { - *dst++ = *src++; - } - } - X11_XChangeProperty(display, data->xwindow, _NET_WM_ICON, XA_CARDINAL, - 32, PropModeReplace, (unsigned char *) propdata, - propsize); - } - SDL_free(propdata); - } else { - X11_XDeleteProperty(display, data->xwindow, _NET_WM_ICON); - } - X11_XFlush(display); -} - -void -X11_SetWindowPosition(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - - X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); - X11_XFlush(display); -} - -void -X11_SetWindowMinimumSize(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - - if (window->flags & SDL_WINDOW_RESIZABLE) { - XSizeHints *sizehints = X11_XAllocSizeHints(); - long userhints; - - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - - sizehints->min_width = window->min_w; - sizehints->min_height = window->min_h; - sizehints->flags |= PMinSize; - - X11_XSetWMNormalHints(display, data->xwindow, sizehints); - - X11_XFree(sizehints); - - /* See comment in X11_SetWindowSize. */ - X11_XResizeWindow(display, data->xwindow, window->w, window->h); - X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); - X11_XRaiseWindow(display, data->xwindow); - } - - X11_XFlush(display); -} - -void -X11_SetWindowMaximumSize(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - - if (window->flags & SDL_WINDOW_RESIZABLE) { - XSizeHints *sizehints = X11_XAllocSizeHints(); - long userhints; - - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - - sizehints->max_width = window->max_w; - sizehints->max_height = window->max_h; - sizehints->flags |= PMaxSize; - - X11_XSetWMNormalHints(display, data->xwindow, sizehints); - - X11_XFree(sizehints); - - /* See comment in X11_SetWindowSize. */ - X11_XResizeWindow(display, data->xwindow, window->w, window->h); - X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); - X11_XRaiseWindow(display, data->xwindow); - } - - X11_XFlush(display); -} - -void -X11_SetWindowSize(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - - if (SDL_IsShapedWindow(window)) { - X11_ResizeWindowShape(window); - } - if (!(window->flags & SDL_WINDOW_RESIZABLE)) { - /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the X11_XResizeWindow, thus - we must set the size hints to adjust the window size. */ - XSizeHints *sizehints = X11_XAllocSizeHints(); - long userhints; - - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - - sizehints->min_width = sizehints->max_width = window->w; - sizehints->min_height = sizehints->max_height = window->h; - sizehints->flags |= PMinSize | PMaxSize; - - X11_XSetWMNormalHints(display, data->xwindow, sizehints); - - X11_XFree(sizehints); - - /* From Pierre-Loup: - WMs each have their little quirks with that. When you change the - size hints, they get a ConfigureNotify event with the - WM_NORMAL_SIZE_HINTS Atom. They all save the hints then, but they - don't all resize the window right away to enforce the new hints. - - Some of them resize only after: - - A user-initiated move or resize - - A code-initiated move or resize - - Hiding & showing window (Unmap & map) - - The following move & resize seems to help a lot of WMs that didn't - properly update after the hints were changed. We don't do a - hide/show, because there are supposedly subtle problems with doing so - and transitioning from windowed to fullscreen in Unity. - */ - X11_XResizeWindow(display, data->xwindow, window->w, window->h); - X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); - X11_XRaiseWindow(display, data->xwindow); - } else { - X11_XResizeWindow(display, data->xwindow, window->w, window->h); - } - - X11_XFlush(display); -} - -int -X11_GetWindowBordersSize(_THIS, SDL_Window * window, int *top, int *left, int *bottom, int *right) -{ - SDL_WindowData *data = (SDL_WindowData *)window->driverdata; - - *left = data->border_left; - *right = data->border_right; - *top = data->border_top; - *bottom = data->border_bottom; - - return 0; -} - -int -X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - Atom _NET_WM_WINDOW_OPACITY = data->videodata->_NET_WM_WINDOW_OPACITY; - - if (opacity == 1.0f) { - X11_XDeleteProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY); - } else { - const Uint32 FullyOpaque = 0xFFFFFFFF; - const long alpha = (long) ((double)opacity * (double)FullyOpaque); - X11_XChangeProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32, - PropModeReplace, (unsigned char *)&alpha, 1); - } - - return 0; -} - -int -X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window) { - SDL_WindowData *data = (SDL_WindowData *) modal_window->driverdata; - SDL_WindowData *parent_data = (SDL_WindowData *) parent_window->driverdata; - Display *display = data->videodata->display; - - X11_XSetTransientForHint(display, data->xwindow, parent_data->xwindow); - return 0; -} - -int -X11_SetWindowInputFocus(_THIS, SDL_Window * window) -{ - if (X11_IsWindowMapped(_this, window)) { - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); - X11_XFlush(display); - return 0; - } - return -1; -} - -void -X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) -{ - const SDL_bool focused = ((window->flags & SDL_WINDOW_INPUT_FOCUS) != 0); - const SDL_bool visible = ((window->flags & SDL_WINDOW_HIDDEN) == 0); - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - Display *display = data->videodata->display; - XEvent event; - - SetWindowBordered(display, displaydata->screen, data->xwindow, bordered); - X11_XFlush(display); - - if (visible) { - XWindowAttributes attr; - do { - X11_XSync(display, False); - X11_XGetWindowAttributes(display, data->xwindow, &attr); - } while (attr.map_state != IsViewable); - - if (focused) { - X11_XSetInputFocus(display, data->xwindow, RevertToParent, CurrentTime); - } - } - - /* make sure these don't make it to the real event queue if they fired here. */ - X11_XSync(display, False); - X11_XCheckIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); - X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); -} - -void -X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - - XSizeHints *sizehints = X11_XAllocSizeHints(); - long userhints; - - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints); - - if (resizable) { - /* FIXME: Is there a better way to get max window size from X? -flibit */ - const int maxsize = 0x7FFFFFFF; - sizehints->min_width = window->min_w; - sizehints->min_height = window->min_h; - sizehints->max_width = (window->max_w == 0) ? maxsize : window->max_w; - sizehints->max_height = (window->max_h == 0) ? maxsize : window->max_h; - } else { - sizehints->min_width = window->w; - sizehints->min_height = window->h; - sizehints->max_width = window->w; - sizehints->max_height = window->h; - } - sizehints->flags |= PMinSize | PMaxSize; - - X11_XSetWMNormalHints(display, data->xwindow, sizehints); - - X11_XFree(sizehints); - - /* See comment in X11_SetWindowSize. */ - X11_XResizeWindow(display, data->xwindow, window->w, window->h); - X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top); - X11_XRaiseWindow(display, data->xwindow); - - X11_XFlush(display); -} - -void -X11_ShowWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - XEvent event; - - if (!X11_IsWindowMapped(_this, window)) { - X11_XMapRaised(display, data->xwindow); - /* Blocking wait for "MapNotify" event. - * We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type, - * and XCheckTypedWindowEvent doesn't block */ - X11_XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow); - X11_XFlush(display); - } - - if (!data->videodata->net_wm) { - /* no WM means no FocusIn event, which confuses us. Force it. */ - X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime); - X11_XFlush(display); - } -} - -void -X11_HideWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - Display *display = data->videodata->display; - XEvent event; - - if (X11_IsWindowMapped(_this, window)) { - X11_XWithdrawWindow(display, data->xwindow, displaydata->screen); - /* Blocking wait for "UnmapNotify" event */ - X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow); - X11_XFlush(display); - } -} - -static void -SetWindowActive(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - Display *display = data->videodata->display; - Atom _NET_ACTIVE_WINDOW = data->videodata->_NET_ACTIVE_WINDOW; - - if (X11_IsWindowMapped(_this, window)) { - XEvent e; - - /*printf("SDL Window %p: sending _NET_ACTIVE_WINDOW with timestamp %lu\n", window, data->user_time);*/ - - SDL_zero(e); - e.xany.type = ClientMessage; - e.xclient.message_type = _NET_ACTIVE_WINDOW; - e.xclient.format = 32; - e.xclient.window = data->xwindow; - e.xclient.data.l[0] = 1; /* source indication. 1 = application */ - e.xclient.data.l[1] = data->user_time; - e.xclient.data.l[2] = 0; - - X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); - - X11_XFlush(display); - } -} - -void -X11_RaiseWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - - X11_XRaiseWindow(display, data->xwindow); - SetWindowActive(_this, window); - X11_XFlush(display); -} - -static void -SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - Display *display = data->videodata->display; - Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; - Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; - Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; - - if (maximized) { - window->flags |= SDL_WINDOW_MAXIMIZED; - } else { - window->flags &= ~SDL_WINDOW_MAXIMIZED; - } - - if (X11_IsWindowMapped(_this, window)) { - XEvent e; - - SDL_zero(e); - e.xany.type = ClientMessage; - e.xclient.message_type = _NET_WM_STATE; - e.xclient.format = 32; - e.xclient.window = data->xwindow; - e.xclient.data.l[0] = - maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; - e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT; - e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ; - e.xclient.data.l[3] = 0l; - - X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); - } else { - X11_SetNetWMState(_this, data->xwindow, window->flags); - } - X11_XFlush(display); -} - -void -X11_MaximizeWindow(_THIS, SDL_Window * window) -{ - SetWindowMaximized(_this, window, SDL_TRUE); -} - -void -X11_MinimizeWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = - (SDL_DisplayData *) SDL_GetDisplayForWindow(window)->driverdata; - Display *display = data->videodata->display; - - X11_XIconifyWindow(display, data->xwindow, displaydata->screen); - X11_XFlush(display); -} - -void -X11_RestoreWindow(_THIS, SDL_Window * window) -{ - SetWindowMaximized(_this, window, SDL_FALSE); - X11_ShowWindow(_this, window); - SetWindowActive(_this, window); -} - -/* This asks the Window Manager to handle fullscreen for us. This is the modern way. */ -static void -X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - Display *display = data->videodata->display; - Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE; - Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN; - - if (X11_IsWindowMapped(_this, window)) { - XEvent e; - - if (!(window->flags & SDL_WINDOW_RESIZABLE)) { - /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we - can be resized to the fullscreen resolution (or reset so we're not resizable again) */ - XSizeHints *sizehints = X11_XAllocSizeHints(); - long flags = 0; - X11_XGetWMNormalHints(display, data->xwindow, sizehints, &flags); - /* set the resize flags on */ - if (fullscreen) { - /* we are going fullscreen so turn the flags off */ - sizehints->flags &= ~(PMinSize | PMaxSize); - } else { - /* Reset the min/max width height to make the window non-resizable again */ - sizehints->flags |= PMinSize | PMaxSize; - sizehints->min_width = sizehints->max_width = window->windowed.w; - sizehints->min_height = sizehints->max_height = window->windowed.h; - } - X11_XSetWMNormalHints(display, data->xwindow, sizehints); - X11_XFree(sizehints); - } - - SDL_zero(e); - e.xany.type = ClientMessage; - e.xclient.message_type = _NET_WM_STATE; - e.xclient.format = 32; - e.xclient.window = data->xwindow; - e.xclient.data.l[0] = - fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; - e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; - e.xclient.data.l[3] = 0l; - - X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); - - /* Fullscreen windows sometimes end up being marked maximized by - window managers. Force it back to how we expect it to be. */ - if (!fullscreen && ((window->flags & SDL_WINDOW_MAXIMIZED) == 0)) { - SDL_zero(e); - e.xany.type = ClientMessage; - e.xclient.message_type = _NET_WM_STATE; - e.xclient.format = 32; - e.xclient.window = data->xwindow; - e.xclient.data.l[0] = _NET_WM_STATE_REMOVE; - e.xclient.data.l[1] = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT; - e.xclient.data.l[2] = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ; - e.xclient.data.l[3] = 0l; - X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0, - SubstructureNotifyMask | SubstructureRedirectMask, &e); - } - } else { - Uint32 flags; - - flags = window->flags; - if (fullscreen) { - flags |= SDL_WINDOW_FULLSCREEN; - } else { - flags &= ~SDL_WINDOW_FULLSCREEN; - } - X11_SetNetWMState(_this, data->xwindow, flags); - } - - if (data->visual->class == DirectColor) { - if ( fullscreen ) { - X11_XInstallColormap(display, data->colormap); - } else { - X11_XUninstallColormap(display, data->colormap); - } - } - - X11_XFlush(display); -} - -/* This handles fullscreen itself, outside the Window Manager. */ -static void -X11_BeginWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - Visual *visual = data->visual; - Display *display = data->videodata->display; - const int screen = displaydata->screen; - Window root = RootWindow(display, screen); - const int def_vis = (visual == DefaultVisual(display, screen)); - unsigned long xattrmask = 0; - XSetWindowAttributes xattr; - XEvent ev; - SDL_Rect rect; - - if ( data->fswindow ) { - return; /* already fullscreen, I hope. */ - } - - X11_GetDisplayBounds(_this, _display, &rect); - - SDL_zero(xattr); - xattr.override_redirect = True; - xattrmask |= CWOverrideRedirect; - xattr.background_pixel = def_vis ? BlackPixel(display, screen) : 0; - xattrmask |= CWBackPixel; - xattr.border_pixel = 0; - xattrmask |= CWBorderPixel; - xattr.colormap = data->colormap; - xattrmask |= CWColormap; - - data->fswindow = X11_XCreateWindow(display, root, - rect.x, rect.y, rect.w, rect.h, 0, - displaydata->depth, InputOutput, - visual, xattrmask, &xattr); - - X11_XSelectInput(display, data->fswindow, StructureNotifyMask); - X11_XSetWindowBackground(display, data->fswindow, 0); - X11_XInstallColormap(display, data->colormap); - X11_XClearWindow(display, data->fswindow); - X11_XMapRaised(display, data->fswindow); - - /* Make sure the fswindow is in view by warping mouse to the corner */ - X11_XUngrabPointer(display, CurrentTime); - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Wait to be mapped, filter Unmap event out if it arrives. */ - X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow); - -#if SDL_VIDEO_DRIVER_X11_XVIDMODE - if ( displaydata->use_vidmode ) { - X11_XF86VidModeLockModeSwitch(display, screen, True); - } -#endif - - SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE); - - /* Center actual window within our cover-the-screen window. */ - X11_XReparentWindow(display, data->xwindow, data->fswindow, - (rect.w - window->w) / 2, (rect.h - window->h) / 2); - - /* Move the mouse to the upper left to make sure it's on-screen */ - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Center mouse in the fullscreen window. */ - rect.x += (rect.w / 2); - rect.y += (rect.h / 2); - X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y); - - /* Wait to be mapped, filter Unmap event out if it arrives. */ - X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); - - SDL_UpdateWindowGrab(window); -} - -static void -X11_EndWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - Display *display = data->videodata->display; - const int screen = displaydata->screen; - Window root = RootWindow(display, screen); - Window fswindow = data->fswindow; - XEvent ev; - - if (!data->fswindow) { - return; /* already not fullscreen, I hope. */ - } - - data->fswindow = None; - -#if SDL_VIDEO_DRIVER_X11_VIDMODE - if ( displaydata->use_vidmode ) { - X11_XF86VidModeLockModeSwitch(display, screen, False); - } -#endif - - SDL_UpdateWindowGrab(window); - - X11_XReparentWindow(display, data->xwindow, root, window->x, window->y); - - /* flush these events so they don't confuse normal event handling */ - X11_XSync(display, False); - X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow); - X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow); - - SetWindowBordered(display, screen, data->xwindow, - (window->flags & SDL_WINDOW_BORDERLESS) == 0); - - X11_XWithdrawWindow(display, fswindow, screen); - - /* Wait to be unmapped. */ - X11_XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow); - X11_XDestroyWindow(display, fswindow); -} - - -void -X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen) -{ - /* !!! FIXME: SDL_Hint? */ - SDL_bool legacy = SDL_FALSE; - const char *env = SDL_getenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN"); - if (env) { - legacy = SDL_atoi(env); - } else { - SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata; - SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata; - if ( displaydata->use_vidmode ) { - legacy = SDL_TRUE; /* the new stuff only works with XRandR. */ - } else if ( !videodata->net_wm ) { - legacy = SDL_TRUE; /* The window manager doesn't support it */ - } else { - /* !!! FIXME: look at the window manager name, and blacklist certain ones? */ - /* http://stackoverflow.com/questions/758648/find-the-name-of-the-x-window-manager */ - legacy = SDL_FALSE; /* try the new way. */ - } - } - - if (legacy) { - if (fullscreen) { - X11_BeginWindowFullscreenLegacy(_this, window, _display); - } else { - X11_EndWindowFullscreenLegacy(_this, window, _display); - } - } else { - X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen); - } -} - - -int -X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - Visual *visual = data->visual; - Colormap colormap = data->colormap; - XColor *colorcells; - int ncolors; - int rmask, gmask, bmask; - int rshift, gshift, bshift; - int i; - - if (visual->class != DirectColor) { - return SDL_SetError("Window doesn't have DirectColor visual"); - } - - ncolors = visual->map_entries; - colorcells = SDL_malloc(ncolors * sizeof(XColor)); - if (!colorcells) { - return SDL_OutOfMemory(); - } - - rshift = 0; - rmask = visual->red_mask; - while (0 == (rmask & 1)) { - rshift++; - rmask >>= 1; - } - - gshift = 0; - gmask = visual->green_mask; - while (0 == (gmask & 1)) { - gshift++; - gmask >>= 1; - } - - bshift = 0; - bmask = visual->blue_mask; - while (0 == (bmask & 1)) { - bshift++; - bmask >>= 1; - } - - /* build the color table pixel values */ - for (i = 0; i < ncolors; i++) { - Uint32 rbits = (rmask * i) / (ncolors - 1); - Uint32 gbits = (gmask * i) / (ncolors - 1); - Uint32 bbits = (bmask * i) / (ncolors - 1); - Uint32 pix = (rbits << rshift) | (gbits << gshift) | (bbits << bshift); - - colorcells[i].pixel = pix; - - colorcells[i].red = ramp[(0 * 256) + i]; - colorcells[i].green = ramp[(1 * 256) + i]; - colorcells[i].blue = ramp[(2 * 256) + i]; - - colorcells[i].flags = DoRed | DoGreen | DoBlue; - } - - X11_XStoreColors(display, colormap, colorcells, ncolors); - X11_XFlush(display); - SDL_free(colorcells); - - return 0; -} - -void -X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - SDL_bool oldstyle_fullscreen; - SDL_bool grab_keyboard; - - /* ICCCM2.0-compliant window managers can handle fullscreen windows - If we're using XVidMode to change resolution we need to confine - the cursor so we don't pan around the virtual desktop. - */ - oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window); - - if (oldstyle_fullscreen || grabbed) { - /* Try to grab the mouse */ - for (;;) { - int result = - X11_XGrabPointer(display, data->xwindow, True, 0, GrabModeAsync, - GrabModeAsync, data->xwindow, None, CurrentTime); - if (result == GrabSuccess) { - break; - } - SDL_Delay(50); - } - - /* Raise the window if we grab the mouse */ - X11_XRaiseWindow(display, data->xwindow); - - /* Now grab the keyboard */ - if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { - grab_keyboard = SDL_TRUE; - } else { - /* We need to do this with the old style override_redirect - fullscreen window otherwise we won't get keyboard focus. - */ - grab_keyboard = oldstyle_fullscreen; - } - if (grab_keyboard) { - X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, - GrabModeAsync, CurrentTime); - } - } else { - X11_XUngrabPointer(display, CurrentTime); - X11_XUngrabKeyboard(display, CurrentTime); - } - X11_XSync(display, False); -} - -void -X11_DestroyWindow(_THIS, SDL_Window * window) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - - if (data) { - SDL_VideoData *videodata = (SDL_VideoData *) data->videodata; - Display *display = videodata->display; - int numwindows = videodata->numwindows; - SDL_WindowData **windowlist = videodata->windowlist; - int i; - - if (windowlist) { - for (i = 0; i < numwindows; ++i) { - if (windowlist[i] && (windowlist[i]->window == window)) { - windowlist[i] = windowlist[numwindows - 1]; - windowlist[numwindows - 1] = NULL; - videodata->numwindows--; - break; - } - } - } -#ifdef X_HAVE_UTF8_STRING - if (data->ic) { - X11_XDestroyIC(data->ic); - } -#endif - if (data->created) { - X11_XDestroyWindow(display, data->xwindow); - X11_XFlush(display); - } - SDL_free(data); - } - window->driverdata = NULL; -} - -SDL_bool -X11_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) -{ - SDL_WindowData *data = (SDL_WindowData *) window->driverdata; - Display *display = data->videodata->display; - - if (info->version.major == SDL_MAJOR_VERSION && - info->version.minor == SDL_MINOR_VERSION) { - info->subsystem = SDL_SYSWM_X11; - info->info.x11.display = display; - info->info.x11.window = data->xwindow; - return SDL_TRUE; - } else { - SDL_SetError("Application not compiled with SDL %d.%d\n", - SDL_MAJOR_VERSION, SDL_MINOR_VERSION); - return SDL_FALSE; - } -} - -int -X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled) -{ - return 0; /* just succeed, the real work is done elsewhere. */ -} - -#endif /* SDL_VIDEO_DRIVER_X11 */ - -/* vi: set ts=4 sw=4 expandtab: */ |