x11_window.c
Go to the documentation of this file.
1 //========================================================================
2 // GLFW 3.3 X11 - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2002-2006 Marcus Geelnard
5 // Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
6 //
7 // This software is provided 'as-is', without any express or implied
8 // warranty. In no event will the authors be held liable for any damages
9 // arising from the use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose,
12 // including commercial applications, and to alter it and redistribute it
13 // freely, subject to the following restrictions:
14 //
15 // 1. The origin of this software must not be misrepresented; you must not
16 // claim that you wrote the original software. If you use this software
17 // in a product, an acknowledgment in the product documentation would
18 // be appreciated but is not required.
19 //
20 // 2. Altered source versions must be plainly marked as such, and must not
21 // be misrepresented as being the original software.
22 //
23 // 3. This notice may not be removed or altered from any source
24 // distribution.
25 //
26 //========================================================================
27 
28 #include "internal.h"
29 
30 #include <X11/cursorfont.h>
31 #include <X11/Xmd.h>
32 
33 #include <sys/select.h>
34 
35 #include <string.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <limits.h>
39 #include <errno.h>
40 #include <assert.h>
41 
42 // Action for EWMH client messages
43 #define _NET_WM_STATE_REMOVE 0
44 #define _NET_WM_STATE_ADD 1
45 #define _NET_WM_STATE_TOGGLE 2
46 
47 // Additional mouse button names for XButtonEvent
48 #define Button6 6
49 #define Button7 7
50 
51 #define _GLFW_XDND_VERSION 5
52 
53 
54 // Wait for data to arrive using select
55 // This avoids blocking other threads via the per-display Xlib lock that also
56 // covers GLX functions
57 //
58 static GLFWbool waitForEvent(double* timeout)
59 {
60  fd_set fds;
61  const int fd = ConnectionNumber(_glfw.x11.display);
62  int count = fd + 1;
63 
64 #if defined(__linux__)
65  if (_glfw.linjs.inotify > fd)
66  count = _glfw.linjs.inotify + 1;
67 #endif
68  for (;;)
69  {
70  FD_ZERO(&fds);
71  FD_SET(fd, &fds);
72 #if defined(__linux__)
73  if (_glfw.linjs.inotify > 0)
74  FD_SET(_glfw.linjs.inotify, &fds);
75 #endif
76 
77  if (timeout)
78  {
79  const long seconds = (long) *timeout;
80  const long microseconds = (long) ((*timeout - seconds) * 1e6);
81  struct timeval tv = { seconds, microseconds };
82  const uint64_t base = _glfwPlatformGetTimerValue();
83 
84  const int result = select(count, &fds, NULL, NULL, &tv);
85  const int error = errno;
86 
87  *timeout -= (_glfwPlatformGetTimerValue() - base) /
89 
90  if (result > 0)
91  return GLFW_TRUE;
92  if ((result == -1 && error == EINTR) || *timeout <= 0.0)
93  return GLFW_FALSE;
94  }
95  else if (select(count, &fds, NULL, NULL, NULL) != -1 || errno != EINTR)
96  return GLFW_TRUE;
97  }
98 }
99 
100 // Waits until a VisibilityNotify event arrives for the specified window or the
101 // timeout period elapses (ICCCM section 4.2.2)
102 //
104 {
105  XEvent dummy;
106  double timeout = 0.1;
107 
108  while (!XCheckTypedWindowEvent(_glfw.x11.display,
109  window->x11.handle,
110  VisibilityNotify,
111  &dummy))
112  {
113  if (!waitForEvent(&timeout))
114  return GLFW_FALSE;
115  }
116 
117  return GLFW_TRUE;
118 }
119 
120 // Returns whether the window is iconified
121 //
123 {
124  int result = WithdrawnState;
125  struct {
126  CARD32 state;
127  Window icon;
128  } *state = NULL;
129 
130  if (_glfwGetWindowPropertyX11(window->x11.handle,
131  _glfw.x11.WM_STATE,
132  _glfw.x11.WM_STATE,
133  (unsigned char**) &state) >= 2)
134  {
135  result = state->state;
136  }
137 
138  if (state)
139  XFree(state);
140 
141  return result;
142 }
143 
144 // Returns whether the event is a selection event
145 //
146 static Bool isSelectionEvent(Display* display, XEvent* event, XPointer pointer)
147 {
148  if (event->xany.window != _glfw.x11.helperWindowHandle)
149  return False;
150 
151  return event->type == SelectionRequest ||
152  event->type == SelectionNotify ||
153  event->type == SelectionClear;
154 }
155 
156 // Returns whether it is a _NET_FRAME_EXTENTS event for the specified window
157 //
158 static Bool isFrameExtentsEvent(Display* display, XEvent* event, XPointer pointer)
159 {
160  _GLFWwindow* window = (_GLFWwindow*) pointer;
161  return event->type == PropertyNotify &&
162  event->xproperty.state == PropertyNewValue &&
163  event->xproperty.window == window->x11.handle &&
164  event->xproperty.atom == _glfw.x11.NET_FRAME_EXTENTS;
165 }
166 
167 // Returns whether it is a property event for the specified selection transfer
168 //
169 static Bool isSelPropNewValueNotify(Display* display, XEvent* event, XPointer pointer)
170 {
171  XEvent* notification = (XEvent*) pointer;
172  return event->type == PropertyNotify &&
173  event->xproperty.state == PropertyNewValue &&
174  event->xproperty.window == notification->xselection.requestor &&
175  event->xproperty.atom == notification->xselection.property;
176 }
177 
178 // Translates an X event modifier state mask
179 //
180 static int translateState(int state)
181 {
182  int mods = 0;
183 
184  if (state & ShiftMask)
185  mods |= GLFW_MOD_SHIFT;
186  if (state & ControlMask)
187  mods |= GLFW_MOD_CONTROL;
188  if (state & Mod1Mask)
189  mods |= GLFW_MOD_ALT;
190  if (state & Mod4Mask)
191  mods |= GLFW_MOD_SUPER;
192  if (state & LockMask)
193  mods |= GLFW_MOD_CAPS_LOCK;
194  if (state & Mod2Mask)
195  mods |= GLFW_MOD_NUM_LOCK;
196 
197  return mods;
198 }
199 
200 // Translates an X11 key code to a GLFW key token
201 //
202 static int translateKey(int scancode)
203 {
204  // Use the pre-filled LUT (see createKeyTables() in x11_init.c)
205  if (scancode < 0 || scancode > 255)
206  return GLFW_KEY_UNKNOWN;
207 
208  return _glfw.x11.keycodes[scancode];
209 }
210 
211 // Sends an EWMH or ICCCM event to the window manager
212 //
214  long a, long b, long c, long d, long e)
215 {
216  XEvent event;
217  memset(&event, 0, sizeof(event));
218 
219  event.type = ClientMessage;
220  event.xclient.window = window->x11.handle;
221  event.xclient.format = 32; // Data is 32-bit longs
222  event.xclient.message_type = type;
223  event.xclient.data.l[0] = a;
224  event.xclient.data.l[1] = b;
225  event.xclient.data.l[2] = c;
226  event.xclient.data.l[3] = d;
227  event.xclient.data.l[4] = e;
228 
229  XSendEvent(_glfw.x11.display, _glfw.x11.root,
230  False,
231  SubstructureNotifyMask | SubstructureRedirectMask,
232  &event);
233 }
234 
235 // Updates the normal hints according to the window settings
236 //
238 {
239  XSizeHints* hints = XAllocSizeHints();
240 
241  if (!window->monitor)
242  {
243  if (window->resizable)
244  {
245  if (window->minwidth != GLFW_DONT_CARE &&
246  window->minheight != GLFW_DONT_CARE)
247  {
248  hints->flags |= PMinSize;
249  hints->min_width = window->minwidth;
250  hints->min_height = window->minheight;
251  }
252 
253  if (window->maxwidth != GLFW_DONT_CARE &&
254  window->maxheight != GLFW_DONT_CARE)
255  {
256  hints->flags |= PMaxSize;
257  hints->max_width = window->maxwidth;
258  hints->max_height = window->maxheight;
259  }
260 
261  if (window->numer != GLFW_DONT_CARE &&
262  window->denom != GLFW_DONT_CARE)
263  {
264  hints->flags |= PAspect;
265  hints->min_aspect.x = hints->max_aspect.x = window->numer;
266  hints->min_aspect.y = hints->max_aspect.y = window->denom;
267  }
268  }
269  else
270  {
271  hints->flags |= (PMinSize | PMaxSize);
272  hints->min_width = hints->max_width = width;
273  hints->min_height = hints->max_height = height;
274  }
275  }
276 
277  hints->flags |= PWinGravity;
278  hints->win_gravity = StaticGravity;
279 
280  XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
281  XFree(hints);
282 }
283 
284 // Updates the full screen status of the window
285 //
287 {
288  if (window->monitor)
289  {
290  if (_glfw.x11.xinerama.available &&
291  _glfw.x11.NET_WM_FULLSCREEN_MONITORS)
292  {
293  sendEventToWM(window,
294  _glfw.x11.NET_WM_FULLSCREEN_MONITORS,
295  window->monitor->x11.index,
296  window->monitor->x11.index,
297  window->monitor->x11.index,
298  window->monitor->x11.index,
299  0);
300  }
301 
302  if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
303  {
304  sendEventToWM(window,
305  _glfw.x11.NET_WM_STATE,
307  _glfw.x11.NET_WM_STATE_FULLSCREEN,
308  0, 1, 0);
309  }
310  else
311  {
312  // This is the butcher's way of removing window decorations
313  // Setting the override-redirect attribute on a window makes the
314  // window manager ignore the window completely (ICCCM, section 4)
315  // The good thing is that this makes undecorated full screen windows
316  // easy to do; the bad thing is that we have to do everything
317  // manually and some things (like iconify/restore) won't work at
318  // all, as those are tasks usually performed by the window manager
319 
320  XSetWindowAttributes attributes;
321  attributes.override_redirect = True;
322  XChangeWindowAttributes(_glfw.x11.display,
323  window->x11.handle,
324  CWOverrideRedirect,
325  &attributes);
326 
327  window->x11.overrideRedirect = GLFW_TRUE;
328  }
329 
330  // Enable compositor bypass
331  if (!window->x11.transparent)
332  {
333  const unsigned long value = 1;
334 
335  XChangeProperty(_glfw.x11.display, window->x11.handle,
336  _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32,
337  PropModeReplace, (unsigned char*) &value, 1);
338  }
339  }
340  else
341  {
342  if (_glfw.x11.xinerama.available &&
343  _glfw.x11.NET_WM_FULLSCREEN_MONITORS)
344  {
345  XDeleteProperty(_glfw.x11.display, window->x11.handle,
346  _glfw.x11.NET_WM_FULLSCREEN_MONITORS);
347  }
348 
349  if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN)
350  {
351  sendEventToWM(window,
352  _glfw.x11.NET_WM_STATE,
354  _glfw.x11.NET_WM_STATE_FULLSCREEN,
355  0, 1, 0);
356  }
357  else
358  {
359  XSetWindowAttributes attributes;
360  attributes.override_redirect = False;
361  XChangeWindowAttributes(_glfw.x11.display,
362  window->x11.handle,
363  CWOverrideRedirect,
364  &attributes);
365 
366  window->x11.overrideRedirect = GLFW_FALSE;
367  }
368 
369  // Disable compositor bypass
370  if (!window->x11.transparent)
371  {
372  XDeleteProperty(_glfw.x11.display, window->x11.handle,
373  _glfw.x11.NET_WM_BYPASS_COMPOSITOR);
374  }
375  }
376 }
377 
378 // Splits and translates a text/uri-list into separate file paths
379 // NOTE: This function destroys the provided string
380 //
381 static char** parseUriList(char* text, int* count)
382 {
383  const char* prefix = "file://";
384  char** paths = NULL;
385  char* line;
386 
387  *count = 0;
388 
389  while ((line = strtok(text, "\r\n")))
390  {
391  text = NULL;
392 
393  if (line[0] == '#')
394  continue;
395 
396  if (strncmp(line, prefix, strlen(prefix)) == 0)
397  {
398  line += strlen(prefix);
399  // TODO: Validate hostname
400  while (*line != '/')
401  line++;
402  }
403 
404  (*count)++;
405 
406  char* path = calloc(strlen(line) + 1, 1);
407  paths = realloc(paths, *count * sizeof(char*));
408  paths[*count - 1] = path;
409 
410  while (*line)
411  {
412  if (line[0] == '%' && line[1] && line[2])
413  {
414  const char digits[3] = { line[1], line[2], '\0' };
415  *path = strtol(digits, NULL, 16);
416  line += 2;
417  }
418  else
419  *path = *line;
420 
421  path++;
422  line++;
423  }
424  }
425 
426  return paths;
427 }
428 
429 // Encode a Unicode code point to a UTF-8 stream
430 // Based on cutef8 by Jeff Bezanson (Public Domain)
431 //
432 static size_t encodeUTF8(char* s, unsigned int ch)
433 {
434  size_t count = 0;
435 
436  if (ch < 0x80)
437  s[count++] = (char) ch;
438  else if (ch < 0x800)
439  {
440  s[count++] = (ch >> 6) | 0xc0;
441  s[count++] = (ch & 0x3f) | 0x80;
442  }
443  else if (ch < 0x10000)
444  {
445  s[count++] = (ch >> 12) | 0xe0;
446  s[count++] = ((ch >> 6) & 0x3f) | 0x80;
447  s[count++] = (ch & 0x3f) | 0x80;
448  }
449  else if (ch < 0x110000)
450  {
451  s[count++] = (ch >> 18) | 0xf0;
452  s[count++] = ((ch >> 12) & 0x3f) | 0x80;
453  s[count++] = ((ch >> 6) & 0x3f) | 0x80;
454  s[count++] = (ch & 0x3f) | 0x80;
455  }
456 
457  return count;
458 }
459 
460 // Decode a Unicode code point from a UTF-8 stream
461 // Based on cutef8 by Jeff Bezanson (Public Domain)
462 //
463 #if defined(X_HAVE_UTF8_STRING)
464 static unsigned int decodeUTF8(const char** s)
465 {
466  unsigned int ch = 0, count = 0;
467  static const unsigned int offsets[] =
468  {
469  0x00000000u, 0x00003080u, 0x000e2080u,
470  0x03c82080u, 0xfa082080u, 0x82082080u
471  };
472 
473  do
474  {
475  ch = (ch << 6) + (unsigned char) **s;
476  (*s)++;
477  count++;
478  } while ((**s & 0xc0) == 0x80);
479 
480  assert(count <= 6);
481  return ch - offsets[count - 1];
482 }
483 #endif /*X_HAVE_UTF8_STRING*/
484 
485 // Convert the specified Latin-1 string to UTF-8
486 //
487 static char* convertLatin1toUTF8(const char* source)
488 {
489  size_t size = 1;
490  const char* sp;
491 
492  for (sp = source; *sp; sp++)
493  size += (*sp & 0x80) ? 2 : 1;
494 
495  char* target = calloc(size, 1);
496  char* tp = target;
497 
498  for (sp = source; *sp; sp++)
499  tp += encodeUTF8(tp, *sp);
500 
501  return target;
502 }
503 
504 // Centers the cursor over the window client area
505 //
507 {
508  int width, height;
509  _glfwPlatformGetWindowSize(window, &width, &height);
510  _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
511 }
512 
513 // Updates the cursor image according to its cursor mode
514 //
516 {
517  if (window->cursorMode == GLFW_CURSOR_NORMAL)
518  {
519  if (window->cursor)
520  {
521  XDefineCursor(_glfw.x11.display, window->x11.handle,
522  window->cursor->x11.handle);
523  }
524  else
525  XUndefineCursor(_glfw.x11.display, window->x11.handle);
526  }
527  else
528  {
529  XDefineCursor(_glfw.x11.display, window->x11.handle,
530  _glfw.x11.hiddenCursorHandle);
531  }
532 }
533 
534 // Apply disabled cursor mode to a focused window
535 //
537 {
538  if (_glfw.x11.xi.available)
539  {
540  XIEventMask em;
541  unsigned char mask[XIMaskLen(XI_RawMotion)] = { 0 };
542 
543  em.deviceid = XIAllMasterDevices;
544  em.mask_len = sizeof(mask);
545  em.mask = mask;
546  XISetMask(mask, XI_RawMotion);
547 
548  XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
549  }
550 
551  _glfw.x11.disabledCursorWindow = window;
553  &_glfw.x11.restoreCursorPosX,
554  &_glfw.x11.restoreCursorPosY);
555  updateCursorImage(window);
556  centerCursor(window);
557  XGrabPointer(_glfw.x11.display, window->x11.handle, True,
558  ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
559  GrabModeAsync, GrabModeAsync,
560  window->x11.handle,
561  _glfw.x11.hiddenCursorHandle,
562  CurrentTime);
563 }
564 
565 // Exit disabled cursor mode for the specified window
566 //
568 {
569  if (_glfw.x11.xi.available)
570  {
571  XIEventMask em;
572  unsigned char mask[] = { 0 };
573 
574  em.deviceid = XIAllMasterDevices;
575  em.mask_len = sizeof(mask);
576  em.mask = mask;
577 
578  XISelectEvents(_glfw.x11.display, _glfw.x11.root, &em, 1);
579  }
580 
581  _glfw.x11.disabledCursorWindow = NULL;
582  XUngrabPointer(_glfw.x11.display, CurrentTime);
584  _glfw.x11.restoreCursorPosX,
585  _glfw.x11.restoreCursorPosY);
586  updateCursorImage(window);
587 }
588 
589 // Create the X11 window (and its colormap)
590 //
592  const _GLFWwndconfig* wndconfig,
593  Visual* visual, int depth)
594 {
595  int width = wndconfig->width;
596  int height = wndconfig->height;
597 
598  if (wndconfig->scaleToMonitor)
599  {
600  width *= _glfw.x11.contentScaleX;
601  height *= _glfw.x11.contentScaleY;
602  }
603 
604  // Create a colormap based on the visual used by the current context
605  window->x11.colormap = XCreateColormap(_glfw.x11.display,
606  _glfw.x11.root,
607  visual,
608  AllocNone);
609 
610  window->x11.transparent = _glfwIsVisualTransparentX11(visual);
611 
612  // Create the actual window
613  {
614  XSetWindowAttributes wa;
615  const unsigned long wamask = CWBorderPixel | CWColormap | CWEventMask;
616 
617  wa.colormap = window->x11.colormap;
618  wa.border_pixel = 0;
619  wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
620  PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
621  ExposureMask | FocusChangeMask | VisibilityChangeMask |
622  EnterWindowMask | LeaveWindowMask | PropertyChangeMask;
623 
625 
626  window->x11.handle = XCreateWindow(_glfw.x11.display,
627  _glfw.x11.root,
628  0, 0,
629  width, height,
630  0, // Border width
631  depth, // Color depth
632  InputOutput,
633  visual,
634  wamask,
635  &wa);
636 
638 
639  if (!window->x11.handle)
640  {
642  "X11: Failed to create window");
643  return GLFW_FALSE;
644  }
645 
646  XSaveContext(_glfw.x11.display,
647  window->x11.handle,
648  _glfw.x11.context,
649  (XPointer) window);
650  }
651 
652  if (!wndconfig->decorated)
654 
655  if (_glfw.x11.NET_WM_STATE && !window->monitor)
656  {
657  Atom states[3];
658  int count = 0;
659 
660  if (wndconfig->floating)
661  {
662  if (_glfw.x11.NET_WM_STATE_ABOVE)
663  states[count++] = _glfw.x11.NET_WM_STATE_ABOVE;
664  }
665 
666  if (wndconfig->maximized)
667  {
668  if (_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
669  _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
670  {
671  states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT;
672  states[count++] = _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ;
673  window->x11.maximized = GLFW_TRUE;
674  }
675  }
676 
677  if (count)
678  {
679  XChangeProperty(_glfw.x11.display, window->x11.handle,
680  _glfw.x11.NET_WM_STATE, XA_ATOM, 32,
681  PropModeReplace, (unsigned char*) &states, count);
682  }
683  }
684 
685  // Declare the WM protocols supported by GLFW
686  {
687  Atom protocols[] =
688  {
689  _glfw.x11.WM_DELETE_WINDOW,
690  _glfw.x11.NET_WM_PING
691  };
692 
693  XSetWMProtocols(_glfw.x11.display, window->x11.handle,
694  protocols, sizeof(protocols) / sizeof(Atom));
695  }
696 
697  // Declare our PID
698  {
699  const long pid = getpid();
700 
701  XChangeProperty(_glfw.x11.display, window->x11.handle,
702  _glfw.x11.NET_WM_PID, XA_CARDINAL, 32,
703  PropModeReplace,
704  (unsigned char*) &pid, 1);
705  }
706 
707  if (_glfw.x11.NET_WM_WINDOW_TYPE && _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL)
708  {
709  Atom type = _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL;
710  XChangeProperty(_glfw.x11.display, window->x11.handle,
711  _glfw.x11.NET_WM_WINDOW_TYPE, XA_ATOM, 32,
712  PropModeReplace, (unsigned char*) &type, 1);
713  }
714 
715  // Set ICCCM WM_HINTS property
716  {
717  XWMHints* hints = XAllocWMHints();
718  if (!hints)
719  {
721  "X11: Failed to allocate WM hints");
722  return GLFW_FALSE;
723  }
724 
725  hints->flags = StateHint;
726  hints->initial_state = NormalState;
727 
728  XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
729  XFree(hints);
730  }
731 
732  updateNormalHints(window, width, height);
733 
734  // Set ICCCM WM_CLASS property
735  {
736  XClassHint* hint = XAllocClassHint();
737 
738  if (strlen(wndconfig->x11.instanceName) &&
739  strlen(wndconfig->x11.className))
740  {
741  hint->res_name = (char*) wndconfig->x11.instanceName;
742  hint->res_class = (char*) wndconfig->x11.className;
743  }
744  else
745  {
746  const char* resourceName = getenv("RESOURCE_NAME");
747  if (resourceName && strlen(resourceName))
748  hint->res_name = (char*) resourceName;
749  else if (strlen(wndconfig->title))
750  hint->res_name = (char*) wndconfig->title;
751  else
752  hint->res_name = (char*) "glfw-application";
753 
754  if (strlen(wndconfig->title))
755  hint->res_class = (char*) wndconfig->title;
756  else
757  hint->res_class = (char*) "GLFW-Application";
758  }
759 
760  XSetClassHint(_glfw.x11.display, window->x11.handle, hint);
761  XFree(hint);
762  }
763 
764  // Announce support for Xdnd (drag and drop)
765  {
766  const Atom version = _GLFW_XDND_VERSION;
767  XChangeProperty(_glfw.x11.display, window->x11.handle,
768  _glfw.x11.XdndAware, XA_ATOM, 32,
769  PropModeReplace, (unsigned char*) &version, 1);
770  }
771 
772  _glfwPlatformSetWindowTitle(window, wndconfig->title);
773 
774  if (_glfw.x11.im)
775  {
776  window->x11.ic = XCreateIC(_glfw.x11.im,
777  XNInputStyle,
778  XIMPreeditNothing | XIMStatusNothing,
779  XNClientWindow,
780  window->x11.handle,
781  XNFocusWindow,
782  window->x11.handle,
783  NULL);
784  }
785 
786  _glfwPlatformGetWindowPos(window, &window->x11.xpos, &window->x11.ypos);
787  _glfwPlatformGetWindowSize(window, &window->x11.width, &window->x11.height);
788 
789  return GLFW_TRUE;
790 }
791 
792 // Set the specified property to the selection converted to the requested target
793 //
794 static Atom writeTargetToProperty(const XSelectionRequestEvent* request)
795 {
796  int i;
797  char* selectionString = NULL;
798  const Atom formats[] = { _glfw.x11.UTF8_STRING, XA_STRING };
799  const int formatCount = sizeof(formats) / sizeof(formats[0]);
800 
801  if (request->selection == _glfw.x11.PRIMARY)
802  selectionString = _glfw.x11.primarySelectionString;
803  else
804  selectionString = _glfw.x11.clipboardString;
805 
806  if (request->property == None)
807  {
808  // The requester is a legacy client (ICCCM section 2.2)
809  // We don't support legacy clients, so fail here
810  return None;
811  }
812 
813  if (request->target == _glfw.x11.TARGETS)
814  {
815  // The list of supported targets was requested
816 
817  const Atom targets[] = { _glfw.x11.TARGETS,
818  _glfw.x11.MULTIPLE,
819  _glfw.x11.UTF8_STRING,
820  XA_STRING };
821 
822  XChangeProperty(_glfw.x11.display,
823  request->requestor,
824  request->property,
825  XA_ATOM,
826  32,
827  PropModeReplace,
828  (unsigned char*) targets,
829  sizeof(targets) / sizeof(targets[0]));
830 
831  return request->property;
832  }
833 
834  if (request->target == _glfw.x11.MULTIPLE)
835  {
836  // Multiple conversions were requested
837 
838  Atom* targets;
839  unsigned long i, count;
840 
841  count = _glfwGetWindowPropertyX11(request->requestor,
842  request->property,
843  _glfw.x11.ATOM_PAIR,
844  (unsigned char**) &targets);
845 
846  for (i = 0; i < count; i += 2)
847  {
848  int j;
849 
850  for (j = 0; j < formatCount; j++)
851  {
852  if (targets[i] == formats[j])
853  break;
854  }
855 
856  if (j < formatCount)
857  {
858  XChangeProperty(_glfw.x11.display,
859  request->requestor,
860  targets[i + 1],
861  targets[i],
862  8,
863  PropModeReplace,
864  (unsigned char *) selectionString,
865  strlen(selectionString));
866  }
867  else
868  targets[i + 1] = None;
869  }
870 
871  XChangeProperty(_glfw.x11.display,
872  request->requestor,
873  request->property,
874  _glfw.x11.ATOM_PAIR,
875  32,
876  PropModeReplace,
877  (unsigned char*) targets,
878  count);
879 
880  XFree(targets);
881 
882  return request->property;
883  }
884 
885  if (request->target == _glfw.x11.SAVE_TARGETS)
886  {
887  // The request is a check whether we support SAVE_TARGETS
888  // It should be handled as a no-op side effect target
889 
890  XChangeProperty(_glfw.x11.display,
891  request->requestor,
892  request->property,
893  _glfw.x11.NULL_,
894  32,
895  PropModeReplace,
896  NULL,
897  0);
898 
899  return request->property;
900  }
901 
902  // Conversion to a data target was requested
903 
904  for (i = 0; i < formatCount; i++)
905  {
906  if (request->target == formats[i])
907  {
908  // The requested target is one we support
909 
910  XChangeProperty(_glfw.x11.display,
911  request->requestor,
912  request->property,
913  request->target,
914  8,
915  PropModeReplace,
916  (unsigned char *) selectionString,
917  strlen(selectionString));
918 
919  return request->property;
920  }
921  }
922 
923  // The requested target is not supported
924 
925  return None;
926 }
927 
928 static void handleSelectionClear(XEvent* event)
929 {
930  if (event->xselectionclear.selection == _glfw.x11.PRIMARY)
931  {
932  free(_glfw.x11.primarySelectionString);
933  _glfw.x11.primarySelectionString = NULL;
934  }
935  else
936  {
937  free(_glfw.x11.clipboardString);
938  _glfw.x11.clipboardString = NULL;
939  }
940 }
941 
942 static void handleSelectionRequest(XEvent* event)
943 {
944  const XSelectionRequestEvent* request = &event->xselectionrequest;
945 
946  XEvent reply;
947  memset(&reply, 0, sizeof(reply));
948 
949  reply.xselection.property = writeTargetToProperty(request);
950  reply.xselection.type = SelectionNotify;
951  reply.xselection.display = request->display;
952  reply.xselection.requestor = request->requestor;
953  reply.xselection.selection = request->selection;
954  reply.xselection.target = request->target;
955  reply.xselection.time = request->time;
956 
957  XSendEvent(_glfw.x11.display, request->requestor, False, 0, &reply);
958 }
959 
960 static const char* getSelectionString(Atom selection)
961 {
962  size_t i;
963  char** selectionString = NULL;
964  const Atom targets[] = { _glfw.x11.UTF8_STRING, XA_STRING };
965  const size_t targetCount = sizeof(targets) / sizeof(targets[0]);
966 
967  if (selection == _glfw.x11.PRIMARY)
968  selectionString = &_glfw.x11.primarySelectionString;
969  else
970  selectionString = &_glfw.x11.clipboardString;
971 
972  if (XGetSelectionOwner(_glfw.x11.display, selection) ==
973  _glfw.x11.helperWindowHandle)
974  {
975  // Instead of doing a large number of X round-trips just to put this
976  // string into a window property and then read it back, just return it
977  return *selectionString;
978  }
979 
980  free(*selectionString);
981  *selectionString = NULL;
982 
983  for (i = 0; i < targetCount; i++)
984  {
985  char* data;
986  Atom actualType;
987  int actualFormat;
988  unsigned long itemCount, bytesAfter;
989  XEvent notification, dummy;
990 
991  XConvertSelection(_glfw.x11.display,
992  selection,
993  targets[i],
994  _glfw.x11.GLFW_SELECTION,
995  _glfw.x11.helperWindowHandle,
996  CurrentTime);
997 
998  while (!XCheckTypedWindowEvent(_glfw.x11.display,
999  _glfw.x11.helperWindowHandle,
1000  SelectionNotify,
1001  &notification))
1002  {
1003  waitForEvent(NULL);
1004  }
1005 
1006  if (notification.xselection.property == None)
1007  continue;
1008 
1009  XCheckIfEvent(_glfw.x11.display,
1010  &dummy,
1012  (XPointer) &notification);
1013 
1014  XGetWindowProperty(_glfw.x11.display,
1015  notification.xselection.requestor,
1016  notification.xselection.property,
1017  0,
1018  LONG_MAX,
1019  True,
1020  AnyPropertyType,
1021  &actualType,
1022  &actualFormat,
1023  &itemCount,
1024  &bytesAfter,
1025  (unsigned char**) &data);
1026 
1027  if (actualType == _glfw.x11.INCR)
1028  {
1029  size_t size = 1;
1030  char* string = NULL;
1031 
1032  for (;;)
1033  {
1034  while (!XCheckIfEvent(_glfw.x11.display,
1035  &dummy,
1037  (XPointer) &notification))
1038  {
1039  waitForEvent(NULL);
1040  }
1041 
1042  XFree(data);
1043  XGetWindowProperty(_glfw.x11.display,
1044  notification.xselection.requestor,
1045  notification.xselection.property,
1046  0,
1047  LONG_MAX,
1048  True,
1049  AnyPropertyType,
1050  &actualType,
1051  &actualFormat,
1052  &itemCount,
1053  &bytesAfter,
1054  (unsigned char**) &data);
1055 
1056  if (itemCount)
1057  {
1058  size += itemCount;
1059  string = realloc(string, size);
1060  string[size - itemCount - 1] = '\0';
1061  strcat(string, data);
1062  }
1063 
1064  if (!itemCount)
1065  {
1066  if (targets[i] == XA_STRING)
1067  {
1068  *selectionString = convertLatin1toUTF8(string);
1069  free(string);
1070  }
1071  else
1072  *selectionString = string;
1073 
1074  break;
1075  }
1076  }
1077  }
1078  else if (actualType == targets[i])
1079  {
1080  if (targets[i] == XA_STRING)
1081  *selectionString = convertLatin1toUTF8(data);
1082  else
1083  *selectionString = _glfw_strdup(data);
1084  }
1085 
1086  XFree(data);
1087 
1088  if (*selectionString)
1089  break;
1090  }
1091 
1092  if (!*selectionString)
1093  {
1095  "X11: Failed to convert selection to string");
1096  }
1097 
1098  return *selectionString;
1099 }
1100 
1101 // Make the specified window and its video mode active on its monitor
1102 //
1104 {
1105  if (_glfw.x11.saver.count == 0)
1106  {
1107  // Remember old screen saver settings
1108  XGetScreenSaver(_glfw.x11.display,
1109  &_glfw.x11.saver.timeout,
1110  &_glfw.x11.saver.interval,
1111  &_glfw.x11.saver.blanking,
1112  &_glfw.x11.saver.exposure);
1113 
1114  // Disable screen saver
1115  XSetScreenSaver(_glfw.x11.display, 0, 0, DontPreferBlanking,
1116  DefaultExposures);
1117  }
1118 
1119  if (!window->monitor->window)
1120  _glfw.x11.saver.count++;
1121 
1122  _glfwSetVideoModeX11(window->monitor, &window->videoMode);
1123 
1124  if (window->x11.overrideRedirect)
1125  {
1126  int xpos, ypos;
1127  GLFWvidmode mode;
1128 
1129  // Manually position the window over its monitor
1130  _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos);
1131  _glfwPlatformGetVideoMode(window->monitor, &mode);
1132 
1133  XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
1134  xpos, ypos, mode.width, mode.height);
1135  }
1136 
1137  _glfwInputMonitorWindow(window->monitor, window);
1138 }
1139 
1140 // Remove the window and restore the original video mode
1141 //
1143 {
1144  if (window->monitor->window != window)
1145  return;
1146 
1149 
1150  _glfw.x11.saver.count--;
1151 
1152  if (_glfw.x11.saver.count == 0)
1153  {
1154  // Restore old screen saver settings
1155  XSetScreenSaver(_glfw.x11.display,
1156  _glfw.x11.saver.timeout,
1157  _glfw.x11.saver.interval,
1158  _glfw.x11.saver.blanking,
1159  _glfw.x11.saver.exposure);
1160  }
1161 }
1162 
1163 // Process the specified X event
1164 //
1165 static void processEvent(XEvent *event)
1166 {
1167  _GLFWwindow* window = NULL;
1168  int keycode = 0;
1169  Bool filtered = False;
1170 
1171  // HACK: Save scancode as some IMs clear the field in XFilterEvent
1172  if (event->type == KeyPress || event->type == KeyRelease)
1173  keycode = event->xkey.keycode;
1174 
1175  if (_glfw.x11.im)
1176  filtered = XFilterEvent(event, None);
1177 
1178  if (_glfw.x11.randr.available)
1179  {
1180  if (event->type == _glfw.x11.randr.eventBase + RRNotify)
1181  {
1182  XRRUpdateConfiguration(event);
1184  return;
1185  }
1186  }
1187 
1188  if (event->type == GenericEvent)
1189  {
1190  if (_glfw.x11.xi.available)
1191  {
1192  _GLFWwindow* window = _glfw.x11.disabledCursorWindow;
1193 
1194  if (window &&
1195  event->xcookie.extension == _glfw.x11.xi.majorOpcode &&
1196  XGetEventData(_glfw.x11.display, &event->xcookie) &&
1197  event->xcookie.evtype == XI_RawMotion)
1198  {
1199  XIRawEvent* re = event->xcookie.data;
1200  if (re->valuators.mask_len)
1201  {
1202  const double* values = re->raw_values;
1203  double xpos = window->virtualCursorPosX;
1204  double ypos = window->virtualCursorPosY;
1205 
1206  if (XIMaskIsSet(re->valuators.mask, 0))
1207  {
1208  xpos += *values;
1209  values++;
1210  }
1211 
1212  if (XIMaskIsSet(re->valuators.mask, 1))
1213  ypos += *values;
1214 
1215  _glfwInputCursorPos(window, xpos, ypos);
1216  }
1217  }
1218 
1219  XFreeEventData(_glfw.x11.display, &event->xcookie);
1220  }
1221 
1222  return;
1223  }
1224 
1225  if (event->type == SelectionClear)
1226  {
1227  handleSelectionClear(event);
1228  return;
1229  }
1230  else if (event->type == SelectionRequest)
1231  {
1232  handleSelectionRequest(event);
1233  return;
1234  }
1235 
1236  if (XFindContext(_glfw.x11.display,
1237  event->xany.window,
1238  _glfw.x11.context,
1239  (XPointer*) &window) != 0)
1240  {
1241  // This is an event for a window that has already been destroyed
1242  return;
1243  }
1244 
1245  switch (event->type)
1246  {
1247  case KeyPress:
1248  {
1249  const int key = translateKey(keycode);
1250  const int mods = translateState(event->xkey.state);
1251  const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
1252 
1253  if (window->x11.ic)
1254  {
1255  // HACK: Ignore duplicate key press events generated by ibus
1256  // These have the same timestamp as the original event
1257  // Corresponding release events are filtered out
1258  // implicitly by the GLFW key repeat logic
1259  if (window->x11.lastKeyTime < event->xkey.time)
1260  {
1261  if (keycode)
1262  _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
1263 
1264  window->x11.lastKeyTime = event->xkey.time;
1265  }
1266 
1267  if (!filtered)
1268  {
1269  int count;
1270  Status status;
1271 #if defined(X_HAVE_UTF8_STRING)
1272  char buffer[100];
1273  char* chars = buffer;
1274 
1275  count = Xutf8LookupString(window->x11.ic,
1276  &event->xkey,
1277  buffer, sizeof(buffer) - 1,
1278  NULL, &status);
1279 
1280  if (status == XBufferOverflow)
1281  {
1282  chars = calloc(count + 1, 1);
1283  count = Xutf8LookupString(window->x11.ic,
1284  &event->xkey,
1285  chars, count,
1286  NULL, &status);
1287  }
1288 
1289  if (status == XLookupChars || status == XLookupBoth)
1290  {
1291  const char* c = chars;
1292  chars[count] = '\0';
1293  while (c - chars < count)
1294  _glfwInputChar(window, decodeUTF8(&c), mods, plain);
1295  }
1296 #else /*X_HAVE_UTF8_STRING*/
1297  wchar_t buffer[16];
1298  wchar_t* chars = buffer;
1299 
1300  count = XwcLookupString(window->x11.ic,
1301  &event->xkey,
1302  buffer,
1303  sizeof(buffer) / sizeof(wchar_t),
1304  NULL,
1305  &status);
1306 
1307  if (status == XBufferOverflow)
1308  {
1309  chars = calloc(count, sizeof(wchar_t));
1310  count = XwcLookupString(window->x11.ic,
1311  &event->xkey,
1312  chars, count,
1313  NULL, &status);
1314  }
1315 
1316  if (status == XLookupChars || status == XLookupBoth)
1317  {
1318  int i;
1319  for (i = 0; i < count; i++)
1320  _glfwInputChar(window, chars[i], mods, plain);
1321  }
1322 #endif /*X_HAVE_UTF8_STRING*/
1323 
1324  if (chars != buffer)
1325  free(chars);
1326  }
1327  }
1328  else
1329  {
1330  KeySym keysym;
1331  XLookupString(&event->xkey, NULL, 0, &keysym, NULL);
1332 
1333  _glfwInputKey(window, key, keycode, GLFW_PRESS, mods);
1334 
1335  const long character = _glfwKeySym2Unicode(keysym);
1336  if (character != -1)
1337  _glfwInputChar(window, character, mods, plain);
1338  }
1339 
1340  return;
1341  }
1342 
1343  case KeyRelease:
1344  {
1345  const int key = translateKey(keycode);
1346  const int mods = translateState(event->xkey.state);
1347 
1348  if (!_glfw.x11.xkb.detectable)
1349  {
1350  // HACK: Key repeat events will arrive as KeyRelease/KeyPress
1351  // pairs with similar or identical time stamps
1352  // The key repeat logic in _glfwInputKey expects only key
1353  // presses to repeat, so detect and discard release events
1354  if (XEventsQueued(_glfw.x11.display, QueuedAfterReading))
1355  {
1356  XEvent next;
1357  XPeekEvent(_glfw.x11.display, &next);
1358 
1359  if (next.type == KeyPress &&
1360  next.xkey.window == event->xkey.window &&
1361  next.xkey.keycode == keycode)
1362  {
1363  // HACK: The time of repeat events sometimes doesn't
1364  // match that of the press event, so add an
1365  // epsilon
1366  // Toshiyuki Takahashi can press a button
1367  // 16 times per second so it's fairly safe to
1368  // assume that no human is pressing the key 50
1369  // times per second (value is ms)
1370  if ((next.xkey.time - event->xkey.time) < 20)
1371  {
1372  // This is very likely a server-generated key repeat
1373  // event, so ignore it
1374  return;
1375  }
1376  }
1377  }
1378  }
1379 
1380  _glfwInputKey(window, key, keycode, GLFW_RELEASE, mods);
1381  return;
1382  }
1383 
1384  case ButtonPress:
1385  {
1386  const int mods = translateState(event->xbutton.state);
1387 
1388  if (event->xbutton.button == Button1)
1390  else if (event->xbutton.button == Button2)
1392  else if (event->xbutton.button == Button3)
1394 
1395  // Modern X provides scroll events as mouse button presses
1396  else if (event->xbutton.button == Button4)
1397  _glfwInputScroll(window, 0.0, 1.0);
1398  else if (event->xbutton.button == Button5)
1399  _glfwInputScroll(window, 0.0, -1.0);
1400  else if (event->xbutton.button == Button6)
1401  _glfwInputScroll(window, 1.0, 0.0);
1402  else if (event->xbutton.button == Button7)
1403  _glfwInputScroll(window, -1.0, 0.0);
1404 
1405  else
1406  {
1407  // Additional buttons after 7 are treated as regular buttons
1408  // We subtract 4 to fill the gap left by scroll input above
1409  _glfwInputMouseClick(window,
1410  event->xbutton.button - Button1 - 4,
1411  GLFW_PRESS,
1412  mods);
1413  }
1414 
1415  return;
1416  }
1417 
1418  case ButtonRelease:
1419  {
1420  const int mods = translateState(event->xbutton.state);
1421 
1422  if (event->xbutton.button == Button1)
1423  {
1424  _glfwInputMouseClick(window,
1426  GLFW_RELEASE,
1427  mods);
1428  }
1429  else if (event->xbutton.button == Button2)
1430  {
1431  _glfwInputMouseClick(window,
1433  GLFW_RELEASE,
1434  mods);
1435  }
1436  else if (event->xbutton.button == Button3)
1437  {
1438  _glfwInputMouseClick(window,
1440  GLFW_RELEASE,
1441  mods);
1442  }
1443  else if (event->xbutton.button > Button7)
1444  {
1445  // Additional buttons after 7 are treated as regular buttons
1446  // We subtract 4 to fill the gap left by scroll input above
1447  _glfwInputMouseClick(window,
1448  event->xbutton.button - Button1 - 4,
1449  GLFW_RELEASE,
1450  mods);
1451  }
1452 
1453  return;
1454  }
1455 
1456  case EnterNotify:
1457  {
1458  // XEnterWindowEvent is XCrossingEvent
1459  const int x = event->xcrossing.x;
1460  const int y = event->xcrossing.y;
1461 
1462  // HACK: This is a workaround for WMs (KWM, Fluxbox) that otherwise
1463  // ignore the defined cursor for hidden cursor mode
1464  if (window->cursorMode == GLFW_CURSOR_HIDDEN)
1465  updateCursorImage(window);
1466 
1468  _glfwInputCursorPos(window, x, y);
1469 
1470  window->x11.lastCursorPosX = x;
1471  window->x11.lastCursorPosY = y;
1472  return;
1473  }
1474 
1475  case LeaveNotify:
1476  {
1478  return;
1479  }
1480 
1481  case MotionNotify:
1482  {
1483  const int x = event->xmotion.x;
1484  const int y = event->xmotion.y;
1485 
1486  if (x != window->x11.warpCursorPosX ||
1487  y != window->x11.warpCursorPosY)
1488  {
1489  // The cursor was moved by something other than GLFW
1490 
1491  if (window->cursorMode == GLFW_CURSOR_DISABLED)
1492  {
1493  if (_glfw.x11.disabledCursorWindow != window)
1494  return;
1495  if (_glfw.x11.xi.available)
1496  return;
1497 
1498  const int dx = x - window->x11.lastCursorPosX;
1499  const int dy = y - window->x11.lastCursorPosY;
1500 
1501  _glfwInputCursorPos(window,
1502  window->virtualCursorPosX + dx,
1503  window->virtualCursorPosY + dy);
1504  }
1505  else
1506  _glfwInputCursorPos(window, x, y);
1507  }
1508 
1509  window->x11.lastCursorPosX = x;
1510  window->x11.lastCursorPosY = y;
1511  return;
1512  }
1513 
1514  case ConfigureNotify:
1515  {
1516  if (event->xconfigure.width != window->x11.width ||
1517  event->xconfigure.height != window->x11.height)
1518  {
1520  event->xconfigure.width,
1521  event->xconfigure.height);
1522 
1523  _glfwInputWindowSize(window,
1524  event->xconfigure.width,
1525  event->xconfigure.height);
1526 
1527  window->x11.width = event->xconfigure.width;
1528  window->x11.height = event->xconfigure.height;
1529  }
1530 
1531  if (event->xconfigure.x != window->x11.xpos ||
1532  event->xconfigure.y != window->x11.ypos)
1533  {
1534  if (window->x11.overrideRedirect || event->xany.send_event)
1535  {
1536  _glfwInputWindowPos(window,
1537  event->xconfigure.x,
1538  event->xconfigure.y);
1539 
1540  window->x11.xpos = event->xconfigure.x;
1541  window->x11.ypos = event->xconfigure.y;
1542  }
1543  }
1544 
1545  return;
1546  }
1547 
1548  case ClientMessage:
1549  {
1550  // Custom client message, probably from the window manager
1551 
1552  if (filtered)
1553  return;
1554 
1555  if (event->xclient.message_type == None)
1556  return;
1557 
1558  if (event->xclient.message_type == _glfw.x11.WM_PROTOCOLS)
1559  {
1560  const Atom protocol = event->xclient.data.l[0];
1561  if (protocol == None)
1562  return;
1563 
1564  if (protocol == _glfw.x11.WM_DELETE_WINDOW)
1565  {
1566  // The window manager was asked to close the window, for
1567  // example by the user pressing a 'close' window decoration
1568  // button
1570  }
1571  else if (protocol == _glfw.x11.NET_WM_PING)
1572  {
1573  // The window manager is pinging the application to ensure
1574  // it's still responding to events
1575 
1576  XEvent reply = *event;
1577  reply.xclient.window = _glfw.x11.root;
1578 
1579  XSendEvent(_glfw.x11.display, _glfw.x11.root,
1580  False,
1581  SubstructureNotifyMask | SubstructureRedirectMask,
1582  &reply);
1583  }
1584  }
1585  else if (event->xclient.message_type == _glfw.x11.XdndEnter)
1586  {
1587  // A drag operation has entered the window
1588  unsigned long i, count;
1589  Atom* formats = NULL;
1590  const GLFWbool list = event->xclient.data.l[1] & 1;
1591 
1592  _glfw.x11.xdnd.source = event->xclient.data.l[0];
1593  _glfw.x11.xdnd.version = event->xclient.data.l[1] >> 24;
1594  _glfw.x11.xdnd.format = None;
1595 
1596  if (_glfw.x11.xdnd.version > _GLFW_XDND_VERSION)
1597  return;
1598 
1599  if (list)
1600  {
1601  count = _glfwGetWindowPropertyX11(_glfw.x11.xdnd.source,
1602  _glfw.x11.XdndTypeList,
1603  XA_ATOM,
1604  (unsigned char**) &formats);
1605  }
1606  else
1607  {
1608  count = 3;
1609  formats = (Atom*) event->xclient.data.l + 2;
1610  }
1611 
1612  for (i = 0; i < count; i++)
1613  {
1614  if (formats[i] == _glfw.x11.text_uri_list)
1615  {
1616  _glfw.x11.xdnd.format = _glfw.x11.text_uri_list;
1617  break;
1618  }
1619  }
1620 
1621  if (list && formats)
1622  XFree(formats);
1623  }
1624  else if (event->xclient.message_type == _glfw.x11.XdndDrop)
1625  {
1626  // The drag operation has finished by dropping on the window
1627  Time time = CurrentTime;
1628 
1629  if (_glfw.x11.xdnd.version > _GLFW_XDND_VERSION)
1630  return;
1631 
1632  if (_glfw.x11.xdnd.format)
1633  {
1634  if (_glfw.x11.xdnd.version >= 1)
1635  time = event->xclient.data.l[2];
1636 
1637  // Request the chosen format from the source window
1638  XConvertSelection(_glfw.x11.display,
1639  _glfw.x11.XdndSelection,
1640  _glfw.x11.xdnd.format,
1641  _glfw.x11.XdndSelection,
1642  window->x11.handle,
1643  time);
1644  }
1645  else if (_glfw.x11.xdnd.version >= 2)
1646  {
1647  XEvent reply;
1648  memset(&reply, 0, sizeof(reply));
1649 
1650  reply.type = ClientMessage;
1651  reply.xclient.window = _glfw.x11.xdnd.source;
1652  reply.xclient.message_type = _glfw.x11.XdndFinished;
1653  reply.xclient.format = 32;
1654  reply.xclient.data.l[0] = window->x11.handle;
1655  reply.xclient.data.l[1] = 0; // The drag was rejected
1656  reply.xclient.data.l[2] = None;
1657 
1658  XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
1659  False, NoEventMask, &reply);
1660  XFlush(_glfw.x11.display);
1661  }
1662  }
1663  else if (event->xclient.message_type == _glfw.x11.XdndPosition)
1664  {
1665  // The drag operation has moved over the window
1666  const int xabs = (event->xclient.data.l[2] >> 16) & 0xffff;
1667  const int yabs = (event->xclient.data.l[2]) & 0xffff;
1668  Window dummy;
1669  int xpos, ypos;
1670 
1671  if (_glfw.x11.xdnd.version > _GLFW_XDND_VERSION)
1672  return;
1673 
1674  XTranslateCoordinates(_glfw.x11.display,
1675  _glfw.x11.root,
1676  window->x11.handle,
1677  xabs, yabs,
1678  &xpos, &ypos,
1679  &dummy);
1680 
1681  _glfwInputCursorPos(window, xpos, ypos);
1682 
1683  XEvent reply;
1684  memset(&reply, 0, sizeof(reply));
1685 
1686  reply.type = ClientMessage;
1687  reply.xclient.window = _glfw.x11.xdnd.source;
1688  reply.xclient.message_type = _glfw.x11.XdndStatus;
1689  reply.xclient.format = 32;
1690  reply.xclient.data.l[0] = window->x11.handle;
1691  reply.xclient.data.l[2] = 0; // Specify an empty rectangle
1692  reply.xclient.data.l[3] = 0;
1693 
1694  if (_glfw.x11.xdnd.format)
1695  {
1696  // Reply that we are ready to copy the dragged data
1697  reply.xclient.data.l[1] = 1; // Accept with no rectangle
1698  if (_glfw.x11.xdnd.version >= 2)
1699  reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy;
1700  }
1701 
1702  XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
1703  False, NoEventMask, &reply);
1704  XFlush(_glfw.x11.display);
1705  }
1706 
1707  return;
1708  }
1709 
1710  case SelectionNotify:
1711  {
1712  if (event->xselection.property == _glfw.x11.XdndSelection)
1713  {
1714  // The converted data from the drag operation has arrived
1715  char* data;
1716  const unsigned long result =
1717  _glfwGetWindowPropertyX11(event->xselection.requestor,
1718  event->xselection.property,
1719  event->xselection.target,
1720  (unsigned char**) &data);
1721 
1722  if (result)
1723  {
1724  int i, count;
1725  char** paths = parseUriList(data, &count);
1726 
1727  _glfwInputDrop(window, count, (const char**) paths);
1728 
1729  for (i = 0; i < count; i++)
1730  free(paths[i]);
1731  free(paths);
1732  }
1733 
1734  if (data)
1735  XFree(data);
1736 
1737  if (_glfw.x11.xdnd.version >= 2)
1738  {
1739  XEvent reply;
1740  memset(&reply, 0, sizeof(reply));
1741 
1742  reply.type = ClientMessage;
1743  reply.xclient.window = _glfw.x11.xdnd.source;
1744  reply.xclient.message_type = _glfw.x11.XdndFinished;
1745  reply.xclient.format = 32;
1746  reply.xclient.data.l[0] = window->x11.handle;
1747  reply.xclient.data.l[1] = result;
1748  reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy;
1749 
1750  XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
1751  False, NoEventMask, &reply);
1752  XFlush(_glfw.x11.display);
1753  }
1754  }
1755 
1756  return;
1757  }
1758 
1759  case FocusIn:
1760  {
1761  if (window->cursorMode == GLFW_CURSOR_DISABLED)
1762  disableCursor(window);
1763 
1764  if (event->xfocus.mode == NotifyGrab ||
1765  event->xfocus.mode == NotifyUngrab)
1766  {
1767  // Ignore focus events from popup indicator windows, window menu
1768  // key chords and window dragging
1769  return;
1770  }
1771 
1772  if (window->x11.ic)
1773  XSetICFocus(window->x11.ic);
1774 
1776  return;
1777  }
1778 
1779  case FocusOut:
1780  {
1781  if (window->cursorMode == GLFW_CURSOR_DISABLED)
1782  enableCursor(window);
1783 
1784  if (event->xfocus.mode == NotifyGrab ||
1785  event->xfocus.mode == NotifyUngrab)
1786  {
1787  // Ignore focus events from popup indicator windows, window menu
1788  // key chords and window dragging
1789  return;
1790  }
1791 
1792  if (window->x11.ic)
1793  XUnsetICFocus(window->x11.ic);
1794 
1795  if (window->monitor && window->autoIconify)
1797 
1799  return;
1800  }
1801 
1802  case Expose:
1803  {
1804  _glfwInputWindowDamage(window);
1805  return;
1806  }
1807 
1808  case PropertyNotify:
1809  {
1810  if (event->xproperty.state != PropertyNewValue)
1811  return;
1812 
1813  if (event->xproperty.atom == _glfw.x11.WM_STATE)
1814  {
1815  const int state = getWindowState(window);
1816  if (state != IconicState && state != NormalState)
1817  return;
1818 
1819  const GLFWbool iconified = (state == IconicState);
1820  if (window->x11.iconified != iconified)
1821  {
1822  if (window->monitor)
1823  {
1824  if (iconified)
1825  releaseMonitor(window);
1826  else
1827  acquireMonitor(window);
1828  }
1829 
1830  window->x11.iconified = iconified;
1831  _glfwInputWindowIconify(window, iconified);
1832  }
1833  }
1834  else if (event->xproperty.atom == _glfw.x11.NET_WM_STATE)
1835  {
1837  if (window->x11.maximized != maximized)
1838  {
1839  window->x11.maximized = maximized;
1840  _glfwInputWindowMaximize(window, maximized);
1841  }
1842  }
1843 
1844  return;
1845  }
1846 
1847  case DestroyNotify:
1848  return;
1849  }
1850 }
1851 
1852 
1856 
1857 // Retrieve a single window property of the specified type
1858 // Inspired by fghGetWindowProperty from freeglut
1859 //
1860 unsigned long _glfwGetWindowPropertyX11(Window window,
1861  Atom property,
1862  Atom type,
1863  unsigned char** value)
1864 {
1865  Atom actualType;
1866  int actualFormat;
1867  unsigned long itemCount, bytesAfter;
1868 
1869  XGetWindowProperty(_glfw.x11.display,
1870  window,
1871  property,
1872  0,
1873  LONG_MAX,
1874  False,
1875  type,
1876  &actualType,
1877  &actualFormat,
1878  &itemCount,
1879  &bytesAfter,
1880  value);
1881 
1882  return itemCount;
1883 }
1884 
1886 {
1887  if (!_glfw.x11.xrender.available)
1888  return GLFW_FALSE;
1889 
1890  XRenderPictFormat* pf = XRenderFindVisualFormat(_glfw.x11.display, visual);
1891  return pf && pf->direct.alphaMask;
1892 }
1893 
1894 // Push contents of our selection to clipboard manager
1895 //
1897 {
1898  XConvertSelection(_glfw.x11.display,
1899  _glfw.x11.CLIPBOARD_MANAGER,
1900  _glfw.x11.SAVE_TARGETS,
1901  None,
1902  _glfw.x11.helperWindowHandle,
1903  CurrentTime);
1904 
1905  for (;;)
1906  {
1907  XEvent event;
1908 
1909  while (XCheckIfEvent(_glfw.x11.display, &event, isSelectionEvent, NULL))
1910  {
1911  switch (event.type)
1912  {
1913  case SelectionRequest:
1914  handleSelectionRequest(&event);
1915  break;
1916 
1917  case SelectionClear:
1918  handleSelectionClear(&event);
1919  break;
1920 
1921  case SelectionNotify:
1922  {
1923  if (event.xselection.target == _glfw.x11.SAVE_TARGETS)
1924  {
1925  // This means one of two things; either the selection
1926  // was not owned, which means there is no clipboard
1927  // manager, or the transfer to the clipboard manager has
1928  // completed
1929  // In either case, it means we are done here
1930  return;
1931  }
1932 
1933  break;
1934  }
1935  }
1936  }
1937 
1938  waitForEvent(NULL);
1939  }
1940 }
1941 
1942 
1946 
1948  const _GLFWwndconfig* wndconfig,
1949  const _GLFWctxconfig* ctxconfig,
1950  const _GLFWfbconfig* fbconfig)
1951 {
1952  Visual* visual;
1953  int depth;
1954 
1955  if (ctxconfig->client != GLFW_NO_API)
1956  {
1957  if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
1958  {
1959  if (!_glfwInitGLX())
1960  return GLFW_FALSE;
1961  if (!_glfwChooseVisualGLX(wndconfig, ctxconfig, fbconfig, &visual, &depth))
1962  return GLFW_FALSE;
1963  }
1964  else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
1965  {
1966  if (!_glfwInitEGL())
1967  return GLFW_FALSE;
1968  if (!_glfwChooseVisualEGL(wndconfig, ctxconfig, fbconfig, &visual, &depth))
1969  return GLFW_FALSE;
1970  }
1971  else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
1972  {
1973  if (!_glfwInitOSMesa())
1974  return GLFW_FALSE;
1975  }
1976  }
1977 
1978  if (ctxconfig->client == GLFW_NO_API ||
1979  ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
1980  {
1981  visual = DefaultVisual(_glfw.x11.display, _glfw.x11.screen);
1982  depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen);
1983  }
1984 
1985  if (!createNativeWindow(window, wndconfig, visual, depth))
1986  return GLFW_FALSE;
1987 
1988  if (ctxconfig->client != GLFW_NO_API)
1989  {
1990  if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API)
1991  {
1992  if (!_glfwCreateContextGLX(window, ctxconfig, fbconfig))
1993  return GLFW_FALSE;
1994  }
1995  else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
1996  {
1997  if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
1998  return GLFW_FALSE;
1999  }
2000  else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
2001  {
2002  if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
2003  return GLFW_FALSE;
2004  }
2005  }
2006 
2007  if (window->monitor)
2008  {
2009  _glfwPlatformShowWindow(window);
2010  updateWindowMode(window);
2011  acquireMonitor(window);
2012  }
2013 
2014  XFlush(_glfw.x11.display);
2015  return GLFW_TRUE;
2016 }
2017 
2019 {
2020  if (_glfw.x11.disabledCursorWindow == window)
2021  _glfw.x11.disabledCursorWindow = NULL;
2022 
2023  if (window->monitor)
2024  releaseMonitor(window);
2025 
2026  if (window->x11.ic)
2027  {
2028  XDestroyIC(window->x11.ic);
2029  window->x11.ic = NULL;
2030  }
2031 
2032  if (window->context.destroy)
2033  window->context.destroy(window);
2034 
2035  if (window->x11.handle)
2036  {
2037  XDeleteContext(_glfw.x11.display, window->x11.handle, _glfw.x11.context);
2038  XUnmapWindow(_glfw.x11.display, window->x11.handle);
2039  XDestroyWindow(_glfw.x11.display, window->x11.handle);
2040  window->x11.handle = (Window) 0;
2041  }
2042 
2043  if (window->x11.colormap)
2044  {
2045  XFreeColormap(_glfw.x11.display, window->x11.colormap);
2046  window->x11.colormap = (Colormap) 0;
2047  }
2048 
2049  XFlush(_glfw.x11.display);
2050 }
2051 
2053 {
2054 #if defined(X_HAVE_UTF8_STRING)
2055  Xutf8SetWMProperties(_glfw.x11.display,
2056  window->x11.handle,
2057  title, title,
2058  NULL, 0,
2059  NULL, NULL, NULL);
2060 #else
2061  // This may be a slightly better fallback than using XStoreName and
2062  // XSetIconName, which always store their arguments using STRING
2063  XmbSetWMProperties(_glfw.x11.display,
2064  window->x11.handle,
2065  title, title,
2066  NULL, 0,
2067  NULL, NULL, NULL);
2068 #endif
2069 
2070  XChangeProperty(_glfw.x11.display, window->x11.handle,
2071  _glfw.x11.NET_WM_NAME, _glfw.x11.UTF8_STRING, 8,
2072  PropModeReplace,
2073  (unsigned char*) title, strlen(title));
2074 
2075  XChangeProperty(_glfw.x11.display, window->x11.handle,
2076  _glfw.x11.NET_WM_ICON_NAME, _glfw.x11.UTF8_STRING, 8,
2077  PropModeReplace,
2078  (unsigned char*) title, strlen(title));
2079 
2080  XFlush(_glfw.x11.display);
2081 }
2082 
2084  int count, const GLFWimage* images)
2085 {
2086  if (count)
2087  {
2088  int i, j, longCount = 0;
2089 
2090  for (i = 0; i < count; i++)
2091  longCount += 2 + images[i].width * images[i].height;
2092 
2093  long* icon = calloc(longCount, sizeof(long));
2094  long* target = icon;
2095 
2096  for (i = 0; i < count; i++)
2097  {
2098  *target++ = images[i].width;
2099  *target++ = images[i].height;
2100 
2101  for (j = 0; j < images[i].width * images[i].height; j++)
2102  {
2103  *target++ = (images[i].pixels[j * 4 + 0] << 16) |
2104  (images[i].pixels[j * 4 + 1] << 8) |
2105  (images[i].pixels[j * 4 + 2] << 0) |
2106  (images[i].pixels[j * 4 + 3] << 24);
2107  }
2108  }
2109 
2110  XChangeProperty(_glfw.x11.display, window->x11.handle,
2111  _glfw.x11.NET_WM_ICON,
2112  XA_CARDINAL, 32,
2113  PropModeReplace,
2114  (unsigned char*) icon,
2115  longCount);
2116 
2117  free(icon);
2118  }
2119  else
2120  {
2121  XDeleteProperty(_glfw.x11.display, window->x11.handle,
2122  _glfw.x11.NET_WM_ICON);
2123  }
2124 
2125  XFlush(_glfw.x11.display);
2126 }
2127 
2129 {
2130  Window dummy;
2131  int x, y;
2132 
2133  XTranslateCoordinates(_glfw.x11.display, window->x11.handle, _glfw.x11.root,
2134  0, 0, &x, &y, &dummy);
2135 
2136  if (xpos)
2137  *xpos = x;
2138  if (ypos)
2139  *ypos = y;
2140 }
2141 
2143 {
2144  // HACK: Explicitly setting PPosition to any value causes some WMs, notably
2145  // Compiz and Metacity, to honor the position of unmapped windows
2146  if (!_glfwPlatformWindowVisible(window))
2147  {
2148  long supplied;
2149  XSizeHints* hints = XAllocSizeHints();
2150 
2151  if (XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied))
2152  {
2153  hints->flags |= PPosition;
2154  hints->x = hints->y = 0;
2155 
2156  XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
2157  }
2158 
2159  XFree(hints);
2160  }
2161 
2162  XMoveWindow(_glfw.x11.display, window->x11.handle, xpos, ypos);
2163  XFlush(_glfw.x11.display);
2164 }
2165 
2167 {
2168  XWindowAttributes attribs;
2169  XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &attribs);
2170 
2171  if (width)
2172  *width = attribs.width;
2173  if (height)
2174  *height = attribs.height;
2175 }
2176 
2178 {
2179  if (window->monitor)
2180  {
2181  if (window->monitor->window == window)
2182  acquireMonitor(window);
2183  }
2184  else
2185  {
2186  if (!window->resizable)
2187  updateNormalHints(window, width, height);
2188 
2189  XResizeWindow(_glfw.x11.display, window->x11.handle, width, height);
2190  }
2191 
2192  XFlush(_glfw.x11.display);
2193 }
2194 
2196  int minwidth, int minheight,
2197  int maxwidth, int maxheight)
2198 {
2199  int width, height;
2200  _glfwPlatformGetWindowSize(window, &width, &height);
2201  updateNormalHints(window, width, height);
2202  XFlush(_glfw.x11.display);
2203 }
2204 
2206 {
2207  int width, height;
2208  _glfwPlatformGetWindowSize(window, &width, &height);
2209  updateNormalHints(window, width, height);
2210  XFlush(_glfw.x11.display);
2211 }
2212 
2214 {
2215  _glfwPlatformGetWindowSize(window, width, height);
2216 }
2217 
2219  int* left, int* top,
2220  int* right, int* bottom)
2221 {
2222  long* extents = NULL;
2223 
2224  if (window->monitor || !window->decorated)
2225  return;
2226 
2227  if (_glfw.x11.NET_FRAME_EXTENTS == None)
2228  return;
2229 
2230  if (!_glfwPlatformWindowVisible(window) &&
2231  _glfw.x11.NET_REQUEST_FRAME_EXTENTS)
2232  {
2233  XEvent event;
2234  double timeout = 0.5;
2235 
2236  // Ensure _NET_FRAME_EXTENTS is set, allowing glfwGetWindowFrameSize to
2237  // function before the window is mapped
2238  sendEventToWM(window, _glfw.x11.NET_REQUEST_FRAME_EXTENTS,
2239  0, 0, 0, 0, 0);
2240 
2241  // HACK: Use a timeout because earlier versions of some window managers
2242  // (at least Unity, Fluxbox and Xfwm) failed to send the reply
2243  // They have been fixed but broken versions are still in the wild
2244  // If you are affected by this and your window manager is NOT
2245  // listed above, PLEASE report it to their and our issue trackers
2246  while (!XCheckIfEvent(_glfw.x11.display,
2247  &event,
2249  (XPointer) window))
2250  {
2251  if (!waitForEvent(&timeout))
2252  {
2254  "X11: The window manager has a broken _NET_REQUEST_FRAME_EXTENTS implementation; please report this issue");
2255  return;
2256  }
2257  }
2258  }
2259 
2260  if (_glfwGetWindowPropertyX11(window->x11.handle,
2261  _glfw.x11.NET_FRAME_EXTENTS,
2262  XA_CARDINAL,
2263  (unsigned char**) &extents) == 4)
2264  {
2265  if (left)
2266  *left = extents[0];
2267  if (top)
2268  *top = extents[2];
2269  if (right)
2270  *right = extents[1];
2271  if (bottom)
2272  *bottom = extents[3];
2273  }
2274 
2275  if (extents)
2276  XFree(extents);
2277 }
2278 
2280  float* xscale, float* yscale)
2281 {
2282  if (xscale)
2283  *xscale = _glfw.x11.contentScaleX;
2284  if (yscale)
2285  *yscale = _glfw.x11.contentScaleY;
2286 }
2287 
2289 {
2290  if (window->x11.overrideRedirect)
2291  {
2292  // Override-redirect windows cannot be iconified or restored, as those
2293  // tasks are performed by the window manager
2295  "X11: Iconification of full screen windows requires a WM that supports EWMH full screen");
2296  return;
2297  }
2298 
2299  XIconifyWindow(_glfw.x11.display, window->x11.handle, _glfw.x11.screen);
2300  XFlush(_glfw.x11.display);
2301 }
2302 
2304 {
2305  if (window->x11.overrideRedirect)
2306  {
2307  // Override-redirect windows cannot be iconified or restored, as those
2308  // tasks are performed by the window manager
2310  "X11: Iconification of full screen windows requires a WM that supports EWMH full screen");
2311  return;
2312  }
2313 
2314  if (_glfwPlatformWindowIconified(window))
2315  {
2316  XMapWindow(_glfw.x11.display, window->x11.handle);
2317  waitForVisibilityNotify(window);
2318  }
2319  else if (_glfwPlatformWindowVisible(window))
2320  {
2321  if (_glfw.x11.NET_WM_STATE &&
2322  _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
2323  _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
2324  {
2325  sendEventToWM(window,
2326  _glfw.x11.NET_WM_STATE,
2328  _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
2329  _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
2330  1, 0);
2331  }
2332  }
2333 
2334  XFlush(_glfw.x11.display);
2335 }
2336 
2338 {
2339  if (_glfw.x11.NET_WM_STATE &&
2340  _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT &&
2341  _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
2342  {
2343  sendEventToWM(window,
2344  _glfw.x11.NET_WM_STATE,
2346  _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT,
2347  _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ,
2348  1, 0);
2349  XFlush(_glfw.x11.display);
2350  }
2351 }
2352 
2354 {
2355  if (_glfwPlatformWindowVisible(window))
2356  return;
2357 
2358  XMapWindow(_glfw.x11.display, window->x11.handle);
2359  waitForVisibilityNotify(window);
2360 }
2361 
2363 {
2364  XUnmapWindow(_glfw.x11.display, window->x11.handle);
2365  XFlush(_glfw.x11.display);
2366 }
2367 
2369 {
2370  sendEventToWM(window,
2371  _glfw.x11.NET_WM_STATE,
2373  _glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION,
2374  0, 1, 0);
2375 }
2376 
2378 {
2379  if (_glfw.x11.NET_ACTIVE_WINDOW)
2380  sendEventToWM(window, _glfw.x11.NET_ACTIVE_WINDOW, 1, 0, 0, 0, 0);
2381  else
2382  {
2383  XRaiseWindow(_glfw.x11.display, window->x11.handle);
2384  XSetInputFocus(_glfw.x11.display, window->x11.handle,
2385  RevertToParent, CurrentTime);
2386  }
2387 
2388  XFlush(_glfw.x11.display);
2389 }
2390 
2392  _GLFWmonitor* monitor,
2393  int xpos, int ypos,
2394  int width, int height,
2395  int refreshRate)
2396 {
2397  if (window->monitor == monitor)
2398  {
2399  if (monitor)
2400  {
2401  if (monitor->window == window)
2402  acquireMonitor(window);
2403  }
2404  else
2405  {
2406  XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
2407  xpos, ypos, width, height);
2408  }
2409 
2410  return;
2411  }
2412 
2413  if (window->monitor)
2414  releaseMonitor(window);
2415 
2416  _glfwInputWindowMonitor(window, monitor);
2417  updateNormalHints(window, width, height);
2418  updateWindowMode(window);
2419 
2420  if (window->monitor)
2421  {
2422  XMapRaised(_glfw.x11.display, window->x11.handle);
2423  if (waitForVisibilityNotify(window))
2424  acquireMonitor(window);
2425  }
2426  else
2427  {
2428  XMoveResizeWindow(_glfw.x11.display, window->x11.handle,
2429  xpos, ypos, width, height);
2430  }
2431 
2432  XFlush(_glfw.x11.display);
2433 }
2434 
2436 {
2437  Window focused;
2438  int state;
2439 
2440  XGetInputFocus(_glfw.x11.display, &focused, &state);
2441  return window->x11.handle == focused;
2442 }
2443 
2445 {
2446  return getWindowState(window) == IconicState;
2447 }
2448 
2450 {
2451  XWindowAttributes wa;
2452  XGetWindowAttributes(_glfw.x11.display, window->x11.handle, &wa);
2453  return wa.map_state == IsViewable;
2454 }
2455 
2457 {
2458  Atom* states;
2459  unsigned long i;
2461 
2462  if (!_glfw.x11.NET_WM_STATE ||
2463  !_glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
2464  !_glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
2465  {
2466  return maximized;
2467  }
2468 
2469  const unsigned long count =
2470  _glfwGetWindowPropertyX11(window->x11.handle,
2471  _glfw.x11.NET_WM_STATE,
2472  XA_ATOM,
2473  (unsigned char**) &states);
2474 
2475  for (i = 0; i < count; i++)
2476  {
2477  if (states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT ||
2478  states[i] == _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ)
2479  {
2480  maximized = GLFW_TRUE;
2481  break;
2482  }
2483  }
2484 
2485  if (states)
2486  XFree(states);
2487 
2488  return maximized;
2489 }
2490 
2492 {
2493  Window w = _glfw.x11.root;
2494  while (w)
2495  {
2496  Window root;
2497  int rootX, rootY, childX, childY;
2498  unsigned int mask;
2499 
2500  if (!XQueryPointer(_glfw.x11.display, w,
2501  &root, &w, &rootX, &rootY, &childX, &childY, &mask))
2502  {
2503  return GLFW_FALSE;
2504  }
2505 
2506  if (w == window->x11.handle)
2507  return GLFW_TRUE;
2508  }
2509 
2510  return GLFW_FALSE;
2511 }
2512 
2514 {
2515  if (!window->x11.transparent)
2516  return GLFW_FALSE;
2517 
2518  return XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx) != None;
2519 }
2520 
2522 {
2523  int width, height;
2524  _glfwPlatformGetWindowSize(window, &width, &height);
2525  updateNormalHints(window, width, height);
2526 }
2527 
2529 {
2530  if (enabled)
2531  {
2532  XDeleteProperty(_glfw.x11.display,
2533  window->x11.handle,
2534  _glfw.x11.MOTIF_WM_HINTS);
2535  }
2536  else
2537  {
2538  struct
2539  {
2540  unsigned long flags;
2541  unsigned long functions;
2542  unsigned long decorations;
2543  long input_mode;
2544  unsigned long status;
2545  } hints;
2546 
2547  hints.flags = 2; // Set decorations
2548  hints.decorations = 0; // No decorations
2549 
2550  XChangeProperty(_glfw.x11.display, window->x11.handle,
2551  _glfw.x11.MOTIF_WM_HINTS,
2552  _glfw.x11.MOTIF_WM_HINTS, 32,
2553  PropModeReplace,
2554  (unsigned char*) &hints,
2555  sizeof(hints) / sizeof(long));
2556  }
2557 }
2558 
2560 {
2561  if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_ABOVE)
2562  return;
2563 
2564  if (_glfwPlatformWindowVisible(window))
2565  {
2566  const Atom action = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
2567  sendEventToWM(window,
2568  _glfw.x11.NET_WM_STATE,
2569  action,
2570  _glfw.x11.NET_WM_STATE_ABOVE,
2571  0, 1, 0);
2572  }
2573  else
2574  {
2575  Atom* states;
2576  unsigned long i, count;
2577 
2578  count = _glfwGetWindowPropertyX11(window->x11.handle,
2579  _glfw.x11.NET_WM_STATE,
2580  XA_ATOM,
2581  (unsigned char**) &states);
2582  if (!states)
2583  return;
2584 
2585  if (enabled)
2586  {
2587  for (i = 0; i < count; i++)
2588  {
2589  if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
2590  break;
2591  }
2592 
2593  if (i == count)
2594  {
2595  XChangeProperty(_glfw.x11.display, window->x11.handle,
2596  _glfw.x11.NET_WM_STATE, XA_ATOM, 32,
2597  PropModeAppend,
2598  (unsigned char*) &_glfw.x11.NET_WM_STATE_ABOVE,
2599  1);
2600  }
2601  }
2602  else
2603  {
2604  for (i = 0; i < count; i++)
2605  {
2606  if (states[i] == _glfw.x11.NET_WM_STATE_ABOVE)
2607  {
2608  states[i] = states[count - 1];
2609  count--;
2610  }
2611  }
2612 
2613  XChangeProperty(_glfw.x11.display, window->x11.handle,
2614  _glfw.x11.NET_WM_STATE, XA_ATOM, 32,
2615  PropModeReplace, (unsigned char*) &states, count);
2616  }
2617 
2618  XFree(states);
2619  }
2620 
2621  XFlush(_glfw.x11.display);
2622 }
2623 
2625 {
2626  float opacity = 1.f;
2627 
2628  if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.NET_WM_CM_Sx))
2629  {
2630  CARD32* value = NULL;
2631 
2632  if (_glfwGetWindowPropertyX11(window->x11.handle,
2633  _glfw.x11.NET_WM_WINDOW_OPACITY,
2634  XA_CARDINAL,
2635  (unsigned char**) &value))
2636  {
2637  opacity = (float) (*value / (double) 0xffffffffu);
2638  }
2639 
2640  if (value)
2641  XFree(value);
2642  }
2643 
2644  return opacity;
2645 }
2646 
2648 {
2649  const CARD32 value = (CARD32) (0xffffffffu * (double) opacity);
2650  XChangeProperty(_glfw.x11.display, window->x11.handle,
2651  _glfw.x11.NET_WM_WINDOW_OPACITY, XA_CARDINAL, 32,
2652  PropModeReplace, (unsigned char*) &value, 1);
2653 }
2654 
2656 {
2658 
2659 #if defined(__linux__)
2661 #endif
2662  XPending(_glfw.x11.display);
2663 
2664  while (XQLength(_glfw.x11.display))
2665  {
2666  XEvent event;
2667  XNextEvent(_glfw.x11.display, &event);
2668  processEvent(&event);
2669  }
2670 
2671  window = _glfw.x11.disabledCursorWindow;
2672  if (window)
2673  {
2674  int width, height;
2675  _glfwPlatformGetWindowSize(window, &width, &height);
2676 
2677  // NOTE: Re-center the cursor only if it has moved since the last call,
2678  // to avoid breaking glfwWaitEvents with MotionNotify
2679  if (window->x11.lastCursorPosX != width / 2 ||
2680  window->x11.lastCursorPosY != height / 2)
2681  {
2682  _glfwPlatformSetCursorPos(window, width / 2, height / 2);
2683  }
2684  }
2685 
2686  XFlush(_glfw.x11.display);
2687 }
2688 
2690 {
2691  while (!XPending(_glfw.x11.display))
2692  waitForEvent(NULL);
2693 
2695 }
2696 
2698 {
2699  while (!XPending(_glfw.x11.display))
2700  {
2701  if (!waitForEvent(&timeout))
2702  break;
2703  }
2704 
2706 }
2707 
2709 {
2710  XEvent event;
2711 
2712  memset(&event, 0, sizeof(event));
2713  event.type = ClientMessage;
2714  event.xclient.window = _glfw.x11.helperWindowHandle;
2715  event.xclient.format = 32; // Data is 32-bit longs
2716  event.xclient.message_type = _glfw.x11.NULL_;
2717 
2718  XSendEvent(_glfw.x11.display, _glfw.x11.helperWindowHandle, False, 0, &event);
2719  XFlush(_glfw.x11.display);
2720 }
2721 
2723 {
2724  Window root, child;
2725  int rootX, rootY, childX, childY;
2726  unsigned int mask;
2727 
2728  XQueryPointer(_glfw.x11.display, window->x11.handle,
2729  &root, &child,
2730  &rootX, &rootY, &childX, &childY,
2731  &mask);
2732 
2733  if (xpos)
2734  *xpos = childX;
2735  if (ypos)
2736  *ypos = childY;
2737 }
2738 
2740 {
2741  // Store the new position so it can be recognized later
2742  window->x11.warpCursorPosX = (int) x;
2743  window->x11.warpCursorPosY = (int) y;
2744 
2745  XWarpPointer(_glfw.x11.display, None, window->x11.handle,
2746  0,0,0,0, (int) x, (int) y);
2747  XFlush(_glfw.x11.display);
2748 }
2749 
2751 {
2752  if (mode == GLFW_CURSOR_DISABLED)
2753  {
2754  if (_glfwPlatformWindowFocused(window))
2755  disableCursor(window);
2756  }
2757  else if (_glfw.x11.disabledCursorWindow == window)
2758  enableCursor(window);
2759  else
2760  updateCursorImage(window);
2761 
2762  XFlush(_glfw.x11.display);
2763 }
2764 
2765 const char* _glfwPlatformGetScancodeName(int scancode)
2766 {
2767  if (!_glfw.x11.xkb.available)
2768  return NULL;
2769 
2770  const KeySym keysym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
2771  if (keysym == NoSymbol)
2772  return NULL;
2773 
2774  const long ch = _glfwKeySym2Unicode(keysym);
2775  if (ch == -1)
2776  return NULL;
2777 
2778  const size_t count = encodeUTF8(_glfw.x11.keyName, (unsigned int) ch);
2779  if (count == 0)
2780  return NULL;
2781 
2782  _glfw.x11.keyName[count] = '\0';
2783  return _glfw.x11.keyName;
2784 }
2785 
2787 {
2788  return _glfw.x11.scancodes[key];
2789 }
2790 
2792  const GLFWimage* image,
2793  int xhot, int yhot)
2794 {
2795  cursor->x11.handle = _glfwCreateCursorX11(image, xhot, yhot);
2796  if (!cursor->x11.handle)
2797  return GLFW_FALSE;
2798 
2799  return GLFW_TRUE;
2800 }
2801 
2803 {
2804  int native = 0;
2805 
2806  if (shape == GLFW_ARROW_CURSOR)
2807  native = XC_left_ptr;
2808  else if (shape == GLFW_IBEAM_CURSOR)
2809  native = XC_xterm;
2810  else if (shape == GLFW_CROSSHAIR_CURSOR)
2811  native = XC_crosshair;
2812  else if (shape == GLFW_HAND_CURSOR)
2813  native = XC_hand1;
2814  else if (shape == GLFW_HRESIZE_CURSOR)
2815  native = XC_sb_h_double_arrow;
2816  else if (shape == GLFW_VRESIZE_CURSOR)
2817  native = XC_sb_v_double_arrow;
2818  else
2819  return GLFW_FALSE;
2820 
2821  cursor->x11.handle = XCreateFontCursor(_glfw.x11.display, native);
2822  if (!cursor->x11.handle)
2823  {
2825  "X11: Failed to create standard cursor");
2826  return GLFW_FALSE;
2827  }
2828 
2829  return GLFW_TRUE;
2830 }
2831 
2833 {
2834  if (cursor->x11.handle)
2835  XFreeCursor(_glfw.x11.display, cursor->x11.handle);
2836 }
2837 
2839 {
2840  if (window->cursorMode == GLFW_CURSOR_NORMAL)
2841  {
2842  updateCursorImage(window);
2843  XFlush(_glfw.x11.display);
2844  }
2845 }
2846 
2847 void _glfwPlatformSetClipboardString(const char* string)
2848 {
2849  free(_glfw.x11.clipboardString);
2850  _glfw.x11.clipboardString = _glfw_strdup(string);
2851 
2852  XSetSelectionOwner(_glfw.x11.display,
2853  _glfw.x11.CLIPBOARD,
2854  _glfw.x11.helperWindowHandle,
2855  CurrentTime);
2856 
2857  if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) !=
2858  _glfw.x11.helperWindowHandle)
2859  {
2861  "X11: Failed to become owner of clipboard selection");
2862  }
2863 }
2864 
2866 {
2867  return getSelectionString(_glfw.x11.CLIPBOARD);
2868 }
2869 
2871 {
2872  if (!_glfw.vk.KHR_surface)
2873  return;
2874 
2875  if (!_glfw.vk.KHR_xcb_surface || !_glfw.x11.x11xcb.handle)
2876  {
2877  if (!_glfw.vk.KHR_xlib_surface)
2878  return;
2879  }
2880 
2881  extensions[0] = "VK_KHR_surface";
2882 
2883  // NOTE: VK_KHR_xcb_surface is preferred due to some early ICDs exposing but
2884  // not correctly implementing VK_KHR_xlib_surface
2885  if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
2886  extensions[1] = "VK_KHR_xcb_surface";
2887  else
2888  extensions[1] = "VK_KHR_xlib_surface";
2889 }
2890 
2893  uint32_t queuefamily)
2894 {
2895  VisualID visualID = XVisualIDFromVisual(DefaultVisual(_glfw.x11.display,
2896  _glfw.x11.screen));
2897 
2898  if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
2899  {
2901  vkGetPhysicalDeviceXcbPresentationSupportKHR =
2903  vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXcbPresentationSupportKHR");
2904  if (!vkGetPhysicalDeviceXcbPresentationSupportKHR)
2905  {
2907  "X11: Vulkan instance missing VK_KHR_xcb_surface extension");
2908  return GLFW_FALSE;
2909  }
2910 
2911  xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
2912  if (!connection)
2913  {
2915  "X11: Failed to retrieve XCB connection");
2916  return GLFW_FALSE;
2917  }
2918 
2919  return vkGetPhysicalDeviceXcbPresentationSupportKHR(device,
2920  queuefamily,
2921  connection,
2922  visualID);
2923  }
2924  else
2925  {
2927  vkGetPhysicalDeviceXlibPresentationSupportKHR =
2929  vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceXlibPresentationSupportKHR");
2930  if (!vkGetPhysicalDeviceXlibPresentationSupportKHR)
2931  {
2933  "X11: Vulkan instance missing VK_KHR_xlib_surface extension");
2934  return GLFW_FALSE;
2935  }
2936 
2937  return vkGetPhysicalDeviceXlibPresentationSupportKHR(device,
2938  queuefamily,
2939  _glfw.x11.display,
2940  visualID);
2941  }
2942 }
2943 
2946  const VkAllocationCallbacks* allocator,
2947  VkSurfaceKHR* surface)
2948 {
2949  if (_glfw.vk.KHR_xcb_surface && _glfw.x11.x11xcb.handle)
2950  {
2951  VkResult err;
2953  PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR;
2954 
2955  xcb_connection_t* connection = XGetXCBConnection(_glfw.x11.display);
2956  if (!connection)
2957  {
2959  "X11: Failed to retrieve XCB connection");
2961  }
2962 
2963  vkCreateXcbSurfaceKHR = (PFN_vkCreateXcbSurfaceKHR)
2964  vkGetInstanceProcAddr(instance, "vkCreateXcbSurfaceKHR");
2965  if (!vkCreateXcbSurfaceKHR)
2966  {
2968  "X11: Vulkan instance missing VK_KHR_xcb_surface extension");
2970  }
2971 
2972  memset(&sci, 0, sizeof(sci));
2974  sci.connection = connection;
2975  sci.window = window->x11.handle;
2976 
2977  err = vkCreateXcbSurfaceKHR(instance, &sci, allocator, surface);
2978  if (err)
2979  {
2981  "X11: Failed to create Vulkan XCB surface: %s",
2983  }
2984 
2985  return err;
2986  }
2987  else
2988  {
2989  VkResult err;
2991  PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR;
2992 
2993  vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)
2994  vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR");
2995  if (!vkCreateXlibSurfaceKHR)
2996  {
2998  "X11: Vulkan instance missing VK_KHR_xlib_surface extension");
3000  }
3001 
3002  memset(&sci, 0, sizeof(sci));
3004  sci.dpy = _glfw.x11.display;
3005  sci.window = window->x11.handle;
3006 
3007  err = vkCreateXlibSurfaceKHR(instance, &sci, allocator, surface);
3008  if (err)
3009  {
3011  "X11: Failed to create Vulkan X11 surface: %s",
3013  }
3014 
3015  return err;
3016  }
3017 }
3018 
3019 
3023 
3025 {
3027  return _glfw.x11.display;
3028 }
3029 
3031 {
3032  _GLFWwindow* window = (_GLFWwindow*) handle;
3034  return window->x11.handle;
3035 }
3036 
3037 GLFWAPI void glfwSetX11SelectionString(const char* string)
3038 {
3040 
3041  free(_glfw.x11.primarySelectionString);
3042  _glfw.x11.primarySelectionString = _glfw_strdup(string);
3043 
3044  XSetSelectionOwner(_glfw.x11.display,
3045  _glfw.x11.PRIMARY,
3046  _glfw.x11.helperWindowHandle,
3047  CurrentTime);
3048 
3049  if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.PRIMARY) !=
3050  _glfw.x11.helperWindowHandle)
3051  {
3053  "X11: Failed to become owner of primary selection");
3054  }
3055 }
3056 
3058 {
3060  return getSelectionString(_glfw.x11.PRIMARY);
3061 }
3062 
void _glfwPlatformSetWindowFloating(_GLFWwindow *window, GLFWbool enabled)
Definition: x11_window.c:2559
void _glfwPlatformSetWindowSize(_GLFWwindow *window, int width, int height)
Definition: x11_window.c:2177
static void enableCursor(_GLFWwindow *window)
Definition: x11_window.c:567
void _glfwPlatformShowWindow(_GLFWwindow *window)
Definition: x11_window.c:2353
void _glfwDetectJoystickConnectionLinux(void)
void _glfwPlatformSetWindowAspectRatio(_GLFWwindow *window, int numer, int denom)
Definition: x11_window.c:2205
state()
Definition: rs-pcl.cpp:12
int height
Definition: glfw3.h:1532
GLboolean GLboolean GLboolean b
GLint y
#define XRenderFindVisualFormat
Definition: x11_platform.h:124
#define GLFW_KEY_UNKNOWN
Definition: glfw3.h:357
GLenum GLsizei const void * pointer
static void updateCursorImage(_GLFWwindow *window)
Definition: x11_window.c:515
#define GLFW_MOD_CONTROL
If this bit is set one or more Control keys were held down.
Definition: glfw3.h:504
VkResult
Definition: vulkan_core.h:122
void _glfwInputWindowCloseRequest(_GLFWwindow *window)
Definition: window.c:131
GLFWbool scaleToMonitor
Definition: internal.h:268
static void sendEventToWM(_GLFWwindow *window, Atom type, long a, long b, long c, long d, long e)
Definition: x11_window.c:213
unsigned char * pixels
Definition: glfw3.h:1598
#define GLFWAPI
Definition: glfw3.h:240
GLdouble GLdouble GLdouble top
#define Button7
Definition: x11_window.c:49
window(int width, int height, const char *title)
Definition: example.hpp:506
GLdouble s
static void disableCursor(_GLFWwindow *window)
Definition: x11_window.c:536
static char ** parseUriList(char *text, int *count)
Definition: x11_window.c:381
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig *wndconfig, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig, Visual **visual, int *depth)
Definition: glx_context.c:636
#define _GLFW_REQUIRE_INIT()
Definition: internal.h:204
int _glfwPlatformWindowVisible(_GLFWwindow *window)
Definition: x11_window.c:2449
const GLint * attribs
Definition: glext.h:11230
void _glfwInputChar(_GLFWwindow *window, unsigned int codepoint, int mods, GLFWbool plain)
Definition: input.c:290
static GLFWwindow * window
Definition: joysticks.c:55
GLFWbool _glfwInitOSMesa(void)
int _glfwPlatformCreateCursor(_GLFWcursor *cursor, const GLFWimage *image, int xhot, int yhot)
Definition: x11_window.c:2791
int width
Definition: glfw3.h:1529
void _glfwInputWindowIconify(_GLFWwindow *window, GLFWbool iconified)
Definition: window.c:89
GLFWAPI void glfwSetX11SelectionString(const char *string)
Definition: x11_window.c:3037
GLFWbool decorated
Definition: internal.h:261
GLuint64 GLenum void * handle
Definition: glext.h:7785
static void updateNormalHints(_GLFWwindow *window, int width, int height)
Definition: x11_window.c:237
#define GLFW_MOUSE_BUTTON_RIGHT
Definition: glfw3.h:547
void _glfwPlatformSetWindowDecorated(_GLFWwindow *window, GLFWbool enabled)
Definition: x11_window.c:2528
void _glfwSetVideoModeX11(_GLFWmonitor *monitor, const GLFWvidmode *desired)
Definition: x11_monitor.c:219
GLsizei const GLchar *const * path
Definition: glext.h:4276
_GLFWdestroycontextfun destroy
Definition: internal.h:353
GLfloat value
GLint GLuint mask
void _glfwInputFramebufferSize(_GLFWwindow *window, int width, int height)
Definition: window.c:106
static void handleSelectionClear(XEvent *event)
Definition: x11_window.c:928
static int translateState(int state)
Definition: x11_window.c:180
GLsizei const GLuint * paths
Definition: glext.h:10532
int _glfwPlatformCreateWindow(_GLFWwindow *window, const _GLFWwndconfig *wndconfig, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: x11_window.c:1947
_GLFWctxconfig context
Definition: internal.h:520
void _glfwPlatformSetCursor(_GLFWwindow *window, _GLFWcursor *cursor)
Definition: x11_window.c:2838
void _glfwPlatformSetWindowTitle(_GLFWwindow *window, const char *title)
Definition: x11_window.c:2052
int height
Definition: glfw3.h:1595
#define XRRUpdateConfiguration
Definition: x11_platform.h:83
void _glfwPlatformWaitEventsTimeout(double timeout)
Definition: x11_window.c:2697
void _glfwInputWindowMaximize(_GLFWwindow *window, GLFWbool maximized)
Definition: window.c:97
void _glfwPlatformSetWindowResizable(_GLFWwindow *window, GLFWbool enabled)
Definition: x11_window.c:2521
#define GLFW_FALSE
Zero.
Definition: glfw3.h:287
GLint GLint GLsizei GLsizei GLsizei depth
int _glfwPlatformWindowFocused(_GLFWwindow *window)
Definition: x11_window.c:2435
uint64_t _glfwPlatformGetTimerFrequency(void)
Definition: cocoa_time.c:56
GLFWbool _glfwInitGLX(void)
Definition: glx_context.c:253
char * _glfw_strdup(const char *source)
Definition: init.c:114
const char * _glfwGetVulkanResultString(VkResult result)
Definition: src/vulkan.c:159
struct _GLFWlibrary::@29 vk
void _glfwPlatformGetVideoMode(_GLFWmonitor *monitor, GLFWvidmode *mode)
Definition: null_monitor.c:57
#define GLFW_MOUSE_BUTTON_LEFT
Definition: glfw3.h:546
#define XGetXCBConnection
Definition: x11_platform.h:103
#define GLFW_CROSSHAIR_CURSOR
The crosshair shape.
Definition: glfw3.h:1040
GLdouble GLdouble GLdouble w
GLsizei const GLchar *const * string
Definition: parser.hpp:57
d
Definition: rmse.py:171
#define GLFW_API_UNAVAILABLE
GLFW could not find support for the requested API on the system.
Definition: glfw3.h:698
#define GLFW_EGL_CONTEXT_API
Definition: glfw3.h:1015
void _glfwPlatformGetWindowPos(_GLFWwindow *window, int *xpos, int *ypos)
Definition: x11_window.c:2128
#define GLFW_FORMAT_UNAVAILABLE
The requested format is not supported or available.
Definition: glfw3.h:745
const char * _glfwPlatformGetClipboardString(void)
Definition: x11_window.c:2865
#define GLFW_ARROW_CURSOR
The regular arrow cursor shape.
Definition: glfw3.h:1030
_GLFWcontext context
Definition: internal.h:394
e
Definition: rmse.py:177
void _glfwPlatformGetCursorPos(_GLFWwindow *window, double *xpos, double *ypos)
Definition: x11_window.c:2722
int GLFWbool
Definition: internal.h:61
GLenum GLfloat * buffer
GLFWbool floating
Definition: internal.h:264
void * handle
Definition: internal.h:547
int _glfwPlatformFramebufferTransparent(_GLFWwindow *window)
Definition: x11_window.c:2513
const char * title
Definition: internal.h:258
void _glfwInputWindowDamage(_GLFWwindow *window)
Definition: window.c:123
GLenum GLenum GLsizei void * image
int _glfwPlatformWindowHovered(_GLFWwindow *window)
Definition: x11_window.c:2491
#define GLFW_DONT_CARE
Definition: glfw3.h:1080
void _glfwInputCursorEnter(_GLFWwindow *window, GLFWbool entered)
Definition: input.c:352
status
Defines return codes that SDK interfaces use. Negative values indicate errors, a zero value indicates...
void _glfwInputWindowPos(_GLFWwindow *window, int xpos, int ypos)
Definition: window.c:72
void _glfwGrabErrorHandlerX11(void)
Definition: x11_init.c:855
GLFWvidmode videoMode
Definition: internal.h:377
void _glfwPlatformGetRequiredInstanceExtensions(char **extensions)
Definition: x11_window.c:2870
GLFWbool KHR_surface
Definition: internal.h:553
void _glfwPlatformFocusWindow(_GLFWwindow *window)
Definition: x11_window.c:2377
void _glfwPlatformHideWindow(_GLFWwindow *window)
Definition: x11_window.c:2362
GLboolean GLboolean GLboolean GLboolean a
void _glfwInputScroll(_GLFWwindow *window, double xoffset, double yoffset)
Definition: input.c:310
#define GLFW_RELEASE
The key or mouse button was released.
Definition: glfw3.h:297
GLuint64 key
Definition: glext.h:8966
static void processEvent(XEvent *event)
Definition: x11_window.c:1165
#define GLFW_CURSOR_DISABLED
Definition: glfw3.h:1008
void _glfwPlatformSetWindowPos(_GLFWwindow *window, int xpos, int ypos)
Definition: x11_window.c:2142
GLFWbool resizable
Definition: internal.h:370
int _glfwPlatformCreateStandardCursor(_GLFWcursor *cursor, int shape)
Definition: x11_window.c:2802
VkResult(APIENTRY * PFN_vkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *)
Definition: x11_platform.h:147
void _glfwPlatformRestoreWindow(_GLFWwindow *window)
Definition: x11_window.c:2303
void _glfwPlatformSetCursorPos(_GLFWwindow *window, double x, double y)
Definition: x11_window.c:2739
#define XISelectEvents
Definition: x11_platform.h:117
int maxwidth
Definition: internal.h:382
#define GLFW_VRESIZE_CURSOR
The vertical resize arrow shape.
Definition: glfw3.h:1055
#define _GLFW_REQUIRE_INIT_OR_RETURN(x)
Definition: internal.h:210
GLenum mode
#define GLFW_MOUSE_BUTTON_MIDDLE
Definition: glfw3.h:548
int _glfwPlatformWindowIconified(_GLFWwindow *window)
Definition: x11_window.c:2444
GLsizeiptr size
GLFWbool _glfwCreateContextEGL(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: egl_context.c:456
void _glfwPlatformSetCursorMode(_GLFWwindow *window, int mode)
Definition: x11_window.c:2750
int maxheight
Definition: internal.h:382
#define GLFW_CURSOR_NORMAL
Definition: glfw3.h:1006
GLFWbool maximized
Definition: internal.h:265
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
Definition: glfw3.h:726
#define GLFW_NATIVE_CONTEXT_API
Definition: glfw3.h:1014
void _glfwInputErrorX11(int error, const char *message)
Definition: x11_init.c:872
_GLFWlibrary _glfw
Definition: init.c:44
const GLubyte * c
Definition: glext.h:12690
void _glfwInputWindowFocus(_GLFWwindow *window, GLFWbool focused)
Definition: window.c:43
#define _GLFW_XDND_VERSION
Definition: x11_window.c:51
#define GLFW_MOD_SUPER
If this bit is set one or more Super keys were held down.
Definition: glfw3.h:514
GLdouble x
void * VkInstance
Definition: internal.h:118
#define GLFW_HAND_CURSOR
The hand shape.
Definition: glfw3.h:1045
unsigned int uint32_t
Definition: stdint.h:80
static size_t encodeUTF8(char *s, unsigned int ch)
Definition: x11_window.c:432
int cursorMode
Definition: internal.h:388
#define GLFW_MOD_SHIFT
If this bit is set one or more Shift keys were held down.
Definition: glfw3.h:499
void * VkPhysicalDevice
Definition: internal.h:119
void _glfwPlatformPostEmptyEvent(void)
Definition: x11_window.c:2708
void _glfwPlatformIconifyWindow(_GLFWwindow *window)
Definition: x11_window.c:2288
static Atom writeTargetToProperty(const XSelectionRequestEvent *request)
Definition: x11_window.c:794
GLuint * states
Definition: glext.h:9573
GLint GLsizei GLsizei height
static GLFWbool waitForVisibilityNotify(_GLFWwindow *window)
Definition: x11_window.c:103
static void handleSelectionRequest(XEvent *event)
Definition: x11_window.c:942
static void releaseMonitor(_GLFWwindow *window)
Definition: x11_window.c:1142
GLFWbool available
Definition: internal.h:546
GLenum target
Definition: glext.h:1565
GLbitfield flags
GLFWAPI const char * glfwGetX11SelectionString(void)
Definition: x11_window.c:3057
unsigned __int64 uint64_t
Definition: stdint.h:90
static void centerCursor(_GLFWwindow *window)
Definition: x11_window.c:506
void _glfwPlatformGetMonitorPos(_GLFWmonitor *monitor, int *xpos, int *ypos)
Definition: null_monitor.c:39
GLenum GLenum GLsizei const GLuint GLboolean enabled
void _glfwInputKey(_GLFWwindow *window, int key, int scancode, int action, int mods)
Definition: input.c:259
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *pName)
GLint j
GLint left
Definition: glext.h:1963
double virtualCursorPosY
Definition: internal.h:392
uint64_t VkSurfaceKHR
Definition: internal.h:120
#define Button6
Definition: x11_window.c:48
#define GLFW_OSMESA_CONTEXT_API
Definition: glfw3.h:1016
_GLFWwndconfig window
Definition: internal.h:519
static char * convertLatin1toUTF8(const char *source)
Definition: x11_window.c:487
static GLFWbool createNativeWindow(_GLFWwindow *window, const _GLFWwndconfig *wndconfig, Visual *visual, int depth)
Definition: x11_window.c:591
int minwidth
Definition: internal.h:381
float _glfwPlatformGetWindowOpacity(_GLFWwindow *window)
Definition: x11_window.c:2624
void _glfwInputError(int code, const char *format,...)
Definition: init.c:129
int _glfwPlatformWindowMaximized(_GLFWwindow *window)
Definition: x11_window.c:2456
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
void _glfwPollMonitorsX11(void)
Definition: x11_monitor.c:100
long _glfwKeySym2Unicode(unsigned int keysym)
Definition: xkb_unicode.c:908
#define GLFW_MOD_ALT
If this bit is set one or more Alt keys were held down.
Definition: glfw3.h:509
unsigned long _glfwGetWindowPropertyX11(Window window, Atom property, Atom type, unsigned char **value)
Definition: x11_window.c:1860
action
Definition: enums.py:62
VkBool32(APIENTRY * PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(VkPhysicalDevice, uint32_t, xcb_connection_t *, xcb_visualid_t)
Definition: x11_platform.h:150
void _glfwInputWindowSize(_GLFWwindow *window, int width, int height)
Definition: window.c:81
GLFWbool _glfwCreateContextGLX(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
Definition: glx_context.c:445
void _glfwPlatformSetClipboardString(const char *string)
Definition: x11_window.c:2847
#define GLFW_MOD_CAPS_LOCK
If this bit is set the Caps Lock key is enabled.
Definition: glfw3.h:520
void _glfwPlatformSetWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor, int xpos, int ypos, int width, int height, int refreshRate)
Definition: x11_window.c:2391
GLuint GLsizei const GLuint const GLintptr * offsets
Definition: glext.h:2580
void _glfwPushSelectionToManagerX11(void)
Definition: x11_window.c:1896
static GLFWbool waitForEvent(double *timeout)
Definition: x11_window.c:58
void _glfwPlatformGetWindowFrameSize(_GLFWwindow *window, int *left, int *top, int *right, int *bottom)
Definition: x11_window.c:2218
uint64_t _glfwPlatformGetTimerValue(void)
Definition: cocoa_time.c:51
static void acquireMonitor(_GLFWwindow *window)
Definition: x11_window.c:1103
struct _cl_event * event
Definition: glext.h:2991
void _glfwInputWindowMonitor(_GLFWwindow *window, _GLFWmonitor *monitor)
Definition: window.c:141
int width
Definition: glfw3.h:1592
char className[256]
Definition: internal.h:274
GLsizei const GLfloat * values
#define GLFW_TRUE
One.
Definition: glfw3.h:279
void next(auto_any_t cur, type2type< T, C > *)
Definition: foreach.hpp:757
void _glfwInputCursorPos(_GLFWwindow *window, double xpos, double ypos)
Definition: input.c:338
GLFWbool autoIconify
Definition: internal.h:372
int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily)
Definition: x11_window.c:2891
static Bool isSelectionEvent(Display *display, XEvent *event, XPointer pointer)
Definition: x11_window.c:146
void _glfwPlatformSetWindowOpacity(_GLFWwindow *window, float opacity)
Definition: x11_window.c:2647
Cursor _glfwCreateCursorX11(const GLFWimage *image, int xhot, int yhot)
Definition: x11_init.c:883
static Bool isFrameExtentsEvent(Display *display, XEvent *event, XPointer pointer)
Definition: x11_window.c:158
void _glfwRestoreVideoModeX11(_GLFWmonitor *monitor)
Definition: x11_monitor.c:277
#define GLFW_CURSOR_HIDDEN
Definition: glfw3.h:1007
Video mode type.
Definition: glfw3.h:1525
VkBool32(APIENTRY * PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID)
Definition: x11_platform.h:148
GLdouble right
GLbitfield GLuint64 timeout
GLenum type
void _glfwPlatformSetWindowSizeLimits(_GLFWwindow *window, int minwidth, int minheight, int maxwidth, int maxheight)
Definition: x11_window.c:2195
#define GLFW_HRESIZE_CURSOR
The horizontal resize arrow shape.
Definition: glfw3.h:1050
void _glfwReleaseErrorHandlerX11(void)
Definition: x11_init.c:863
#define GLFW_OUT_OF_MEMORY
A memory allocation failed.
Definition: glfw3.h:682
GLFWAPI Display * glfwGetX11Display(void)
Definition: x11_window.c:3024
static double xpos
Definition: splitview.c:33
void _glfwPlatformGetFramebufferSize(_GLFWwindow *window, int *width, int *height)
Definition: x11_window.c:2213
#define GLFW_IBEAM_CURSOR
The text input I-beam cursor shape.
Definition: glfw3.h:1035
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow *window, const _GLFWctxconfig *ctxconfig, const _GLFWfbconfig *fbconfig)
static const char * maximized
Definition: model-views.h:183
void _glfwPlatformRequestWindowAttention(_GLFWwindow *window)
Definition: x11_window.c:2368
void _glfwPlatformPollEvents(void)
Definition: x11_window.c:2655
GLint GLsizei count
void _glfwInputMonitorWindow(_GLFWmonitor *monitor, _GLFWwindow *window)
Definition: monitor.c:149
int _glfwPlatformGetKeyScancode(int key)
Definition: x11_window.c:2786
GLFWAPI Window glfwGetX11Window(GLFWwindow *handle)
Definition: x11_window.c:3030
static Bool isSelPropNewValueNotify(Display *display, XEvent *event, XPointer pointer)
Definition: x11_window.c:169
void _glfwPlatformMaximizeWindow(_GLFWwindow *window)
Definition: x11_window.c:2337
#define _NET_WM_STATE_REMOVE
Definition: x11_window.c:43
_GLFWcursor * cursor
Definition: internal.h:379
xcb_connection_t * connection
Definition: x11_platform.h:143
static void updateWindowMode(_GLFWwindow *window)
Definition: x11_window.c:286
int minheight
Definition: internal.h:381
GLsizei GLsizei GLchar * source
void display(void)
Definition: boing.c:194
void _glfwPlatformGetWindowSize(_GLFWwindow *window, int *width, int *height)
Definition: x11_window.c:2166
#define NULL
Definition: tinycthread.c:47
int i
void _glfwPlatformGetWindowContentScale(_GLFWwindow *window, float *xscale, float *yscale)
Definition: x11_window.c:2279
struct xcb_connection_t xcb_connection_t
Definition: x11_platform.h:101
void _glfwPlatformDestroyWindow(_GLFWwindow *window)
Definition: x11_window.c:2018
Image data.
Definition: glfw3.h:1588
static int getWindowState(_GLFWwindow *window)
Definition: x11_window.c:122
void _glfwInputMouseClick(_GLFWwindow *window, int button, int action, int mods)
Definition: input.c:318
GLFWbool _glfwInitEGL(void)
Definition: egl_context.c:300
GLuint64 GLenum GLint fd
Definition: glext.h:7768
root
Definition: repo.py:7
::std_msgs::Time_< std::allocator< void > > Time
Definition: Time.h:47
VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, _GLFWwindow *window, const VkAllocationCallbacks *allocator, VkSurfaceKHR *surface)
Definition: x11_window.c:2944
GLboolean * data
double virtualCursorPosX
Definition: internal.h:392
_GLFWwindow * window
Definition: internal.h:431
static int translateKey(int scancode)
Definition: x11_window.c:202
void _glfwPlatformWaitEvents(void)
Definition: x11_window.c:2689
#define GLFW_PRESS
The key or mouse button was pressed.
Definition: glfw3.h:304
const char * _glfwPlatformGetScancodeName(int scancode)
Definition: x11_window.c:2765
_GLFWmonitor * monitor
Definition: internal.h:378
GLuint64EXT * result
Definition: glext.h:10921
void _glfwInputDrop(_GLFWwindow *window, int count, const char **paths)
Definition: input.c:360
GLFWbool decorated
Definition: internal.h:371
#define _NET_WM_STATE_ADD
Definition: x11_window.c:44
struct _GLFWwndconfig::@24 x11
char instanceName[256]
Definition: internal.h:275
auto device
Definition: pyrs_net.cpp:17
void _glfwPlatformDestroyCursor(_GLFWcursor *cursor)
Definition: x11_window.c:2832
struct GLFWwindow GLFWwindow
static const char * getSelectionString(Atom selection)
Definition: x11_window.c:960
GLint GLsizei width
#define GLFW_MOD_NUM_LOCK
If this bit is set the Num Lock key is enabled.
Definition: glfw3.h:526
VkResult(APIENTRY * PFN_vkCreateXcbSurfaceKHR)(VkInstance, const VkXcbSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *)
Definition: x11_platform.h:149
static double ypos
Definition: splitview.c:33
void _glfwPlatformSetWindowIcon(_GLFWwindow *window, int count, const GLFWimage *images)
Definition: x11_window.c:2083
#define GLFW_NO_API
Definition: glfw3.h:989
GLFWbool _glfwIsVisualTransparentX11(Visual *visual)
Definition: x11_window.c:1885
GLdouble GLdouble bottom


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:23