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