Atlas - wl_init.c

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