wl_init.c (45125B)
1 //======================================================================== 2 // GLFW 3.4 Wayland (modified for raylib) - www.glfw.org; www.raylib.com 3 //------------------------------------------------------------------------ 4 // Copyright (c) 2014 Jonas Ã…dahl <jadahl@gmail.com> 5 // Copyright (c) 2024 M374LX <wilsalx@gmail.com> 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 #if defined(_GLFW_WAYLAND) 31 32 #include <errno.h> 33 #include <limits.h> 34 #include <linux/input.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <sys/mman.h> 39 #include <sys/timerfd.h> 40 #include <unistd.h> 41 #include <time.h> 42 #include <assert.h> 43 44 #include "wayland-client-protocol.h" 45 #include "xdg-shell-client-protocol.h" 46 #include "xdg-decoration-unstable-v1-client-protocol.h" 47 #include "viewporter-client-protocol.h" 48 #include "relative-pointer-unstable-v1-client-protocol.h" 49 #include "pointer-constraints-unstable-v1-client-protocol.h" 50 #include "fractional-scale-v1-client-protocol.h" 51 #include "xdg-activation-v1-client-protocol.h" 52 #include "idle-inhibit-unstable-v1-client-protocol.h" 53 54 // NOTE: Versions of wayland-scanner prior to 1.17.91 named every global array of 55 // wl_interface pointers 'types', making it impossible to combine several unmodified 56 // private-code files into a single compilation unit 57 // HACK: We override this name with a macro for each file, allowing them to coexist 58 59 #define types _glfw_wayland_types 60 #include "wayland-client-protocol-code.h" 61 #undef types 62 63 #define types _glfw_xdg_shell_types 64 #include "xdg-shell-client-protocol-code.h" 65 #undef types 66 67 #define types _glfw_xdg_decoration_types 68 #include "xdg-decoration-unstable-v1-client-protocol-code.h" 69 #undef types 70 71 #define types _glfw_viewporter_types 72 #include "viewporter-client-protocol-code.h" 73 #undef types 74 75 #define types _glfw_relative_pointer_types 76 #include "relative-pointer-unstable-v1-client-protocol-code.h" 77 #undef types 78 79 #define types _glfw_pointer_constraints_types 80 #include "pointer-constraints-unstable-v1-client-protocol-code.h" 81 #undef types 82 83 #define types _glfw_fractional_scale_types 84 #include "fractional-scale-v1-client-protocol-code.h" 85 #undef types 86 87 #define types _glfw_xdg_activation_types 88 #include "xdg-activation-v1-client-protocol-code.h" 89 #undef types 90 91 #define types _glfw_idle_inhibit_types 92 #include "idle-inhibit-unstable-v1-client-protocol-code.h" 93 #undef types 94 95 static void wmBaseHandlePing(void* userData, 96 struct xdg_wm_base* wmBase, 97 uint32_t serial) 98 { 99 xdg_wm_base_pong(wmBase, serial); 100 } 101 102 static const struct xdg_wm_base_listener wmBaseListener = 103 { 104 wmBaseHandlePing 105 }; 106 107 static void registryHandleGlobal(void* userData, 108 struct wl_registry* registry, 109 uint32_t name, 110 const char* interface, 111 uint32_t version) 112 { 113 if (strcmp(interface, "wl_compositor") == 0) 114 { 115 _glfw.wl.compositor = 116 wl_registry_bind(registry, name, &wl_compositor_interface, 117 _glfw_min(3, version)); 118 } 119 else if (strcmp(interface, "wl_subcompositor") == 0) 120 { 121 _glfw.wl.subcompositor = 122 wl_registry_bind(registry, name, &wl_subcompositor_interface, 1); 123 } 124 else if (strcmp(interface, "wl_shm") == 0) 125 { 126 _glfw.wl.shm = 127 wl_registry_bind(registry, name, &wl_shm_interface, 1); 128 } 129 else if (strcmp(interface, "wl_output") == 0) 130 { 131 _glfwAddOutputWayland(name, version); 132 } 133 else if (strcmp(interface, "wl_seat") == 0) 134 { 135 if (!_glfw.wl.seat) 136 { 137 _glfw.wl.seat = 138 wl_registry_bind(registry, name, &wl_seat_interface, 139 _glfw_min(4, version)); 140 _glfwAddSeatListenerWayland(_glfw.wl.seat); 141 } 142 } 143 else if (strcmp(interface, "wl_data_device_manager") == 0) 144 { 145 if (!_glfw.wl.dataDeviceManager) 146 { 147 _glfw.wl.dataDeviceManager = 148 wl_registry_bind(registry, name, 149 &wl_data_device_manager_interface, 1); 150 } 151 } 152 else if (strcmp(interface, "xdg_wm_base") == 0) 153 { 154 _glfw.wl.wmBase = 155 wl_registry_bind(registry, name, &xdg_wm_base_interface, 1); 156 xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL); 157 } 158 else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) 159 { 160 _glfw.wl.decorationManager = 161 wl_registry_bind(registry, name, 162 &zxdg_decoration_manager_v1_interface, 163 1); 164 } 165 else if (strcmp(interface, "wp_viewporter") == 0) 166 { 167 _glfw.wl.viewporter = 168 wl_registry_bind(registry, name, &wp_viewporter_interface, 1); 169 } 170 else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) 171 { 172 _glfw.wl.relativePointerManager = 173 wl_registry_bind(registry, name, 174 &zwp_relative_pointer_manager_v1_interface, 175 1); 176 } 177 else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) 178 { 179 _glfw.wl.pointerConstraints = 180 wl_registry_bind(registry, name, 181 &zwp_pointer_constraints_v1_interface, 182 1); 183 } 184 else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) 185 { 186 _glfw.wl.idleInhibitManager = 187 wl_registry_bind(registry, name, 188 &zwp_idle_inhibit_manager_v1_interface, 189 1); 190 } 191 else if (strcmp(interface, "xdg_activation_v1") == 0) 192 { 193 _glfw.wl.activationManager = 194 wl_registry_bind(registry, name, 195 &xdg_activation_v1_interface, 196 1); 197 } 198 else if (strcmp(interface, "wp_fractional_scale_manager_v1") == 0) 199 { 200 _glfw.wl.fractionalScaleManager = 201 wl_registry_bind(registry, name, 202 &wp_fractional_scale_manager_v1_interface, 203 1); 204 } 205 } 206 207 static void registryHandleGlobalRemove(void* userData, 208 struct wl_registry* registry, 209 uint32_t name) 210 { 211 for (int i = 0; i < _glfw.monitorCount; ++i) 212 { 213 _GLFWmonitor* monitor = _glfw.monitors[i]; 214 if (monitor->wl.name == name) 215 { 216 _glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0); 217 return; 218 } 219 } 220 } 221 222 223 static const struct wl_registry_listener registryListener = 224 { 225 registryHandleGlobal, 226 registryHandleGlobalRemove 227 }; 228 229 void libdecorHandleError(struct libdecor* context, 230 enum libdecor_error error, 231 const char* message) 232 { 233 _glfwInputError(GLFW_PLATFORM_ERROR, 234 "Wayland: libdecor error %u: %s", 235 error, message); 236 } 237 238 static const struct libdecor_interface libdecorInterface = 239 { 240 libdecorHandleError 241 }; 242 243 static void libdecorReadyCallback(void* userData, 244 struct wl_callback* callback, 245 uint32_t time) 246 { 247 _glfw.wl.libdecor.ready = GLFW_TRUE; 248 249 assert(_glfw.wl.libdecor.callback == callback); 250 wl_callback_destroy(_glfw.wl.libdecor.callback); 251 _glfw.wl.libdecor.callback = NULL; 252 } 253 254 static const struct wl_callback_listener libdecorReadyListener = 255 { 256 libdecorReadyCallback 257 }; 258 259 // Create key code translation tables 260 // 261 static void createKeyTablesWayland(void) 262 { 263 memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes)); 264 memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes)); 265 266 _glfw.wl.keycodes[KEY_GRAVE] = GLFW_KEY_GRAVE_ACCENT; 267 _glfw.wl.keycodes[KEY_1] = GLFW_KEY_1; 268 _glfw.wl.keycodes[KEY_2] = GLFW_KEY_2; 269 _glfw.wl.keycodes[KEY_3] = GLFW_KEY_3; 270 _glfw.wl.keycodes[KEY_4] = GLFW_KEY_4; 271 _glfw.wl.keycodes[KEY_5] = GLFW_KEY_5; 272 _glfw.wl.keycodes[KEY_6] = GLFW_KEY_6; 273 _glfw.wl.keycodes[KEY_7] = GLFW_KEY_7; 274 _glfw.wl.keycodes[KEY_8] = GLFW_KEY_8; 275 _glfw.wl.keycodes[KEY_9] = GLFW_KEY_9; 276 _glfw.wl.keycodes[KEY_0] = GLFW_KEY_0; 277 _glfw.wl.keycodes[KEY_SPACE] = GLFW_KEY_SPACE; 278 _glfw.wl.keycodes[KEY_MINUS] = GLFW_KEY_MINUS; 279 _glfw.wl.keycodes[KEY_EQUAL] = GLFW_KEY_EQUAL; 280 _glfw.wl.keycodes[KEY_Q] = GLFW_KEY_Q; 281 _glfw.wl.keycodes[KEY_W] = GLFW_KEY_W; 282 _glfw.wl.keycodes[KEY_E] = GLFW_KEY_E; 283 _glfw.wl.keycodes[KEY_R] = GLFW_KEY_R; 284 _glfw.wl.keycodes[KEY_T] = GLFW_KEY_T; 285 _glfw.wl.keycodes[KEY_Y] = GLFW_KEY_Y; 286 _glfw.wl.keycodes[KEY_U] = GLFW_KEY_U; 287 _glfw.wl.keycodes[KEY_I] = GLFW_KEY_I; 288 _glfw.wl.keycodes[KEY_O] = GLFW_KEY_O; 289 _glfw.wl.keycodes[KEY_P] = GLFW_KEY_P; 290 _glfw.wl.keycodes[KEY_LEFTBRACE] = GLFW_KEY_LEFT_BRACKET; 291 _glfw.wl.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET; 292 _glfw.wl.keycodes[KEY_A] = GLFW_KEY_A; 293 _glfw.wl.keycodes[KEY_S] = GLFW_KEY_S; 294 _glfw.wl.keycodes[KEY_D] = GLFW_KEY_D; 295 _glfw.wl.keycodes[KEY_F] = GLFW_KEY_F; 296 _glfw.wl.keycodes[KEY_G] = GLFW_KEY_G; 297 _glfw.wl.keycodes[KEY_H] = GLFW_KEY_H; 298 _glfw.wl.keycodes[KEY_J] = GLFW_KEY_J; 299 _glfw.wl.keycodes[KEY_K] = GLFW_KEY_K; 300 _glfw.wl.keycodes[KEY_L] = GLFW_KEY_L; 301 _glfw.wl.keycodes[KEY_SEMICOLON] = GLFW_KEY_SEMICOLON; 302 _glfw.wl.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE; 303 _glfw.wl.keycodes[KEY_Z] = GLFW_KEY_Z; 304 _glfw.wl.keycodes[KEY_X] = GLFW_KEY_X; 305 _glfw.wl.keycodes[KEY_C] = GLFW_KEY_C; 306 _glfw.wl.keycodes[KEY_V] = GLFW_KEY_V; 307 _glfw.wl.keycodes[KEY_B] = GLFW_KEY_B; 308 _glfw.wl.keycodes[KEY_N] = GLFW_KEY_N; 309 _glfw.wl.keycodes[KEY_M] = GLFW_KEY_M; 310 _glfw.wl.keycodes[KEY_COMMA] = GLFW_KEY_COMMA; 311 _glfw.wl.keycodes[KEY_DOT] = GLFW_KEY_PERIOD; 312 _glfw.wl.keycodes[KEY_SLASH] = GLFW_KEY_SLASH; 313 _glfw.wl.keycodes[KEY_BACKSLASH] = GLFW_KEY_BACKSLASH; 314 _glfw.wl.keycodes[KEY_ESC] = GLFW_KEY_ESCAPE; 315 _glfw.wl.keycodes[KEY_TAB] = GLFW_KEY_TAB; 316 _glfw.wl.keycodes[KEY_LEFTSHIFT] = GLFW_KEY_LEFT_SHIFT; 317 _glfw.wl.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT; 318 _glfw.wl.keycodes[KEY_LEFTCTRL] = GLFW_KEY_LEFT_CONTROL; 319 _glfw.wl.keycodes[KEY_RIGHTCTRL] = GLFW_KEY_RIGHT_CONTROL; 320 _glfw.wl.keycodes[KEY_LEFTALT] = GLFW_KEY_LEFT_ALT; 321 _glfw.wl.keycodes[KEY_RIGHTALT] = GLFW_KEY_RIGHT_ALT; 322 _glfw.wl.keycodes[KEY_LEFTMETA] = GLFW_KEY_LEFT_SUPER; 323 _glfw.wl.keycodes[KEY_RIGHTMETA] = GLFW_KEY_RIGHT_SUPER; 324 _glfw.wl.keycodes[KEY_COMPOSE] = GLFW_KEY_MENU; 325 _glfw.wl.keycodes[KEY_NUMLOCK] = GLFW_KEY_NUM_LOCK; 326 _glfw.wl.keycodes[KEY_CAPSLOCK] = GLFW_KEY_CAPS_LOCK; 327 _glfw.wl.keycodes[KEY_PRINT] = GLFW_KEY_PRINT_SCREEN; 328 _glfw.wl.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK; 329 _glfw.wl.keycodes[KEY_PAUSE] = GLFW_KEY_PAUSE; 330 _glfw.wl.keycodes[KEY_DELETE] = GLFW_KEY_DELETE; 331 _glfw.wl.keycodes[KEY_BACKSPACE] = GLFW_KEY_BACKSPACE; 332 _glfw.wl.keycodes[KEY_ENTER] = GLFW_KEY_ENTER; 333 _glfw.wl.keycodes[KEY_HOME] = GLFW_KEY_HOME; 334 _glfw.wl.keycodes[KEY_END] = GLFW_KEY_END; 335 _glfw.wl.keycodes[KEY_PAGEUP] = GLFW_KEY_PAGE_UP; 336 _glfw.wl.keycodes[KEY_PAGEDOWN] = GLFW_KEY_PAGE_DOWN; 337 _glfw.wl.keycodes[KEY_INSERT] = GLFW_KEY_INSERT; 338 _glfw.wl.keycodes[KEY_LEFT] = GLFW_KEY_LEFT; 339 _glfw.wl.keycodes[KEY_RIGHT] = GLFW_KEY_RIGHT; 340 _glfw.wl.keycodes[KEY_DOWN] = GLFW_KEY_DOWN; 341 _glfw.wl.keycodes[KEY_UP] = GLFW_KEY_UP; 342 _glfw.wl.keycodes[KEY_F1] = GLFW_KEY_F1; 343 _glfw.wl.keycodes[KEY_F2] = GLFW_KEY_F2; 344 _glfw.wl.keycodes[KEY_F3] = GLFW_KEY_F3; 345 _glfw.wl.keycodes[KEY_F4] = GLFW_KEY_F4; 346 _glfw.wl.keycodes[KEY_F5] = GLFW_KEY_F5; 347 _glfw.wl.keycodes[KEY_F6] = GLFW_KEY_F6; 348 _glfw.wl.keycodes[KEY_F7] = GLFW_KEY_F7; 349 _glfw.wl.keycodes[KEY_F8] = GLFW_KEY_F8; 350 _glfw.wl.keycodes[KEY_F9] = GLFW_KEY_F9; 351 _glfw.wl.keycodes[KEY_F10] = GLFW_KEY_F10; 352 _glfw.wl.keycodes[KEY_F11] = GLFW_KEY_F11; 353 _glfw.wl.keycodes[KEY_F12] = GLFW_KEY_F12; 354 _glfw.wl.keycodes[KEY_F13] = GLFW_KEY_F13; 355 _glfw.wl.keycodes[KEY_F14] = GLFW_KEY_F14; 356 _glfw.wl.keycodes[KEY_F15] = GLFW_KEY_F15; 357 _glfw.wl.keycodes[KEY_F16] = GLFW_KEY_F16; 358 _glfw.wl.keycodes[KEY_F17] = GLFW_KEY_F17; 359 _glfw.wl.keycodes[KEY_F18] = GLFW_KEY_F18; 360 _glfw.wl.keycodes[KEY_F19] = GLFW_KEY_F19; 361 _glfw.wl.keycodes[KEY_F20] = GLFW_KEY_F20; 362 _glfw.wl.keycodes[KEY_F21] = GLFW_KEY_F21; 363 _glfw.wl.keycodes[KEY_F22] = GLFW_KEY_F22; 364 _glfw.wl.keycodes[KEY_F23] = GLFW_KEY_F23; 365 _glfw.wl.keycodes[KEY_F24] = GLFW_KEY_F24; 366 _glfw.wl.keycodes[KEY_KPSLASH] = GLFW_KEY_KP_DIVIDE; 367 _glfw.wl.keycodes[KEY_KPASTERISK] = GLFW_KEY_KP_MULTIPLY; 368 _glfw.wl.keycodes[KEY_KPMINUS] = GLFW_KEY_KP_SUBTRACT; 369 _glfw.wl.keycodes[KEY_KPPLUS] = GLFW_KEY_KP_ADD; 370 _glfw.wl.keycodes[KEY_KP0] = GLFW_KEY_KP_0; 371 _glfw.wl.keycodes[KEY_KP1] = GLFW_KEY_KP_1; 372 _glfw.wl.keycodes[KEY_KP2] = GLFW_KEY_KP_2; 373 _glfw.wl.keycodes[KEY_KP3] = GLFW_KEY_KP_3; 374 _glfw.wl.keycodes[KEY_KP4] = GLFW_KEY_KP_4; 375 _glfw.wl.keycodes[KEY_KP5] = GLFW_KEY_KP_5; 376 _glfw.wl.keycodes[KEY_KP6] = GLFW_KEY_KP_6; 377 _glfw.wl.keycodes[KEY_KP7] = GLFW_KEY_KP_7; 378 _glfw.wl.keycodes[KEY_KP8] = GLFW_KEY_KP_8; 379 _glfw.wl.keycodes[KEY_KP9] = GLFW_KEY_KP_9; 380 _glfw.wl.keycodes[KEY_KPDOT] = GLFW_KEY_KP_DECIMAL; 381 _glfw.wl.keycodes[KEY_KPEQUAL] = GLFW_KEY_KP_EQUAL; 382 _glfw.wl.keycodes[KEY_KPENTER] = GLFW_KEY_KP_ENTER; 383 _glfw.wl.keycodes[KEY_102ND] = GLFW_KEY_WORLD_2; 384 385 for (int scancode = 0; scancode < 256; scancode++) 386 { 387 if (_glfw.wl.keycodes[scancode] > 0) 388 _glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode; 389 } 390 } 391 392 static GLFWbool loadCursorTheme(void) 393 { 394 int cursorSize = 16; 395 396 const char* sizeString = getenv("XCURSOR_SIZE"); 397 if (sizeString) 398 { 399 errno = 0; 400 const long cursorSizeLong = strtol(sizeString, NULL, 10); 401 if (errno == 0 && cursorSizeLong > 0 && cursorSizeLong < INT_MAX) 402 cursorSize = (int) cursorSizeLong; 403 } 404 405 const char* themeName = getenv("XCURSOR_THEME"); 406 407 _glfw.wl.cursorTheme = wl_cursor_theme_load(themeName, cursorSize, _glfw.wl.shm); 408 if (!_glfw.wl.cursorTheme) 409 { 410 _glfwInputError(GLFW_PLATFORM_ERROR, 411 "Wayland: Failed to load default cursor theme"); 412 return GLFW_FALSE; 413 } 414 415 // If this happens to be NULL, we just fallback to the scale=1 version. 416 _glfw.wl.cursorThemeHiDPI = 417 wl_cursor_theme_load(themeName, cursorSize * 2, _glfw.wl.shm); 418 419 _glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor); 420 _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); 421 return GLFW_TRUE; 422 } 423 424 425 ////////////////////////////////////////////////////////////////////////// 426 ////// GLFW platform API ////// 427 ////////////////////////////////////////////////////////////////////////// 428 429 GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform) 430 { 431 const _GLFWplatform wayland = 432 { 433 .platformID = GLFW_PLATFORM_WAYLAND, 434 .init = _glfwInitWayland, 435 .terminate = _glfwTerminateWayland, 436 .getCursorPos = _glfwGetCursorPosWayland, 437 .setCursorPos = _glfwSetCursorPosWayland, 438 .setCursorMode = _glfwSetCursorModeWayland, 439 .setRawMouseMotion = _glfwSetRawMouseMotionWayland, 440 .rawMouseMotionSupported = _glfwRawMouseMotionSupportedWayland, 441 .createCursor = _glfwCreateCursorWayland, 442 .createStandardCursor = _glfwCreateStandardCursorWayland, 443 .destroyCursor = _glfwDestroyCursorWayland, 444 .setCursor = _glfwSetCursorWayland, 445 .getScancodeName = _glfwGetScancodeNameWayland, 446 .getKeyScancode = _glfwGetKeyScancodeWayland, 447 .setClipboardString = _glfwSetClipboardStringWayland, 448 .getClipboardString = _glfwGetClipboardStringWayland, 449 #if defined(GLFW_BUILD_LINUX_JOYSTICK) 450 .initJoysticks = _glfwInitJoysticksLinux, 451 .terminateJoysticks = _glfwTerminateJoysticksLinux, 452 .pollJoystick = _glfwPollJoystickLinux, 453 .getMappingName = _glfwGetMappingNameLinux, 454 .updateGamepadGUID = _glfwUpdateGamepadGUIDLinux, 455 #else 456 .initJoysticks = _glfwInitJoysticksNull, 457 .terminateJoysticks = _glfwTerminateJoysticksNull, 458 .pollJoystick = _glfwPollJoystickNull, 459 .getMappingName = _glfwGetMappingNameNull, 460 .updateGamepadGUID = _glfwUpdateGamepadGUIDNull, 461 #endif 462 .freeMonitor = _glfwFreeMonitorWayland, 463 .getMonitorPos = _glfwGetMonitorPosWayland, 464 .getMonitorContentScale = _glfwGetMonitorContentScaleWayland, 465 .getMonitorWorkarea = _glfwGetMonitorWorkareaWayland, 466 .getVideoModes = _glfwGetVideoModesWayland, 467 .getVideoMode = _glfwGetVideoModeWayland, 468 .getGammaRamp = _glfwGetGammaRampWayland, 469 .setGammaRamp = _glfwSetGammaRampWayland, 470 .createWindow = _glfwCreateWindowWayland, 471 .destroyWindow = _glfwDestroyWindowWayland, 472 .setWindowTitle = _glfwSetWindowTitleWayland, 473 .setWindowIcon = _glfwSetWindowIconWayland, 474 .getWindowPos = _glfwGetWindowPosWayland, 475 .setWindowPos = _glfwSetWindowPosWayland, 476 .getWindowSize = _glfwGetWindowSizeWayland, 477 .setWindowSize = _glfwSetWindowSizeWayland, 478 .setWindowSizeLimits = _glfwSetWindowSizeLimitsWayland, 479 .setWindowAspectRatio = _glfwSetWindowAspectRatioWayland, 480 .getFramebufferSize = _glfwGetFramebufferSizeWayland, 481 .getWindowFrameSize = _glfwGetWindowFrameSizeWayland, 482 .getWindowContentScale = _glfwGetWindowContentScaleWayland, 483 .iconifyWindow = _glfwIconifyWindowWayland, 484 .restoreWindow = _glfwRestoreWindowWayland, 485 .maximizeWindow = _glfwMaximizeWindowWayland, 486 .showWindow = _glfwShowWindowWayland, 487 .hideWindow = _glfwHideWindowWayland, 488 .requestWindowAttention = _glfwRequestWindowAttentionWayland, 489 .focusWindow = _glfwFocusWindowWayland, 490 .setWindowMonitor = _glfwSetWindowMonitorWayland, 491 .windowFocused = _glfwWindowFocusedWayland, 492 .windowIconified = _glfwWindowIconifiedWayland, 493 .windowVisible = _glfwWindowVisibleWayland, 494 .windowMaximized = _glfwWindowMaximizedWayland, 495 .windowHovered = _glfwWindowHoveredWayland, 496 .framebufferTransparent = _glfwFramebufferTransparentWayland, 497 .getWindowOpacity = _glfwGetWindowOpacityWayland, 498 .setWindowResizable = _glfwSetWindowResizableWayland, 499 .setWindowDecorated = _glfwSetWindowDecoratedWayland, 500 .setWindowFloating = _glfwSetWindowFloatingWayland, 501 .setWindowOpacity = _glfwSetWindowOpacityWayland, 502 .setWindowMousePassthrough = _glfwSetWindowMousePassthroughWayland, 503 .pollEvents = _glfwPollEventsWayland, 504 .waitEvents = _glfwWaitEventsWayland, 505 .waitEventsTimeout = _glfwWaitEventsTimeoutWayland, 506 .postEmptyEvent = _glfwPostEmptyEventWayland, 507 .getEGLPlatform = _glfwGetEGLPlatformWayland, 508 .getEGLNativeDisplay = _glfwGetEGLNativeDisplayWayland, 509 .getEGLNativeWindow = _glfwGetEGLNativeWindowWayland, 510 .getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWayland, 511 .getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWayland, 512 .createWindowSurface = _glfwCreateWindowSurfaceWayland 513 }; 514 515 void* module = _glfwPlatformLoadModule("libwayland-client.so.0"); 516 if (!module) 517 { 518 if (platformID == GLFW_PLATFORM_WAYLAND) 519 { 520 _glfwInputError(GLFW_PLATFORM_ERROR, 521 "Wayland: Failed to load libwayland-client"); 522 } 523 524 return GLFW_FALSE; 525 } 526 527 PFN_wl_display_connect wl_display_connect = (PFN_wl_display_connect) 528 _glfwPlatformGetModuleSymbol(module, "wl_display_connect"); 529 if (!wl_display_connect) 530 { 531 if (platformID == GLFW_PLATFORM_WAYLAND) 532 { 533 _glfwInputError(GLFW_PLATFORM_ERROR, 534 "Wayland: Failed to load libwayland-client entry point"); 535 } 536 537 _glfwPlatformFreeModule(module); 538 return GLFW_FALSE; 539 } 540 541 struct wl_display* display = wl_display_connect(NULL); 542 if (!display) 543 { 544 if (platformID == GLFW_PLATFORM_WAYLAND) 545 _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to connect to display"); 546 547 _glfwPlatformFreeModule(module); 548 return GLFW_FALSE; 549 } 550 551 _glfw.wl.display = display; 552 _glfw.wl.client.handle = module; 553 554 *platform = wayland; 555 return GLFW_TRUE; 556 } 557 558 int _glfwInitWayland(void) 559 { 560 // These must be set before any failure checks 561 _glfw.wl.keyRepeatTimerfd = -1; 562 _glfw.wl.cursorTimerfd = -1; 563 564 _glfw.wl.tag = glfwGetVersionString(); 565 566 _glfw.wl.client.display_flush = (PFN_wl_display_flush) 567 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush"); 568 _glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read) 569 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_cancel_read"); 570 _glfw.wl.client.display_dispatch_pending = (PFN_wl_display_dispatch_pending) 571 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_dispatch_pending"); 572 _glfw.wl.client.display_read_events = (PFN_wl_display_read_events) 573 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_read_events"); 574 _glfw.wl.client.display_disconnect = (PFN_wl_display_disconnect) 575 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_disconnect"); 576 _glfw.wl.client.display_roundtrip = (PFN_wl_display_roundtrip) 577 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_roundtrip"); 578 _glfw.wl.client.display_get_fd = (PFN_wl_display_get_fd) 579 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_get_fd"); 580 _glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read) 581 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read"); 582 _glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal) 583 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal"); 584 _glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener) 585 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_add_listener"); 586 _glfw.wl.client.proxy_destroy = (PFN_wl_proxy_destroy) 587 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_destroy"); 588 _glfw.wl.client.proxy_marshal_constructor = (PFN_wl_proxy_marshal_constructor) 589 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor"); 590 _glfw.wl.client.proxy_marshal_constructor_versioned = (PFN_wl_proxy_marshal_constructor_versioned) 591 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor_versioned"); 592 _glfw.wl.client.proxy_get_user_data = (PFN_wl_proxy_get_user_data) 593 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data"); 594 _glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data) 595 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data"); 596 _glfw.wl.client.proxy_get_tag = (PFN_wl_proxy_get_tag) 597 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_tag"); 598 _glfw.wl.client.proxy_set_tag = (PFN_wl_proxy_set_tag) 599 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_tag"); 600 _glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version) 601 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version"); 602 _glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags) 603 _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_flags"); 604 605 if (!_glfw.wl.client.display_flush || 606 !_glfw.wl.client.display_cancel_read || 607 !_glfw.wl.client.display_dispatch_pending || 608 !_glfw.wl.client.display_read_events || 609 !_glfw.wl.client.display_disconnect || 610 !_glfw.wl.client.display_roundtrip || 611 !_glfw.wl.client.display_get_fd || 612 !_glfw.wl.client.display_prepare_read || 613 !_glfw.wl.client.proxy_marshal || 614 !_glfw.wl.client.proxy_add_listener || 615 !_glfw.wl.client.proxy_destroy || 616 !_glfw.wl.client.proxy_marshal_constructor || 617 !_glfw.wl.client.proxy_marshal_constructor_versioned || 618 !_glfw.wl.client.proxy_get_user_data || 619 !_glfw.wl.client.proxy_set_user_data || 620 !_glfw.wl.client.proxy_get_tag || 621 !_glfw.wl.client.proxy_set_tag) 622 { 623 _glfwInputError(GLFW_PLATFORM_ERROR, 624 "Wayland: Failed to load libwayland-client entry point"); 625 return GLFW_FALSE; 626 } 627 628 _glfw.wl.cursor.handle = _glfwPlatformLoadModule("libwayland-cursor.so.0"); 629 if (!_glfw.wl.cursor.handle) 630 { 631 _glfwInputError(GLFW_PLATFORM_ERROR, 632 "Wayland: Failed to load libwayland-cursor"); 633 return GLFW_FALSE; 634 } 635 636 _glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load) 637 _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_load"); 638 _glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy) 639 _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy"); 640 _glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor) 641 _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor"); 642 _glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer) 643 _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer"); 644 645 _glfw.wl.egl.handle = _glfwPlatformLoadModule("libwayland-egl.so.1"); 646 if (!_glfw.wl.egl.handle) 647 { 648 _glfwInputError(GLFW_PLATFORM_ERROR, 649 "Wayland: Failed to load libwayland-egl"); 650 return GLFW_FALSE; 651 } 652 653 _glfw.wl.egl.window_create = (PFN_wl_egl_window_create) 654 _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_create"); 655 _glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy) 656 _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_destroy"); 657 _glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize) 658 _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_resize"); 659 660 _glfw.wl.xkb.handle = _glfwPlatformLoadModule("libxkbcommon.so.0"); 661 if (!_glfw.wl.xkb.handle) 662 { 663 _glfwInputError(GLFW_PLATFORM_ERROR, 664 "Wayland: Failed to load libxkbcommon"); 665 return GLFW_FALSE; 666 } 667 668 _glfw.wl.xkb.context_new = (PFN_xkb_context_new) 669 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_new"); 670 _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref) 671 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_unref"); 672 _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string) 673 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string"); 674 _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref) 675 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_unref"); 676 _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index) 677 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index"); 678 _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats) 679 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats"); 680 _glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level) 681 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level"); 682 _glfw.wl.xkb.state_new = (PFN_xkb_state_new) 683 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new"); 684 _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref) 685 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_unref"); 686 _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms) 687 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_syms"); 688 _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask) 689 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask"); 690 _glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout) 691 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout"); 692 _glfw.wl.xkb.state_mod_index_is_active = (PFN_xkb_state_mod_index_is_active) 693 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_mod_index_is_active"); 694 _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale) 695 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale"); 696 _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref) 697 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_unref"); 698 _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new) 699 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_new"); 700 _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref) 701 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_unref"); 702 _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed) 703 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_feed"); 704 _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status) 705 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status"); 706 _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym) 707 _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym"); 708 709 if (!_glfw.wl.xkb.context_new || 710 !_glfw.wl.xkb.context_unref || 711 !_glfw.wl.xkb.keymap_new_from_string || 712 !_glfw.wl.xkb.keymap_unref || 713 !_glfw.wl.xkb.keymap_mod_get_index || 714 !_glfw.wl.xkb.keymap_key_repeats || 715 !_glfw.wl.xkb.keymap_key_get_syms_by_level || 716 !_glfw.wl.xkb.state_new || 717 !_glfw.wl.xkb.state_unref || 718 !_glfw.wl.xkb.state_key_get_syms || 719 !_glfw.wl.xkb.state_update_mask || 720 !_glfw.wl.xkb.state_key_get_layout || 721 !_glfw.wl.xkb.state_mod_index_is_active || 722 !_glfw.wl.xkb.compose_table_new_from_locale || 723 !_glfw.wl.xkb.compose_table_unref || 724 !_glfw.wl.xkb.compose_state_new || 725 !_glfw.wl.xkb.compose_state_unref || 726 !_glfw.wl.xkb.compose_state_feed || 727 !_glfw.wl.xkb.compose_state_get_status || 728 !_glfw.wl.xkb.compose_state_get_one_sym) 729 { 730 _glfwInputError(GLFW_PLATFORM_ERROR, 731 "Wayland: Failed to load all entry points from libxkbcommon"); 732 return GLFW_FALSE; 733 } 734 735 if (_glfw.hints.init.wl.libdecorMode == GLFW_WAYLAND_PREFER_LIBDECOR) 736 _glfw.wl.libdecor.handle = _glfwPlatformLoadModule("libdecor-0.so.0"); 737 738 if (_glfw.wl.libdecor.handle) 739 { 740 _glfw.wl.libdecor.libdecor_new_ = (PFN_libdecor_new) 741 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_new"); 742 _glfw.wl.libdecor.libdecor_unref_ = (PFN_libdecor_unref) 743 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_unref"); 744 _glfw.wl.libdecor.libdecor_get_fd_ = (PFN_libdecor_get_fd) 745 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_get_fd"); 746 _glfw.wl.libdecor.libdecor_dispatch_ = (PFN_libdecor_dispatch) 747 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_dispatch"); 748 _glfw.wl.libdecor.libdecor_decorate_ = (PFN_libdecor_decorate) 749 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_decorate"); 750 _glfw.wl.libdecor.libdecor_frame_unref_ = (PFN_libdecor_frame_unref) 751 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unref"); 752 _glfw.wl.libdecor.libdecor_frame_set_app_id_ = (PFN_libdecor_frame_set_app_id) 753 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_app_id"); 754 _glfw.wl.libdecor.libdecor_frame_set_title_ = (PFN_libdecor_frame_set_title) 755 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_title"); 756 _glfw.wl.libdecor.libdecor_frame_set_minimized_ = (PFN_libdecor_frame_set_minimized) 757 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_minimized"); 758 _glfw.wl.libdecor.libdecor_frame_set_fullscreen_ = (PFN_libdecor_frame_set_fullscreen) 759 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_fullscreen"); 760 _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ = (PFN_libdecor_frame_unset_fullscreen) 761 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_fullscreen"); 762 _glfw.wl.libdecor.libdecor_frame_map_ = (PFN_libdecor_frame_map) 763 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_map"); 764 _glfw.wl.libdecor.libdecor_frame_commit_ = (PFN_libdecor_frame_commit) 765 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_commit"); 766 _glfw.wl.libdecor.libdecor_frame_set_min_content_size_ = (PFN_libdecor_frame_set_min_content_size) 767 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_min_content_size"); 768 _glfw.wl.libdecor.libdecor_frame_set_max_content_size_ = (PFN_libdecor_frame_set_max_content_size) 769 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_max_content_size"); 770 _glfw.wl.libdecor.libdecor_frame_set_maximized_ = (PFN_libdecor_frame_set_maximized) 771 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_maximized"); 772 _glfw.wl.libdecor.libdecor_frame_unset_maximized_ = (PFN_libdecor_frame_unset_maximized) 773 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_maximized"); 774 _glfw.wl.libdecor.libdecor_frame_set_capabilities_ = (PFN_libdecor_frame_set_capabilities) 775 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_capabilities"); 776 _glfw.wl.libdecor.libdecor_frame_unset_capabilities_ = (PFN_libdecor_frame_unset_capabilities) 777 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_unset_capabilities"); 778 _glfw.wl.libdecor.libdecor_frame_set_visibility_ = (PFN_libdecor_frame_set_visibility) 779 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_set_visibility"); 780 _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ = (PFN_libdecor_frame_get_xdg_toplevel) 781 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_frame_get_xdg_toplevel"); 782 _glfw.wl.libdecor.libdecor_configuration_get_content_size_ = (PFN_libdecor_configuration_get_content_size) 783 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_content_size"); 784 _glfw.wl.libdecor.libdecor_configuration_get_window_state_ = (PFN_libdecor_configuration_get_window_state) 785 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_configuration_get_window_state"); 786 _glfw.wl.libdecor.libdecor_state_new_ = (PFN_libdecor_state_new) 787 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_new"); 788 _glfw.wl.libdecor.libdecor_state_free_ = (PFN_libdecor_state_free) 789 _glfwPlatformGetModuleSymbol(_glfw.wl.libdecor.handle, "libdecor_state_free"); 790 791 if (!_glfw.wl.libdecor.libdecor_new_ || 792 !_glfw.wl.libdecor.libdecor_unref_ || 793 !_glfw.wl.libdecor.libdecor_get_fd_ || 794 !_glfw.wl.libdecor.libdecor_dispatch_ || 795 !_glfw.wl.libdecor.libdecor_decorate_ || 796 !_glfw.wl.libdecor.libdecor_frame_unref_ || 797 !_glfw.wl.libdecor.libdecor_frame_set_app_id_ || 798 !_glfw.wl.libdecor.libdecor_frame_set_title_ || 799 !_glfw.wl.libdecor.libdecor_frame_set_minimized_ || 800 !_glfw.wl.libdecor.libdecor_frame_set_fullscreen_ || 801 !_glfw.wl.libdecor.libdecor_frame_unset_fullscreen_ || 802 !_glfw.wl.libdecor.libdecor_frame_map_ || 803 !_glfw.wl.libdecor.libdecor_frame_commit_ || 804 !_glfw.wl.libdecor.libdecor_frame_set_min_content_size_ || 805 !_glfw.wl.libdecor.libdecor_frame_set_max_content_size_ || 806 !_glfw.wl.libdecor.libdecor_frame_set_maximized_ || 807 !_glfw.wl.libdecor.libdecor_frame_unset_maximized_ || 808 !_glfw.wl.libdecor.libdecor_frame_set_capabilities_ || 809 !_glfw.wl.libdecor.libdecor_frame_unset_capabilities_ || 810 !_glfw.wl.libdecor.libdecor_frame_set_visibility_ || 811 !_glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_ || 812 !_glfw.wl.libdecor.libdecor_configuration_get_content_size_ || 813 !_glfw.wl.libdecor.libdecor_configuration_get_window_state_ || 814 !_glfw.wl.libdecor.libdecor_state_new_ || 815 !_glfw.wl.libdecor.libdecor_state_free_) 816 { 817 _glfwPlatformFreeModule(_glfw.wl.libdecor.handle); 818 memset(&_glfw.wl.libdecor, 0, sizeof(_glfw.wl.libdecor)); 819 } 820 } 821 822 _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display); 823 wl_registry_add_listener(_glfw.wl.registry, ®istryListener, NULL); 824 825 createKeyTablesWayland(); 826 827 _glfw.wl.xkb.context = xkb_context_new(0); 828 if (!_glfw.wl.xkb.context) 829 { 830 _glfwInputError(GLFW_PLATFORM_ERROR, 831 "Wayland: Failed to initialize xkb context"); 832 return GLFW_FALSE; 833 } 834 835 // Sync so we got all registry objects 836 wl_display_roundtrip(_glfw.wl.display); 837 838 // Sync so we got all initial output events 839 wl_display_roundtrip(_glfw.wl.display); 840 841 if (_glfw.wl.libdecor.handle) 842 { 843 _glfw.wl.libdecor.context = libdecor_new(_glfw.wl.display, &libdecorInterface); 844 if (_glfw.wl.libdecor.context) 845 { 846 // Perform an initial dispatch and flush to get the init started 847 libdecor_dispatch(_glfw.wl.libdecor.context, 0); 848 849 // Create sync point to "know" when libdecor is ready for use 850 _glfw.wl.libdecor.callback = wl_display_sync(_glfw.wl.display); 851 wl_callback_add_listener(_glfw.wl.libdecor.callback, 852 &libdecorReadyListener, 853 NULL); 854 } 855 } 856 857 if (wl_seat_get_version(_glfw.wl.seat) >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) 858 { 859 _glfw.wl.keyRepeatTimerfd = 860 timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK); 861 } 862 863 if (!_glfw.wl.wmBase) 864 { 865 _glfwInputError(GLFW_PLATFORM_ERROR, 866 "Wayland: Failed to find xdg-shell in your compositor"); 867 return GLFW_FALSE; 868 } 869 870 if (!_glfw.wl.shm) 871 { 872 _glfwInputError(GLFW_PLATFORM_ERROR, 873 "Wayland: Failed to find wl_shm in your compositor"); 874 return GLFW_FALSE; 875 } 876 877 if (!loadCursorTheme()) 878 return GLFW_FALSE; 879 880 if (_glfw.wl.seat && _glfw.wl.dataDeviceManager) 881 { 882 _glfw.wl.dataDevice = 883 wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager, 884 _glfw.wl.seat); 885 _glfwAddDataDeviceListenerWayland(_glfw.wl.dataDevice); 886 } 887 888 return GLFW_TRUE; 889 } 890 891 void _glfwTerminateWayland(void) 892 { 893 _glfwTerminateEGL(); 894 _glfwTerminateOSMesa(); 895 896 if (_glfw.wl.libdecor.context) 897 { 898 // Allow libdecor to finish receiving all its requested globals 899 // and ensure the associated sync callback object is destroyed 900 while (!_glfw.wl.libdecor.ready) 901 _glfwWaitEventsWayland(); 902 903 libdecor_unref(_glfw.wl.libdecor.context); 904 } 905 906 if (_glfw.wl.libdecor.handle) 907 { 908 _glfwPlatformFreeModule(_glfw.wl.libdecor.handle); 909 _glfw.wl.libdecor.handle = NULL; 910 } 911 912 if (_glfw.wl.egl.handle) 913 { 914 _glfwPlatformFreeModule(_glfw.wl.egl.handle); 915 _glfw.wl.egl.handle = NULL; 916 } 917 918 if (_glfw.wl.xkb.composeState) 919 xkb_compose_state_unref(_glfw.wl.xkb.composeState); 920 if (_glfw.wl.xkb.keymap) 921 xkb_keymap_unref(_glfw.wl.xkb.keymap); 922 if (_glfw.wl.xkb.state) 923 xkb_state_unref(_glfw.wl.xkb.state); 924 if (_glfw.wl.xkb.context) 925 xkb_context_unref(_glfw.wl.xkb.context); 926 if (_glfw.wl.xkb.handle) 927 { 928 _glfwPlatformFreeModule(_glfw.wl.xkb.handle); 929 _glfw.wl.xkb.handle = NULL; 930 } 931 932 if (_glfw.wl.cursorTheme) 933 wl_cursor_theme_destroy(_glfw.wl.cursorTheme); 934 if (_glfw.wl.cursorThemeHiDPI) 935 wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI); 936 if (_glfw.wl.cursor.handle) 937 { 938 _glfwPlatformFreeModule(_glfw.wl.cursor.handle); 939 _glfw.wl.cursor.handle = NULL; 940 } 941 942 for (unsigned int i = 0; i < _glfw.wl.offerCount; i++) 943 wl_data_offer_destroy(_glfw.wl.offers[i].offer); 944 945 _glfw_free(_glfw.wl.offers); 946 947 if (_glfw.wl.cursorSurface) 948 wl_surface_destroy(_glfw.wl.cursorSurface); 949 if (_glfw.wl.subcompositor) 950 wl_subcompositor_destroy(_glfw.wl.subcompositor); 951 if (_glfw.wl.compositor) 952 wl_compositor_destroy(_glfw.wl.compositor); 953 if (_glfw.wl.shm) 954 wl_shm_destroy(_glfw.wl.shm); 955 if (_glfw.wl.viewporter) 956 wp_viewporter_destroy(_glfw.wl.viewporter); 957 if (_glfw.wl.decorationManager) 958 zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager); 959 if (_glfw.wl.wmBase) 960 xdg_wm_base_destroy(_glfw.wl.wmBase); 961 if (_glfw.wl.selectionOffer) 962 wl_data_offer_destroy(_glfw.wl.selectionOffer); 963 if (_glfw.wl.dragOffer) 964 wl_data_offer_destroy(_glfw.wl.dragOffer); 965 if (_glfw.wl.selectionSource) 966 wl_data_source_destroy(_glfw.wl.selectionSource); 967 if (_glfw.wl.dataDevice) 968 wl_data_device_destroy(_glfw.wl.dataDevice); 969 if (_glfw.wl.dataDeviceManager) 970 wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager); 971 if (_glfw.wl.pointer) 972 wl_pointer_destroy(_glfw.wl.pointer); 973 if (_glfw.wl.keyboard) 974 wl_keyboard_destroy(_glfw.wl.keyboard); 975 if (_glfw.wl.seat) 976 wl_seat_destroy(_glfw.wl.seat); 977 if (_glfw.wl.relativePointerManager) 978 zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager); 979 if (_glfw.wl.pointerConstraints) 980 zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints); 981 if (_glfw.wl.idleInhibitManager) 982 zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager); 983 if (_glfw.wl.activationManager) 984 xdg_activation_v1_destroy(_glfw.wl.activationManager); 985 if (_glfw.wl.fractionalScaleManager) 986 wp_fractional_scale_manager_v1_destroy(_glfw.wl.fractionalScaleManager); 987 if (_glfw.wl.registry) 988 wl_registry_destroy(_glfw.wl.registry); 989 if (_glfw.wl.display) 990 { 991 wl_display_flush(_glfw.wl.display); 992 wl_display_disconnect(_glfw.wl.display); 993 } 994 995 if (_glfw.wl.keyRepeatTimerfd >= 0) 996 close(_glfw.wl.keyRepeatTimerfd); 997 if (_glfw.wl.cursorTimerfd >= 0) 998 close(_glfw.wl.cursorTimerfd); 999 1000 _glfw_free(_glfw.wl.clipboardString); 1001 } 1002 1003 #endif // _GLFW_WAYLAND 1004