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