x11_init.c
Go to the documentation of this file.
1 //========================================================================
2 // GLFW 3.3 X11 - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2002-2006 Marcus Geelnard
5 // Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
6 //
7 // This software is provided 'as-is', without any express or implied
8 // warranty. In no event will the authors be held liable for any damages
9 // arising from the use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose,
12 // including commercial applications, and to alter it and redistribute it
13 // freely, subject to the following restrictions:
14 //
15 // 1. The origin of this software must not be misrepresented; you must not
16 // claim that you wrote the original software. If you use this software
17 // in a product, an acknowledgment in the product documentation would
18 // be appreciated but is not required.
19 //
20 // 2. Altered source versions must be plainly marked as such, and must not
21 // be misrepresented as being the original software.
22 //
23 // 3. This notice may not be removed or altered from any source
24 // distribution.
25 //
26 //========================================================================
27 
28 #include "internal.h"
29 
30 #include <X11/Xresource.h>
31 
32 #include <stdlib.h>
33 #include <string.h>
34 #include <limits.h>
35 #include <stdio.h>
36 #include <locale.h>
37 
38 
39 // Translate an X11 key code to a GLFW key code.
40 //
41 static int translateKeyCode(int scancode)
42 {
43  int keySym;
44 
45  // Valid key code range is [8,255], according to the Xlib manual
46  if (scancode < 8 || scancode > 255)
47  return GLFW_KEY_UNKNOWN;
48 
49  if (_glfw.x11.xkb.available)
50  {
51  // Try secondary keysym, for numeric keypad keys
52  // Note: This way we always force "NumLock = ON", which is intentional
53  // since the returned key code should correspond to a physical
54  // location.
55  keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 1);
56  switch (keySym)
57  {
58  case XK_KP_0: return GLFW_KEY_KP_0;
59  case XK_KP_1: return GLFW_KEY_KP_1;
60  case XK_KP_2: return GLFW_KEY_KP_2;
61  case XK_KP_3: return GLFW_KEY_KP_3;
62  case XK_KP_4: return GLFW_KEY_KP_4;
63  case XK_KP_5: return GLFW_KEY_KP_5;
64  case XK_KP_6: return GLFW_KEY_KP_6;
65  case XK_KP_7: return GLFW_KEY_KP_7;
66  case XK_KP_8: return GLFW_KEY_KP_8;
67  case XK_KP_9: return GLFW_KEY_KP_9;
68  case XK_KP_Separator:
69  case XK_KP_Decimal: return GLFW_KEY_KP_DECIMAL;
70  case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;
71  case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
72  default: break;
73  }
74 
75  // Now try primary keysym for function keys (non-printable keys)
76  // These should not depend on the current keyboard layout
77  keySym = XkbKeycodeToKeysym(_glfw.x11.display, scancode, 0, 0);
78  }
79  else
80  {
81  int dummy;
82  KeySym* keySyms;
83 
84  keySyms = XGetKeyboardMapping(_glfw.x11.display, scancode, 1, &dummy);
85  keySym = keySyms[0];
86  XFree(keySyms);
87  }
88 
89  switch (keySym)
90  {
91  case XK_Escape: return GLFW_KEY_ESCAPE;
92  case XK_Tab: return GLFW_KEY_TAB;
93  case XK_Shift_L: return GLFW_KEY_LEFT_SHIFT;
94  case XK_Shift_R: return GLFW_KEY_RIGHT_SHIFT;
95  case XK_Control_L: return GLFW_KEY_LEFT_CONTROL;
96  case XK_Control_R: return GLFW_KEY_RIGHT_CONTROL;
97  case XK_Meta_L:
98  case XK_Alt_L: return GLFW_KEY_LEFT_ALT;
99  case XK_Mode_switch: // Mapped to Alt_R on many keyboards
100  case XK_ISO_Level3_Shift: // AltGr on at least some machines
101  case XK_Meta_R:
102  case XK_Alt_R: return GLFW_KEY_RIGHT_ALT;
103  case XK_Super_L: return GLFW_KEY_LEFT_SUPER;
104  case XK_Super_R: return GLFW_KEY_RIGHT_SUPER;
105  case XK_Menu: return GLFW_KEY_MENU;
106  case XK_Num_Lock: return GLFW_KEY_NUM_LOCK;
107  case XK_Caps_Lock: return GLFW_KEY_CAPS_LOCK;
108  case XK_Print: return GLFW_KEY_PRINT_SCREEN;
109  case XK_Scroll_Lock: return GLFW_KEY_SCROLL_LOCK;
110  case XK_Pause: return GLFW_KEY_PAUSE;
111  case XK_Delete: return GLFW_KEY_DELETE;
112  case XK_BackSpace: return GLFW_KEY_BACKSPACE;
113  case XK_Return: return GLFW_KEY_ENTER;
114  case XK_Home: return GLFW_KEY_HOME;
115  case XK_End: return GLFW_KEY_END;
116  case XK_Page_Up: return GLFW_KEY_PAGE_UP;
117  case XK_Page_Down: return GLFW_KEY_PAGE_DOWN;
118  case XK_Insert: return GLFW_KEY_INSERT;
119  case XK_Left: return GLFW_KEY_LEFT;
120  case XK_Right: return GLFW_KEY_RIGHT;
121  case XK_Down: return GLFW_KEY_DOWN;
122  case XK_Up: return GLFW_KEY_UP;
123  case XK_F1: return GLFW_KEY_F1;
124  case XK_F2: return GLFW_KEY_F2;
125  case XK_F3: return GLFW_KEY_F3;
126  case XK_F4: return GLFW_KEY_F4;
127  case XK_F5: return GLFW_KEY_F5;
128  case XK_F6: return GLFW_KEY_F6;
129  case XK_F7: return GLFW_KEY_F7;
130  case XK_F8: return GLFW_KEY_F8;
131  case XK_F9: return GLFW_KEY_F9;
132  case XK_F10: return GLFW_KEY_F10;
133  case XK_F11: return GLFW_KEY_F11;
134  case XK_F12: return GLFW_KEY_F12;
135  case XK_F13: return GLFW_KEY_F13;
136  case XK_F14: return GLFW_KEY_F14;
137  case XK_F15: return GLFW_KEY_F15;
138  case XK_F16: return GLFW_KEY_F16;
139  case XK_F17: return GLFW_KEY_F17;
140  case XK_F18: return GLFW_KEY_F18;
141  case XK_F19: return GLFW_KEY_F19;
142  case XK_F20: return GLFW_KEY_F20;
143  case XK_F21: return GLFW_KEY_F21;
144  case XK_F22: return GLFW_KEY_F22;
145  case XK_F23: return GLFW_KEY_F23;
146  case XK_F24: return GLFW_KEY_F24;
147  case XK_F25: return GLFW_KEY_F25;
148 
149  // Numeric keypad
150  case XK_KP_Divide: return GLFW_KEY_KP_DIVIDE;
151  case XK_KP_Multiply: return GLFW_KEY_KP_MULTIPLY;
152  case XK_KP_Subtract: return GLFW_KEY_KP_SUBTRACT;
153  case XK_KP_Add: return GLFW_KEY_KP_ADD;
154 
155  // These should have been detected in secondary keysym test above!
156  case XK_KP_Insert: return GLFW_KEY_KP_0;
157  case XK_KP_End: return GLFW_KEY_KP_1;
158  case XK_KP_Down: return GLFW_KEY_KP_2;
159  case XK_KP_Page_Down: return GLFW_KEY_KP_3;
160  case XK_KP_Left: return GLFW_KEY_KP_4;
161  case XK_KP_Right: return GLFW_KEY_KP_6;
162  case XK_KP_Home: return GLFW_KEY_KP_7;
163  case XK_KP_Up: return GLFW_KEY_KP_8;
164  case XK_KP_Page_Up: return GLFW_KEY_KP_9;
165  case XK_KP_Delete: return GLFW_KEY_KP_DECIMAL;
166  case XK_KP_Equal: return GLFW_KEY_KP_EQUAL;
167  case XK_KP_Enter: return GLFW_KEY_KP_ENTER;
168 
169  // Last resort: Check for printable keys (should not happen if the XKB
170  // extension is available). This will give a layout dependent mapping
171  // (which is wrong, and we may miss some keys, especially on non-US
172  // keyboards), but it's better than nothing...
173  case XK_a: return GLFW_KEY_A;
174  case XK_b: return GLFW_KEY_B;
175  case XK_c: return GLFW_KEY_C;
176  case XK_d: return GLFW_KEY_D;
177  case XK_e: return GLFW_KEY_E;
178  case XK_f: return GLFW_KEY_F;
179  case XK_g: return GLFW_KEY_G;
180  case XK_h: return GLFW_KEY_H;
181  case XK_i: return GLFW_KEY_I;
182  case XK_j: return GLFW_KEY_J;
183  case XK_k: return GLFW_KEY_K;
184  case XK_l: return GLFW_KEY_L;
185  case XK_m: return GLFW_KEY_M;
186  case XK_n: return GLFW_KEY_N;
187  case XK_o: return GLFW_KEY_O;
188  case XK_p: return GLFW_KEY_P;
189  case XK_q: return GLFW_KEY_Q;
190  case XK_r: return GLFW_KEY_R;
191  case XK_s: return GLFW_KEY_S;
192  case XK_t: return GLFW_KEY_T;
193  case XK_u: return GLFW_KEY_U;
194  case XK_v: return GLFW_KEY_V;
195  case XK_w: return GLFW_KEY_W;
196  case XK_x: return GLFW_KEY_X;
197  case XK_y: return GLFW_KEY_Y;
198  case XK_z: return GLFW_KEY_Z;
199  case XK_1: return GLFW_KEY_1;
200  case XK_2: return GLFW_KEY_2;
201  case XK_3: return GLFW_KEY_3;
202  case XK_4: return GLFW_KEY_4;
203  case XK_5: return GLFW_KEY_5;
204  case XK_6: return GLFW_KEY_6;
205  case XK_7: return GLFW_KEY_7;
206  case XK_8: return GLFW_KEY_8;
207  case XK_9: return GLFW_KEY_9;
208  case XK_0: return GLFW_KEY_0;
209  case XK_space: return GLFW_KEY_SPACE;
210  case XK_minus: return GLFW_KEY_MINUS;
211  case XK_equal: return GLFW_KEY_EQUAL;
212  case XK_bracketleft: return GLFW_KEY_LEFT_BRACKET;
213  case XK_bracketright: return GLFW_KEY_RIGHT_BRACKET;
214  case XK_backslash: return GLFW_KEY_BACKSLASH;
215  case XK_semicolon: return GLFW_KEY_SEMICOLON;
216  case XK_apostrophe: return GLFW_KEY_APOSTROPHE;
217  case XK_grave: return GLFW_KEY_GRAVE_ACCENT;
218  case XK_comma: return GLFW_KEY_COMMA;
219  case XK_period: return GLFW_KEY_PERIOD;
220  case XK_slash: return GLFW_KEY_SLASH;
221  case XK_less: return GLFW_KEY_WORLD_1; // At least in some layouts...
222  default: break;
223  }
224 
225  // No matching translation was found
226  return GLFW_KEY_UNKNOWN;
227 }
228 
229 // Create key code translation tables
230 //
231 static void createKeyTables(void)
232 {
233  int scancode, key;
234 
235  memset(_glfw.x11.keycodes, -1, sizeof(_glfw.x11.keycodes));
236  memset(_glfw.x11.scancodes, -1, sizeof(_glfw.x11.scancodes));
237 
238  if (_glfw.x11.xkb.available)
239  {
240  // Use XKB to determine physical key locations independently of the
241  // current keyboard layout
242 
243  char name[XkbKeyNameLength + 1];
244  XkbDescPtr desc = XkbGetMap(_glfw.x11.display, 0, XkbUseCoreKbd);
245  XkbGetNames(_glfw.x11.display, XkbKeyNamesMask, desc);
246 
247  // Find the X11 key code -> GLFW key code mapping
248  for (scancode = desc->min_key_code; scancode <= desc->max_key_code; scancode++)
249  {
250  memcpy(name, desc->names->keys[scancode].name, XkbKeyNameLength);
251  name[XkbKeyNameLength] = '\0';
252 
253  // Map the key name to a GLFW key code. Note: We only map printable
254  // keys here, and we use the US keyboard layout. The rest of the
255  // keys (function keys) are mapped using traditional KeySym
256  // translations.
257  if (strcmp(name, "TLDE") == 0) key = GLFW_KEY_GRAVE_ACCENT;
258  else if (strcmp(name, "AE01") == 0) key = GLFW_KEY_1;
259  else if (strcmp(name, "AE02") == 0) key = GLFW_KEY_2;
260  else if (strcmp(name, "AE03") == 0) key = GLFW_KEY_3;
261  else if (strcmp(name, "AE04") == 0) key = GLFW_KEY_4;
262  else if (strcmp(name, "AE05") == 0) key = GLFW_KEY_5;
263  else if (strcmp(name, "AE06") == 0) key = GLFW_KEY_6;
264  else if (strcmp(name, "AE07") == 0) key = GLFW_KEY_7;
265  else if (strcmp(name, "AE08") == 0) key = GLFW_KEY_8;
266  else if (strcmp(name, "AE09") == 0) key = GLFW_KEY_9;
267  else if (strcmp(name, "AE10") == 0) key = GLFW_KEY_0;
268  else if (strcmp(name, "AE11") == 0) key = GLFW_KEY_MINUS;
269  else if (strcmp(name, "AE12") == 0) key = GLFW_KEY_EQUAL;
270  else if (strcmp(name, "AD01") == 0) key = GLFW_KEY_Q;
271  else if (strcmp(name, "AD02") == 0) key = GLFW_KEY_W;
272  else if (strcmp(name, "AD03") == 0) key = GLFW_KEY_E;
273  else if (strcmp(name, "AD04") == 0) key = GLFW_KEY_R;
274  else if (strcmp(name, "AD05") == 0) key = GLFW_KEY_T;
275  else if (strcmp(name, "AD06") == 0) key = GLFW_KEY_Y;
276  else if (strcmp(name, "AD07") == 0) key = GLFW_KEY_U;
277  else if (strcmp(name, "AD08") == 0) key = GLFW_KEY_I;
278  else if (strcmp(name, "AD09") == 0) key = GLFW_KEY_O;
279  else if (strcmp(name, "AD10") == 0) key = GLFW_KEY_P;
280  else if (strcmp(name, "AD11") == 0) key = GLFW_KEY_LEFT_BRACKET;
281  else if (strcmp(name, "AD12") == 0) key = GLFW_KEY_RIGHT_BRACKET;
282  else if (strcmp(name, "AC01") == 0) key = GLFW_KEY_A;
283  else if (strcmp(name, "AC02") == 0) key = GLFW_KEY_S;
284  else if (strcmp(name, "AC03") == 0) key = GLFW_KEY_D;
285  else if (strcmp(name, "AC04") == 0) key = GLFW_KEY_F;
286  else if (strcmp(name, "AC05") == 0) key = GLFW_KEY_G;
287  else if (strcmp(name, "AC06") == 0) key = GLFW_KEY_H;
288  else if (strcmp(name, "AC07") == 0) key = GLFW_KEY_J;
289  else if (strcmp(name, "AC08") == 0) key = GLFW_KEY_K;
290  else if (strcmp(name, "AC09") == 0) key = GLFW_KEY_L;
291  else if (strcmp(name, "AC10") == 0) key = GLFW_KEY_SEMICOLON;
292  else if (strcmp(name, "AC11") == 0) key = GLFW_KEY_APOSTROPHE;
293  else if (strcmp(name, "AB01") == 0) key = GLFW_KEY_Z;
294  else if (strcmp(name, "AB02") == 0) key = GLFW_KEY_X;
295  else if (strcmp(name, "AB03") == 0) key = GLFW_KEY_C;
296  else if (strcmp(name, "AB04") == 0) key = GLFW_KEY_V;
297  else if (strcmp(name, "AB05") == 0) key = GLFW_KEY_B;
298  else if (strcmp(name, "AB06") == 0) key = GLFW_KEY_N;
299  else if (strcmp(name, "AB07") == 0) key = GLFW_KEY_M;
300  else if (strcmp(name, "AB08") == 0) key = GLFW_KEY_COMMA;
301  else if (strcmp(name, "AB09") == 0) key = GLFW_KEY_PERIOD;
302  else if (strcmp(name, "AB10") == 0) key = GLFW_KEY_SLASH;
303  else if (strcmp(name, "BKSL") == 0) key = GLFW_KEY_BACKSLASH;
304  else if (strcmp(name, "LSGT") == 0) key = GLFW_KEY_WORLD_1;
305  else key = GLFW_KEY_UNKNOWN;
306 
307  if ((scancode >= 0) && (scancode < 256))
308  _glfw.x11.keycodes[scancode] = key;
309  }
310 
311  XkbFreeNames(desc, XkbKeyNamesMask, True);
312  XkbFreeKeyboard(desc, 0, True);
313  }
314 
315  for (scancode = 0; scancode < 256; scancode++)
316  {
317  // Translate the un-translated key codes using traditional X11 KeySym
318  // lookups
319  if (_glfw.x11.keycodes[scancode] < 0)
320  _glfw.x11.keycodes[scancode] = translateKeyCode(scancode);
321 
322  // Store the reverse translation for faster key name lookup
323  if (_glfw.x11.keycodes[scancode] > 0)
324  _glfw.x11.scancodes[_glfw.x11.keycodes[scancode]] = scancode;
325  }
326 }
327 
328 // Check whether the IM has a usable style
329 //
331 {
332  unsigned int i;
333  GLFWbool found = GLFW_FALSE;
334  XIMStyles* styles = NULL;
335 
336  if (XGetIMValues(_glfw.x11.im, XNQueryInputStyle, &styles, NULL) != NULL)
337  return GLFW_FALSE;
338 
339  for (i = 0; i < styles->count_styles; i++)
340  {
341  if (styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing))
342  {
343  found = GLFW_TRUE;
344  break;
345  }
346  }
347 
348  XFree(styles);
349  return found;
350 }
351 
352 // Check whether the specified atom is supported
353 //
354 static Atom getSupportedAtom(Atom* supportedAtoms,
355  unsigned long atomCount,
356  const char* atomName)
357 {
358  unsigned long i;
359  const Atom atom = XInternAtom(_glfw.x11.display, atomName, False);
360 
361  for (i = 0; i < atomCount; i++)
362  {
363  if (supportedAtoms[i] == atom)
364  return atom;
365  }
366 
367  return None;
368 }
369 
370 // Check whether the running window manager is EWMH-compliant
371 //
372 static void detectEWMH(void)
373 {
374  Window* windowFromRoot = NULL;
375  Window* windowFromChild = NULL;
376 
377  // First we need a couple of atoms
378  const Atom supportingWmCheck =
379  XInternAtom(_glfw.x11.display, "_NET_SUPPORTING_WM_CHECK", False);
380  const Atom wmSupported =
381  XInternAtom(_glfw.x11.display, "_NET_SUPPORTED", False);
382 
383  // Then we look for the _NET_SUPPORTING_WM_CHECK property of the root window
384  if (!_glfwGetWindowPropertyX11(_glfw.x11.root,
385  supportingWmCheck,
386  XA_WINDOW,
387  (unsigned char**) &windowFromRoot))
388  {
389  return;
390  }
391 
393 
394  // It should be the ID of a child window (of the root)
395  // Then we look for the same property on the child window
396  if (!_glfwGetWindowPropertyX11(*windowFromRoot,
397  supportingWmCheck,
398  XA_WINDOW,
399  (unsigned char**) &windowFromChild))
400  {
401  XFree(windowFromRoot);
402  return;
403  }
404 
406 
407  // It should be the ID of that same child window
408  if (*windowFromRoot != *windowFromChild)
409  {
410  XFree(windowFromRoot);
411  XFree(windowFromChild);
412  return;
413  }
414 
415  XFree(windowFromRoot);
416  XFree(windowFromChild);
417 
418  // We are now fairly sure that an EWMH-compliant window manager is running
419 
420  Atom* supportedAtoms;
421  unsigned long atomCount;
422 
423  // Now we need to check the _NET_SUPPORTED property of the root window
424  // It should be a list of supported WM protocol and state atoms
425  atomCount = _glfwGetWindowPropertyX11(_glfw.x11.root,
426  wmSupported,
427  XA_ATOM,
428  (unsigned char**) &supportedAtoms);
429 
430  // See which of the atoms we support that are supported by the WM
431  _glfw.x11.NET_WM_STATE =
432  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
433  _glfw.x11.NET_WM_STATE_ABOVE =
434  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_ABOVE");
435  _glfw.x11.NET_WM_STATE_FULLSCREEN =
436  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN");
437  _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT =
438  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_VERT");
439  _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ =
440  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_MAXIMIZED_HORZ");
441  _glfw.x11.NET_WM_STATE_DEMANDS_ATTENTION =
442  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_DEMANDS_ATTENTION");
443  _glfw.x11.NET_WM_FULLSCREEN_MONITORS =
444  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_FULLSCREEN_MONITORS");
445  _glfw.x11.NET_WM_WINDOW_TYPE =
446  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE");
447  _glfw.x11.NET_WM_WINDOW_TYPE_NORMAL =
448  getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_WINDOW_TYPE_NORMAL");
449  _glfw.x11.NET_ACTIVE_WINDOW =
450  getSupportedAtom(supportedAtoms, atomCount, "_NET_ACTIVE_WINDOW");
451  _glfw.x11.NET_FRAME_EXTENTS =
452  getSupportedAtom(supportedAtoms, atomCount, "_NET_FRAME_EXTENTS");
453  _glfw.x11.NET_REQUEST_FRAME_EXTENTS =
454  getSupportedAtom(supportedAtoms, atomCount, "_NET_REQUEST_FRAME_EXTENTS");
455 
456  if (supportedAtoms)
457  XFree(supportedAtoms);
458 }
459 
460 // Look for and initialize supported X11 extensions
461 //
463 {
464  _glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1");
465  if (_glfw.x11.vidmode.handle)
466  {
467  _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
468  _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
469  _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp)
470  _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
471  _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp)
472  _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
473  _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize)
474  _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");
475 
476  _glfw.x11.vidmode.available =
477  XF86VidModeQueryExtension(_glfw.x11.display,
478  &_glfw.x11.vidmode.eventBase,
479  &_glfw.x11.vidmode.errorBase);
480  }
481 
482 #if defined(__CYGWIN__)
483  _glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so");
484 #else
485  _glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6");
486 #endif
487  if (_glfw.x11.xi.handle)
488  {
489  _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
490  _glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
491  _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
492  _glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents");
493 
494  if (XQueryExtension(_glfw.x11.display,
495  "XInputExtension",
496  &_glfw.x11.xi.majorOpcode,
497  &_glfw.x11.xi.eventBase,
498  &_glfw.x11.xi.errorBase))
499  {
500  _glfw.x11.xi.major = 2;
501  _glfw.x11.xi.minor = 0;
502 
503  if (XIQueryVersion(_glfw.x11.display,
504  &_glfw.x11.xi.major,
505  &_glfw.x11.xi.minor) == Success)
506  {
507  _glfw.x11.xi.available = GLFW_TRUE;
508  }
509  }
510  }
511 
512 #if defined(__CYGWIN__)
513  _glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so");
514 #else
515  _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2");
516 #endif
517  if (_glfw.x11.randr.handle)
518  {
519  _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
520  _glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
521  _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
522  _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
523  _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
524  _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
525  _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
526  _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
527  _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
528  _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
529  _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
530  _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
531  _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
532  _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
533  _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
534  _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
535  _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
536  _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
537  _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
538  _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
539  _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
540  _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
541  _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
542  _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
543  _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
544  _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
545  _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
546  _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
547  _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
548  _glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
549  _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
550  _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
551  _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
552  _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
553  _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
554  _glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");
555 
556  if (XRRQueryExtension(_glfw.x11.display,
557  &_glfw.x11.randr.eventBase,
558  &_glfw.x11.randr.errorBase))
559  {
560  if (XRRQueryVersion(_glfw.x11.display,
561  &_glfw.x11.randr.major,
562  &_glfw.x11.randr.minor))
563  {
564  // The GLFW RandR path requires at least version 1.3
565  if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
566  _glfw.x11.randr.available = GLFW_TRUE;
567  }
568  else
569  {
571  "X11: Failed to query RandR version");
572  }
573  }
574  }
575 
576  if (_glfw.x11.randr.available)
577  {
578  XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
579  _glfw.x11.root);
580 
581  if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
582  {
583  // This is likely an older Nvidia driver with broken gamma support
584  // Flag it as useless and fall back to xf86vm gamma, if available
585  _glfw.x11.randr.gammaBroken = GLFW_TRUE;
586  }
587 
588  if (!sr->ncrtc)
589  {
590  // A system without CRTCs is likely a system with broken RandR
591  // Disable the RandR monitor path and fall back to core functions
592  _glfw.x11.randr.monitorBroken = GLFW_TRUE;
593  }
594 
596  }
597 
598  if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
599  {
600  XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
601  RROutputChangeNotifyMask);
602  }
603 
604 #if defined(__CYGWIN__)
605  _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so");
606 #else
607  _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1");
608 #endif
609  if (_glfw.x11.xcursor.handle)
610  {
611  _glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
612  _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
613  _glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
614  _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
615  _glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
616  _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
617  }
618 
619 #if defined(__CYGWIN__)
620  _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so");
621 #else
622  _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1");
623 #endif
624  if (_glfw.x11.xinerama.handle)
625  {
626  _glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
627  _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
628  _glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
629  _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
630  _glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
631  _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");
632 
633  if (XineramaQueryExtension(_glfw.x11.display,
634  &_glfw.x11.xinerama.major,
635  &_glfw.x11.xinerama.minor))
636  {
637  if (XineramaIsActive(_glfw.x11.display))
638  _glfw.x11.xinerama.available = GLFW_TRUE;
639  }
640  }
641 
642  _glfw.x11.xkb.major = 1;
643  _glfw.x11.xkb.minor = 0;
644  _glfw.x11.xkb.available =
645  XkbQueryExtension(_glfw.x11.display,
646  &_glfw.x11.xkb.majorOpcode,
647  &_glfw.x11.xkb.eventBase,
648  &_glfw.x11.xkb.errorBase,
649  &_glfw.x11.xkb.major,
650  &_glfw.x11.xkb.minor);
651 
652  if (_glfw.x11.xkb.available)
653  {
654  Bool supported;
655 
656  if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
657  {
658  if (supported)
659  _glfw.x11.xkb.detectable = GLFW_TRUE;
660  }
661  }
662 
663 #if defined(__CYGWIN__)
664  _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so");
665 #else
666  _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1");
667 #endif
668  if (_glfw.x11.x11xcb.handle)
669  {
670  _glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
671  _glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
672  }
673 
674 #if defined(__CYGWIN__)
675  _glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so");
676 #else
677  _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1");
678 #endif
679  if (_glfw.x11.xrender.handle)
680  {
681  _glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
682  _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension");
683  _glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion)
684  _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion");
685  _glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat)
686  _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat");
687 
688  if (XRenderQueryExtension(_glfw.x11.display,
689  &_glfw.x11.xrender.errorBase,
690  &_glfw.x11.xrender.eventBase))
691  {
692  if (XRenderQueryVersion(_glfw.x11.display,
693  &_glfw.x11.xrender.major,
694  &_glfw.x11.xrender.minor))
695  {
696  _glfw.x11.xrender.available = GLFW_TRUE;
697  }
698  }
699  }
700 
701  // Update the key code LUT
702  // FIXME: We should listen to XkbMapNotify events to track changes to
703  // the keyboard mapping.
704  createKeyTables();
705 
706  // Detect whether an EWMH-conformant window manager is running
707  detectEWMH();
708 
709  // String format atoms
710  _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
711  _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
712  _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);
713 
714  // Custom selection property atom
715  _glfw.x11.GLFW_SELECTION =
716  XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False);
717 
718  // ICCCM standard clipboard atoms
719  _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
720  _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
721  _glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
722  _glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False);
723  _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);
724 
725  // Clipboard manager atoms
726  _glfw.x11.CLIPBOARD_MANAGER =
727  XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);
728  _glfw.x11.SAVE_TARGETS =
729  XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);
730 
731  // Xdnd (drag and drop) atoms
732  _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False);
733  _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False);
734  _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False);
735  _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);
736  _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False);
737  _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False);
738  _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False);
739  _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False);
740  _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False);
741  _glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False);
742 
743  // ICCCM, EWMH and Motif window property atoms
744  // These can be set safely even without WM support
745  // The EWMH atoms that require WM support are handled in detectEWMH
746  _glfw.x11.WM_PROTOCOLS =
747  XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False);
748  _glfw.x11.WM_STATE =
749  XInternAtom(_glfw.x11.display, "WM_STATE", False);
750  _glfw.x11.WM_DELETE_WINDOW =
751  XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
752  _glfw.x11.NET_WM_ICON =
753  XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
754  _glfw.x11.NET_WM_PING =
755  XInternAtom(_glfw.x11.display, "_NET_WM_PING", False);
756  _glfw.x11.NET_WM_PID =
757  XInternAtom(_glfw.x11.display, "_NET_WM_PID", False);
758  _glfw.x11.NET_WM_NAME =
759  XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False);
760  _glfw.x11.NET_WM_ICON_NAME =
761  XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False);
762  _glfw.x11.NET_WM_BYPASS_COMPOSITOR =
763  XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False);
764  _glfw.x11.NET_WM_WINDOW_OPACITY =
765  XInternAtom(_glfw.x11.display, "_NET_WM_WINDOW_OPACITY", False);
766  _glfw.x11.MOTIF_WM_HINTS =
767  XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);
768 
769  // The compositing manager selection name contains the screen number
770  {
771  char name[32];
772  snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen);
773  _glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
774  }
775 
776  return GLFW_TRUE;
777 }
778 
779 // Retrieve system content scale via folklore heuristics
780 //
781 static void getSystemContentScale(float* xscale, float* yscale)
782 {
783  // NOTE: Fall back to the display-wide DPI instead of RandR monitor DPI if
784  // Xft.dpi retrieval below fails as we don't currently have an exact
785  // policy for which monitor a window is considered to "be on"
786  float xdpi = DisplayWidth(_glfw.x11.display, _glfw.x11.screen) *
787  25.4f / DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
788  float ydpi = DisplayHeight(_glfw.x11.display, _glfw.x11.screen) *
789  25.4f / DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
790 
791  // NOTE: Basing the scale on Xft.dpi where available should provide the most
792  // consistent user experience (matches Qt, Gtk, etc), although not
793  // always the most accurate one
794  char* rms = XResourceManagerString(_glfw.x11.display);
795  if (rms)
796  {
797  XrmDatabase db = XrmGetStringDatabase(rms);
798  if (db)
799  {
800  XrmValue value;
801  char* type = NULL;
802 
803  if (XrmGetResource(db, "Xft.dpi", "Xft.Dpi", &type, &value))
804  {
805  if (type && strcmp(type, "String") == 0)
806  xdpi = ydpi = atof(value.addr);
807  }
808 
809  XrmDestroyDatabase(db);
810  }
811  }
812 
813  *xscale = xdpi / 96.f;
814  *yscale = ydpi / 96.f;
815 }
816 
817 // Create a blank cursor for hidden and disabled cursor modes
818 //
819 static Cursor createHiddenCursor(void)
820 {
821  unsigned char pixels[16 * 16 * 4] = { 0 };
822  GLFWimage image = { 16, 16, pixels };
823  return _glfwCreateCursorX11(&image, 0, 0);
824 }
825 
826 // Create a helper window for IPC
827 //
828 static Window createHelperWindow(void)
829 {
830  XSetWindowAttributes wa;
831  wa.event_mask = PropertyChangeMask;
832 
833  return XCreateWindow(_glfw.x11.display, _glfw.x11.root,
834  0, 0, 1, 1, 0, 0,
835  InputOnly,
836  DefaultVisual(_glfw.x11.display, _glfw.x11.screen),
837  CWEventMask, &wa);
838 }
839 
840 // X error handler
841 //
842 static int errorHandler(Display *display, XErrorEvent* event)
843 {
844  _glfw.x11.errorCode = event->error_code;
845  return 0;
846 }
847 
848 
852 
853 // Sets the X error handler callback
854 //
856 {
857  _glfw.x11.errorCode = Success;
858  XSetErrorHandler(errorHandler);
859 }
860 
861 // Clears the X error handler callback
862 //
864 {
865  // Synchronize to make sure all commands are processed
866  XSync(_glfw.x11.display, False);
867  XSetErrorHandler(NULL);
868 }
869 
870 // Reports the specified error, appending information about the last X error
871 //
872 void _glfwInputErrorX11(int error, const char* message)
873 {
875  XGetErrorText(_glfw.x11.display, _glfw.x11.errorCode,
876  buffer, sizeof(buffer));
877 
878  _glfwInputError(error, "%s: %s", message, buffer);
879 }
880 
881 // Creates a native cursor object from the specified image and hotspot
882 //
883 Cursor _glfwCreateCursorX11(const GLFWimage* image, int xhot, int yhot)
884 {
885  int i;
886  Cursor cursor;
887 
888  if (!_glfw.x11.xcursor.handle)
889  return None;
890 
891  XcursorImage* native = XcursorImageCreate(image->width, image->height);
892  if (native == NULL)
893  return None;
894 
895  native->xhot = xhot;
896  native->yhot = yhot;
897 
898  unsigned char* source = (unsigned char*) image->pixels;
899  XcursorPixel* target = native->pixels;
900 
901  for (i = 0; i < image->width * image->height; i++, target++, source += 4)
902  {
903  unsigned int alpha = source[3];
904 
905  *target = (alpha << 24) |
906  ((unsigned char) ((source[0] * alpha) / 255) << 16) |
907  ((unsigned char) ((source[1] * alpha) / 255) << 8) |
908  ((unsigned char) ((source[2] * alpha) / 255) << 0);
909  }
910 
911  cursor = XcursorImageLoadCursor(_glfw.x11.display, native);
912  XcursorImageDestroy(native);
913 
914  return cursor;
915 }
916 
917 
921 
923 {
924 #if !defined(X_HAVE_UTF8_STRING)
925  // HACK: If the current locale is "C" and the Xlib UTF-8 functions are
926  // unavailable, apply the environment's locale in the hope that it's
927  // both available and not "C"
928  // This is done because the "C" locale breaks wide character input,
929  // which is what we fall back on when UTF-8 support is missing
930  if (strcmp(setlocale(LC_CTYPE, NULL), "C") == 0)
931  setlocale(LC_CTYPE, "");
932 #endif
933 
934  XInitThreads();
935  XrmInitialize();
936 
937  _glfw.x11.display = XOpenDisplay(NULL);
938  if (!_glfw.x11.display)
939  {
940  const char* display = getenv("DISPLAY");
941  if (display)
942  {
944  "X11: Failed to open display %s", display);
945  }
946  else
947  {
949  "X11: The DISPLAY environment variable is missing");
950  }
951 
952  return GLFW_FALSE;
953  }
954 
955  _glfw.x11.screen = DefaultScreen(_glfw.x11.display);
956  _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);
957  _glfw.x11.context = XUniqueContext();
958 
959  getSystemContentScale(&_glfw.x11.contentScaleX, &_glfw.x11.contentScaleY);
960 
961  if (!initExtensions())
962  return GLFW_FALSE;
963 
964  _glfw.x11.helperWindowHandle = createHelperWindow();
965  _glfw.x11.hiddenCursorHandle = createHiddenCursor();
966 
967  if (XSupportsLocale())
968  {
969  XSetLocaleModifiers("");
970 
971  _glfw.x11.im = XOpenIM(_glfw.x11.display, 0, NULL, NULL);
972  if (_glfw.x11.im)
973  {
975  {
976  XCloseIM(_glfw.x11.im);
977  _glfw.x11.im = NULL;
978  }
979  }
980  }
981 
982 #if defined(__linux__)
984  return GLFW_FALSE;
985 #endif
986 
988 
990  return GLFW_TRUE;
991 }
992 
994 {
995  if (_glfw.x11.helperWindowHandle)
996  {
997  if (XGetSelectionOwner(_glfw.x11.display, _glfw.x11.CLIPBOARD) ==
998  _glfw.x11.helperWindowHandle)
999  {
1001  }
1002 
1003  XDestroyWindow(_glfw.x11.display, _glfw.x11.helperWindowHandle);
1004  _glfw.x11.helperWindowHandle = None;
1005  }
1006 
1007  if (_glfw.x11.hiddenCursorHandle)
1008  {
1009  XFreeCursor(_glfw.x11.display, _glfw.x11.hiddenCursorHandle);
1010  _glfw.x11.hiddenCursorHandle = (Cursor) 0;
1011  }
1012 
1013  free(_glfw.x11.primarySelectionString);
1014  free(_glfw.x11.clipboardString);
1015 
1016  if (_glfw.x11.im)
1017  {
1018  XCloseIM(_glfw.x11.im);
1019  _glfw.x11.im = NULL;
1020  }
1021 
1022  if (_glfw.x11.display)
1023  {
1024  XCloseDisplay(_glfw.x11.display);
1025  _glfw.x11.display = NULL;
1026  }
1027 
1028  if (_glfw.x11.x11xcb.handle)
1029  {
1030  _glfw_dlclose(_glfw.x11.x11xcb.handle);
1031  _glfw.x11.x11xcb.handle = NULL;
1032  }
1033 
1034  if (_glfw.x11.xcursor.handle)
1035  {
1036  _glfw_dlclose(_glfw.x11.xcursor.handle);
1037  _glfw.x11.xcursor.handle = NULL;
1038  }
1039 
1040  if (_glfw.x11.randr.handle)
1041  {
1042  _glfw_dlclose(_glfw.x11.randr.handle);
1043  _glfw.x11.randr.handle = NULL;
1044  }
1045 
1046  if (_glfw.x11.xinerama.handle)
1047  {
1048  _glfw_dlclose(_glfw.x11.xinerama.handle);
1049  _glfw.x11.xinerama.handle = NULL;
1050  }
1051 
1052  if (_glfw.x11.xrender.handle)
1053  {
1054  _glfw_dlclose(_glfw.x11.xrender.handle);
1055  _glfw.x11.xrender.handle = NULL;
1056  }
1057 
1058  if (_glfw.x11.vidmode.handle)
1059  {
1060  _glfw_dlclose(_glfw.x11.vidmode.handle);
1061  _glfw.x11.vidmode.handle = NULL;
1062  }
1063 
1064  if (_glfw.x11.xi.handle)
1065  {
1066  _glfw_dlclose(_glfw.x11.xi.handle);
1067  _glfw.x11.xi.handle = NULL;
1068  }
1069 
1070  // NOTE: These need to be unloaded after XCloseDisplay, as they register
1071  // cleanup callbacks that get called by that function
1074 
1075 #if defined(__linux__)
1077 #endif
1078 }
1079 
1081 {
1082  return _GLFW_VERSION_NUMBER " X11 GLX EGL"
1083 #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
1084  " clock_gettime"
1085 #else
1086  " gettimeofday"
1087 #endif
1088 #if defined(__linux__)
1089  " evdev"
1090 #endif
1091 #if defined(_GLFW_BUILD_DLL)
1092  " shared"
1093 #endif
1094  ;
1095 }
1096 
#define GLFW_KEY_SCROLL_LOCK
Definition: glfw3.h:427
#define GLFW_KEY_KP_1
Definition: glfw3.h:457
int(* PFN_XISelectEvents)(Display *, Window, XIEventMask *, int)
Definition: x11_platform.h:115
GLenum GLuint GLenum GLsizei const GLchar * message
#define GLFW_KEY_F6
Definition: glfw3.h:436
#define GLFW_KEY_F14
Definition: glfw3.h:444
xcb_connection_t *(* PFN_XGetXCBConnection)(Display *)
Definition: x11_platform.h:102
#define XRRGetCrtcGammaSize
Definition: x11_platform.h:73
#define XF86VidModeQueryExtension
Definition: x11_platform.h:109
#define GLFW_KEY_RIGHT_CONTROL
Definition: glfw3.h:478
XRenderPictFormat *(* PFN_XRenderFindVisualFormat)(Display *, Visual const *)
Definition: x11_platform.h:121
#define GLFW_KEY_INSERT
Definition: glfw3.h:416
#define GLFW_KEY_KP_DIVIDE
Definition: glfw3.h:467
Bool(* PFN_XineramaQueryExtension)(Display *, int *, int *)
Definition: x11_platform.h:93
#define GLFW_KEY_UNKNOWN
Definition: glfw3.h:357
#define GLFW_KEY_LEFT
Definition: glfw3.h:419
#define GLFW_KEY_I
Definition: glfw3.h:386
GLuint const GLchar * name
void(* PFN_XRRFreeOutputInfo)(XRROutputInfo *)
Definition: x11_platform.h:53
#define GLFW_KEY_F
Definition: glfw3.h:383
XRRScreenResources *(* PFN_XRRGetScreenResourcesCurrent)(Display *, Window)
Definition: x11_platform.h:60
unsigned char * pixels
Definition: glfw3.h:1598
static void createKeyTables(void)
Definition: x11_init.c:231
#define GLFW_KEY_KP_5
Definition: glfw3.h:461
#define _GLFW_VERSION_NUMBER
Definition: internal.h:199
#define GLFW_KEY_SEMICOLON
Definition: glfw3.h:376
#define GLFW_KEY_KP_3
Definition: glfw3.h:459
void _glfwPushSelectionToManagerX11(void)
Definition: x11_window.c:1896
#define GLFW_KEY_PERIOD
Definition: glfw3.h:364
#define GLFW_KEY_UP
Definition: glfw3.h:421
#define GLFW_KEY_KP_6
Definition: glfw3.h:462
#define GLFW_KEY_X
Definition: glfw3.h:401
#define GLFW_KEY_6
Definition: glfw3.h:372
GLfloat value
XRROutputInfo *(* PFN_XRRGetOutputInfo)(Display *, XRRScreenResources *, RROutput)
Definition: x11_platform.h:58
#define GLFW_KEY_GRAVE_ACCENT
Definition: glfw3.h:407
_GLFWctxconfig context
Definition: internal.h:520
#define GLFW_KEY_SPACE
Definition: glfw3.h:360
int height
Definition: glfw3.h:1595
#define GLFW_KEY_PAUSE
Definition: glfw3.h:430
static Cursor createHiddenCursor(void)
Definition: x11_init.c:819
static Window createHelperWindow(void)
Definition: x11_init.c:828
void(* PFN_XRRFreeCrtcInfo)(XRRCrtcInfo *)
Definition: x11_platform.h:51
#define GLFW_KEY_KP_2
Definition: glfw3.h:458
#define GLFW_KEY_F7
Definition: glfw3.h:437
void _glfwInitTimerPOSIX(void)
Definition: posix_time.c:40
#define GLFW_KEY_LEFT_SHIFT
Definition: glfw3.h:473
#define GLFW_FALSE
Zero.
Definition: glfw3.h:287
#define _glfw_dlopen(name)
#define GLFW_KEY_8
Definition: glfw3.h:374
#define GLFW_KEY_F8
Definition: glfw3.h:438
static GLFWbool hasUsableInputMethodStyle(void)
Definition: x11_init.c:330
#define GLFW_KEY_P
Definition: glfw3.h:393
#define GLFW_KEY_PAGE_DOWN
Definition: glfw3.h:423
#define GLFW_KEY_F2
Definition: glfw3.h:432
#define GLFW_KEY_LEFT_BRACKET
Definition: glfw3.h:404
Definition: parser.hpp:57
#define GLFW_KEY_HOME
Definition: glfw3.h:424
#define GLFW_KEY_K
Definition: glfw3.h:388
#define GLFW_KEY_E
Definition: glfw3.h:382
#define GLFW_KEY_PAGE_UP
Definition: glfw3.h:422
XcursorImage *(* PFN_XcursorImageCreate)(int, int)
Definition: x11_platform.h:85
int GLFWbool
Definition: internal.h:61
#define XineramaIsActive
Definition: x11_platform.h:95
GLenum GLfloat * buffer
#define GLFW_KEY_Z
Definition: glfw3.h:403
int _glfwPlatformInit(void)
Definition: x11_init.c:922
#define GLFW_KEY_B
Definition: glfw3.h:379
#define GLFW_KEY_7
Definition: glfw3.h:373
#define GLFW_KEY_H
Definition: glfw3.h:385
#define GLFW_KEY_BACKSPACE
Definition: glfw3.h:415
void * handle
Definition: internal.h:547
GLenum GLenum GLsizei void * image
#define XcursorImageLoadCursor
Definition: x11_platform.h:90
#define GLFW_KEY_A
Definition: glfw3.h:378
void _glfwGrabErrorHandlerX11(void)
Definition: x11_init.c:855
#define GLFW_KEY_F15
Definition: glfw3.h:445
#define GLFW_KEY_V
Definition: glfw3.h:399
static int translateKeyCode(int scancode)
Definition: x11_init.c:41
#define XRRGetScreenResourcesCurrent
Definition: x11_platform.h:77
GLuint64 key
Definition: glext.h:8966
#define GLFW_KEY_F13
Definition: glfw3.h:443
#define XRenderQueryExtension
Definition: x11_platform.h:122
#define GLFW_KEY_KP_DECIMAL
Definition: glfw3.h:466
static int errorHandler(Display *display, XErrorEvent *event)
Definition: x11_init.c:842
#define GLFW_KEY_F5
Definition: glfw3.h:435
#define GLFW_KEY_F20
Definition: glfw3.h:450
Status(* PFN_XIQueryVersion)(Display *, int *, int *)
Definition: x11_platform.h:114
#define _glfw_dlclose(handle)
#define GLFW_KEY_F9
Definition: glfw3.h:439
#define GLFW_KEY_F10
Definition: glfw3.h:440
#define GLFW_KEY_T
Definition: glfw3.h:397
#define GLFW_KEY_KP_9
Definition: glfw3.h:465
void(* PFN_XRRSelectInput)(Display *, Window, int)
Definition: x11_platform.h:63
#define GLFW_KEY_1
Definition: glfw3.h:367
GLfloat GLfloat GLfloat alpha
#define GLFW_KEY_RIGHT_SUPER
Definition: glfw3.h:480
const char * _glfwPlatformGetVersionString(void)
Definition: x11_init.c:1080
void(* PFN_XRRFreeGamma)(XRRCrtcGamma *)
Definition: x11_platform.h:52
#define GLFW_KEY_KP_ADD
Definition: glfw3.h:470
#define GLFW_PLATFORM_ERROR
A platform-specific error occurred that does not match any of the more specific categories.
Definition: glfw3.h:726
#define GLFW_KEY_END
Definition: glfw3.h:425
void _glfwInputErrorX11(int error, const char *message)
Definition: x11_init.c:872
_GLFWlibrary _glfw
Definition: init.c:44
#define GLFW_KEY_F11
Definition: glfw3.h:441
Cursor(* PFN_XcursorImageLoadCursor)(Display *, const XcursorImage *)
Definition: x11_platform.h:87
#define GLFW_KEY_KP_7
Definition: glfw3.h:463
#define XRRQueryVersion
Definition: x11_platform.h:79
#define GLFW_KEY_EQUAL
Definition: glfw3.h:377
static Atom getSupportedAtom(Atom *supportedAtoms, unsigned long atomCount, const char *atomName)
Definition: x11_init.c:354
int(* PFN_XRRUpdateConfiguration)(XEvent *)
Definition: x11_platform.h:66
#define GLFW_KEY_CAPS_LOCK
Definition: glfw3.h:426
#define GLFW_KEY_DELETE
Definition: glfw3.h:417
#define GLFW_KEY_ESCAPE
Definition: glfw3.h:412
#define GLFW_KEY_KP_MULTIPLY
Definition: glfw3.h:468
#define GLFW_KEY_S
Definition: glfw3.h:396
#define GLFW_KEY_F1
Definition: glfw3.h:431
Bool(* PFN_XF86VidModeSetGammaRamp)(Display *, int, int, unsigned short *, unsigned short *, unsigned short *)
Definition: x11_platform.h:107
void _glfwTerminateEGL(void)
Definition: egl_context.c:432
#define GLFW_KEY_0
Definition: glfw3.h:366
#define GLFW_KEY_NUM_LOCK
Definition: glfw3.h:428
#define XRRQueryExtension
Definition: x11_platform.h:78
void _glfwPlatformTerminate(void)
Definition: x11_init.c:993
#define GLFW_KEY_TAB
Definition: glfw3.h:414
GLFWbool available
Definition: internal.h:546
GLenum target
Definition: glext.h:1565
#define GLFW_KEY_W
Definition: glfw3.h:400
XineramaScreenInfo *(* PFN_XineramaQueryScreens)(Display *, int *)
Definition: x11_platform.h:94
#define GLFW_KEY_U
Definition: glfw3.h:398
#define GLFW_KEY_4
Definition: glfw3.h:370
int(* PFN_XRRGetCrtcGammaSize)(Display *, RRCrtc)
Definition: x11_platform.h:56
#define GLFW_KEY_N
Definition: glfw3.h:391
#define GLFW_KEY_F12
Definition: glfw3.h:442
#define GLFW_KEY_F17
Definition: glfw3.h:447
#define GLFW_KEY_KP_4
Definition: glfw3.h:460
#define GLFW_KEY_2
Definition: glfw3.h:368
#define GLFW_KEY_3
Definition: glfw3.h:369
#define GLFW_KEY_MENU
Definition: glfw3.h:481
#define GLFW_KEY_ENTER
Definition: glfw3.h:413
Bool(* PFN_XRRQueryExtension)(Display *, int *, int *)
Definition: x11_platform.h:61
void _glfwInputError(int code, const char *format,...)
Definition: init.c:129
#define GLFW_KEY_G
Definition: glfw3.h:384
GLint GLint GLsizei GLint GLenum GLenum const void * pixels
#define GLFW_KEY_D
Definition: glfw3.h:381
void _glfwPollMonitorsX11(void)
Definition: x11_monitor.c:100
Status(* PFN_XRRSetCrtcConfig)(Display *, XRRScreenResources *, RRCrtc, Time, int, int, RRMode, Rotation, RROutput *, int)
Definition: x11_platform.h:64
static void detectEWMH(void)
Definition: x11_init.c:372
static GLFWbool initExtensions(void)
Definition: x11_init.c:462
#define XRRSelectInput
Definition: x11_platform.h:80
#define GLFW_KEY_F23
Definition: glfw3.h:453
struct _cl_event * event
Definition: glext.h:2991
int width
Definition: glfw3.h:1592
#define GLFW_KEY_M
Definition: glfw3.h:390
#define GLFW_TRUE
One.
Definition: glfw3.h:279
#define GLFW_KEY_F4
Definition: glfw3.h:434
void _glfwTerminateGLX(void)
Definition: glx_context.c:424
Bool(* PFN_XF86VidModeGetGammaRampSize)(Display *, int, int *)
Definition: x11_platform.h:108
#define GLFW_KEY_RIGHT_BRACKET
Definition: glfw3.h:406
Cursor _glfwCreateCursorX11(const GLFWimage *image, int xhot, int yhot)
Definition: x11_init.c:883
#define GLFW_KEY_DOWN
Definition: glfw3.h:420
XRRCrtcInfo *(* PFN_XRRGetCrtcInfo)(Display *, XRRScreenResources *, RRCrtc)
Definition: x11_platform.h:57
#define GLFW_KEY_J
Definition: glfw3.h:387
#define XRenderQueryVersion
Definition: x11_platform.h:123
Bool(* PFN_XineramaIsActive)(Display *)
Definition: x11_platform.h:92
#define GLFW_KEY_L
Definition: glfw3.h:389
#define GLFW_KEY_KP_ENTER
Definition: glfw3.h:471
#define GLFW_KEY_KP_SUBTRACT
Definition: glfw3.h:469
RROutput(* PFN_XRRGetOutputPrimary)(Display *, Window)
Definition: x11_platform.h:59
#define XIQueryVersion
Definition: x11_platform.h:116
#define GLFW_KEY_9
Definition: glfw3.h:375
GLenum type
void _glfwReleaseErrorHandlerX11(void)
Definition: x11_init.c:863
#define GLFW_KEY_COMMA
Definition: glfw3.h:362
#define GLFW_KEY_RIGHT_ALT
Definition: glfw3.h:479
#define GLFW_KEY_F19
Definition: glfw3.h:449
#define GLFW_KEY_SLASH
Definition: glfw3.h:365
#define GLFW_KEY_PRINT_SCREEN
Definition: glfw3.h:429
#define GLFW_KEY_F22
Definition: glfw3.h:452
static void getSystemContentScale(float *xscale, float *yscale)
Definition: x11_init.c:781
void(* PFN_XRRSetCrtcGamma)(Display *, RRCrtc, XRRCrtcGamma *)
Definition: x11_platform.h:65
#define GLFW_KEY_LEFT_CONTROL
Definition: glfw3.h:474
void _glfwTerminateJoysticksLinux(void)
#define GLFW_KEY_KP_8
Definition: glfw3.h:464
#define GLFW_KEY_Q
Definition: glfw3.h:394
#define GLFW_KEY_KP_0
Definition: glfw3.h:456
#define GLFW_KEY_KP_EQUAL
Definition: glfw3.h:472
#define XineramaQueryExtension
Definition: x11_platform.h:96
GLsizei GLsizei GLchar * source
void display(void)
Definition: boing.c:194
#define NULL
Definition: tinycthread.c:47
#define GLFW_KEY_WORLD_1
Definition: glfw3.h:408
int i
#define GLFW_KEY_F25
Definition: glfw3.h:455
#define GLFW_KEY_LEFT_ALT
Definition: glfw3.h:475
Image data.
Definition: glfw3.h:1588
#define _glfw_dlsym(handle, name)
#define _GLFW_MESSAGE_SIZE
Definition: internal.h:59
#define GLFW_KEY_F3
Definition: glfw3.h:433
Status(* PFN_XRenderQueryVersion)(Display *dpy, int *, int *)
Definition: x11_platform.h:120
#define GLFW_KEY_F21
Definition: glfw3.h:451
#define GLFW_KEY_RIGHT_SHIFT
Definition: glfw3.h:477
#define GLFW_KEY_R
Definition: glfw3.h:395
#define GLFW_KEY_F16
Definition: glfw3.h:446
Bool(* PFN_XF86VidModeGetGammaRamp)(Display *, int, int, unsigned short *, unsigned short *, unsigned short *)
Definition: x11_platform.h:106
Bool(* PFN_XRenderQueryExtension)(Display *, int *, int *)
Definition: x11_platform.h:119
#define GLFW_KEY_RIGHT
Definition: glfw3.h:418
#define GLFW_KEY_Y
Definition: glfw3.h:402
GLFWbool _glfwInitJoysticksLinux(void)
#define GLFW_KEY_BACKSLASH
Definition: glfw3.h:405
void(* PFN_XcursorImageDestroy)(XcursorImage *)
Definition: x11_platform.h:86
#define XRRFreeScreenResources
Definition: x11_platform.h:71
XRRCrtcGamma *(* PFN_XRRAllocGamma)(int)
Definition: x11_platform.h:50
#define GLFW_KEY_F18
Definition: glfw3.h:448
#define GLFW_KEY_O
Definition: glfw3.h:392
#define GLFW_KEY_APOSTROPHE
Definition: glfw3.h:361
#define GLFW_KEY_MINUS
Definition: glfw3.h:363
#define XcursorImageDestroy
Definition: x11_platform.h:89
XRRCrtcGamma *(* PFN_XRRGetCrtcGamma)(Display *, RRCrtc)
Definition: x11_platform.h:55
#define GLFW_KEY_F24
Definition: glfw3.h:454
Bool(* PFN_XF86VidModeQueryExtension)(Display *, int *, int *)
Definition: x11_platform.h:105
void(* PFN_XRRFreeScreenResources)(XRRScreenResources *)
Definition: x11_platform.h:54
unsigned long _glfwGetWindowPropertyX11(Window window, Atom property, Atom type, unsigned char **value)
Definition: x11_window.c:1860
#define GLFW_KEY_5
Definition: glfw3.h:371
#define GLFW_KEY_LEFT_SUPER
Definition: glfw3.h:476
#define GLFW_KEY_C
Definition: glfw3.h:380
#define XcursorImageCreate
Definition: x11_platform.h:88
Status(* PFN_XRRQueryVersion)(Display *, int *, int *)
Definition: x11_platform.h:62


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