SDL  2.0
SDL_x11window.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #if SDL_VIDEO_DRIVER_X11
24 
25 #include "SDL_assert.h"
26 #include "SDL_hints.h"
27 #include "../SDL_sysvideo.h"
28 #include "../SDL_pixels_c.h"
29 #include "../../events/SDL_keyboard_c.h"
30 #include "../../events/SDL_mouse_c.h"
31 
32 #include "SDL_x11video.h"
33 #include "SDL_x11mouse.h"
34 #include "SDL_x11shape.h"
35 #include "SDL_x11xinput2.h"
36 
37 #if SDL_VIDEO_OPENGL_EGL
38 #include "SDL_x11opengles.h"
39 #endif
40 
41 #include "SDL_timer.h"
42 #include "SDL_syswm.h"
43 #include "SDL_log.h"
44 
45 #define _NET_WM_STATE_REMOVE 0l
46 #define _NET_WM_STATE_ADD 1l
47 
48 static Bool isMapNotify(Display *dpy, XEvent *ev, XPointer win)
49 {
50  return ev->type == MapNotify && ev->xmap.window == *((Window*)win);
51 }
52 static Bool isUnmapNotify(Display *dpy, XEvent *ev, XPointer win)
53 {
54  return ev->type == UnmapNotify && ev->xunmap.window == *((Window*)win);
55 }
56 
57 /*
58 static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win)
59 {
60  return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win);
61 }
62 static Bool
63 X11_XIfEventTimeout(Display *display, XEvent *event_return, Bool (*predicate)(), XPointer arg, int timeoutMS)
64 {
65  Uint32 start = SDL_GetTicks();
66 
67  while (!X11_XCheckIfEvent(display, event_return, predicate, arg)) {
68  if (SDL_TICKS_PASSED(SDL_GetTicks(), start + timeoutMS)) {
69  return False;
70  }
71  }
72  return True;
73 }
74 */
75 
76 static SDL_bool
77 X11_IsWindowLegacyFullscreen(_THIS, SDL_Window * window)
78 {
79  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
80  return (data->fswindow != 0);
81 }
82 
83 static SDL_bool
84 X11_IsWindowMapped(_THIS, SDL_Window * window)
85 {
86  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
87  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
88  XWindowAttributes attr;
89 
90  X11_XGetWindowAttributes(videodata->display, data->xwindow, &attr);
91  if (attr.map_state != IsUnmapped) {
92  return SDL_TRUE;
93  } else {
94  return SDL_FALSE;
95  }
96 }
97 
98 #if 0
99 static SDL_bool
100 X11_IsActionAllowed(SDL_Window *window, Atom action)
101 {
102  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
103  Atom _NET_WM_ALLOWED_ACTIONS = data->videodata->_NET_WM_ALLOWED_ACTIONS;
104  Atom type;
105  Display *display = data->videodata->display;
106  int form;
107  unsigned long remain;
108  unsigned long len, i;
109  Atom *list;
110  SDL_bool ret = SDL_FALSE;
111 
112  if (X11_XGetWindowProperty(display, data->xwindow, _NET_WM_ALLOWED_ACTIONS, 0, 1024, False, XA_ATOM, &type, &form, &len, &remain, (unsigned char **)&list) == Success)
113  {
114  for (i=0; i<len; ++i)
115  {
116  if (list[i] == action) {
117  ret = SDL_TRUE;
118  break;
119  }
120  }
121  X11_XFree(list);
122  }
123  return ret;
124 }
125 #endif /* 0 */
126 
127 void
128 X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags)
129 {
130  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
131  Display *display = videodata->display;
132  /* !!! FIXME: just dereference videodata below instead of copying to locals. */
133  Atom _NET_WM_STATE = videodata->_NET_WM_STATE;
134  /* Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN; */
135  Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED;
136  Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT;
137  Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
138  Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN;
139  Atom _NET_WM_STATE_ABOVE = videodata->_NET_WM_STATE_ABOVE;
140  Atom _NET_WM_STATE_SKIP_TASKBAR = videodata->_NET_WM_STATE_SKIP_TASKBAR;
141  Atom _NET_WM_STATE_SKIP_PAGER = videodata->_NET_WM_STATE_SKIP_PAGER;
142  Atom atoms[16];
143  int count = 0;
144 
145  /* The window manager sets this property, we shouldn't set it.
146  If we did, this would indicate to the window manager that we don't
147  actually want to be mapped during X11_XMapRaised(), which would be bad.
148  *
149  if (flags & SDL_WINDOW_HIDDEN) {
150  atoms[count++] = _NET_WM_STATE_HIDDEN;
151  }
152  */
153 
155  atoms[count++] = _NET_WM_STATE_ABOVE;
156  }
158  atoms[count++] = _NET_WM_STATE_SKIP_TASKBAR;
159  atoms[count++] = _NET_WM_STATE_SKIP_PAGER;
160  }
162  atoms[count++] = _NET_WM_STATE_FOCUSED;
163  }
164  if (flags & SDL_WINDOW_MAXIMIZED) {
165  atoms[count++] = _NET_WM_STATE_MAXIMIZED_VERT;
166  atoms[count++] = _NET_WM_STATE_MAXIMIZED_HORZ;
167  }
169  atoms[count++] = _NET_WM_STATE_FULLSCREEN;
170  }
171 
172  SDL_assert(count <= SDL_arraysize(atoms));
173 
174  if (count > 0) {
175  X11_XChangeProperty(display, xwindow, _NET_WM_STATE, XA_ATOM, 32,
176  PropModeReplace, (unsigned char *)atoms, count);
177  } else {
178  X11_XDeleteProperty(display, xwindow, _NET_WM_STATE);
179  }
180 }
181 
182 Uint32
183 X11_GetNetWMState(_THIS, Window xwindow)
184 {
185  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
186  Display *display = videodata->display;
187  Atom _NET_WM_STATE = videodata->_NET_WM_STATE;
188  Atom _NET_WM_STATE_HIDDEN = videodata->_NET_WM_STATE_HIDDEN;
189  Atom _NET_WM_STATE_FOCUSED = videodata->_NET_WM_STATE_FOCUSED;
190  Atom _NET_WM_STATE_MAXIMIZED_VERT = videodata->_NET_WM_STATE_MAXIMIZED_VERT;
191  Atom _NET_WM_STATE_MAXIMIZED_HORZ = videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
192  Atom _NET_WM_STATE_FULLSCREEN = videodata->_NET_WM_STATE_FULLSCREEN;
193  Atom actualType;
194  int actualFormat;
195  unsigned long i, numItems, bytesAfter;
196  unsigned char *propertyValue = NULL;
197  long maxLength = 1024;
198  Uint32 flags = 0;
199 
200  if (X11_XGetWindowProperty(display, xwindow, _NET_WM_STATE,
201  0l, maxLength, False, XA_ATOM, &actualType,
202  &actualFormat, &numItems, &bytesAfter,
203  &propertyValue) == Success) {
204  Atom *atoms = (Atom *) propertyValue;
205  int maximized = 0;
206  int fullscreen = 0;
207 
208  for (i = 0; i < numItems; ++i) {
209  if (atoms[i] == _NET_WM_STATE_HIDDEN) {
211  } else if (atoms[i] == _NET_WM_STATE_FOCUSED) {
213  } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
214  maximized |= 1;
215  } else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
216  maximized |= 2;
217  } else if ( atoms[i] == _NET_WM_STATE_FULLSCREEN) {
218  fullscreen = 1;
219  }
220  }
221  if (maximized == 3) {
223  }
224 
225  if (fullscreen == 1) {
227  }
228 
229  /* If the window is unmapped, numItems will be zero and _NET_WM_STATE_HIDDEN
230  * will not be set. Do an additional check to see if the window is unmapped
231  * and mark it as SDL_WINDOW_HIDDEN if it is.
232  */
233  {
234  XWindowAttributes attr;
235  SDL_memset(&attr,0,sizeof(attr));
236  X11_XGetWindowAttributes(videodata->display, xwindow, &attr);
237  if (attr.map_state == IsUnmapped) {
239  }
240  }
241  X11_XFree(propertyValue);
242  }
243 
244  /* FIXME, check the size hints for resizable */
245  /* flags |= SDL_WINDOW_RESIZABLE; */
246 
247  return flags;
248 }
249 
250 static int
251 SetupWindowData(_THIS, SDL_Window * window, Window w, BOOL created)
252 {
253  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
255  int numwindows = videodata->numwindows;
256  int windowlistlength = videodata->windowlistlength;
257  SDL_WindowData **windowlist = videodata->windowlist;
258 
259  /* Allocate the window data */
260  data = (SDL_WindowData *) SDL_calloc(1, sizeof(*data));
261  if (!data) {
262  return SDL_OutOfMemory();
263  }
264  data->window = window;
265  data->xwindow = w;
266 #ifdef X_HAVE_UTF8_STRING
267  if (SDL_X11_HAVE_UTF8 && videodata->im) {
268  data->ic =
269  X11_XCreateIC(videodata->im, XNClientWindow, w, XNFocusWindow, w,
270  XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
271  NULL);
272  }
273 #endif
274  data->created = created;
275  data->videodata = videodata;
276 
277  /* Associate the data with the window */
278 
279  if (numwindows < windowlistlength) {
280  windowlist[numwindows] = data;
281  videodata->numwindows++;
282  } else {
283  windowlist =
284  (SDL_WindowData **) SDL_realloc(windowlist,
285  (numwindows +
286  1) * sizeof(*windowlist));
287  if (!windowlist) {
288  SDL_free(data);
289  return SDL_OutOfMemory();
290  }
291  windowlist[numwindows] = data;
292  videodata->numwindows++;
293  videodata->windowlistlength++;
294  videodata->windowlist = windowlist;
295  }
296 
297  /* Fill in the SDL window with the window data */
298  {
299  XWindowAttributes attrib;
300 
301  X11_XGetWindowAttributes(data->videodata->display, w, &attrib);
302  window->x = attrib.x;
303  window->y = attrib.y;
304  window->w = attrib.width;
305  window->h = attrib.height;
306  if (attrib.map_state != IsUnmapped) {
307  window->flags |= SDL_WINDOW_SHOWN;
308  } else {
309  window->flags &= ~SDL_WINDOW_SHOWN;
310  }
311  data->visual = attrib.visual;
312  data->colormap = attrib.colormap;
313  }
314 
315  window->flags |= X11_GetNetWMState(_this, w);
316 
317  {
318  Window FocalWindow;
319  int RevertTo=0;
320  X11_XGetInputFocus(data->videodata->display, &FocalWindow, &RevertTo);
321  if (FocalWindow==w)
322  {
323  window->flags |= SDL_WINDOW_INPUT_FOCUS;
324  }
325 
326  if (window->flags & SDL_WINDOW_INPUT_FOCUS) {
327  SDL_SetKeyboardFocus(data->window);
328  }
329 
330  if (window->flags & SDL_WINDOW_INPUT_GRABBED) {
331  /* Tell x11 to clip mouse */
332  }
333  }
334 
335  /* All done! */
336  window->driverdata = data;
337  return 0;
338 }
339 
340 static void
341 SetWindowBordered(Display *display, int screen, Window window, SDL_bool border)
342 {
343  /*
344  * this code used to check for KWM_WIN_DECORATION, but KDE hasn't
345  * supported it for years and years. It now respects _MOTIF_WM_HINTS.
346  * Gnome is similar: just use the Motif atom.
347  */
348 
349  Atom WM_HINTS = X11_XInternAtom(display, "_MOTIF_WM_HINTS", True);
350  if (WM_HINTS != None) {
351  /* Hints used by Motif compliant window managers */
352  struct
353  {
354  unsigned long flags;
355  unsigned long functions;
356  unsigned long decorations;
357  long input_mode;
358  unsigned long status;
359  } MWMHints = {
360  (1L << 1), 0, border ? 1 : 0, 0, 0
361  };
362 
363  X11_XChangeProperty(display, window, WM_HINTS, WM_HINTS, 32,
364  PropModeReplace, (unsigned char *) &MWMHints,
365  sizeof(MWMHints) / sizeof(long));
366  } else { /* set the transient hints instead, if necessary */
367  X11_XSetTransientForHint(display, window, RootWindow(display, screen));
368  }
369 }
370 
371 int
373 {
375  SDL_DisplayData *displaydata =
377  SDL_WindowData *windowdata;
378  Display *display = data->display;
379  int screen = displaydata->screen;
380  Visual *visual;
381  int depth;
382  XSetWindowAttributes xattr;
383  Window w;
384  XSizeHints *sizehints;
385  XWMHints *wmhints;
386  XClassHint *classhints;
387  Atom _NET_WM_BYPASS_COMPOSITOR;
388  Atom _NET_WM_WINDOW_TYPE;
389  Atom wintype;
390  const char *wintype_name = NULL;
391  long compositor = 1;
392  Atom _NET_WM_PID;
393  long fevent = 0;
394 
395 #if SDL_VIDEO_OPENGL_GLX || SDL_VIDEO_OPENGL_EGL
396  if ((window->flags & SDL_WINDOW_OPENGL) &&
397  !SDL_getenv("SDL_VIDEO_X11_VISUALID")) {
398  XVisualInfo *vinfo = NULL;
399 
400 #if SDL_VIDEO_OPENGL_EGL
403  && ( !_this->gl_data || X11_GL_UseEGL(_this) )
404 #endif
405  ) {
406  vinfo = X11_GLES_GetVisual(_this, display, screen);
407  } else
408 #endif
409  {
410 #if SDL_VIDEO_OPENGL_GLX
411  vinfo = X11_GL_GetVisual(_this, display, screen);
412 #endif
413  }
414 
415  if (!vinfo) {
416  return -1;
417  }
418  visual = vinfo->visual;
419  depth = vinfo->depth;
420  X11_XFree(vinfo);
421  } else
422 #endif
423  {
424  visual = displaydata->visual;
425  depth = displaydata->depth;
426  }
427 
428  xattr.override_redirect = ((window->flags & SDL_WINDOW_TOOLTIP) || (window->flags & SDL_WINDOW_POPUP_MENU)) ? True : False;
429  xattr.background_pixmap = None;
430  xattr.border_pixel = 0;
431 
432  if (visual->class == DirectColor) {
433  XColor *colorcells;
434  int i;
435  int ncolors;
436  int rmax, gmax, bmax;
437  int rmask, gmask, bmask;
438  int rshift, gshift, bshift;
439 
440  xattr.colormap =
441  X11_XCreateColormap(display, RootWindow(display, screen),
442  visual, AllocAll);
443 
444  /* If we can't create a colormap, then we must die */
445  if (!xattr.colormap) {
446  return SDL_SetError("Could not create writable colormap");
447  }
448 
449  /* OK, we got a colormap, now fill it in as best as we can */
450  colorcells = SDL_malloc(visual->map_entries * sizeof(XColor));
451  if (!colorcells) {
452  return SDL_OutOfMemory();
453  }
454  ncolors = visual->map_entries;
455  rmax = 0xffff;
456  gmax = 0xffff;
457  bmax = 0xffff;
458 
459  rshift = 0;
460  rmask = visual->red_mask;
461  while (0 == (rmask & 1)) {
462  rshift++;
463  rmask >>= 1;
464  }
465 
466  gshift = 0;
467  gmask = visual->green_mask;
468  while (0 == (gmask & 1)) {
469  gshift++;
470  gmask >>= 1;
471  }
472 
473  bshift = 0;
474  bmask = visual->blue_mask;
475  while (0 == (bmask & 1)) {
476  bshift++;
477  bmask >>= 1;
478  }
479 
480  /* build the color table pixel values */
481  for (i = 0; i < ncolors; i++) {
482  Uint32 red = (rmax * i) / (ncolors - 1);
483  Uint32 green = (gmax * i) / (ncolors - 1);
484  Uint32 blue = (bmax * i) / (ncolors - 1);
485 
486  Uint32 rbits = (rmask * i) / (ncolors - 1);
487  Uint32 gbits = (gmask * i) / (ncolors - 1);
488  Uint32 bbits = (bmask * i) / (ncolors - 1);
489 
490  Uint32 pix =
491  (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
492 
493  colorcells[i].pixel = pix;
494 
495  colorcells[i].red = red;
496  colorcells[i].green = green;
497  colorcells[i].blue = blue;
498 
499  colorcells[i].flags = DoRed | DoGreen | DoBlue;
500  }
501 
502  X11_XStoreColors(display, xattr.colormap, colorcells, ncolors);
503 
504  SDL_free(colorcells);
505  } else {
506  xattr.colormap =
507  X11_XCreateColormap(display, RootWindow(display, screen),
508  visual, AllocNone);
509  }
510 
511  w = X11_XCreateWindow(display, RootWindow(display, screen),
512  window->x, window->y, window->w, window->h,
513  0, depth, InputOutput, visual,
514  (CWOverrideRedirect | CWBackPixmap | CWBorderPixel |
515  CWColormap), &xattr);
516  if (!w) {
517  return SDL_SetError("Couldn't create window");
518  }
519 
520  SetWindowBordered(display, screen, w,
521  (window->flags & SDL_WINDOW_BORDERLESS) == 0);
522 
523  sizehints = X11_XAllocSizeHints();
524  /* Setup the normal size hints */
525  sizehints->flags = 0;
526  if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
527  sizehints->min_width = sizehints->max_width = window->w;
528  sizehints->min_height = sizehints->max_height = window->h;
529  sizehints->flags |= (PMaxSize | PMinSize);
530  }
531  sizehints->x = window->x;
532  sizehints->y = window->y;
533  sizehints->flags |= USPosition;
534 
535  /* Setup the input hints so we get keyboard input */
536  wmhints = X11_XAllocWMHints();
537  wmhints->input = True;
538  wmhints->window_group = data->window_group;
539  wmhints->flags = InputHint | WindowGroupHint;
540 
541  /* Setup the class hints so we can get an icon (AfterStep) */
542  classhints = X11_XAllocClassHint();
543  classhints->res_name = data->classname;
544  classhints->res_class = data->classname;
545 
546  /* Set the size, input and class hints, and define WM_CLIENT_MACHINE and WM_LOCALE_NAME */
547  X11_XSetWMProperties(display, w, NULL, NULL, NULL, 0, sizehints, wmhints, classhints);
548 
549  X11_XFree(sizehints);
550  X11_XFree(wmhints);
551  X11_XFree(classhints);
552  /* Set the PID related to the window for the given hostname, if possible */
553  if (data->pid > 0) {
554  long pid = (long) data->pid;
555  _NET_WM_PID = X11_XInternAtom(display, "_NET_WM_PID", False);
556  X11_XChangeProperty(display, w, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace,
557  (unsigned char *) &pid, 1);
558  }
559 
560  /* Set the window manager state */
562 
563  compositor = 2; /* don't disable compositing except for "normal" windows */
564 
565  if (window->flags & SDL_WINDOW_UTILITY) {
566  wintype_name = "_NET_WM_WINDOW_TYPE_UTILITY";
567  } else if (window->flags & SDL_WINDOW_TOOLTIP) {
568  wintype_name = "_NET_WM_WINDOW_TYPE_TOOLTIP";
569  } else if (window->flags & SDL_WINDOW_POPUP_MENU) {
570  wintype_name = "_NET_WM_WINDOW_TYPE_POPUP_MENU";
571  } else {
572  wintype_name = "_NET_WM_WINDOW_TYPE_NORMAL";
573  compositor = 1; /* disable compositing for "normal" windows */
574  }
575 
576  /* Let the window manager know what type of window we are. */
577  _NET_WM_WINDOW_TYPE = X11_XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
578  wintype = X11_XInternAtom(display, wintype_name, False);
579  X11_XChangeProperty(display, w, _NET_WM_WINDOW_TYPE, XA_ATOM, 32,
580  PropModeReplace, (unsigned char *)&wintype, 1);
582  _NET_WM_BYPASS_COMPOSITOR = X11_XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False);
583  X11_XChangeProperty(display, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
584  PropModeReplace,
585  (unsigned char *)&compositor, 1);
586  }
587 
588  {
589  Atom protocols[3];
590  int proto_count = 0;
591 
592  protocols[proto_count++] = data->WM_DELETE_WINDOW; /* Allow window to be deleted by the WM */
593  protocols[proto_count++] = data->WM_TAKE_FOCUS; /* Since we will want to set input focus explicitly */
594 
595  /* Default to using ping if there is no hint */
597  protocols[proto_count++] = data->_NET_WM_PING; /* Respond so WM knows we're alive */
598  }
599 
600  SDL_assert(proto_count <= sizeof(protocols) / sizeof(protocols[0]));
601 
602  X11_XSetWMProtocols(display, w, protocols, proto_count);
603  }
604 
605  if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
606  X11_XDestroyWindow(display, w);
607  return -1;
608  }
609  windowdata = (SDL_WindowData *) window->driverdata;
610 
612  if ((window->flags & SDL_WINDOW_OPENGL) &&
614 #if SDL_VIDEO_OPENGL_GLX
615  && ( !_this->gl_data || X11_GL_UseEGL(_this) )
616 #endif
617  ) {
618 #if SDL_VIDEO_OPENGL_EGL
619  if (!_this->egl_data) {
620  X11_XDestroyWindow(display, w);
621  return -1;
622  }
623 
624  /* Create the GLES window surface */
625  windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) w);
626 
627  if (windowdata->egl_surface == EGL_NO_SURFACE) {
628  X11_XDestroyWindow(display, w);
629  return SDL_SetError("Could not create GLES window surface");
630  }
631 #else
632  return SDL_SetError("Could not create GLES window surface (EGL support not configured)");
633 #endif /* SDL_VIDEO_OPENGL_EGL */
634  }
635 #endif
636 
637 
638 #ifdef X_HAVE_UTF8_STRING
639  if (SDL_X11_HAVE_UTF8 && windowdata->ic) {
640  X11_XGetICValues(windowdata->ic, XNFilterEvents, &fevent, NULL);
641  }
642 #endif
643 
645 
646  X11_XSelectInput(display, w,
647  (FocusChangeMask | EnterWindowMask | LeaveWindowMask |
648  ExposureMask | ButtonPressMask | ButtonReleaseMask |
649  PointerMotionMask | KeyPressMask | KeyReleaseMask |
650  PropertyChangeMask | StructureNotifyMask |
651  KeymapStateMask | fevent));
652 
653  X11_XFlush(display);
654 
655  return 0;
656 }
657 
658 int
660 {
661  Window w = (Window) data;
662 
663  window->title = X11_GetWindowTitle(_this, w);
664 
665  if (SetupWindowData(_this, window, w, SDL_FALSE) < 0) {
666  return -1;
667  }
668  return 0;
669 }
670 
671 char *
672 X11_GetWindowTitle(_THIS, Window xwindow)
673 {
675  Display *display = data->display;
676  int status, real_format;
677  Atom real_type;
678  unsigned long items_read, items_left;
679  unsigned char *propdata;
680  char *title = NULL;
681 
682  status = X11_XGetWindowProperty(display, xwindow, data->_NET_WM_NAME,
683  0L, 8192L, False, data->UTF8_STRING, &real_type, &real_format,
684  &items_read, &items_left, &propdata);
685  if (status == Success && propdata) {
686  title = SDL_strdup(SDL_static_cast(char*, propdata));
687  X11_XFree(propdata);
688  } else {
689  status = X11_XGetWindowProperty(display, xwindow, XA_WM_NAME,
690  0L, 8192L, False, XA_STRING, &real_type, &real_format,
691  &items_read, &items_left, &propdata);
692  if (status == Success && propdata) {
693  title = SDL_iconv_string("UTF-8", "", SDL_static_cast(char*, propdata), items_read+1);
694  X11_XFree(propdata);
695  } else {
696  title = SDL_strdup("");
697  }
698  }
699  return title;
700 }
701 
702 void
704 {
705  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
706  Display *display = data->videodata->display;
707  XTextProperty titleprop;
708  Status status;
709  const char *title = window->title ? window->title : "";
710  char *title_locale = NULL;
711 
712 #ifdef X_HAVE_UTF8_STRING
713  Atom _NET_WM_NAME = data->videodata->_NET_WM_NAME;
714 #endif
715 
716  title_locale = SDL_iconv_utf8_locale(title);
717  if (!title_locale) {
718  SDL_OutOfMemory();
719  return;
720  }
721 
722  status = X11_XStringListToTextProperty(&title_locale, 1, &titleprop);
723  SDL_free(title_locale);
724  if (status) {
725  X11_XSetTextProperty(display, data->xwindow, &titleprop, XA_WM_NAME);
726  X11_XFree(titleprop.value);
727  }
728 #ifdef X_HAVE_UTF8_STRING
729  if (SDL_X11_HAVE_UTF8) {
730  status = X11_Xutf8TextListToTextProperty(display, (char **) &title, 1,
731  XUTF8StringStyle, &titleprop);
732  if (status == Success) {
733  X11_XSetTextProperty(display, data->xwindow, &titleprop,
734  _NET_WM_NAME);
735  X11_XFree(titleprop.value);
736  }
737  }
738 #endif
739 
740  X11_XFlush(display);
741 }
742 
743 void
745 {
746  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
747  Display *display = data->videodata->display;
748  Atom _NET_WM_ICON = data->videodata->_NET_WM_ICON;
749 
750  if (icon) {
751  int propsize;
752  long *propdata;
753 
754  /* Set the _NET_WM_ICON property */
756  propsize = 2 + (icon->w * icon->h);
757  propdata = SDL_malloc(propsize * sizeof(long));
758  if (propdata) {
759  int x, y;
760  Uint32 *src;
761  long *dst;
762 
763  propdata[0] = icon->w;
764  propdata[1] = icon->h;
765  dst = &propdata[2];
766  for (y = 0; y < icon->h; ++y) {
767  src = (Uint32*)((Uint8*)icon->pixels + y * icon->pitch);
768  for (x = 0; x < icon->w; ++x) {
769  *dst++ = *src++;
770  }
771  }
772  X11_XChangeProperty(display, data->xwindow, _NET_WM_ICON, XA_CARDINAL,
773  32, PropModeReplace, (unsigned char *) propdata,
774  propsize);
775  }
776  SDL_free(propdata);
777  } else {
778  X11_XDeleteProperty(display, data->xwindow, _NET_WM_ICON);
779  }
780  X11_XFlush(display);
781 }
782 
783 void
785 {
786  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
787  Display *display = data->videodata->display;
788 
789  X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
790  X11_XFlush(display);
791 }
792 
793 void
795 {
796  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
797  Display *display = data->videodata->display;
798 
799  if (window->flags & SDL_WINDOW_RESIZABLE) {
800  XSizeHints *sizehints = X11_XAllocSizeHints();
801  long userhints;
802 
803  X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
804 
805  sizehints->min_width = window->min_w;
806  sizehints->min_height = window->min_h;
807  sizehints->flags |= PMinSize;
808 
809  X11_XSetWMNormalHints(display, data->xwindow, sizehints);
810 
811  X11_XFree(sizehints);
812 
813  /* See comment in X11_SetWindowSize. */
814  X11_XResizeWindow(display, data->xwindow, window->w, window->h);
815  X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
816  X11_XRaiseWindow(display, data->xwindow);
817  }
818 
819  X11_XFlush(display);
820 }
821 
822 void
824 {
825  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
826  Display *display = data->videodata->display;
827 
828  if (window->flags & SDL_WINDOW_RESIZABLE) {
829  XSizeHints *sizehints = X11_XAllocSizeHints();
830  long userhints;
831 
832  X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
833 
834  sizehints->max_width = window->max_w;
835  sizehints->max_height = window->max_h;
836  sizehints->flags |= PMaxSize;
837 
838  X11_XSetWMNormalHints(display, data->xwindow, sizehints);
839 
840  X11_XFree(sizehints);
841 
842  /* See comment in X11_SetWindowSize. */
843  X11_XResizeWindow(display, data->xwindow, window->w, window->h);
844  X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
845  X11_XRaiseWindow(display, data->xwindow);
846  }
847 
848  X11_XFlush(display);
849 }
850 
851 void
853 {
854  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
855  Display *display = data->videodata->display;
856 
857  if (SDL_IsShapedWindow(window)) {
859  }
860  if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
861  /* Apparently, if the X11 Window is set to a 'non-resizable' window, you cannot resize it using the X11_XResizeWindow, thus
862  we must set the size hints to adjust the window size. */
863  XSizeHints *sizehints = X11_XAllocSizeHints();
864  long userhints;
865 
866  X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
867 
868  sizehints->min_width = sizehints->max_width = window->w;
869  sizehints->min_height = sizehints->max_height = window->h;
870  sizehints->flags |= PMinSize | PMaxSize;
871 
872  X11_XSetWMNormalHints(display, data->xwindow, sizehints);
873 
874  X11_XFree(sizehints);
875 
876  /* From Pierre-Loup:
877  WMs each have their little quirks with that. When you change the
878  size hints, they get a ConfigureNotify event with the
879  WM_NORMAL_SIZE_HINTS Atom. They all save the hints then, but they
880  don't all resize the window right away to enforce the new hints.
881 
882  Some of them resize only after:
883  - A user-initiated move or resize
884  - A code-initiated move or resize
885  - Hiding & showing window (Unmap & map)
886 
887  The following move & resize seems to help a lot of WMs that didn't
888  properly update after the hints were changed. We don't do a
889  hide/show, because there are supposedly subtle problems with doing so
890  and transitioning from windowed to fullscreen in Unity.
891  */
892  X11_XResizeWindow(display, data->xwindow, window->w, window->h);
893  X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
894  X11_XRaiseWindow(display, data->xwindow);
895  } else {
896  X11_XResizeWindow(display, data->xwindow, window->w, window->h);
897  }
898 
899  X11_XFlush(display);
900 }
901 
902 int
904 {
905  SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
906 
907  *left = data->border_left;
908  *right = data->border_right;
909  *top = data->border_top;
910  *bottom = data->border_bottom;
911 
912  return 0;
913 }
914 
915 int
916 X11_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
917 {
918  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
919  Display *display = data->videodata->display;
920  Atom _NET_WM_WINDOW_OPACITY = data->videodata->_NET_WM_WINDOW_OPACITY;
921 
922  if (opacity == 1.0f) {
923  X11_XDeleteProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY);
924  } else {
925  const Uint32 FullyOpaque = 0xFFFFFFFF;
926  const long alpha = (long) ((double)opacity * (double)FullyOpaque);
927  X11_XChangeProperty(display, data->xwindow, _NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32,
928  PropModeReplace, (unsigned char *)&alpha, 1);
929  }
930 
931  return 0;
932 }
933 
934 int
935 X11_SetWindowModalFor(_THIS, SDL_Window * modal_window, SDL_Window * parent_window) {
936  SDL_WindowData *data = (SDL_WindowData *) modal_window->driverdata;
937  SDL_WindowData *parent_data = (SDL_WindowData *) parent_window->driverdata;
938  Display *display = data->videodata->display;
939 
940  X11_XSetTransientForHint(display, data->xwindow, parent_data->xwindow);
941  return 0;
942 }
943 
944 int
946 {
947  if (X11_IsWindowMapped(_this, window)) {
948  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
949  Display *display = data->videodata->display;
950  X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime);
951  X11_XFlush(display);
952  return 0;
953  }
954  return -1;
955 }
956 
957 void
959 {
960  const SDL_bool focused = ((window->flags & SDL_WINDOW_INPUT_FOCUS) != 0);
961  const SDL_bool visible = ((window->flags & SDL_WINDOW_HIDDEN) == 0);
962  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
963  SDL_DisplayData *displaydata =
965  Display *display = data->videodata->display;
966  XEvent event;
967 
968  SetWindowBordered(display, displaydata->screen, data->xwindow, bordered);
969  X11_XFlush(display);
970 
971  if (visible) {
972  XWindowAttributes attr;
973  do {
974  X11_XSync(display, False);
975  X11_XGetWindowAttributes(display, data->xwindow, &attr);
976  } while (attr.map_state != IsViewable);
977 
978  if (focused) {
979  X11_XSetInputFocus(display, data->xwindow, RevertToParent, CurrentTime);
980  }
981  }
982 
983  /* make sure these don't make it to the real event queue if they fired here. */
984  X11_XSync(display, False);
985  X11_XCheckIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow);
986  X11_XCheckIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow);
987 }
988 
989 void
991 {
992  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
993  Display *display = data->videodata->display;
994 
995  XSizeHints *sizehints = X11_XAllocSizeHints();
996  long userhints;
997 
998  X11_XGetWMNormalHints(display, data->xwindow, sizehints, &userhints);
999 
1000  if (resizable) {
1001  /* FIXME: Is there a better way to get max window size from X? -flibit */
1002  const int maxsize = 0x7FFFFFFF;
1003  sizehints->min_width = window->min_w;
1004  sizehints->min_height = window->min_h;
1005  sizehints->max_width = (window->max_w == 0) ? maxsize : window->max_w;
1006  sizehints->max_height = (window->max_h == 0) ? maxsize : window->max_h;
1007  } else {
1008  sizehints->min_width = window->w;
1009  sizehints->min_height = window->h;
1010  sizehints->max_width = window->w;
1011  sizehints->max_height = window->h;
1012  }
1013  sizehints->flags |= PMinSize | PMaxSize;
1014 
1015  X11_XSetWMNormalHints(display, data->xwindow, sizehints);
1016 
1017  X11_XFree(sizehints);
1018 
1019  /* See comment in X11_SetWindowSize. */
1020  X11_XResizeWindow(display, data->xwindow, window->w, window->h);
1021  X11_XMoveWindow(display, data->xwindow, window->x - data->border_left, window->y - data->border_top);
1022  X11_XRaiseWindow(display, data->xwindow);
1023 
1024  X11_XFlush(display);
1025 }
1026 
1027 void
1029 {
1030  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1031  Display *display = data->videodata->display;
1032  XEvent event;
1033 
1034  if (!X11_IsWindowMapped(_this, window)) {
1035  X11_XMapRaised(display, data->xwindow);
1036  /* Blocking wait for "MapNotify" event.
1037  * We use X11_XIfEvent because pXWindowEvent takes a mask rather than a type,
1038  * and XCheckTypedWindowEvent doesn't block */
1039  if(!(window->flags & SDL_WINDOW_FOREIGN))
1040  X11_XIfEvent(display, &event, &isMapNotify, (XPointer)&data->xwindow);
1041  X11_XFlush(display);
1042  }
1043 
1044  if (!data->videodata->net_wm) {
1045  /* no WM means no FocusIn event, which confuses us. Force it. */
1046  X11_XSetInputFocus(display, data->xwindow, RevertToNone, CurrentTime);
1047  X11_XFlush(display);
1048  }
1049 }
1050 
1051 void
1053 {
1054  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1056  Display *display = data->videodata->display;
1057  XEvent event;
1058 
1059  if (X11_IsWindowMapped(_this, window)) {
1060  X11_XWithdrawWindow(display, data->xwindow, displaydata->screen);
1061  /* Blocking wait for "UnmapNotify" event */
1062  if(!(window->flags & SDL_WINDOW_FOREIGN))
1063  X11_XIfEvent(display, &event, &isUnmapNotify, (XPointer)&data->xwindow);
1064  X11_XFlush(display);
1065  }
1066 }
1067 
1068 static void
1069 SetWindowActive(_THIS, SDL_Window * window)
1070 {
1071  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1072  SDL_DisplayData *displaydata =
1074  Display *display = data->videodata->display;
1075  Atom _NET_ACTIVE_WINDOW = data->videodata->_NET_ACTIVE_WINDOW;
1076 
1077  if (X11_IsWindowMapped(_this, window)) {
1078  XEvent e;
1079 
1080  /*printf("SDL Window %p: sending _NET_ACTIVE_WINDOW with timestamp %lu\n", window, data->user_time);*/
1081 
1082  SDL_zero(e);
1083  e.xany.type = ClientMessage;
1084  e.xclient.message_type = _NET_ACTIVE_WINDOW;
1085  e.xclient.format = 32;
1086  e.xclient.window = data->xwindow;
1087  e.xclient.data.l[0] = 1; /* source indication. 1 = application */
1088  e.xclient.data.l[1] = data->user_time;
1089  e.xclient.data.l[2] = 0;
1090 
1091  X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1092  SubstructureNotifyMask | SubstructureRedirectMask, &e);
1093 
1094  X11_XFlush(display);
1095  }
1096 }
1097 
1098 void
1100 {
1101  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1102  Display *display = data->videodata->display;
1103 
1104  X11_XRaiseWindow(display, data->xwindow);
1105  SetWindowActive(_this, window);
1106  X11_XFlush(display);
1107 }
1108 
1109 static void
1110 SetWindowMaximized(_THIS, SDL_Window * window, SDL_bool maximized)
1111 {
1112  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1113  SDL_DisplayData *displaydata =
1115  Display *display = data->videodata->display;
1116  Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
1117  Atom _NET_WM_STATE_MAXIMIZED_VERT = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
1118  Atom _NET_WM_STATE_MAXIMIZED_HORZ = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
1119 
1120  if (maximized) {
1121  window->flags |= SDL_WINDOW_MAXIMIZED;
1122  } else {
1123  window->flags &= ~SDL_WINDOW_MAXIMIZED;
1124  }
1125 
1126  if (X11_IsWindowMapped(_this, window)) {
1127  XEvent e;
1128 
1129  SDL_zero(e);
1130  e.xany.type = ClientMessage;
1131  e.xclient.message_type = _NET_WM_STATE;
1132  e.xclient.format = 32;
1133  e.xclient.window = data->xwindow;
1134  e.xclient.data.l[0] =
1135  maximized ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1136  e.xclient.data.l[1] = _NET_WM_STATE_MAXIMIZED_VERT;
1137  e.xclient.data.l[2] = _NET_WM_STATE_MAXIMIZED_HORZ;
1138  e.xclient.data.l[3] = 0l;
1139 
1140  X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1141  SubstructureNotifyMask | SubstructureRedirectMask, &e);
1142  } else {
1143  X11_SetNetWMState(_this, data->xwindow, window->flags);
1144  }
1145  X11_XFlush(display);
1146 }
1147 
1148 void
1150 {
1151  SetWindowMaximized(_this, window, SDL_TRUE);
1152 }
1153 
1154 void
1156 {
1157  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1158  SDL_DisplayData *displaydata =
1160  Display *display = data->videodata->display;
1161 
1162  X11_XIconifyWindow(display, data->xwindow, displaydata->screen);
1163  X11_XFlush(display);
1164 }
1165 
1166 void
1168 {
1169  SetWindowMaximized(_this, window, SDL_FALSE);
1171  SetWindowActive(_this, window);
1172 }
1173 
1174 /* This asks the Window Manager to handle fullscreen for us. This is the modern way. */
1175 static void
1176 X11_SetWindowFullscreenViaWM(_THIS, SDL_Window * window, SDL_VideoDisplay * _display, SDL_bool fullscreen)
1177 {
1178  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1179  SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
1180  Display *display = data->videodata->display;
1181  Atom _NET_WM_STATE = data->videodata->_NET_WM_STATE;
1182  Atom _NET_WM_STATE_FULLSCREEN = data->videodata->_NET_WM_STATE_FULLSCREEN;
1183 
1184  if (X11_IsWindowMapped(_this, window)) {
1185  XEvent e;
1186 
1187  if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
1188  /* Compiz refuses fullscreen toggle if we're not resizable, so update the hints so we
1189  can be resized to the fullscreen resolution (or reset so we're not resizable again) */
1190  XSizeHints *sizehints = X11_XAllocSizeHints();
1191  long flags = 0;
1192  X11_XGetWMNormalHints(display, data->xwindow, sizehints, &flags);
1193  /* set the resize flags on */
1194  if (fullscreen) {
1195  /* we are going fullscreen so turn the flags off */
1196  sizehints->flags &= ~(PMinSize | PMaxSize);
1197  } else {
1198  /* Reset the min/max width height to make the window non-resizable again */
1199  sizehints->flags |= PMinSize | PMaxSize;
1200  sizehints->min_width = sizehints->max_width = window->windowed.w;
1201  sizehints->min_height = sizehints->max_height = window->windowed.h;
1202  }
1203  X11_XSetWMNormalHints(display, data->xwindow, sizehints);
1204  X11_XFree(sizehints);
1205  }
1206 
1207  SDL_zero(e);
1208  e.xany.type = ClientMessage;
1209  e.xclient.message_type = _NET_WM_STATE;
1210  e.xclient.format = 32;
1211  e.xclient.window = data->xwindow;
1212  e.xclient.data.l[0] =
1213  fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1214  e.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN;
1215  e.xclient.data.l[3] = 0l;
1216 
1217  X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1218  SubstructureNotifyMask | SubstructureRedirectMask, &e);
1219 
1220  /* Fullscreen windows sometimes end up being marked maximized by
1221  window managers. Force it back to how we expect it to be. */
1222  if (!fullscreen && ((window->flags & SDL_WINDOW_MAXIMIZED) == 0)) {
1223  SDL_zero(e);
1224  e.xany.type = ClientMessage;
1225  e.xclient.message_type = _NET_WM_STATE;
1226  e.xclient.format = 32;
1227  e.xclient.window = data->xwindow;
1228  e.xclient.data.l[0] = _NET_WM_STATE_REMOVE;
1229  e.xclient.data.l[1] = data->videodata->_NET_WM_STATE_MAXIMIZED_VERT;
1230  e.xclient.data.l[2] = data->videodata->_NET_WM_STATE_MAXIMIZED_HORZ;
1231  e.xclient.data.l[3] = 0l;
1232  X11_XSendEvent(display, RootWindow(display, displaydata->screen), 0,
1233  SubstructureNotifyMask | SubstructureRedirectMask, &e);
1234  }
1235  } else {
1236  Uint32 flags;
1237 
1238  flags = window->flags;
1239  if (fullscreen) {
1241  } else {
1243  }
1244  X11_SetNetWMState(_this, data->xwindow, flags);
1245  }
1246 
1247  if (data->visual->class == DirectColor) {
1248  if ( fullscreen ) {
1249  X11_XInstallColormap(display, data->colormap);
1250  } else {
1251  X11_XUninstallColormap(display, data->colormap);
1252  }
1253  }
1254 
1255  X11_XFlush(display);
1256 }
1257 
1258 /* This handles fullscreen itself, outside the Window Manager. */
1259 static void
1260 X11_BeginWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display)
1261 {
1262  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1263  SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
1264  Visual *visual = data->visual;
1265  Display *display = data->videodata->display;
1266  const int screen = displaydata->screen;
1267  Window root = RootWindow(display, screen);
1268  const int def_vis = (visual == DefaultVisual(display, screen));
1269  unsigned long xattrmask = 0;
1270  XSetWindowAttributes xattr;
1271  XEvent ev;
1272  SDL_Rect rect;
1273 
1274  if ( data->fswindow ) {
1275  return; /* already fullscreen, I hope. */
1276  }
1277 
1278  X11_GetDisplayBounds(_this, _display, &rect);
1279 
1280  SDL_zero(xattr);
1281  xattr.override_redirect = True;
1282  xattrmask |= CWOverrideRedirect;
1283  xattr.background_pixel = def_vis ? BlackPixel(display, screen) : 0;
1284  xattrmask |= CWBackPixel;
1285  xattr.border_pixel = 0;
1286  xattrmask |= CWBorderPixel;
1287  xattr.colormap = data->colormap;
1288  xattrmask |= CWColormap;
1289 
1290  data->fswindow = X11_XCreateWindow(display, root,
1291  rect.x, rect.y, rect.w, rect.h, 0,
1292  displaydata->depth, InputOutput,
1293  visual, xattrmask, &xattr);
1294 
1295  X11_XSelectInput(display, data->fswindow, StructureNotifyMask);
1296  X11_XSetWindowBackground(display, data->fswindow, 0);
1297  X11_XInstallColormap(display, data->colormap);
1298  X11_XClearWindow(display, data->fswindow);
1299  X11_XMapRaised(display, data->fswindow);
1300 
1301  /* Make sure the fswindow is in view by warping mouse to the corner */
1302  X11_XUngrabPointer(display, CurrentTime);
1303  X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
1304 
1305  /* Wait to be mapped, filter Unmap event out if it arrives. */
1306  X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow);
1307  X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow);
1308 
1309 #if SDL_VIDEO_DRIVER_X11_XVIDMODE
1310  if ( displaydata->use_vidmode ) {
1311  X11_XF86VidModeLockModeSwitch(display, screen, True);
1312  }
1313 #endif
1314 
1315  SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE);
1316 
1317  /* Center actual window within our cover-the-screen window. */
1318  X11_XReparentWindow(display, data->xwindow, data->fswindow,
1319  (rect.w - window->w) / 2, (rect.h - window->h) / 2);
1320 
1321  /* Move the mouse to the upper left to make sure it's on-screen */
1322  X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
1323 
1324  /* Center mouse in the fullscreen window. */
1325  rect.x += (rect.w / 2);
1326  rect.y += (rect.h / 2);
1327  X11_XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
1328 
1329  /* Wait to be mapped, filter Unmap event out if it arrives. */
1330  X11_XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
1331  X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
1332 
1334 }
1335 
1336 static void
1337 X11_EndWindowFullscreenLegacy(_THIS, SDL_Window * window, SDL_VideoDisplay * _display)
1338 {
1339  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1340  SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
1341  Display *display = data->videodata->display;
1342  const int screen = displaydata->screen;
1343  Window root = RootWindow(display, screen);
1344  Window fswindow = data->fswindow;
1345  XEvent ev;
1346 
1347  if (!data->fswindow) {
1348  return; /* already not fullscreen, I hope. */
1349  }
1350 
1351  data->fswindow = None;
1352 
1353 #if SDL_VIDEO_DRIVER_X11_VIDMODE
1354  if ( displaydata->use_vidmode ) {
1355  X11_XF86VidModeLockModeSwitch(display, screen, False);
1356  }
1357 #endif
1358 
1360 
1361  X11_XReparentWindow(display, data->xwindow, root, window->x, window->y);
1362 
1363  /* flush these events so they don't confuse normal event handling */
1364  X11_XSync(display, False);
1365  X11_XCheckIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
1366  X11_XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
1367 
1368  SetWindowBordered(display, screen, data->xwindow,
1369  (window->flags & SDL_WINDOW_BORDERLESS) == 0);
1370 
1371  X11_XWithdrawWindow(display, fswindow, screen);
1372 
1373  /* Wait to be unmapped. */
1374  X11_XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow);
1375  X11_XDestroyWindow(display, fswindow);
1376 }
1377 
1378 
1379 void
1381 {
1382  /* !!! FIXME: SDL_Hint? */
1383  SDL_bool legacy = SDL_FALSE;
1384  const char *env = SDL_getenv("SDL_VIDEO_X11_LEGACY_FULLSCREEN");
1385  if (env) {
1386  legacy = SDL_atoi(env);
1387  } else {
1388  SDL_VideoData *videodata = (SDL_VideoData *) _this->driverdata;
1389  SDL_DisplayData *displaydata = (SDL_DisplayData *) _display->driverdata;
1390  if ( displaydata->use_vidmode ) {
1391  legacy = SDL_TRUE; /* the new stuff only works with XRandR. */
1392  } else if ( !videodata->net_wm ) {
1393  legacy = SDL_TRUE; /* The window manager doesn't support it */
1394  } else {
1395  /* !!! FIXME: look at the window manager name, and blacklist certain ones? */
1396  /* http://stackoverflow.com/questions/758648/find-the-name-of-the-x-window-manager */
1397  legacy = SDL_FALSE; /* try the new way. */
1398  }
1399  }
1400 
1401  if (legacy) {
1402  if (fullscreen) {
1403  X11_BeginWindowFullscreenLegacy(_this, window, _display);
1404  } else {
1405  X11_EndWindowFullscreenLegacy(_this, window, _display);
1406  }
1407  } else {
1408  X11_SetWindowFullscreenViaWM(_this, window, _display, fullscreen);
1409  }
1410 }
1411 
1412 
1413 int
1415 {
1416  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1417  Display *display = data->videodata->display;
1418  Visual *visual = data->visual;
1419  Colormap colormap = data->colormap;
1420  XColor *colorcells;
1421  int ncolors;
1422  int rmask, gmask, bmask;
1423  int rshift, gshift, bshift;
1424  int i;
1425 
1426  if (visual->class != DirectColor) {
1427  return SDL_SetError("Window doesn't have DirectColor visual");
1428  }
1429 
1430  ncolors = visual->map_entries;
1431  colorcells = SDL_malloc(ncolors * sizeof(XColor));
1432  if (!colorcells) {
1433  return SDL_OutOfMemory();
1434  }
1435 
1436  rshift = 0;
1437  rmask = visual->red_mask;
1438  while (0 == (rmask & 1)) {
1439  rshift++;
1440  rmask >>= 1;
1441  }
1442 
1443  gshift = 0;
1444  gmask = visual->green_mask;
1445  while (0 == (gmask & 1)) {
1446  gshift++;
1447  gmask >>= 1;
1448  }
1449 
1450  bshift = 0;
1451  bmask = visual->blue_mask;
1452  while (0 == (bmask & 1)) {
1453  bshift++;
1454  bmask >>= 1;
1455  }
1456 
1457  /* build the color table pixel values */
1458  for (i = 0; i < ncolors; i++) {
1459  Uint32 rbits = (rmask * i) / (ncolors - 1);
1460  Uint32 gbits = (gmask * i) / (ncolors - 1);
1461  Uint32 bbits = (bmask * i) / (ncolors - 1);
1462  Uint32 pix = (rbits << rshift) | (gbits << gshift) | (bbits << bshift);
1463 
1464  colorcells[i].pixel = pix;
1465 
1466  colorcells[i].red = ramp[(0 * 256) + i];
1467  colorcells[i].green = ramp[(1 * 256) + i];
1468  colorcells[i].blue = ramp[(2 * 256) + i];
1469 
1470  colorcells[i].flags = DoRed | DoGreen | DoBlue;
1471  }
1472 
1473  X11_XStoreColors(display, colormap, colorcells, ncolors);
1474  X11_XFlush(display);
1475  SDL_free(colorcells);
1476 
1477  return 0;
1478 }
1479 
1480 void
1482 {
1483  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1484  Display *display = data->videodata->display;
1485  SDL_bool oldstyle_fullscreen;
1486  SDL_bool grab_keyboard;
1487 
1488  /* ICCCM2.0-compliant window managers can handle fullscreen windows
1489  If we're using XVidMode to change resolution we need to confine
1490  the cursor so we don't pan around the virtual desktop.
1491  */
1492  oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window);
1493 
1494  if (oldstyle_fullscreen || grabbed) {
1495  /* Try to grab the mouse */
1496  if (!data->videodata->broken_pointer_grab) {
1497  const unsigned int mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | FocusChangeMask;
1498  int attempts;
1499  int result;
1500 
1501  /* Try for up to 5000ms (5s) to grab. If it still fails, stop trying. */
1502  for (attempts = 0; attempts < 100; attempts++) {
1503  result = X11_XGrabPointer(display, data->xwindow, True, mask, GrabModeAsync,
1504  GrabModeAsync, data->xwindow, None, CurrentTime);
1505  if (result == GrabSuccess) {
1506  break;
1507  }
1508  SDL_Delay(50);
1509  }
1510 
1511  if (result != GrabSuccess) {
1512  SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "The X server refused to let us grab the mouse. You might experience input bugs.");
1513  data->videodata->broken_pointer_grab = SDL_TRUE; /* don't try again. */
1514  }
1515  }
1516 
1517  /* Raise the window if we grab the mouse */
1518  X11_XRaiseWindow(display, data->xwindow);
1519 
1520  /* Now grab the keyboard */
1522  grab_keyboard = SDL_TRUE;
1523  } else {
1524  /* We need to do this with the old style override_redirect
1525  fullscreen window otherwise we won't get keyboard focus.
1526  */
1527  grab_keyboard = oldstyle_fullscreen;
1528  }
1529  if (grab_keyboard) {
1530  X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
1531  GrabModeAsync, CurrentTime);
1532  }
1533  } else {
1534  X11_XUngrabPointer(display, CurrentTime);
1535  X11_XUngrabKeyboard(display, CurrentTime);
1536  }
1537  X11_XSync(display, False);
1538 }
1539 
1540 void
1542 {
1543  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1544 
1545  if (data) {
1546  SDL_VideoData *videodata = (SDL_VideoData *) data->videodata;
1547  Display *display = videodata->display;
1548  int numwindows = videodata->numwindows;
1549  SDL_WindowData **windowlist = videodata->windowlist;
1550  int i;
1551 
1552  if (windowlist) {
1553  for (i = 0; i < numwindows; ++i) {
1554  if (windowlist[i] && (windowlist[i]->window == window)) {
1555  windowlist[i] = windowlist[numwindows - 1];
1556  windowlist[numwindows - 1] = NULL;
1557  videodata->numwindows--;
1558  break;
1559  }
1560  }
1561  }
1562 #ifdef X_HAVE_UTF8_STRING
1563  if (data->ic) {
1564  X11_XDestroyIC(data->ic);
1565  }
1566 #endif
1567  if (data->created) {
1568  X11_XDestroyWindow(display, data->xwindow);
1569  X11_XFlush(display);
1570  }
1571  SDL_free(data);
1572  }
1573  window->driverdata = NULL;
1574 }
1575 
1576 SDL_bool
1578 {
1579  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1580  Display *display = data->videodata->display;
1581 
1582  if (info->version.major == SDL_MAJOR_VERSION &&
1583  info->version.minor == SDL_MINOR_VERSION) {
1584  info->subsystem = SDL_SYSWM_X11;
1585  info->info.x11.display = display;
1586  info->info.x11.window = data->xwindow;
1587  return SDL_TRUE;
1588  } else {
1589  SDL_SetError("Application not compiled with SDL %d.%d",
1591  return SDL_FALSE;
1592  }
1593 }
1594 
1595 int
1597 {
1598  return 0; /* just succeed, the real work is done elsewhere. */
1599 }
1600 
1601 void
1603 {
1604  SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
1605  Display *display = data->videodata->display;
1606  Atom XdndAware = X11_XInternAtom(display, "XdndAware", False);
1607 
1608  if (accept) {
1609  Atom xdnd_version = 5;
1610  X11_XChangeProperty(display, data->xwindow, XdndAware, XA_ATOM, 32,
1611  PropModeReplace, (unsigned char*)&xdnd_version, 1);
1612  } else {
1613  X11_XDeleteProperty(display, data->xwindow, XdndAware);
1614  }
1615 }
1616 
1617 #endif /* SDL_VIDEO_DRIVER_X11 */
1618 
1619 /* vi: set ts=4 sw=4 expandtab: */
SDL_VideoData::net_wm
SDL_bool net_wm
Definition: SDL_x11video.h:89
X11_MaximizeWindow
void X11_MaximizeWindow(_THIS, SDL_Window *window)
SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
X11_DestroyWindow
void X11_DestroyWindow(_THIS, SDL_Window *window)
SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
#define SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR
A variable controlling whether the X11 _NET_WM_BYPASS_COMPOSITOR hint should be used.
Definition: SDL_hints.h:224
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
X11_SetWindowIcon
void X11_SetWindowIcon(_THIS, SDL_Window *window, SDL_Surface *icon)
X11_MinimizeWindow
void X11_MinimizeWindow(_THIS, SDL_Window *window)
screen
SDL_Renderer * screen
Definition: testgamecontroller.c:64
SDL_VideoDevice::driverdata
void * driverdata
Definition: SDL_sysvideo.h:381
SDL_VideoData::_NET_WM_STATE_ABOVE
Atom _NET_WM_STATE_ABOVE
Definition: SDL_x11video.h:101
SDL_static_cast
#define SDL_static_cast(type, expression)
Definition: SDL_stdinc.h:138
right
GLdouble GLdouble right
Definition: SDL_opengl_glext.h:6103
SDL_x11video.h
SDL_WindowData::border_left
int border_left
Definition: SDL_x11window.h:59
mask
GLenum GLint GLuint mask
Definition: SDL_opengl_glext.h:657
SDL_x11mouse.h
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
SDL_WINDOW_ALWAYS_ON_TOP
Definition: SDL_video.h:117
SDL_VIDEO_OPENGL_GLX
#define SDL_VIDEO_OPENGL_GLX
Definition: SDL_config.h:379
SDL_IsShapedWindow
#define SDL_IsShapedWindow
Definition: SDL_dynapi_overrides.h:371
NULL
#define NULL
Definition: begin_code.h:167
SDL_PixelFormat::format
Uint32 format
Definition: SDL_pixels.h:317
SDL_VideoDevice::gl_config
struct SDL_VideoDevice::@262 gl_config
SDL_timer.h
SDL_Surface::pixels
void * pixels
Definition: SDL_surface.h:76
SDL_SysWMinfo::info
union SDL_SysWMinfo::@17 info
NativeWindowType
EGLNativeWindowType NativeWindowType
Definition: eglplatform.h:112
SDL_SysWMinfo
Definition: SDL_syswm.h:197
dpy
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display dpy)
Definition: SDL_x11sym.h:44
SDL_log.h
SDL_Surface::w
int w
Definition: SDL_surface.h:74
SDL_WindowData
Definition: SDL_androidwindow.h:38
SDL_x11shape.h
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1570
SDL_version::minor
Uint8 minor
Definition: SDL_version.h:54
SDL_GetDisplayForWindow
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
Definition: SDL_video.c:1089
X11_SetWindowHitTest
int X11_SetWindowHitTest(SDL_Window *window, SDL_bool enabled)
SDL_WINDOW_FULLSCREEN
Definition: SDL_video.h:100
X11_RestoreWindow
void X11_RestoreWindow(_THIS, SDL_Window *window)
SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
SDL_VideoDevice::gl_data
struct SDL_GLDriverData * gl_data
Definition: SDL_sysvideo.h:382
SDL_realloc
#define SDL_realloc
Definition: SDL_dynapi_overrides.h:376
top
GLdouble GLdouble GLdouble GLdouble top
Definition: SDL_opengl_glext.h:6103
X11_GetWindowBordersSize
int X11_GetWindowBordersSize(_THIS, SDL_Window *window, int *top, int *left, int *bottom, int *right)
red
const GLubyte GLuint red
Definition: SDL_glfuncs.h:79
SDL_VideoData::windowlistlength
int windowlistlength
Definition: SDL_x11video.h:84
SDL_SetKeyboardFocus
void SDL_SetKeyboardFocus(SDL_Window *window)
Definition: SDL_keyboard.c:630
SDL_WINDOW_FOREIGN
Definition: SDL_video.h:112
SDL_iconv_utf8_locale
#define SDL_iconv_utf8_locale(S)
Definition: SDL_stdinc.h:562
SDL_VideoDevice::profile_mask
int profile_mask
Definition: SDL_sysvideo.h:346
SDL_WINDOW_MAXIMIZED
Definition: SDL_video.h:107
bottom
GLint GLint bottom
Definition: SDL_opengl_glext.h:1949
X11_SetWindowMinimumSize
void X11_SetWindowMinimumSize(_THIS, SDL_Window *window)
SDL_VideoData::windowlist
SDL_WindowData ** windowlist
Definition: SDL_x11video.h:83
SDL_Rect::x
int x
Definition: SDL_rect.h:79
X11_GetWindowWMInfo
SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window *window, struct SDL_SysWMinfo *info)
X11_SetWindowOpacity
int X11_SetWindowOpacity(_THIS, SDL_Window *window, float opacity)
SDL_WINDOW_INPUT_FOCUS
Definition: SDL_video.h:109
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9432
SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:105
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1973
SDL_Rect::w
int w
Definition: SDL_rect.h:80
X11_HideWindow
void X11_HideWindow(_THIS, SDL_Window *window)
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:73
alpha
GLfloat GLfloat GLfloat alpha
Definition: SDL_opengl_glext.h:412
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_Surface::pitch
int pitch
Definition: SDL_surface.h:75
X11_GetWindowTitle
char * X11_GetWindowTitle(_THIS, Window xwindow)
SDL_VIDEO_OPENGL_ES
#define SDL_VIDEO_OPENGL_ES
Definition: SDL_config_android.h:158
X11_SetWindowInputFocus
int X11_SetWindowInputFocus(_THIS, SDL_Window *window)
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2926
SDL_WINDOW_POPUP_MENU
Definition: SDL_video.h:121
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_GetHintBoolean
#define SDL_GetHintBoolean
Definition: SDL_dynapi_overrides.h:608
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_VideoData::numwindows
int numwindows
Definition: SDL_x11video.h:82
X11_SetWindowPosition
void X11_SetWindowPosition(_THIS, SDL_Window *window)
SDL_SysWMinfo::x11
struct SDL_SysWMinfo::@17::@18 x11
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
SDL_MINOR_VERSION
#define SDL_MINOR_VERSION
Definition: SDL_version.h:61
SDL_VideoData::_NET_WM_STATE_MAXIMIZED_HORZ
Atom _NET_WM_STATE_MAXIMIZED_HORZ
Definition: SDL_x11video.h:99
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1573
SDL_SysWMinfo::subsystem
SDL_SYSWM_TYPE subsystem
Definition: SDL_syswm.h:200
SDL_HINT_GRAB_KEYBOARD
#define SDL_HINT_GRAB_KEYBOARD
A variable controlling whether grabbing input grabs the keyboard.
Definition: SDL_hints.h:263
X11_ShowWindow
void X11_ShowWindow(_THIS, SDL_Window *window)
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
EGL_NO_SURFACE
#define EGL_NO_SURFACE
Definition: egl.h:100
SDL_Rect::y
int y
Definition: SDL_rect.h:79
SDL_Rect::h
int h
Definition: SDL_rect.h:80
X11_SetWindowModalFor
int X11_SetWindowModalFor(_THIS, SDL_Window *modal_window, SDL_Window *parent_window)
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
SDL_VideoData::im
XIM im
Definition: SDL_x11video.h:80
SDL_VideoData::_NET_WM_STATE_SKIP_TASKBAR
Atom _NET_WM_STATE_SKIP_TASKBAR
Definition: SDL_x11video.h:102
X11_SetWindowTitle
void X11_SetWindowTitle(_THIS, SDL_Window *window)
SDL_SYSWM_X11
Definition: SDL_syswm.h:123
SDL_VideoData::_NET_WM_STATE_HIDDEN
Atom _NET_WM_STATE_HIDDEN
Definition: SDL_x11video.h:96
SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_HINT_VIDEO_X11_NET_WM_PING
#define SDL_HINT_VIDEO_X11_NET_WM_PING
A variable controlling whether the X11 _NET_WM_PING protocol should be supported.
Definition: SDL_hints.h:212
SDL_VideoData::_NET_WM_STATE_MAXIMIZED_VERT
Atom _NET_WM_STATE_MAXIMIZED_VERT
Definition: SDL_x11video.h:98
rect
SDL_Rect rect
Definition: testrelative.c:27
X11_AcceptDragAndDrop
void X11_AcceptDragAndDrop(SDL_Window *window, SDL_bool accept)
SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:233
SDL_WINDOW_TOOLTIP
Definition: SDL_video.h:120
SDL_LOG_CATEGORY_VIDEO
Definition: SDL_log.h:71
X11_SetWindowResizable
void X11_SetWindowResizable(_THIS, SDL_Window *window, SDL_bool resizable)
SDL_assert.h
X11_RaiseWindow
void X11_RaiseWindow(_THIS, SDL_Window *window)
_THIS
#define _THIS
Definition: SDL_alsa_audio.h:31
SDL_UpdateWindowGrab
void SDL_UpdateWindowGrab(SDL_Window *window)
Definition: SDL_video.c:2520
SDL_WINDOW_INPUT_GRABBED
Definition: SDL_video.h:108
X11_SetWindowBordered
void X11_SetWindowBordered(_THIS, SDL_Window *window, SDL_bool bordered)
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:248
blue
GLbyte GLbyte blue
Definition: SDL_opengl_glext.h:379
green
GLbyte green
Definition: SDL_opengl_glext.h:379
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
depth
GLint GLint GLsizei GLsizei GLsizei depth
Definition: SDL_opengl.h:1571
SDL_WINDOW_SHOWN
Definition: SDL_video.h:102
SDL_VideoDisplay::driverdata
void * driverdata
Definition: SDL_sysvideo.h:139
SDL_DisplayData
Definition: SDL_cocoamodes.h:26
SDL_x11opengles.h
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_VideoDevice::flags
int flags
Definition: SDL_sysvideo.h:345
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1573
SDL_WINDOW_UTILITY
Definition: SDL_video.h:119
SDL_VideoData::_NET_WM_ALLOWED_ACTIONS
Atom _NET_WM_ALLOWED_ACTIONS
Definition: SDL_x11video.h:104
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_Surface::h
int h
Definition: SDL_surface.h:74
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_atoi
#define SDL_atoi
Definition: SDL_dynapi_overrides.h:410
SDL_VideoData::display
struct wl_display * display
Definition: SDL_waylandvideo.h:50
X11_CreateWindow
int X11_CreateWindow(_THIS, SDL_Window *window)
X11_GetNetWMState
Uint32 X11_GetNetWMState(_THIS, Window xwindow)
SDL_Window::driverdata
void * driverdata
Definition: SDL_sysvideo.h:111
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_getenv
#define SDL_getenv
Definition: SDL_dynapi_overrides.h:378
X11_SetWindowGrab
void X11_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed)
SDL_WINDOW_HIDDEN
Definition: SDL_video.h:103
SDL_WindowData::ic
XIC ic
Definition: SDL_x11window.h:57
X11_SetWindowGammaRamp
int X11_SetWindowGammaRamp(_THIS, SDL_Window *window, const Uint16 *ramp)
SDL_SysWMinfo::version
SDL_version version
Definition: SDL_syswm.h:199
SDL_iconv_string
#define SDL_iconv_string
Definition: SDL_dynapi_overrides.h:441
X11_SetWindowMaximumSize
void X11_SetWindowMaximumSize(_THIS, SDL_Window *window)
SDL_VideoDisplay
Definition: SDL_sysvideo.h:125
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
X11_GetDisplayBounds
int X11_GetDisplayBounds(_THIS, SDL_VideoDisplay *sdl_display, SDL_Rect *rect)
SDL_Rect
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:77
SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_x11xinput2.h
SDL_hints.h
e
const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char const char const SDL_SCANF_FORMAT_STRING char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 Uint32 * e
Definition: SDL_dynapi_procs.h:117
left
GLint left
Definition: SDL_opengl_glext.h:1949
SDL_VideoData::_NET_WM_STATE
Atom _NET_WM_STATE
Definition: SDL_x11video.h:95
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
enabled
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: SDL_opengl_glext.h:2479
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_WindowData::videodata
struct SDL_VideoData * videodata
Definition: SDL_cocoawindow.h:121
SDL_VideoData::_NET_WM_STATE_SKIP_PAGER
Atom _NET_WM_STATE_SKIP_PAGER
Definition: SDL_x11video.h:103
SDL_VIDEO_OPENGL_ES2
#define SDL_VIDEO_OPENGL_ES2
Definition: SDL_config.h:375
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_version::major
Uint8 major
Definition: SDL_version.h:53
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
SDL_MAJOR_VERSION
#define SDL_MAJOR_VERSION
Definition: SDL_version.h:60
X11_SetWindowSize
void X11_SetWindowSize(_THIS, SDL_Window *window)
X11_CreateWindowFrom
int X11_CreateWindowFrom(_THIS, SDL_Window *window, const void *data)
SDL_LogWarn
#define SDL_LogWarn
Definition: SDL_dynapi_overrides.h:35
X11_SetWindowFullscreen
void X11_SetWindowFullscreen(_THIS, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
X11_Xinput2SelectTouch
void X11_Xinput2SelectTouch(_THIS, SDL_Window *window)
SDL_WINDOW_SKIP_TASKBAR
Definition: SDL_video.h:118
SDL_WindowData::egl_surface
EGLSurface egl_surface
Definition: SDL_androidwindow.h:40
border
GLint GLint GLsizei GLsizei GLsizei GLint border
Definition: SDL_opengl.h:1571
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:73
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1570
i
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
X11_SetNetWMState
void X11_SetNetWMState(_THIS, Window xwindow, Uint32 flags)
maxLength
GLsizei maxLength
Definition: SDL_opengl_glext.h:3644
X11_ResizeWindowShape
int X11_ResizeWindowShape(SDL_Window *window)
Uint16
uint16_t Uint16
Definition: SDL_stdinc.h:191
SDL_VideoData::_NET_WM_STATE_FULLSCREEN
Atom _NET_WM_STATE_FULLSCREEN
Definition: SDL_x11video.h:100
SDL_VideoData
Definition: SDL_androidvideo.h:36
SDL_VideoData::_NET_WM_STATE_FOCUSED
Atom _NET_WM_STATE_FOCUSED
Definition: SDL_x11video.h:97
SDL_syswm.h
SDL_WINDOW_BORDERLESS
Definition: SDL_video.h:104
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731