• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //========================================================================
2 // GLFW 3.2 Wayland - www.glfw.org
3 //------------------------------------------------------------------------
4 // Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
5 //
6 // This software is provided 'as-is', without any express or implied
7 // warranty. In no event will the authors be held liable for any damages
8 // arising from the use of this software.
9 //
10 // Permission is granted to anyone to use this software for any purpose,
11 // including commercial applications, and to alter it and redistribute it
12 // freely, subject to the following restrictions:
13 //
14 // 1. The origin of this software must not be misrepresented; you must not
15 //    claim that you wrote the original software. If you use this software
16 //    in a product, an acknowledgment in the product documentation would
17 //    be appreciated but is not required.
18 //
19 // 2. Altered source versions must be plainly marked as such, and must not
20 //    be misrepresented as being the original software.
21 //
22 // 3. This notice may not be removed or altered from any source
23 //    distribution.
24 //
25 //========================================================================
26 
27 #include "internal.h"
28 
29 #include <linux/input.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/mman.h>
34 #include <unistd.h>
35 #include <wayland-client.h>
36 #include <wayland-cursor.h>
37 
38 
min(int n1,int n2)39 static inline int min(int n1, int n2)
40 {
41     return n1 < n2 ? n1 : n2;
42 }
43 
pointerHandleEnter(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface,wl_fixed_t sx,wl_fixed_t sy)44 static void pointerHandleEnter(void* data,
45                                struct wl_pointer* pointer,
46                                uint32_t serial,
47                                struct wl_surface* surface,
48                                wl_fixed_t sx,
49                                wl_fixed_t sy)
50 {
51     _GLFWwindow* window = wl_surface_get_user_data(surface);
52 
53     _glfw.wl.pointerSerial = serial;
54     _glfw.wl.pointerFocus = window;
55 
56     _glfwPlatformSetCursor(window, window->wl.currentCursor);
57     _glfwInputCursorEnter(window, GLFW_TRUE);
58 }
59 
pointerHandleLeave(void * data,struct wl_pointer * pointer,uint32_t serial,struct wl_surface * surface)60 static void pointerHandleLeave(void* data,
61                                struct wl_pointer* pointer,
62                                uint32_t serial,
63                                struct wl_surface* surface)
64 {
65     _GLFWwindow* window = _glfw.wl.pointerFocus;
66 
67     if (!window)
68         return;
69 
70     _glfw.wl.pointerSerial = serial;
71     _glfw.wl.pointerFocus = NULL;
72     _glfwInputCursorEnter(window, GLFW_FALSE);
73 }
74 
pointerHandleMotion(void * data,struct wl_pointer * pointer,uint32_t time,wl_fixed_t sx,wl_fixed_t sy)75 static void pointerHandleMotion(void* data,
76                                 struct wl_pointer* pointer,
77                                 uint32_t time,
78                                 wl_fixed_t sx,
79                                 wl_fixed_t sy)
80 {
81     _GLFWwindow* window = _glfw.wl.pointerFocus;
82 
83     if (!window)
84         return;
85 
86     if (window->cursorMode == GLFW_CURSOR_DISABLED)
87         return;
88     else
89     {
90         window->wl.cursorPosX = wl_fixed_to_double(sx);
91         window->wl.cursorPosY = wl_fixed_to_double(sy);
92     }
93 
94     _glfwInputCursorPos(window,
95                         wl_fixed_to_double(sx),
96                         wl_fixed_to_double(sy));
97 }
98 
pointerHandleButton(void * data,struct wl_pointer * wl_pointer,uint32_t serial,uint32_t time,uint32_t button,uint32_t state)99 static void pointerHandleButton(void* data,
100                                 struct wl_pointer* wl_pointer,
101                                 uint32_t serial,
102                                 uint32_t time,
103                                 uint32_t button,
104                                 uint32_t state)
105 {
106     _GLFWwindow* window = _glfw.wl.pointerFocus;
107     int glfwButton;
108 
109     if (!window)
110         return;
111 
112     /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
113      * codes. */
114     glfwButton = button - BTN_LEFT;
115 
116     _glfwInputMouseClick(window,
117                          glfwButton,
118                          state == WL_POINTER_BUTTON_STATE_PRESSED
119                                 ? GLFW_PRESS
120                                 : GLFW_RELEASE,
121                          _glfw.wl.xkb.modifiers);
122 }
123 
pointerHandleAxis(void * data,struct wl_pointer * wl_pointer,uint32_t time,uint32_t axis,wl_fixed_t value)124 static void pointerHandleAxis(void* data,
125                               struct wl_pointer* wl_pointer,
126                               uint32_t time,
127                               uint32_t axis,
128                               wl_fixed_t value)
129 {
130     _GLFWwindow* window = _glfw.wl.pointerFocus;
131     double scroll_factor;
132     double x, y;
133 
134     if (!window)
135         return;
136 
137     /* Wayland scroll events are in pointer motion coordinate space (think
138      * two finger scroll). The factor 10 is commonly used to convert to
139      * "scroll step means 1.0. */
140     scroll_factor = 1.0/10.0;
141 
142     switch (axis)
143     {
144         case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
145             x = wl_fixed_to_double(value) * scroll_factor;
146             y = 0.0;
147             break;
148         case WL_POINTER_AXIS_VERTICAL_SCROLL:
149             x = 0.0;
150             y = wl_fixed_to_double(value) * scroll_factor;
151             break;
152         default:
153             break;
154     }
155 
156     _glfwInputScroll(window, x, y);
157 }
158 
159 static const struct wl_pointer_listener pointerListener = {
160     pointerHandleEnter,
161     pointerHandleLeave,
162     pointerHandleMotion,
163     pointerHandleButton,
164     pointerHandleAxis,
165 };
166 
keyboardHandleKeymap(void * data,struct wl_keyboard * keyboard,uint32_t format,int fd,uint32_t size)167 static void keyboardHandleKeymap(void* data,
168                                  struct wl_keyboard* keyboard,
169                                  uint32_t format,
170                                  int fd,
171                                  uint32_t size)
172 {
173     struct xkb_keymap* keymap;
174     struct xkb_state* state;
175     char* mapStr;
176 
177     if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
178     {
179         close(fd);
180         return;
181     }
182 
183     mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
184     if (mapStr == MAP_FAILED) {
185         close(fd);
186         return;
187     }
188 
189     keymap = xkb_map_new_from_string(_glfw.wl.xkb.context,
190                                      mapStr,
191                                      XKB_KEYMAP_FORMAT_TEXT_V1,
192                                      0);
193     munmap(mapStr, size);
194     close(fd);
195 
196     if (!keymap)
197     {
198         _glfwInputError(GLFW_PLATFORM_ERROR,
199                         "Wayland: Failed to compile keymap");
200         return;
201     }
202 
203     state = xkb_state_new(keymap);
204     if (!state)
205     {
206         _glfwInputError(GLFW_PLATFORM_ERROR,
207                         "Wayland: Failed to create XKB state");
208         xkb_map_unref(keymap);
209         return;
210     }
211 
212     xkb_keymap_unref(_glfw.wl.xkb.keymap);
213     xkb_state_unref(_glfw.wl.xkb.state);
214     _glfw.wl.xkb.keymap = keymap;
215     _glfw.wl.xkb.state = state;
216 
217     _glfw.wl.xkb.control_mask =
218         1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Control");
219     _glfw.wl.xkb.alt_mask =
220         1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Mod1");
221     _glfw.wl.xkb.shift_mask =
222         1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Shift");
223     _glfw.wl.xkb.super_mask =
224         1 << xkb_map_mod_get_index(_glfw.wl.xkb.keymap, "Mod4");
225 }
226 
keyboardHandleEnter(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)227 static void keyboardHandleEnter(void* data,
228                                 struct wl_keyboard* keyboard,
229                                 uint32_t serial,
230                                 struct wl_surface* surface,
231                                 struct wl_array* keys)
232 {
233     _GLFWwindow* window = wl_surface_get_user_data(surface);
234 
235     _glfw.wl.keyboardFocus = window;
236     _glfwInputWindowFocus(window, GLFW_TRUE);
237 }
238 
keyboardHandleLeave(void * data,struct wl_keyboard * keyboard,uint32_t serial,struct wl_surface * surface)239 static void keyboardHandleLeave(void* data,
240                                 struct wl_keyboard* keyboard,
241                                 uint32_t serial,
242                                 struct wl_surface* surface)
243 {
244     _GLFWwindow* window = _glfw.wl.keyboardFocus;
245 
246     if (!window)
247         return;
248 
249     _glfw.wl.keyboardFocus = NULL;
250     _glfwInputWindowFocus(window, GLFW_FALSE);
251 }
252 
toGLFWKeyCode(uint32_t key)253 static int toGLFWKeyCode(uint32_t key)
254 {
255     if (key < sizeof(_glfw.wl.publicKeys) / sizeof(_glfw.wl.publicKeys[0]))
256         return _glfw.wl.publicKeys[key];
257 
258     return GLFW_KEY_UNKNOWN;
259 }
260 
keyboardHandleKey(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state)261 static void keyboardHandleKey(void* data,
262                               struct wl_keyboard* keyboard,
263                               uint32_t serial,
264                               uint32_t time,
265                               uint32_t key,
266                               uint32_t state)
267 {
268     uint32_t code, num_syms;
269     long cp;
270     int keyCode;
271     int action;
272     const xkb_keysym_t *syms;
273     _GLFWwindow* window = _glfw.wl.keyboardFocus;
274 
275     if (!window)
276         return;
277 
278     keyCode = toGLFWKeyCode(key);
279     action = state == WL_KEYBOARD_KEY_STATE_PRESSED
280             ? GLFW_PRESS : GLFW_RELEASE;
281 
282     _glfwInputKey(window, keyCode, key, action,
283                   _glfw.wl.xkb.modifiers);
284 
285     code = key + 8;
286     num_syms = xkb_key_get_syms(_glfw.wl.xkb.state, code, &syms);
287 
288     if (num_syms == 1)
289     {
290         cp = _glfwKeySym2Unicode(syms[0]);
291         if (cp != -1)
292         {
293             const int mods = _glfw.wl.xkb.modifiers;
294             const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
295             _glfwInputChar(window, cp, mods, plain);
296         }
297     }
298 }
299 
keyboardHandleModifiers(void * data,struct wl_keyboard * keyboard,uint32_t serial,uint32_t modsDepressed,uint32_t modsLatched,uint32_t modsLocked,uint32_t group)300 static void keyboardHandleModifiers(void* data,
301                                     struct wl_keyboard* keyboard,
302                                     uint32_t serial,
303                                     uint32_t modsDepressed,
304                                     uint32_t modsLatched,
305                                     uint32_t modsLocked,
306                                     uint32_t group)
307 {
308     xkb_mod_mask_t mask;
309     unsigned int modifiers = 0;
310 
311     if (!_glfw.wl.xkb.keymap)
312         return;
313 
314     xkb_state_update_mask(_glfw.wl.xkb.state,
315                           modsDepressed,
316                           modsLatched,
317                           modsLocked,
318                           0,
319                           0,
320                           group);
321 
322     mask = xkb_state_serialize_mods(_glfw.wl.xkb.state,
323                                     XKB_STATE_DEPRESSED |
324                                     XKB_STATE_LATCHED);
325     if (mask & _glfw.wl.xkb.control_mask)
326         modifiers |= GLFW_MOD_CONTROL;
327     if (mask & _glfw.wl.xkb.alt_mask)
328         modifiers |= GLFW_MOD_ALT;
329     if (mask & _glfw.wl.xkb.shift_mask)
330         modifiers |= GLFW_MOD_SHIFT;
331     if (mask & _glfw.wl.xkb.super_mask)
332         modifiers |= GLFW_MOD_SUPER;
333     _glfw.wl.xkb.modifiers = modifiers;
334 }
335 
336 static const struct wl_keyboard_listener keyboardListener = {
337     keyboardHandleKeymap,
338     keyboardHandleEnter,
339     keyboardHandleLeave,
340     keyboardHandleKey,
341     keyboardHandleModifiers,
342 };
343 
seatHandleCapabilities(void * data,struct wl_seat * seat,enum wl_seat_capability caps)344 static void seatHandleCapabilities(void* data,
345                                    struct wl_seat* seat,
346                                    enum wl_seat_capability caps)
347 {
348     if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer)
349     {
350         _glfw.wl.pointer = wl_seat_get_pointer(seat);
351         wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL);
352     }
353     else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
354     {
355         wl_pointer_destroy(_glfw.wl.pointer);
356         _glfw.wl.pointer = NULL;
357     }
358 
359     if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard)
360     {
361         _glfw.wl.keyboard = wl_seat_get_keyboard(seat);
362         wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);
363     }
364     else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
365     {
366         wl_keyboard_destroy(_glfw.wl.keyboard);
367         _glfw.wl.keyboard = NULL;
368     }
369 }
370 
371 static const struct wl_seat_listener seatListener = {
372     seatHandleCapabilities
373 };
374 
registryHandleGlobal(void * data,struct wl_registry * registry,uint32_t name,const char * interface,uint32_t version)375 static void registryHandleGlobal(void* data,
376                                  struct wl_registry* registry,
377                                  uint32_t name,
378                                  const char* interface,
379                                  uint32_t version)
380 {
381     if (strcmp(interface, "wl_compositor") == 0)
382     {
383         _glfw.wl.wl_compositor_version = min(3, version);
384         _glfw.wl.compositor =
385             wl_registry_bind(registry, name, &wl_compositor_interface,
386                              _glfw.wl.wl_compositor_version);
387     }
388     else if (strcmp(interface, "wl_shm") == 0)
389     {
390         _glfw.wl.shm =
391             wl_registry_bind(registry, name, &wl_shm_interface, 1);
392     }
393     else if (strcmp(interface, "wl_shell") == 0)
394     {
395         _glfw.wl.shell =
396             wl_registry_bind(registry, name, &wl_shell_interface, 1);
397     }
398     else if (strcmp(interface, "wl_output") == 0)
399     {
400         _glfwAddOutputWayland(name, version);
401     }
402     else if (strcmp(interface, "wl_seat") == 0)
403     {
404         if (!_glfw.wl.seat)
405         {
406             _glfw.wl.seat =
407                 wl_registry_bind(registry, name, &wl_seat_interface, 1);
408             wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);
409         }
410     }
411     else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)
412     {
413         _glfw.wl.relativePointerManager =
414             wl_registry_bind(registry, name,
415                              &zwp_relative_pointer_manager_v1_interface,
416                              1);
417     }
418     else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0)
419     {
420         _glfw.wl.pointerConstraints =
421             wl_registry_bind(registry, name,
422                              &zwp_pointer_constraints_v1_interface,
423                              1);
424     }
425 }
426 
registryHandleGlobalRemove(void * data,struct wl_registry * registry,uint32_t name)427 static void registryHandleGlobalRemove(void *data,
428                                        struct wl_registry *registry,
429                                        uint32_t name)
430 {
431 }
432 
433 
434 static const struct wl_registry_listener registryListener = {
435     registryHandleGlobal,
436     registryHandleGlobalRemove
437 };
438 
439 // Create key code translation tables
440 //
createKeyTables(void)441 static void createKeyTables(void)
442 {
443     memset(_glfw.wl.publicKeys, -1, sizeof(_glfw.wl.publicKeys));
444 
445     _glfw.wl.publicKeys[KEY_GRAVE]      = GLFW_KEY_GRAVE_ACCENT;
446     _glfw.wl.publicKeys[KEY_1]          = GLFW_KEY_1;
447     _glfw.wl.publicKeys[KEY_2]          = GLFW_KEY_2;
448     _glfw.wl.publicKeys[KEY_3]          = GLFW_KEY_3;
449     _glfw.wl.publicKeys[KEY_4]          = GLFW_KEY_4;
450     _glfw.wl.publicKeys[KEY_5]          = GLFW_KEY_5;
451     _glfw.wl.publicKeys[KEY_6]          = GLFW_KEY_6;
452     _glfw.wl.publicKeys[KEY_7]          = GLFW_KEY_7;
453     _glfw.wl.publicKeys[KEY_8]          = GLFW_KEY_8;
454     _glfw.wl.publicKeys[KEY_9]          = GLFW_KEY_9;
455     _glfw.wl.publicKeys[KEY_0]          = GLFW_KEY_0;
456     _glfw.wl.publicKeys[KEY_MINUS]      = GLFW_KEY_MINUS;
457     _glfw.wl.publicKeys[KEY_EQUAL]      = GLFW_KEY_EQUAL;
458     _glfw.wl.publicKeys[KEY_Q]          = GLFW_KEY_Q;
459     _glfw.wl.publicKeys[KEY_W]          = GLFW_KEY_W;
460     _glfw.wl.publicKeys[KEY_E]          = GLFW_KEY_E;
461     _glfw.wl.publicKeys[KEY_R]          = GLFW_KEY_R;
462     _glfw.wl.publicKeys[KEY_T]          = GLFW_KEY_T;
463     _glfw.wl.publicKeys[KEY_Y]          = GLFW_KEY_Y;
464     _glfw.wl.publicKeys[KEY_U]          = GLFW_KEY_U;
465     _glfw.wl.publicKeys[KEY_I]          = GLFW_KEY_I;
466     _glfw.wl.publicKeys[KEY_O]          = GLFW_KEY_O;
467     _glfw.wl.publicKeys[KEY_P]          = GLFW_KEY_P;
468     _glfw.wl.publicKeys[KEY_LEFTBRACE]  = GLFW_KEY_LEFT_BRACKET;
469     _glfw.wl.publicKeys[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;
470     _glfw.wl.publicKeys[KEY_A]          = GLFW_KEY_A;
471     _glfw.wl.publicKeys[KEY_S]          = GLFW_KEY_S;
472     _glfw.wl.publicKeys[KEY_D]          = GLFW_KEY_D;
473     _glfw.wl.publicKeys[KEY_F]          = GLFW_KEY_F;
474     _glfw.wl.publicKeys[KEY_G]          = GLFW_KEY_G;
475     _glfw.wl.publicKeys[KEY_H]          = GLFW_KEY_H;
476     _glfw.wl.publicKeys[KEY_J]          = GLFW_KEY_J;
477     _glfw.wl.publicKeys[KEY_K]          = GLFW_KEY_K;
478     _glfw.wl.publicKeys[KEY_L]          = GLFW_KEY_L;
479     _glfw.wl.publicKeys[KEY_SEMICOLON]  = GLFW_KEY_SEMICOLON;
480     _glfw.wl.publicKeys[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
481     _glfw.wl.publicKeys[KEY_Z]          = GLFW_KEY_Z;
482     _glfw.wl.publicKeys[KEY_X]          = GLFW_KEY_X;
483     _glfw.wl.publicKeys[KEY_C]          = GLFW_KEY_C;
484     _glfw.wl.publicKeys[KEY_V]          = GLFW_KEY_V;
485     _glfw.wl.publicKeys[KEY_B]          = GLFW_KEY_B;
486     _glfw.wl.publicKeys[KEY_N]          = GLFW_KEY_N;
487     _glfw.wl.publicKeys[KEY_M]          = GLFW_KEY_M;
488     _glfw.wl.publicKeys[KEY_COMMA]      = GLFW_KEY_COMMA;
489     _glfw.wl.publicKeys[KEY_DOT]        = GLFW_KEY_PERIOD;
490     _glfw.wl.publicKeys[KEY_SLASH]      = GLFW_KEY_SLASH;
491     _glfw.wl.publicKeys[KEY_BACKSLASH]  = GLFW_KEY_BACKSLASH;
492     _glfw.wl.publicKeys[KEY_ESC]        = GLFW_KEY_ESCAPE;
493     _glfw.wl.publicKeys[KEY_TAB]        = GLFW_KEY_TAB;
494     _glfw.wl.publicKeys[KEY_LEFTSHIFT]  = GLFW_KEY_LEFT_SHIFT;
495     _glfw.wl.publicKeys[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;
496     _glfw.wl.publicKeys[KEY_LEFTCTRL]   = GLFW_KEY_LEFT_CONTROL;
497     _glfw.wl.publicKeys[KEY_RIGHTCTRL]  = GLFW_KEY_RIGHT_CONTROL;
498     _glfw.wl.publicKeys[KEY_LEFTALT]    = GLFW_KEY_LEFT_ALT;
499     _glfw.wl.publicKeys[KEY_RIGHTALT]   = GLFW_KEY_RIGHT_ALT;
500     _glfw.wl.publicKeys[KEY_LEFTMETA]   = GLFW_KEY_LEFT_SUPER;
501     _glfw.wl.publicKeys[KEY_RIGHTMETA]  = GLFW_KEY_RIGHT_SUPER;
502     _glfw.wl.publicKeys[KEY_MENU]       = GLFW_KEY_MENU;
503     _glfw.wl.publicKeys[KEY_NUMLOCK]    = GLFW_KEY_NUM_LOCK;
504     _glfw.wl.publicKeys[KEY_CAPSLOCK]   = GLFW_KEY_CAPS_LOCK;
505     _glfw.wl.publicKeys[KEY_PRINT]      = GLFW_KEY_PRINT_SCREEN;
506     _glfw.wl.publicKeys[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;
507     _glfw.wl.publicKeys[KEY_PAUSE]      = GLFW_KEY_PAUSE;
508     _glfw.wl.publicKeys[KEY_DELETE]     = GLFW_KEY_DELETE;
509     _glfw.wl.publicKeys[KEY_BACKSPACE]  = GLFW_KEY_BACKSPACE;
510     _glfw.wl.publicKeys[KEY_ENTER]      = GLFW_KEY_ENTER;
511     _glfw.wl.publicKeys[KEY_HOME]       = GLFW_KEY_HOME;
512     _glfw.wl.publicKeys[KEY_END]        = GLFW_KEY_END;
513     _glfw.wl.publicKeys[KEY_PAGEUP]     = GLFW_KEY_PAGE_UP;
514     _glfw.wl.publicKeys[KEY_PAGEDOWN]   = GLFW_KEY_PAGE_DOWN;
515     _glfw.wl.publicKeys[KEY_INSERT]     = GLFW_KEY_INSERT;
516     _glfw.wl.publicKeys[KEY_LEFT]       = GLFW_KEY_LEFT;
517     _glfw.wl.publicKeys[KEY_RIGHT]      = GLFW_KEY_RIGHT;
518     _glfw.wl.publicKeys[KEY_DOWN]       = GLFW_KEY_DOWN;
519     _glfw.wl.publicKeys[KEY_UP]         = GLFW_KEY_UP;
520     _glfw.wl.publicKeys[KEY_F1]         = GLFW_KEY_F1;
521     _glfw.wl.publicKeys[KEY_F2]         = GLFW_KEY_F2;
522     _glfw.wl.publicKeys[KEY_F3]         = GLFW_KEY_F3;
523     _glfw.wl.publicKeys[KEY_F4]         = GLFW_KEY_F4;
524     _glfw.wl.publicKeys[KEY_F5]         = GLFW_KEY_F5;
525     _glfw.wl.publicKeys[KEY_F6]         = GLFW_KEY_F6;
526     _glfw.wl.publicKeys[KEY_F7]         = GLFW_KEY_F7;
527     _glfw.wl.publicKeys[KEY_F8]         = GLFW_KEY_F8;
528     _glfw.wl.publicKeys[KEY_F9]         = GLFW_KEY_F9;
529     _glfw.wl.publicKeys[KEY_F10]        = GLFW_KEY_F10;
530     _glfw.wl.publicKeys[KEY_F11]        = GLFW_KEY_F11;
531     _glfw.wl.publicKeys[KEY_F12]        = GLFW_KEY_F12;
532     _glfw.wl.publicKeys[KEY_F13]        = GLFW_KEY_F13;
533     _glfw.wl.publicKeys[KEY_F14]        = GLFW_KEY_F14;
534     _glfw.wl.publicKeys[KEY_F15]        = GLFW_KEY_F15;
535     _glfw.wl.publicKeys[KEY_F16]        = GLFW_KEY_F16;
536     _glfw.wl.publicKeys[KEY_F17]        = GLFW_KEY_F17;
537     _glfw.wl.publicKeys[KEY_F18]        = GLFW_KEY_F18;
538     _glfw.wl.publicKeys[KEY_F19]        = GLFW_KEY_F19;
539     _glfw.wl.publicKeys[KEY_F20]        = GLFW_KEY_F20;
540     _glfw.wl.publicKeys[KEY_F21]        = GLFW_KEY_F21;
541     _glfw.wl.publicKeys[KEY_F22]        = GLFW_KEY_F22;
542     _glfw.wl.publicKeys[KEY_F23]        = GLFW_KEY_F23;
543     _glfw.wl.publicKeys[KEY_F24]        = GLFW_KEY_F24;
544     _glfw.wl.publicKeys[KEY_KPSLASH]    = GLFW_KEY_KP_DIVIDE;
545     _glfw.wl.publicKeys[KEY_KPDOT]      = GLFW_KEY_KP_MULTIPLY;
546     _glfw.wl.publicKeys[KEY_KPMINUS]    = GLFW_KEY_KP_SUBTRACT;
547     _glfw.wl.publicKeys[KEY_KPPLUS]     = GLFW_KEY_KP_ADD;
548     _glfw.wl.publicKeys[KEY_KP0]        = GLFW_KEY_KP_0;
549     _glfw.wl.publicKeys[KEY_KP1]        = GLFW_KEY_KP_1;
550     _glfw.wl.publicKeys[KEY_KP2]        = GLFW_KEY_KP_2;
551     _glfw.wl.publicKeys[KEY_KP3]        = GLFW_KEY_KP_3;
552     _glfw.wl.publicKeys[KEY_KP4]        = GLFW_KEY_KP_4;
553     _glfw.wl.publicKeys[KEY_KP5]        = GLFW_KEY_KP_5;
554     _glfw.wl.publicKeys[KEY_KP6]        = GLFW_KEY_KP_6;
555     _glfw.wl.publicKeys[KEY_KP7]        = GLFW_KEY_KP_7;
556     _glfw.wl.publicKeys[KEY_KP8]        = GLFW_KEY_KP_8;
557     _glfw.wl.publicKeys[KEY_KP9]        = GLFW_KEY_KP_9;
558     _glfw.wl.publicKeys[KEY_KPCOMMA]    = GLFW_KEY_KP_DECIMAL;
559     _glfw.wl.publicKeys[KEY_KPEQUAL]    = GLFW_KEY_KP_EQUAL;
560     _glfw.wl.publicKeys[KEY_KPENTER]    = GLFW_KEY_KP_ENTER;
561 }
562 
563 
564 //////////////////////////////////////////////////////////////////////////
565 //////                       GLFW platform API                      //////
566 //////////////////////////////////////////////////////////////////////////
567 
_glfwPlatformInit(void)568 int _glfwPlatformInit(void)
569 {
570     _glfw.wl.display = wl_display_connect(NULL);
571     if (!_glfw.wl.display)
572     {
573         _glfwInputError(GLFW_PLATFORM_ERROR,
574                         "Wayland: Failed to connect to display");
575         return GLFW_FALSE;
576     }
577 
578     _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
579     wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
580 
581     _glfw.wl.monitors = calloc(4, sizeof(_GLFWmonitor*));
582     _glfw.wl.monitorsSize = 4;
583 
584     createKeyTables();
585 
586     _glfw.wl.xkb.context = xkb_context_new(0);
587     if (!_glfw.wl.xkb.context)
588     {
589         _glfwInputError(GLFW_PLATFORM_ERROR,
590                         "Wayland: Failed to initialize xkb context");
591         return GLFW_FALSE;
592     }
593 
594     // Sync so we got all registry objects
595     wl_display_roundtrip(_glfw.wl.display);
596 
597     // Sync so we got all initial output events
598     wl_display_roundtrip(_glfw.wl.display);
599 
600     if (!_glfwInitThreadLocalStoragePOSIX())
601         return GLFW_FALSE;
602 
603     if (!_glfwInitJoysticksLinux())
604         return GLFW_FALSE;
605 
606     _glfwInitTimerPOSIX();
607 
608     if (_glfw.wl.pointer && _glfw.wl.shm)
609     {
610         _glfw.wl.cursorTheme = wl_cursor_theme_load(NULL, 32, _glfw.wl.shm);
611         if (!_glfw.wl.cursorTheme)
612         {
613             _glfwInputError(GLFW_PLATFORM_ERROR,
614                             "Wayland: Unable to load default cursor theme\n");
615             return GLFW_FALSE;
616         }
617         _glfw.wl.cursorSurface =
618             wl_compositor_create_surface(_glfw.wl.compositor);
619     }
620 
621     return GLFW_TRUE;
622 }
623 
_glfwPlatformTerminate(void)624 void _glfwPlatformTerminate(void)
625 {
626     _glfwTerminateEGL();
627     _glfwTerminateJoysticksLinux();
628     _glfwTerminateThreadLocalStoragePOSIX();
629 
630     if (_glfw.wl.cursorTheme)
631         wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
632     if (_glfw.wl.cursorSurface)
633         wl_surface_destroy(_glfw.wl.cursorSurface);
634     if (_glfw.wl.registry)
635         wl_registry_destroy(_glfw.wl.registry);
636     if (_glfw.wl.display)
637         wl_display_flush(_glfw.wl.display);
638     if (_glfw.wl.display)
639         wl_display_disconnect(_glfw.wl.display);
640 }
641 
_glfwPlatformGetVersionString(void)642 const char* _glfwPlatformGetVersionString(void)
643 {
644     return _GLFW_VERSION_NUMBER " Wayland EGL"
645 #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
646         " clock_gettime"
647 #else
648         " gettimeofday"
649 #endif
650 #if defined(__linux__)
651         " /dev/js"
652 #endif
653 #if defined(_GLFW_BUILD_DLL)
654         " shared"
655 #endif
656         ;
657 }
658 
659