wl_init.c 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318
  1. //========================================================================
  2. // GLFW 3.4 Wayland - www.glfw.org
  3. //------------------------------------------------------------------------
  4. // Copyright (c) 2014 Jonas Ådahl <[email protected]>
  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. // It is fine to use C99 in this file because it will not be built with VS
  27. //========================================================================
  28. #define _POSIX_C_SOURCE 199309L
  29. #include "internal.h"
  30. #include <assert.h>
  31. #include <errno.h>
  32. #include <limits.h>
  33. #include <linux/input.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <sys/mman.h>
  38. #include <sys/timerfd.h>
  39. #include <unistd.h>
  40. #include <time.h>
  41. #include <wayland-client.h>
  42. static inline int min(int n1, int n2)
  43. {
  44. return n1 < n2 ? n1 : n2;
  45. }
  46. static _GLFWwindow* findWindowFromDecorationSurface(struct wl_surface* surface,
  47. int* which)
  48. {
  49. int focus;
  50. _GLFWwindow* window = _glfw.windowListHead;
  51. if (!which)
  52. which = &focus;
  53. while (window)
  54. {
  55. if (surface == window->wl.decorations.top.surface)
  56. {
  57. *which = topDecoration;
  58. break;
  59. }
  60. if (surface == window->wl.decorations.left.surface)
  61. {
  62. *which = leftDecoration;
  63. break;
  64. }
  65. if (surface == window->wl.decorations.right.surface)
  66. {
  67. *which = rightDecoration;
  68. break;
  69. }
  70. if (surface == window->wl.decorations.bottom.surface)
  71. {
  72. *which = bottomDecoration;
  73. break;
  74. }
  75. window = window->next;
  76. }
  77. return window;
  78. }
  79. static void pointerHandleEnter(void* data,
  80. struct wl_pointer* pointer,
  81. uint32_t serial,
  82. struct wl_surface* surface,
  83. wl_fixed_t sx,
  84. wl_fixed_t sy)
  85. {
  86. // Happens in the case we just destroyed the surface.
  87. if (!surface)
  88. return;
  89. int focus = 0;
  90. _GLFWwindow* window = wl_surface_get_user_data(surface);
  91. if (!window)
  92. {
  93. window = findWindowFromDecorationSurface(surface, &focus);
  94. if (!window)
  95. return;
  96. }
  97. window->wl.decorations.focus = focus;
  98. _glfw.wl.serial = serial;
  99. _glfw.wl.pointerFocus = window;
  100. window->wl.hovered = GLFW_TRUE;
  101. _glfwPlatformSetCursor(window, window->wl.currentCursor);
  102. _glfwInputCursorEnter(window, GLFW_TRUE);
  103. }
  104. static void pointerHandleLeave(void* data,
  105. struct wl_pointer* pointer,
  106. uint32_t serial,
  107. struct wl_surface* surface)
  108. {
  109. _GLFWwindow* window = _glfw.wl.pointerFocus;
  110. if (!window)
  111. return;
  112. window->wl.hovered = GLFW_FALSE;
  113. _glfw.wl.serial = serial;
  114. _glfw.wl.pointerFocus = NULL;
  115. _glfwInputCursorEnter(window, GLFW_FALSE);
  116. _glfw.wl.cursorPreviousName = NULL;
  117. }
  118. static void setCursor(_GLFWwindow* window, const char* name)
  119. {
  120. struct wl_buffer* buffer;
  121. struct wl_cursor* cursor;
  122. struct wl_cursor_image* image;
  123. struct wl_surface* surface = _glfw.wl.cursorSurface;
  124. struct wl_cursor_theme* theme = _glfw.wl.cursorTheme;
  125. int scale = 1;
  126. if (window->wl.scale > 1 && _glfw.wl.cursorThemeHiDPI)
  127. {
  128. // We only support up to scale=2 for now, since libwayland-cursor
  129. // requires us to load a different theme for each size.
  130. scale = 2;
  131. theme = _glfw.wl.cursorThemeHiDPI;
  132. }
  133. cursor = wl_cursor_theme_get_cursor(theme, name);
  134. if (!cursor)
  135. {
  136. _glfwInputError(GLFW_PLATFORM_ERROR,
  137. "Wayland: Standard cursor not found");
  138. return;
  139. }
  140. // TODO: handle animated cursors too.
  141. image = cursor->images[0];
  142. if (!image)
  143. return;
  144. buffer = wl_cursor_image_get_buffer(image);
  145. if (!buffer)
  146. return;
  147. wl_pointer_set_cursor(_glfw.wl.pointer, _glfw.wl.serial,
  148. surface,
  149. image->hotspot_x / scale,
  150. image->hotspot_y / scale);
  151. wl_surface_set_buffer_scale(surface, scale);
  152. wl_surface_attach(surface, buffer, 0, 0);
  153. wl_surface_damage(surface, 0, 0,
  154. image->width, image->height);
  155. wl_surface_commit(surface);
  156. _glfw.wl.cursorPreviousName = name;
  157. }
  158. static void pointerHandleMotion(void* data,
  159. struct wl_pointer* pointer,
  160. uint32_t time,
  161. wl_fixed_t sx,
  162. wl_fixed_t sy)
  163. {
  164. _GLFWwindow* window = _glfw.wl.pointerFocus;
  165. const char* cursorName = NULL;
  166. double x, y;
  167. if (!window)
  168. return;
  169. if (window->cursorMode == GLFW_CURSOR_DISABLED)
  170. return;
  171. x = wl_fixed_to_double(sx);
  172. y = wl_fixed_to_double(sy);
  173. switch (window->wl.decorations.focus)
  174. {
  175. case mainWindow:
  176. window->wl.cursorPosX = x;
  177. window->wl.cursorPosY = y;
  178. _glfwInputCursorPos(window, x, y);
  179. _glfw.wl.cursorPreviousName = NULL;
  180. return;
  181. case topDecoration:
  182. if (y < _GLFW_DECORATION_WIDTH)
  183. cursorName = "n-resize";
  184. else
  185. cursorName = "left_ptr";
  186. break;
  187. case leftDecoration:
  188. if (y < _GLFW_DECORATION_WIDTH)
  189. cursorName = "nw-resize";
  190. else
  191. cursorName = "w-resize";
  192. break;
  193. case rightDecoration:
  194. if (y < _GLFW_DECORATION_WIDTH)
  195. cursorName = "ne-resize";
  196. else
  197. cursorName = "e-resize";
  198. break;
  199. case bottomDecoration:
  200. if (x < _GLFW_DECORATION_WIDTH)
  201. cursorName = "sw-resize";
  202. else if (x > window->wl.width + _GLFW_DECORATION_WIDTH)
  203. cursorName = "se-resize";
  204. else
  205. cursorName = "s-resize";
  206. break;
  207. default:
  208. assert(0);
  209. }
  210. if (_glfw.wl.cursorPreviousName != cursorName)
  211. setCursor(window, cursorName);
  212. }
  213. static void pointerHandleButton(void* data,
  214. struct wl_pointer* pointer,
  215. uint32_t serial,
  216. uint32_t time,
  217. uint32_t button,
  218. uint32_t state)
  219. {
  220. _GLFWwindow* window = _glfw.wl.pointerFocus;
  221. int glfwButton;
  222. uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_NONE;
  223. if (!window)
  224. return;
  225. if (button == BTN_LEFT)
  226. {
  227. switch (window->wl.decorations.focus)
  228. {
  229. case mainWindow:
  230. break;
  231. case topDecoration:
  232. if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
  233. edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP;
  234. else
  235. {
  236. xdg_toplevel_move(window->wl.xdg.toplevel, _glfw.wl.seat, serial);
  237. }
  238. break;
  239. case leftDecoration:
  240. if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
  241. edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT;
  242. else
  243. edges = XDG_TOPLEVEL_RESIZE_EDGE_LEFT;
  244. break;
  245. case rightDecoration:
  246. if (window->wl.cursorPosY < _GLFW_DECORATION_WIDTH)
  247. edges = XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT;
  248. else
  249. edges = XDG_TOPLEVEL_RESIZE_EDGE_RIGHT;
  250. break;
  251. case bottomDecoration:
  252. if (window->wl.cursorPosX < _GLFW_DECORATION_WIDTH)
  253. edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
  254. else if (window->wl.cursorPosX > window->wl.width + _GLFW_DECORATION_WIDTH)
  255. edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
  256. else
  257. edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
  258. break;
  259. default:
  260. assert(0);
  261. }
  262. if (edges != XDG_TOPLEVEL_RESIZE_EDGE_NONE)
  263. {
  264. xdg_toplevel_resize(window->wl.xdg.toplevel, _glfw.wl.seat,
  265. serial, edges);
  266. }
  267. }
  268. else if (button == BTN_RIGHT)
  269. {
  270. if (window->wl.decorations.focus != mainWindow && window->wl.xdg.toplevel)
  271. {
  272. xdg_toplevel_show_window_menu(window->wl.xdg.toplevel,
  273. _glfw.wl.seat, serial,
  274. window->wl.cursorPosX,
  275. window->wl.cursorPosY);
  276. return;
  277. }
  278. }
  279. // Don’t pass the button to the user if it was related to a decoration.
  280. if (window->wl.decorations.focus != mainWindow)
  281. return;
  282. _glfw.wl.serial = serial;
  283. /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev
  284. * codes. */
  285. glfwButton = button - BTN_LEFT;
  286. _glfwInputMouseClick(window,
  287. glfwButton,
  288. state == WL_POINTER_BUTTON_STATE_PRESSED
  289. ? GLFW_PRESS
  290. : GLFW_RELEASE,
  291. _glfw.wl.xkb.modifiers);
  292. }
  293. static void pointerHandleAxis(void* data,
  294. struct wl_pointer* pointer,
  295. uint32_t time,
  296. uint32_t axis,
  297. wl_fixed_t value)
  298. {
  299. _GLFWwindow* window = _glfw.wl.pointerFocus;
  300. double x = 0.0, y = 0.0;
  301. // Wayland scroll events are in pointer motion coordinate space (think two
  302. // finger scroll). The factor 10 is commonly used to convert to "scroll
  303. // step means 1.0.
  304. const double scrollFactor = 1.0 / 10.0;
  305. if (!window)
  306. return;
  307. assert(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ||
  308. axis == WL_POINTER_AXIS_VERTICAL_SCROLL);
  309. if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
  310. x = wl_fixed_to_double(value) * scrollFactor;
  311. else if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
  312. y = wl_fixed_to_double(value) * scrollFactor;
  313. _glfwInputScroll(window, x, y);
  314. }
  315. static const struct wl_pointer_listener pointerListener = {
  316. pointerHandleEnter,
  317. pointerHandleLeave,
  318. pointerHandleMotion,
  319. pointerHandleButton,
  320. pointerHandleAxis,
  321. };
  322. static void keyboardHandleKeymap(void* data,
  323. struct wl_keyboard* keyboard,
  324. uint32_t format,
  325. int fd,
  326. uint32_t size)
  327. {
  328. struct xkb_keymap* keymap;
  329. struct xkb_state* state;
  330. #ifdef HAVE_XKBCOMMON_COMPOSE_H
  331. struct xkb_compose_table* composeTable;
  332. struct xkb_compose_state* composeState;
  333. #endif
  334. char* mapStr;
  335. const char* locale;
  336. if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
  337. {
  338. close(fd);
  339. return;
  340. }
  341. mapStr = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
  342. if (mapStr == MAP_FAILED) {
  343. close(fd);
  344. return;
  345. }
  346. keymap = xkb_keymap_new_from_string(_glfw.wl.xkb.context,
  347. mapStr,
  348. XKB_KEYMAP_FORMAT_TEXT_V1,
  349. 0);
  350. munmap(mapStr, size);
  351. close(fd);
  352. if (!keymap)
  353. {
  354. _glfwInputError(GLFW_PLATFORM_ERROR,
  355. "Wayland: Failed to compile keymap");
  356. return;
  357. }
  358. state = xkb_state_new(keymap);
  359. if (!state)
  360. {
  361. _glfwInputError(GLFW_PLATFORM_ERROR,
  362. "Wayland: Failed to create XKB state");
  363. xkb_keymap_unref(keymap);
  364. return;
  365. }
  366. // Look up the preferred locale, falling back to "C" as default.
  367. locale = getenv("LC_ALL");
  368. if (!locale)
  369. locale = getenv("LC_CTYPE");
  370. if (!locale)
  371. locale = getenv("LANG");
  372. if (!locale)
  373. locale = "C";
  374. #ifdef HAVE_XKBCOMMON_COMPOSE_H
  375. composeTable =
  376. xkb_compose_table_new_from_locale(_glfw.wl.xkb.context, locale,
  377. XKB_COMPOSE_COMPILE_NO_FLAGS);
  378. if (composeTable)
  379. {
  380. composeState =
  381. xkb_compose_state_new(composeTable, XKB_COMPOSE_STATE_NO_FLAGS);
  382. xkb_compose_table_unref(composeTable);
  383. if (composeState)
  384. _glfw.wl.xkb.composeState = composeState;
  385. else
  386. _glfwInputError(GLFW_PLATFORM_ERROR,
  387. "Wayland: Failed to create XKB compose state");
  388. }
  389. else
  390. {
  391. _glfwInputError(GLFW_PLATFORM_ERROR,
  392. "Wayland: Failed to create XKB compose table");
  393. }
  394. #endif
  395. xkb_keymap_unref(_glfw.wl.xkb.keymap);
  396. xkb_state_unref(_glfw.wl.xkb.state);
  397. _glfw.wl.xkb.keymap = keymap;
  398. _glfw.wl.xkb.state = state;
  399. _glfw.wl.xkb.controlMask =
  400. 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Control");
  401. _glfw.wl.xkb.altMask =
  402. 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod1");
  403. _glfw.wl.xkb.shiftMask =
  404. 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Shift");
  405. _glfw.wl.xkb.superMask =
  406. 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod4");
  407. _glfw.wl.xkb.capsLockMask =
  408. 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Lock");
  409. _glfw.wl.xkb.numLockMask =
  410. 1 << xkb_keymap_mod_get_index(_glfw.wl.xkb.keymap, "Mod2");
  411. }
  412. static void keyboardHandleEnter(void* data,
  413. struct wl_keyboard* keyboard,
  414. uint32_t serial,
  415. struct wl_surface* surface,
  416. struct wl_array* keys)
  417. {
  418. // Happens in the case we just destroyed the surface.
  419. if (!surface)
  420. return;
  421. _GLFWwindow* window = wl_surface_get_user_data(surface);
  422. if (!window)
  423. {
  424. window = findWindowFromDecorationSurface(surface, NULL);
  425. if (!window)
  426. return;
  427. }
  428. _glfw.wl.serial = serial;
  429. _glfw.wl.keyboardFocus = window;
  430. _glfwInputWindowFocus(window, GLFW_TRUE);
  431. }
  432. static void keyboardHandleLeave(void* data,
  433. struct wl_keyboard* keyboard,
  434. uint32_t serial,
  435. struct wl_surface* surface)
  436. {
  437. _GLFWwindow* window = _glfw.wl.keyboardFocus;
  438. if (!window)
  439. return;
  440. _glfw.wl.serial = serial;
  441. _glfw.wl.keyboardFocus = NULL;
  442. _glfwInputWindowFocus(window, GLFW_FALSE);
  443. }
  444. static int toGLFWKeyCode(uint32_t key)
  445. {
  446. if (key < sizeof(_glfw.wl.keycodes) / sizeof(_glfw.wl.keycodes[0]))
  447. return _glfw.wl.keycodes[key];
  448. return GLFW_KEY_UNKNOWN;
  449. }
  450. #ifdef HAVE_XKBCOMMON_COMPOSE_H
  451. static xkb_keysym_t composeSymbol(xkb_keysym_t sym)
  452. {
  453. if (sym == XKB_KEY_NoSymbol || !_glfw.wl.xkb.composeState)
  454. return sym;
  455. if (xkb_compose_state_feed(_glfw.wl.xkb.composeState, sym)
  456. != XKB_COMPOSE_FEED_ACCEPTED)
  457. return sym;
  458. switch (xkb_compose_state_get_status(_glfw.wl.xkb.composeState))
  459. {
  460. case XKB_COMPOSE_COMPOSED:
  461. return xkb_compose_state_get_one_sym(_glfw.wl.xkb.composeState);
  462. case XKB_COMPOSE_COMPOSING:
  463. case XKB_COMPOSE_CANCELLED:
  464. return XKB_KEY_NoSymbol;
  465. case XKB_COMPOSE_NOTHING:
  466. default:
  467. return sym;
  468. }
  469. }
  470. #endif
  471. static GLFWbool inputChar(_GLFWwindow* window, uint32_t key)
  472. {
  473. uint32_t code, numSyms;
  474. long cp;
  475. const xkb_keysym_t *syms;
  476. xkb_keysym_t sym;
  477. code = key + 8;
  478. numSyms = xkb_state_key_get_syms(_glfw.wl.xkb.state, code, &syms);
  479. if (numSyms == 1)
  480. {
  481. #ifdef HAVE_XKBCOMMON_COMPOSE_H
  482. sym = composeSymbol(syms[0]);
  483. #else
  484. sym = syms[0];
  485. #endif
  486. cp = _glfwKeySym2Unicode(sym);
  487. if (cp != -1)
  488. {
  489. const int mods = _glfw.wl.xkb.modifiers;
  490. const int plain = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));
  491. _glfwInputChar(window, cp, mods, plain);
  492. }
  493. }
  494. return xkb_keymap_key_repeats(_glfw.wl.xkb.keymap, syms[0]);
  495. }
  496. static void keyboardHandleKey(void* data,
  497. struct wl_keyboard* keyboard,
  498. uint32_t serial,
  499. uint32_t time,
  500. uint32_t key,
  501. uint32_t state)
  502. {
  503. int keyCode;
  504. int action;
  505. _GLFWwindow* window = _glfw.wl.keyboardFocus;
  506. GLFWbool shouldRepeat;
  507. struct itimerspec timer = {};
  508. if (!window)
  509. return;
  510. keyCode = toGLFWKeyCode(key);
  511. action = state == WL_KEYBOARD_KEY_STATE_PRESSED
  512. ? GLFW_PRESS : GLFW_RELEASE;
  513. _glfw.wl.serial = serial;
  514. _glfwInputKey(window, keyCode, key, action,
  515. _glfw.wl.xkb.modifiers);
  516. if (action == GLFW_PRESS)
  517. {
  518. shouldRepeat = inputChar(window, key);
  519. if (shouldRepeat && _glfw.wl.keyboardRepeatRate > 0)
  520. {
  521. _glfw.wl.keyboardLastKey = keyCode;
  522. _glfw.wl.keyboardLastScancode = key;
  523. if (_glfw.wl.keyboardRepeatRate > 1)
  524. timer.it_interval.tv_nsec = 1000000000 / _glfw.wl.keyboardRepeatRate;
  525. else
  526. timer.it_interval.tv_sec = 1;
  527. timer.it_value.tv_sec = _glfw.wl.keyboardRepeatDelay / 1000;
  528. timer.it_value.tv_nsec = (_glfw.wl.keyboardRepeatDelay % 1000) * 1000000;
  529. }
  530. }
  531. timerfd_settime(_glfw.wl.timerfd, 0, &timer, NULL);
  532. }
  533. static void keyboardHandleModifiers(void* data,
  534. struct wl_keyboard* keyboard,
  535. uint32_t serial,
  536. uint32_t modsDepressed,
  537. uint32_t modsLatched,
  538. uint32_t modsLocked,
  539. uint32_t group)
  540. {
  541. xkb_mod_mask_t mask;
  542. unsigned int modifiers = 0;
  543. _glfw.wl.serial = serial;
  544. if (!_glfw.wl.xkb.keymap)
  545. return;
  546. xkb_state_update_mask(_glfw.wl.xkb.state,
  547. modsDepressed,
  548. modsLatched,
  549. modsLocked,
  550. 0,
  551. 0,
  552. group);
  553. mask = xkb_state_serialize_mods(_glfw.wl.xkb.state,
  554. XKB_STATE_MODS_DEPRESSED |
  555. XKB_STATE_LAYOUT_DEPRESSED |
  556. XKB_STATE_MODS_LATCHED |
  557. XKB_STATE_LAYOUT_LATCHED);
  558. if (mask & _glfw.wl.xkb.controlMask)
  559. modifiers |= GLFW_MOD_CONTROL;
  560. if (mask & _glfw.wl.xkb.altMask)
  561. modifiers |= GLFW_MOD_ALT;
  562. if (mask & _glfw.wl.xkb.shiftMask)
  563. modifiers |= GLFW_MOD_SHIFT;
  564. if (mask & _glfw.wl.xkb.superMask)
  565. modifiers |= GLFW_MOD_SUPER;
  566. if (mask & _glfw.wl.xkb.capsLockMask)
  567. modifiers |= GLFW_MOD_CAPS_LOCK;
  568. if (mask & _glfw.wl.xkb.numLockMask)
  569. modifiers |= GLFW_MOD_NUM_LOCK;
  570. _glfw.wl.xkb.modifiers = modifiers;
  571. }
  572. #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
  573. static void keyboardHandleRepeatInfo(void* data,
  574. struct wl_keyboard* keyboard,
  575. int32_t rate,
  576. int32_t delay)
  577. {
  578. if (keyboard != _glfw.wl.keyboard)
  579. return;
  580. _glfw.wl.keyboardRepeatRate = rate;
  581. _glfw.wl.keyboardRepeatDelay = delay;
  582. }
  583. #endif
  584. static const struct wl_keyboard_listener keyboardListener = {
  585. keyboardHandleKeymap,
  586. keyboardHandleEnter,
  587. keyboardHandleLeave,
  588. keyboardHandleKey,
  589. keyboardHandleModifiers,
  590. #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
  591. keyboardHandleRepeatInfo,
  592. #endif
  593. };
  594. static void seatHandleCapabilities(void* data,
  595. struct wl_seat* seat,
  596. enum wl_seat_capability caps)
  597. {
  598. if ((caps & WL_SEAT_CAPABILITY_POINTER) && !_glfw.wl.pointer)
  599. {
  600. _glfw.wl.pointer = wl_seat_get_pointer(seat);
  601. wl_pointer_add_listener(_glfw.wl.pointer, &pointerListener, NULL);
  602. }
  603. else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && _glfw.wl.pointer)
  604. {
  605. wl_pointer_destroy(_glfw.wl.pointer);
  606. _glfw.wl.pointer = NULL;
  607. }
  608. if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !_glfw.wl.keyboard)
  609. {
  610. _glfw.wl.keyboard = wl_seat_get_keyboard(seat);
  611. wl_keyboard_add_listener(_glfw.wl.keyboard, &keyboardListener, NULL);
  612. }
  613. else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && _glfw.wl.keyboard)
  614. {
  615. wl_keyboard_destroy(_glfw.wl.keyboard);
  616. _glfw.wl.keyboard = NULL;
  617. }
  618. }
  619. static void seatHandleName(void* data,
  620. struct wl_seat* seat,
  621. const char* name)
  622. {
  623. }
  624. static const struct wl_seat_listener seatListener = {
  625. seatHandleCapabilities,
  626. seatHandleName,
  627. };
  628. static void dataOfferHandleOffer(void* data,
  629. struct wl_data_offer* dataOffer,
  630. const char* mimeType)
  631. {
  632. }
  633. static const struct wl_data_offer_listener dataOfferListener = {
  634. dataOfferHandleOffer,
  635. };
  636. static void dataDeviceHandleDataOffer(void* data,
  637. struct wl_data_device* dataDevice,
  638. struct wl_data_offer* id)
  639. {
  640. if (_glfw.wl.dataOffer)
  641. wl_data_offer_destroy(_glfw.wl.dataOffer);
  642. _glfw.wl.dataOffer = id;
  643. wl_data_offer_add_listener(_glfw.wl.dataOffer, &dataOfferListener, NULL);
  644. }
  645. static void dataDeviceHandleEnter(void* data,
  646. struct wl_data_device* dataDevice,
  647. uint32_t serial,
  648. struct wl_surface *surface,
  649. wl_fixed_t x,
  650. wl_fixed_t y,
  651. struct wl_data_offer *id)
  652. {
  653. }
  654. static void dataDeviceHandleLeave(void* data,
  655. struct wl_data_device* dataDevice)
  656. {
  657. }
  658. static void dataDeviceHandleMotion(void* data,
  659. struct wl_data_device* dataDevice,
  660. uint32_t time,
  661. wl_fixed_t x,
  662. wl_fixed_t y)
  663. {
  664. }
  665. static void dataDeviceHandleDrop(void* data,
  666. struct wl_data_device* dataDevice)
  667. {
  668. }
  669. static void dataDeviceHandleSelection(void* data,
  670. struct wl_data_device* dataDevice,
  671. struct wl_data_offer* id)
  672. {
  673. }
  674. static const struct wl_data_device_listener dataDeviceListener = {
  675. dataDeviceHandleDataOffer,
  676. dataDeviceHandleEnter,
  677. dataDeviceHandleLeave,
  678. dataDeviceHandleMotion,
  679. dataDeviceHandleDrop,
  680. dataDeviceHandleSelection,
  681. };
  682. static void wmBaseHandlePing(void* data,
  683. struct xdg_wm_base* wmBase,
  684. uint32_t serial)
  685. {
  686. xdg_wm_base_pong(wmBase, serial);
  687. }
  688. static const struct xdg_wm_base_listener wmBaseListener = {
  689. wmBaseHandlePing
  690. };
  691. static void registryHandleGlobal(void* data,
  692. struct wl_registry* registry,
  693. uint32_t name,
  694. const char* interface,
  695. uint32_t version)
  696. {
  697. if (strcmp(interface, "wl_compositor") == 0)
  698. {
  699. _glfw.wl.compositorVersion = min(3, version);
  700. _glfw.wl.compositor =
  701. wl_registry_bind(registry, name, &wl_compositor_interface,
  702. _glfw.wl.compositorVersion);
  703. }
  704. else if (strcmp(interface, "wl_subcompositor") == 0)
  705. {
  706. _glfw.wl.subcompositor =
  707. wl_registry_bind(registry, name, &wl_subcompositor_interface, 1);
  708. }
  709. else if (strcmp(interface, "wl_shm") == 0)
  710. {
  711. _glfw.wl.shm =
  712. wl_registry_bind(registry, name, &wl_shm_interface, 1);
  713. }
  714. else if (strcmp(interface, "wl_output") == 0)
  715. {
  716. _glfwAddOutputWayland(name, version);
  717. }
  718. else if (strcmp(interface, "wl_seat") == 0)
  719. {
  720. if (!_glfw.wl.seat)
  721. {
  722. _glfw.wl.seatVersion = min(4, version);
  723. _glfw.wl.seat =
  724. wl_registry_bind(registry, name, &wl_seat_interface,
  725. _glfw.wl.seatVersion);
  726. wl_seat_add_listener(_glfw.wl.seat, &seatListener, NULL);
  727. }
  728. }
  729. else if (strcmp(interface, "wl_data_device_manager") == 0)
  730. {
  731. if (!_glfw.wl.dataDeviceManager)
  732. {
  733. _glfw.wl.dataDeviceManager =
  734. wl_registry_bind(registry, name,
  735. &wl_data_device_manager_interface, 1);
  736. }
  737. }
  738. else if (strcmp(interface, "xdg_wm_base") == 0)
  739. {
  740. _glfw.wl.wmBase =
  741. wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
  742. xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL);
  743. }
  744. else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0)
  745. {
  746. _glfw.wl.decorationManager =
  747. wl_registry_bind(registry, name,
  748. &zxdg_decoration_manager_v1_interface,
  749. 1);
  750. }
  751. else if (strcmp(interface, "wp_viewporter") == 0)
  752. {
  753. _glfw.wl.viewporter =
  754. wl_registry_bind(registry, name, &wp_viewporter_interface, 1);
  755. }
  756. else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)
  757. {
  758. _glfw.wl.relativePointerManager =
  759. wl_registry_bind(registry, name,
  760. &zwp_relative_pointer_manager_v1_interface,
  761. 1);
  762. }
  763. else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0)
  764. {
  765. _glfw.wl.pointerConstraints =
  766. wl_registry_bind(registry, name,
  767. &zwp_pointer_constraints_v1_interface,
  768. 1);
  769. }
  770. else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0)
  771. {
  772. _glfw.wl.idleInhibitManager =
  773. wl_registry_bind(registry, name,
  774. &zwp_idle_inhibit_manager_v1_interface,
  775. 1);
  776. }
  777. }
  778. static void registryHandleGlobalRemove(void *data,
  779. struct wl_registry *registry,
  780. uint32_t name)
  781. {
  782. int i;
  783. _GLFWmonitor* monitor;
  784. for (i = 0; i < _glfw.monitorCount; ++i)
  785. {
  786. monitor = _glfw.monitors[i];
  787. if (monitor->wl.name == name)
  788. {
  789. _glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0);
  790. return;
  791. }
  792. }
  793. }
  794. static const struct wl_registry_listener registryListener = {
  795. registryHandleGlobal,
  796. registryHandleGlobalRemove
  797. };
  798. // Create key code translation tables
  799. //
  800. static void createKeyTables(void)
  801. {
  802. int scancode;
  803. memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes));
  804. memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes));
  805. _glfw.wl.keycodes[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT;
  806. _glfw.wl.keycodes[KEY_1] = GLFW_KEY_1;
  807. _glfw.wl.keycodes[KEY_2] = GLFW_KEY_2;
  808. _glfw.wl.keycodes[KEY_3] = GLFW_KEY_3;
  809. _glfw.wl.keycodes[KEY_4] = GLFW_KEY_4;
  810. _glfw.wl.keycodes[KEY_5] = GLFW_KEY_5;
  811. _glfw.wl.keycodes[KEY_6] = GLFW_KEY_6;
  812. _glfw.wl.keycodes[KEY_7] = GLFW_KEY_7;
  813. _glfw.wl.keycodes[KEY_8] = GLFW_KEY_8;
  814. _glfw.wl.keycodes[KEY_9] = GLFW_KEY_9;
  815. _glfw.wl.keycodes[KEY_0] = GLFW_KEY_0;
  816. _glfw.wl.keycodes[KEY_SPACE] = GLFW_KEY_SPACE;
  817. _glfw.wl.keycodes[KEY_MINUS] = GLFW_KEY_MINUS;
  818. _glfw.wl.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL;
  819. _glfw.wl.keycodes[KEY_Q] = GLFW_KEY_Q;
  820. _glfw.wl.keycodes[KEY_W] = GLFW_KEY_W;
  821. _glfw.wl.keycodes[KEY_E] = GLFW_KEY_E;
  822. _glfw.wl.keycodes[KEY_R] = GLFW_KEY_R;
  823. _glfw.wl.keycodes[KEY_T] = GLFW_KEY_T;
  824. _glfw.wl.keycodes[KEY_Y] = GLFW_KEY_Y;
  825. _glfw.wl.keycodes[KEY_U] = GLFW_KEY_U;
  826. _glfw.wl.keycodes[KEY_I] = GLFW_KEY_I;
  827. _glfw.wl.keycodes[KEY_O] = GLFW_KEY_O;
  828. _glfw.wl.keycodes[KEY_P] = GLFW_KEY_P;
  829. _glfw.wl.keycodes[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET;
  830. _glfw.wl.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;
  831. _glfw.wl.keycodes[KEY_A] = GLFW_KEY_A;
  832. _glfw.wl.keycodes[KEY_S] = GLFW_KEY_S;
  833. _glfw.wl.keycodes[KEY_D] = GLFW_KEY_D;
  834. _glfw.wl.keycodes[KEY_F] = GLFW_KEY_F;
  835. _glfw.wl.keycodes[KEY_G] = GLFW_KEY_G;
  836. _glfw.wl.keycodes[KEY_H] = GLFW_KEY_H;
  837. _glfw.wl.keycodes[KEY_J] = GLFW_KEY_J;
  838. _glfw.wl.keycodes[KEY_K] = GLFW_KEY_K;
  839. _glfw.wl.keycodes[KEY_L] = GLFW_KEY_L;
  840. _glfw.wl.keycodes[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON;
  841. _glfw.wl.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
  842. _glfw.wl.keycodes[KEY_Z] = GLFW_KEY_Z;
  843. _glfw.wl.keycodes[KEY_X] = GLFW_KEY_X;
  844. _glfw.wl.keycodes[KEY_C] = GLFW_KEY_C;
  845. _glfw.wl.keycodes[KEY_V] = GLFW_KEY_V;
  846. _glfw.wl.keycodes[KEY_B] = GLFW_KEY_B;
  847. _glfw.wl.keycodes[KEY_N] = GLFW_KEY_N;
  848. _glfw.wl.keycodes[KEY_M] = GLFW_KEY_M;
  849. _glfw.wl.keycodes[KEY_COMMA] = GLFW_KEY_COMMA;
  850. _glfw.wl.keycodes[KEY_DOT] = GLFW_KEY_PERIOD;
  851. _glfw.wl.keycodes[KEY_SLASH] = GLFW_KEY_SLASH;
  852. _glfw.wl.keycodes[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH;
  853. _glfw.wl.keycodes[KEY_ESC] = GLFW_KEY_ESCAPE;
  854. _glfw.wl.keycodes[KEY_TAB] = GLFW_KEY_TAB;
  855. _glfw.wl.keycodes[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT;
  856. _glfw.wl.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;
  857. _glfw.wl.keycodes[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL;
  858. _glfw.wl.keycodes[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL;
  859. _glfw.wl.keycodes[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT;
  860. _glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT;
  861. _glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER;
  862. _glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER;
  863. _glfw.wl.keycodes[KEY_MENU] = GLFW_KEY_MENU;
  864. _glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK;
  865. _glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK;
  866. _glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN;
  867. _glfw.wl.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;
  868. _glfw.wl.keycodes[KEY_PAUSE] = GLFW_KEY_PAUSE;
  869. _glfw.wl.keycodes[KEY_DELETE] = GLFW_KEY_DELETE;
  870. _glfw.wl.keycodes[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE;
  871. _glfw.wl.keycodes[KEY_ENTER] = GLFW_KEY_ENTER;
  872. _glfw.wl.keycodes[KEY_HOME] = GLFW_KEY_HOME;
  873. _glfw.wl.keycodes[KEY_END] = GLFW_KEY_END;
  874. _glfw.wl.keycodes[KEY_PAGEUP] = GLFW_KEY_PAGE_UP;
  875. _glfw.wl.keycodes[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN;
  876. _glfw.wl.keycodes[KEY_INSERT] = GLFW_KEY_INSERT;
  877. _glfw.wl.keycodes[KEY_LEFT] = GLFW_KEY_LEFT;
  878. _glfw.wl.keycodes[KEY_RIGHT] = GLFW_KEY_RIGHT;
  879. _glfw.wl.keycodes[KEY_DOWN] = GLFW_KEY_DOWN;
  880. _glfw.wl.keycodes[KEY_UP] = GLFW_KEY_UP;
  881. _glfw.wl.keycodes[KEY_F1] = GLFW_KEY_F1;
  882. _glfw.wl.keycodes[KEY_F2] = GLFW_KEY_F2;
  883. _glfw.wl.keycodes[KEY_F3] = GLFW_KEY_F3;
  884. _glfw.wl.keycodes[KEY_F4] = GLFW_KEY_F4;
  885. _glfw.wl.keycodes[KEY_F5] = GLFW_KEY_F5;
  886. _glfw.wl.keycodes[KEY_F6] = GLFW_KEY_F6;
  887. _glfw.wl.keycodes[KEY_F7] = GLFW_KEY_F7;
  888. _glfw.wl.keycodes[KEY_F8] = GLFW_KEY_F8;
  889. _glfw.wl.keycodes[KEY_F9] = GLFW_KEY_F9;
  890. _glfw.wl.keycodes[KEY_F10] = GLFW_KEY_F10;
  891. _glfw.wl.keycodes[KEY_F11] = GLFW_KEY_F11;
  892. _glfw.wl.keycodes[KEY_F12] = GLFW_KEY_F12;
  893. _glfw.wl.keycodes[KEY_F13] = GLFW_KEY_F13;
  894. _glfw.wl.keycodes[KEY_F14] = GLFW_KEY_F14;
  895. _glfw.wl.keycodes[KEY_F15] = GLFW_KEY_F15;
  896. _glfw.wl.keycodes[KEY_F16] = GLFW_KEY_F16;
  897. _glfw.wl.keycodes[KEY_F17] = GLFW_KEY_F17;
  898. _glfw.wl.keycodes[KEY_F18] = GLFW_KEY_F18;
  899. _glfw.wl.keycodes[KEY_F19] = GLFW_KEY_F19;
  900. _glfw.wl.keycodes[KEY_F20] = GLFW_KEY_F20;
  901. _glfw.wl.keycodes[KEY_F21] = GLFW_KEY_F21;
  902. _glfw.wl.keycodes[KEY_F22] = GLFW_KEY_F22;
  903. _glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23;
  904. _glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24;
  905. _glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE;
  906. _glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_MULTIPLY;
  907. _glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT;
  908. _glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD;
  909. _glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0;
  910. _glfw.wl.keycodes[KEY_KP1] = GLFW_KEY_KP_1;
  911. _glfw.wl.keycodes[KEY_KP2] = GLFW_KEY_KP_2;
  912. _glfw.wl.keycodes[KEY_KP3] = GLFW_KEY_KP_3;
  913. _glfw.wl.keycodes[KEY_KP4] = GLFW_KEY_KP_4;
  914. _glfw.wl.keycodes[KEY_KP5] = GLFW_KEY_KP_5;
  915. _glfw.wl.keycodes[KEY_KP6] = GLFW_KEY_KP_6;
  916. _glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7;
  917. _glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8;
  918. _glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9;
  919. _glfw.wl.keycodes[KEY_KPCOMMA] = GLFW_KEY_KP_DECIMAL;
  920. _glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL;
  921. _glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER;
  922. for (scancode = 0; scancode < 256; scancode++)
  923. {
  924. if (_glfw.wl.keycodes[scancode] > 0)
  925. _glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode;
  926. }
  927. }
  928. //////////////////////////////////////////////////////////////////////////
  929. ////// GLFW platform API //////
  930. //////////////////////////////////////////////////////////////////////////
  931. int _glfwPlatformInit(void)
  932. {
  933. const char *cursorTheme;
  934. const char *cursorSizeStr;
  935. char *cursorSizeEnd;
  936. long cursorSizeLong;
  937. int cursorSize;
  938. _glfw.wl.cursor.handle = _glfw_dlopen("libwayland-cursor.so.0");
  939. if (!_glfw.wl.cursor.handle)
  940. {
  941. _glfwInputError(GLFW_PLATFORM_ERROR,
  942. "Wayland: Failed to open libwayland-cursor");
  943. return GLFW_FALSE;
  944. }
  945. _glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
  946. _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
  947. _glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
  948. _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
  949. _glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
  950. _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
  951. _glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
  952. _glfw_dlsym(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
  953. _glfw.wl.egl.handle = _glfw_dlopen("libwayland-egl.so.1");
  954. if (!_glfw.wl.egl.handle)
  955. {
  956. _glfwInputError(GLFW_PLATFORM_ERROR,
  957. "Wayland: Failed to open libwayland-egl");
  958. return GLFW_FALSE;
  959. }
  960. _glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
  961. _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_create");
  962. _glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
  963. _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_destroy");
  964. _glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
  965. _glfw_dlsym(_glfw.wl.egl.handle, "wl_egl_window_resize");
  966. _glfw.wl.xkb.handle = _glfw_dlopen("libxkbcommon.so.0");
  967. if (!_glfw.wl.xkb.handle)
  968. {
  969. _glfwInputError(GLFW_PLATFORM_ERROR,
  970. "Wayland: Failed to open libxkbcommon");
  971. return GLFW_FALSE;
  972. }
  973. _glfw.wl.xkb.context_new = (PFN_xkb_context_new)
  974. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_new");
  975. _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref)
  976. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_context_unref");
  977. _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string)
  978. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string");
  979. _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref)
  980. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_unref");
  981. _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index)
  982. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
  983. _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
  984. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
  985. _glfw.wl.xkb.state_new = (PFN_xkb_state_new)
  986. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_new");
  987. _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
  988. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_unref");
  989. _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms)
  990. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_key_get_syms");
  991. _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask)
  992. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_update_mask");
  993. _glfw.wl.xkb.state_serialize_mods = (PFN_xkb_state_serialize_mods)
  994. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_state_serialize_mods");
  995. #ifdef HAVE_XKBCOMMON_COMPOSE_H
  996. _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
  997. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
  998. _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
  999. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_table_unref");
  1000. _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new)
  1001. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_new");
  1002. _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref)
  1003. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_unref");
  1004. _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed)
  1005. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_feed");
  1006. _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status)
  1007. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
  1008. _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
  1009. _glfw_dlsym(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
  1010. #endif
  1011. _glfw.wl.display = wl_display_connect(NULL);
  1012. if (!_glfw.wl.display)
  1013. {
  1014. _glfwInputError(GLFW_PLATFORM_ERROR,
  1015. "Wayland: Failed to connect to display");
  1016. return GLFW_FALSE;
  1017. }
  1018. _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
  1019. wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
  1020. createKeyTables();
  1021. _glfw.wl.xkb.context = xkb_context_new(0);
  1022. if (!_glfw.wl.xkb.context)
  1023. {
  1024. _glfwInputError(GLFW_PLATFORM_ERROR,
  1025. "Wayland: Failed to initialize xkb context");
  1026. return GLFW_FALSE;
  1027. }
  1028. // Sync so we got all registry objects
  1029. wl_display_roundtrip(_glfw.wl.display);
  1030. // Sync so we got all initial output events
  1031. wl_display_roundtrip(_glfw.wl.display);
  1032. #ifdef __linux__
  1033. if (!_glfwInitJoysticksLinux())
  1034. return GLFW_FALSE;
  1035. #endif
  1036. _glfwInitTimerPOSIX();
  1037. _glfw.wl.timerfd = -1;
  1038. if (_glfw.wl.seatVersion >= 4)
  1039. _glfw.wl.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
  1040. if (!_glfw.wl.wmBase)
  1041. {
  1042. _glfwInputError(GLFW_PLATFORM_ERROR,
  1043. "Wayland: Failed to find xdg-shell in your compositor");
  1044. return GLFW_FALSE;
  1045. }
  1046. if (_glfw.wl.pointer && _glfw.wl.shm)
  1047. {
  1048. cursorTheme = getenv("XCURSOR_THEME");
  1049. cursorSizeStr = getenv("XCURSOR_SIZE");
  1050. cursorSize = 32;
  1051. if (cursorSizeStr)
  1052. {
  1053. errno = 0;
  1054. cursorSizeLong = strtol(cursorSizeStr, &cursorSizeEnd, 10);
  1055. if (!*cursorSizeEnd && !errno && cursorSizeLong > 0 && cursorSizeLong <= INT_MAX)
  1056. cursorSize = (int)cursorSizeLong;
  1057. }
  1058. _glfw.wl.cursorTheme =
  1059. wl_cursor_theme_load(cursorTheme, cursorSize, _glfw.wl.shm);
  1060. if (!_glfw.wl.cursorTheme)
  1061. {
  1062. _glfwInputError(GLFW_PLATFORM_ERROR,
  1063. "Wayland: Unable to load default cursor theme");
  1064. return GLFW_FALSE;
  1065. }
  1066. // If this happens to be NULL, we just fallback to the scale=1 version.
  1067. _glfw.wl.cursorThemeHiDPI =
  1068. wl_cursor_theme_load(cursorTheme, 2 * cursorSize, _glfw.wl.shm);
  1069. _glfw.wl.cursorSurface =
  1070. wl_compositor_create_surface(_glfw.wl.compositor);
  1071. _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
  1072. }
  1073. if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
  1074. {
  1075. _glfw.wl.dataDevice =
  1076. wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
  1077. _glfw.wl.seat);
  1078. wl_data_device_add_listener(_glfw.wl.dataDevice, &dataDeviceListener, NULL);
  1079. _glfw.wl.clipboardString = malloc(4096);
  1080. if (!_glfw.wl.clipboardString)
  1081. {
  1082. _glfwInputError(GLFW_PLATFORM_ERROR,
  1083. "Wayland: Unable to allocate clipboard memory");
  1084. return GLFW_FALSE;
  1085. }
  1086. _glfw.wl.clipboardSize = 4096;
  1087. }
  1088. return GLFW_TRUE;
  1089. }
  1090. void _glfwPlatformTerminate(void)
  1091. {
  1092. #ifdef __linux__
  1093. _glfwTerminateJoysticksLinux();
  1094. #endif
  1095. _glfwTerminateEGL();
  1096. if (_glfw.wl.egl.handle)
  1097. {
  1098. _glfw_dlclose(_glfw.wl.egl.handle);
  1099. _glfw.wl.egl.handle = NULL;
  1100. }
  1101. #ifdef HAVE_XKBCOMMON_COMPOSE_H
  1102. if (_glfw.wl.xkb.composeState)
  1103. xkb_compose_state_unref(_glfw.wl.xkb.composeState);
  1104. #endif
  1105. if (_glfw.wl.xkb.keymap)
  1106. xkb_keymap_unref(_glfw.wl.xkb.keymap);
  1107. if (_glfw.wl.xkb.state)
  1108. xkb_state_unref(_glfw.wl.xkb.state);
  1109. if (_glfw.wl.xkb.context)
  1110. xkb_context_unref(_glfw.wl.xkb.context);
  1111. if (_glfw.wl.xkb.handle)
  1112. {
  1113. _glfw_dlclose(_glfw.wl.xkb.handle);
  1114. _glfw.wl.xkb.handle = NULL;
  1115. }
  1116. if (_glfw.wl.cursorTheme)
  1117. wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
  1118. if (_glfw.wl.cursorThemeHiDPI)
  1119. wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
  1120. if (_glfw.wl.cursor.handle)
  1121. {
  1122. _glfw_dlclose(_glfw.wl.cursor.handle);
  1123. _glfw.wl.cursor.handle = NULL;
  1124. }
  1125. if (_glfw.wl.cursorSurface)
  1126. wl_surface_destroy(_glfw.wl.cursorSurface);
  1127. if (_glfw.wl.subcompositor)
  1128. wl_subcompositor_destroy(_glfw.wl.subcompositor);
  1129. if (_glfw.wl.compositor)
  1130. wl_compositor_destroy(_glfw.wl.compositor);
  1131. if (_glfw.wl.shm)
  1132. wl_shm_destroy(_glfw.wl.shm);
  1133. if (_glfw.wl.viewporter)
  1134. wp_viewporter_destroy(_glfw.wl.viewporter);
  1135. if (_glfw.wl.decorationManager)
  1136. zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager);
  1137. if (_glfw.wl.wmBase)
  1138. xdg_wm_base_destroy(_glfw.wl.wmBase);
  1139. if (_glfw.wl.dataSource)
  1140. wl_data_source_destroy(_glfw.wl.dataSource);
  1141. if (_glfw.wl.dataDevice)
  1142. wl_data_device_destroy(_glfw.wl.dataDevice);
  1143. if (_glfw.wl.dataOffer)
  1144. wl_data_offer_destroy(_glfw.wl.dataOffer);
  1145. if (_glfw.wl.dataDeviceManager)
  1146. wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager);
  1147. if (_glfw.wl.pointer)
  1148. wl_pointer_destroy(_glfw.wl.pointer);
  1149. if (_glfw.wl.keyboard)
  1150. wl_keyboard_destroy(_glfw.wl.keyboard);
  1151. if (_glfw.wl.seat)
  1152. wl_seat_destroy(_glfw.wl.seat);
  1153. if (_glfw.wl.relativePointerManager)
  1154. zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager);
  1155. if (_glfw.wl.pointerConstraints)
  1156. zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints);
  1157. if (_glfw.wl.idleInhibitManager)
  1158. zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager);
  1159. if (_glfw.wl.registry)
  1160. wl_registry_destroy(_glfw.wl.registry);
  1161. if (_glfw.wl.display)
  1162. {
  1163. wl_display_flush(_glfw.wl.display);
  1164. wl_display_disconnect(_glfw.wl.display);
  1165. }
  1166. if (_glfw.wl.timerfd >= 0)
  1167. close(_glfw.wl.timerfd);
  1168. if (_glfw.wl.cursorTimerfd >= 0)
  1169. close(_glfw.wl.cursorTimerfd);
  1170. if (_glfw.wl.clipboardString)
  1171. free(_glfw.wl.clipboardString);
  1172. if (_glfw.wl.clipboardSendString)
  1173. free(_glfw.wl.clipboardSendString);
  1174. }
  1175. const char* _glfwPlatformGetVersionString(void)
  1176. {
  1177. return _GLFW_VERSION_NUMBER " Wayland EGL OSMesa"
  1178. #if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK)
  1179. " clock_gettime"
  1180. #else
  1181. " gettimeofday"
  1182. #endif
  1183. " evdev"
  1184. #if defined(_GLFW_BUILD_DLL)
  1185. " shared"
  1186. #endif
  1187. ;
  1188. }