github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/raylib/external/glfw/src/wl_init.c (about)

     1  //========================================================================
     2  // GLFW 3.4 Wayland - www.glfw.org
     3  //------------------------------------------------------------------------
     4  // Copyright (c) 2014 Jonas Ã…dahl <jadahl@gmail.com>
     5  //
     6  // This software is provided 'as-is', without any express or implied
     7  // warranty. In no event will the authors be held liable for any damages
     8  // arising from the use of this software.
     9  //
    10  // Permission is granted to anyone to use this software for any purpose,
    11  // including commercial applications, and to alter it and redistribute it
    12  // freely, subject to the following restrictions:
    13  //
    14  // 1. The origin of this software must not be misrepresented; you must not
    15  //    claim that you wrote the original software. If you use this software
    16  //    in a product, an acknowledgment in the product documentation would
    17  //    be appreciated but is not required.
    18  //
    19  // 2. Altered source versions must be plainly marked as such, and must not
    20  //    be misrepresented as being the original software.
    21  //
    22  // 3. This notice may not be removed or altered from any source
    23  //    distribution.
    24  //
    25  //========================================================================
    26  // It is fine to use C99 in this file because it will not be built with VS
    27  //========================================================================
    28  
    29  #include "internal.h"
    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  
    42  #include "wayland-client-protocol.h"
    43  #include "wayland-xdg-shell-client-protocol.h"
    44  #include "wayland-xdg-decoration-client-protocol.h"
    45  #include "wayland-viewporter-client-protocol.h"
    46  #include "wayland-relative-pointer-unstable-v1-client-protocol.h"
    47  #include "wayland-pointer-constraints-unstable-v1-client-protocol.h"
    48  #include "wayland-idle-inhibit-unstable-v1-client-protocol.h"
    49  
    50  // NOTE: Versions of wayland-scanner prior to 1.17.91 named every global array of
    51  //       wl_interface pointers 'types', making it impossible to combine several unmodified
    52  //       private-code files into a single compilation unit
    53  // HACK: We override this name with a macro for each file, allowing them to coexist
    54  
    55  #define types _glfw_wayland_types
    56  #include "wayland-client-protocol-code.h"
    57  #undef types
    58  
    59  #define types _glfw_xdg_shell_types
    60  #include "wayland-xdg-shell-client-protocol-code.h"
    61  #undef types
    62  
    63  #define types _glfw_xdg_decoration_types
    64  #include "wayland-xdg-decoration-client-protocol-code.h"
    65  #undef types
    66  
    67  #define types _glfw_viewporter_types
    68  #include "wayland-viewporter-client-protocol-code.h"
    69  #undef types
    70  
    71  #define types _glfw_relative_pointer_types
    72  #include "wayland-relative-pointer-unstable-v1-client-protocol-code.h"
    73  #undef types
    74  
    75  #define types _glfw_pointer_constraints_types
    76  #include "wayland-pointer-constraints-unstable-v1-client-protocol-code.h"
    77  #undef types
    78  
    79  #define types _glfw_idle_inhibit_types
    80  #include "wayland-idle-inhibit-unstable-v1-client-protocol-code.h"
    81  #undef types
    82  
    83  static void wmBaseHandlePing(void* userData,
    84                               struct xdg_wm_base* wmBase,
    85                               uint32_t serial)
    86  {
    87      xdg_wm_base_pong(wmBase, serial);
    88  }
    89  
    90  static const struct xdg_wm_base_listener wmBaseListener =
    91  {
    92      wmBaseHandlePing
    93  };
    94  
    95  static void registryHandleGlobal(void* userData,
    96                                   struct wl_registry* registry,
    97                                   uint32_t name,
    98                                   const char* interface,
    99                                   uint32_t version)
   100  {
   101      if (strcmp(interface, "wl_compositor") == 0)
   102      {
   103          _glfw.wl.compositorVersion = _glfw_min(3, version);
   104          _glfw.wl.compositor =
   105              wl_registry_bind(registry, name, &wl_compositor_interface,
   106                               _glfw.wl.compositorVersion);
   107      }
   108      else if (strcmp(interface, "wl_subcompositor") == 0)
   109      {
   110          _glfw.wl.subcompositor =
   111              wl_registry_bind(registry, name, &wl_subcompositor_interface, 1);
   112      }
   113      else if (strcmp(interface, "wl_shm") == 0)
   114      {
   115          _glfw.wl.shm =
   116              wl_registry_bind(registry, name, &wl_shm_interface, 1);
   117      }
   118      else if (strcmp(interface, "wl_output") == 0)
   119      {
   120          _glfwAddOutputWayland(name, version);
   121      }
   122      else if (strcmp(interface, "wl_seat") == 0)
   123      {
   124          if (!_glfw.wl.seat)
   125          {
   126              _glfw.wl.seatVersion = _glfw_min(4, version);
   127              _glfw.wl.seat =
   128                  wl_registry_bind(registry, name, &wl_seat_interface,
   129                                   _glfw.wl.seatVersion);
   130              _glfwAddSeatListenerWayland(_glfw.wl.seat);
   131          }
   132      }
   133      else if (strcmp(interface, "wl_data_device_manager") == 0)
   134      {
   135          if (!_glfw.wl.dataDeviceManager)
   136          {
   137              _glfw.wl.dataDeviceManager =
   138                  wl_registry_bind(registry, name,
   139                                   &wl_data_device_manager_interface, 1);
   140          }
   141      }
   142      else if (strcmp(interface, "xdg_wm_base") == 0)
   143      {
   144          _glfw.wl.wmBase =
   145              wl_registry_bind(registry, name, &xdg_wm_base_interface, 1);
   146          xdg_wm_base_add_listener(_glfw.wl.wmBase, &wmBaseListener, NULL);
   147      }
   148      else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0)
   149      {
   150          _glfw.wl.decorationManager =
   151              wl_registry_bind(registry, name,
   152                               &zxdg_decoration_manager_v1_interface,
   153                               1);
   154      }
   155      else if (strcmp(interface, "wp_viewporter") == 0)
   156      {
   157          _glfw.wl.viewporter =
   158              wl_registry_bind(registry, name, &wp_viewporter_interface, 1);
   159      }
   160      else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)
   161      {
   162          _glfw.wl.relativePointerManager =
   163              wl_registry_bind(registry, name,
   164                               &zwp_relative_pointer_manager_v1_interface,
   165                               1);
   166      }
   167      else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0)
   168      {
   169          _glfw.wl.pointerConstraints =
   170              wl_registry_bind(registry, name,
   171                               &zwp_pointer_constraints_v1_interface,
   172                               1);
   173      }
   174      else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0)
   175      {
   176          _glfw.wl.idleInhibitManager =
   177              wl_registry_bind(registry, name,
   178                               &zwp_idle_inhibit_manager_v1_interface,
   179                               1);
   180      }
   181  }
   182  
   183  static void registryHandleGlobalRemove(void* userData,
   184                                         struct wl_registry* registry,
   185                                         uint32_t name)
   186  {
   187      for (int i = 0; i < _glfw.monitorCount; ++i)
   188      {
   189          _GLFWmonitor* monitor = _glfw.monitors[i];
   190          if (monitor->wl.name == name)
   191          {
   192              _glfwInputMonitor(monitor, GLFW_DISCONNECTED, 0);
   193              return;
   194          }
   195      }
   196  }
   197  
   198  
   199  static const struct wl_registry_listener registryListener =
   200  {
   201      registryHandleGlobal,
   202      registryHandleGlobalRemove
   203  };
   204  
   205  // Create key code translation tables
   206  //
   207  static void createKeyTables(void)
   208  {
   209      memset(_glfw.wl.keycodes, -1, sizeof(_glfw.wl.keycodes));
   210      memset(_glfw.wl.scancodes, -1, sizeof(_glfw.wl.scancodes));
   211  
   212      _glfw.wl.keycodes[KEY_GRAVE]      = GLFW_KEY_GRAVE_ACCENT;
   213      _glfw.wl.keycodes[KEY_1]          = GLFW_KEY_1;
   214      _glfw.wl.keycodes[KEY_2]          = GLFW_KEY_2;
   215      _glfw.wl.keycodes[KEY_3]          = GLFW_KEY_3;
   216      _glfw.wl.keycodes[KEY_4]          = GLFW_KEY_4;
   217      _glfw.wl.keycodes[KEY_5]          = GLFW_KEY_5;
   218      _glfw.wl.keycodes[KEY_6]          = GLFW_KEY_6;
   219      _glfw.wl.keycodes[KEY_7]          = GLFW_KEY_7;
   220      _glfw.wl.keycodes[KEY_8]          = GLFW_KEY_8;
   221      _glfw.wl.keycodes[KEY_9]          = GLFW_KEY_9;
   222      _glfw.wl.keycodes[KEY_0]          = GLFW_KEY_0;
   223      _glfw.wl.keycodes[KEY_SPACE]      = GLFW_KEY_SPACE;
   224      _glfw.wl.keycodes[KEY_MINUS]      = GLFW_KEY_MINUS;
   225      _glfw.wl.keycodes[KEY_EQUAL]      = GLFW_KEY_EQUAL;
   226      _glfw.wl.keycodes[KEY_Q]          = GLFW_KEY_Q;
   227      _glfw.wl.keycodes[KEY_W]          = GLFW_KEY_W;
   228      _glfw.wl.keycodes[KEY_E]          = GLFW_KEY_E;
   229      _glfw.wl.keycodes[KEY_R]          = GLFW_KEY_R;
   230      _glfw.wl.keycodes[KEY_T]          = GLFW_KEY_T;
   231      _glfw.wl.keycodes[KEY_Y]          = GLFW_KEY_Y;
   232      _glfw.wl.keycodes[KEY_U]          = GLFW_KEY_U;
   233      _glfw.wl.keycodes[KEY_I]          = GLFW_KEY_I;
   234      _glfw.wl.keycodes[KEY_O]          = GLFW_KEY_O;
   235      _glfw.wl.keycodes[KEY_P]          = GLFW_KEY_P;
   236      _glfw.wl.keycodes[KEY_LEFTBRACE]  = GLFW_KEY_LEFT_BRACKET;
   237      _glfw.wl.keycodes[KEY_RIGHTBRACE] = GLFW_KEY_RIGHT_BRACKET;
   238      _glfw.wl.keycodes[KEY_A]          = GLFW_KEY_A;
   239      _glfw.wl.keycodes[KEY_S]          = GLFW_KEY_S;
   240      _glfw.wl.keycodes[KEY_D]          = GLFW_KEY_D;
   241      _glfw.wl.keycodes[KEY_F]          = GLFW_KEY_F;
   242      _glfw.wl.keycodes[KEY_G]          = GLFW_KEY_G;
   243      _glfw.wl.keycodes[KEY_H]          = GLFW_KEY_H;
   244      _glfw.wl.keycodes[KEY_J]          = GLFW_KEY_J;
   245      _glfw.wl.keycodes[KEY_K]          = GLFW_KEY_K;
   246      _glfw.wl.keycodes[KEY_L]          = GLFW_KEY_L;
   247      _glfw.wl.keycodes[KEY_SEMICOLON]  = GLFW_KEY_SEMICOLON;
   248      _glfw.wl.keycodes[KEY_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
   249      _glfw.wl.keycodes[KEY_Z]          = GLFW_KEY_Z;
   250      _glfw.wl.keycodes[KEY_X]          = GLFW_KEY_X;
   251      _glfw.wl.keycodes[KEY_C]          = GLFW_KEY_C;
   252      _glfw.wl.keycodes[KEY_V]          = GLFW_KEY_V;
   253      _glfw.wl.keycodes[KEY_B]          = GLFW_KEY_B;
   254      _glfw.wl.keycodes[KEY_N]          = GLFW_KEY_N;
   255      _glfw.wl.keycodes[KEY_M]          = GLFW_KEY_M;
   256      _glfw.wl.keycodes[KEY_COMMA]      = GLFW_KEY_COMMA;
   257      _glfw.wl.keycodes[KEY_DOT]        = GLFW_KEY_PERIOD;
   258      _glfw.wl.keycodes[KEY_SLASH]      = GLFW_KEY_SLASH;
   259      _glfw.wl.keycodes[KEY_BACKSLASH]  = GLFW_KEY_BACKSLASH;
   260      _glfw.wl.keycodes[KEY_ESC]        = GLFW_KEY_ESCAPE;
   261      _glfw.wl.keycodes[KEY_TAB]        = GLFW_KEY_TAB;
   262      _glfw.wl.keycodes[KEY_LEFTSHIFT]  = GLFW_KEY_LEFT_SHIFT;
   263      _glfw.wl.keycodes[KEY_RIGHTSHIFT] = GLFW_KEY_RIGHT_SHIFT;
   264      _glfw.wl.keycodes[KEY_LEFTCTRL]   = GLFW_KEY_LEFT_CONTROL;
   265      _glfw.wl.keycodes[KEY_RIGHTCTRL]  = GLFW_KEY_RIGHT_CONTROL;
   266      _glfw.wl.keycodes[KEY_LEFTALT]    = GLFW_KEY_LEFT_ALT;
   267      _glfw.wl.keycodes[KEY_RIGHTALT]   = GLFW_KEY_RIGHT_ALT;
   268      _glfw.wl.keycodes[KEY_LEFTMETA]   = GLFW_KEY_LEFT_SUPER;
   269      _glfw.wl.keycodes[KEY_RIGHTMETA]  = GLFW_KEY_RIGHT_SUPER;
   270      _glfw.wl.keycodes[KEY_COMPOSE]    = GLFW_KEY_MENU;
   271      _glfw.wl.keycodes[KEY_NUMLOCK]    = GLFW_KEY_NUM_LOCK;
   272      _glfw.wl.keycodes[KEY_CAPSLOCK]   = GLFW_KEY_CAPS_LOCK;
   273      _glfw.wl.keycodes[KEY_PRINT]      = GLFW_KEY_PRINT_SCREEN;
   274      _glfw.wl.keycodes[KEY_SCROLLLOCK] = GLFW_KEY_SCROLL_LOCK;
   275      _glfw.wl.keycodes[KEY_PAUSE]      = GLFW_KEY_PAUSE;
   276      _glfw.wl.keycodes[KEY_DELETE]     = GLFW_KEY_DELETE;
   277      _glfw.wl.keycodes[KEY_BACKSPACE]  = GLFW_KEY_BACKSPACE;
   278      _glfw.wl.keycodes[KEY_ENTER]      = GLFW_KEY_ENTER;
   279      _glfw.wl.keycodes[KEY_HOME]       = GLFW_KEY_HOME;
   280      _glfw.wl.keycodes[KEY_END]        = GLFW_KEY_END;
   281      _glfw.wl.keycodes[KEY_PAGEUP]     = GLFW_KEY_PAGE_UP;
   282      _glfw.wl.keycodes[KEY_PAGEDOWN]   = GLFW_KEY_PAGE_DOWN;
   283      _glfw.wl.keycodes[KEY_INSERT]     = GLFW_KEY_INSERT;
   284      _glfw.wl.keycodes[KEY_LEFT]       = GLFW_KEY_LEFT;
   285      _glfw.wl.keycodes[KEY_RIGHT]      = GLFW_KEY_RIGHT;
   286      _glfw.wl.keycodes[KEY_DOWN]       = GLFW_KEY_DOWN;
   287      _glfw.wl.keycodes[KEY_UP]         = GLFW_KEY_UP;
   288      _glfw.wl.keycodes[KEY_F1]         = GLFW_KEY_F1;
   289      _glfw.wl.keycodes[KEY_F2]         = GLFW_KEY_F2;
   290      _glfw.wl.keycodes[KEY_F3]         = GLFW_KEY_F3;
   291      _glfw.wl.keycodes[KEY_F4]         = GLFW_KEY_F4;
   292      _glfw.wl.keycodes[KEY_F5]         = GLFW_KEY_F5;
   293      _glfw.wl.keycodes[KEY_F6]         = GLFW_KEY_F6;
   294      _glfw.wl.keycodes[KEY_F7]         = GLFW_KEY_F7;
   295      _glfw.wl.keycodes[KEY_F8]         = GLFW_KEY_F8;
   296      _glfw.wl.keycodes[KEY_F9]         = GLFW_KEY_F9;
   297      _glfw.wl.keycodes[KEY_F10]        = GLFW_KEY_F10;
   298      _glfw.wl.keycodes[KEY_F11]        = GLFW_KEY_F11;
   299      _glfw.wl.keycodes[KEY_F12]        = GLFW_KEY_F12;
   300      _glfw.wl.keycodes[KEY_F13]        = GLFW_KEY_F13;
   301      _glfw.wl.keycodes[KEY_F14]        = GLFW_KEY_F14;
   302      _glfw.wl.keycodes[KEY_F15]        = GLFW_KEY_F15;
   303      _glfw.wl.keycodes[KEY_F16]        = GLFW_KEY_F16;
   304      _glfw.wl.keycodes[KEY_F17]        = GLFW_KEY_F17;
   305      _glfw.wl.keycodes[KEY_F18]        = GLFW_KEY_F18;
   306      _glfw.wl.keycodes[KEY_F19]        = GLFW_KEY_F19;
   307      _glfw.wl.keycodes[KEY_F20]        = GLFW_KEY_F20;
   308      _glfw.wl.keycodes[KEY_F21]        = GLFW_KEY_F21;
   309      _glfw.wl.keycodes[KEY_F22]        = GLFW_KEY_F22;
   310      _glfw.wl.keycodes[KEY_F23]        = GLFW_KEY_F23;
   311      _glfw.wl.keycodes[KEY_F24]        = GLFW_KEY_F24;
   312      _glfw.wl.keycodes[KEY_KPSLASH]    = GLFW_KEY_KP_DIVIDE;
   313      _glfw.wl.keycodes[KEY_KPASTERISK] = GLFW_KEY_KP_MULTIPLY;
   314      _glfw.wl.keycodes[KEY_KPMINUS]    = GLFW_KEY_KP_SUBTRACT;
   315      _glfw.wl.keycodes[KEY_KPPLUS]     = GLFW_KEY_KP_ADD;
   316      _glfw.wl.keycodes[KEY_KP0]        = GLFW_KEY_KP_0;
   317      _glfw.wl.keycodes[KEY_KP1]        = GLFW_KEY_KP_1;
   318      _glfw.wl.keycodes[KEY_KP2]        = GLFW_KEY_KP_2;
   319      _glfw.wl.keycodes[KEY_KP3]        = GLFW_KEY_KP_3;
   320      _glfw.wl.keycodes[KEY_KP4]        = GLFW_KEY_KP_4;
   321      _glfw.wl.keycodes[KEY_KP5]        = GLFW_KEY_KP_5;
   322      _glfw.wl.keycodes[KEY_KP6]        = GLFW_KEY_KP_6;
   323      _glfw.wl.keycodes[KEY_KP7]        = GLFW_KEY_KP_7;
   324      _glfw.wl.keycodes[KEY_KP8]        = GLFW_KEY_KP_8;
   325      _glfw.wl.keycodes[KEY_KP9]        = GLFW_KEY_KP_9;
   326      _glfw.wl.keycodes[KEY_KPDOT]      = GLFW_KEY_KP_DECIMAL;
   327      _glfw.wl.keycodes[KEY_KPEQUAL]    = GLFW_KEY_KP_EQUAL;
   328      _glfw.wl.keycodes[KEY_KPENTER]    = GLFW_KEY_KP_ENTER;
   329      _glfw.wl.keycodes[KEY_102ND]      = GLFW_KEY_WORLD_2;
   330  
   331      for (int scancode = 0;  scancode < 256;  scancode++)
   332      {
   333          if (_glfw.wl.keycodes[scancode] > 0)
   334              _glfw.wl.scancodes[_glfw.wl.keycodes[scancode]] = scancode;
   335      }
   336  }
   337  
   338  static GLFWbool loadCursorTheme(void)
   339  {
   340      int cursorSize = 32;
   341  
   342      const char* sizeString = getenv("XCURSOR_SIZE");
   343      if (sizeString)
   344      {
   345          errno = 0;
   346          const long cursorSizeLong = strtol(sizeString, NULL, 10);
   347          if (errno == 0 && cursorSizeLong > 0 && cursorSizeLong < INT_MAX)
   348              cursorSize = (int) cursorSizeLong;
   349      }
   350  
   351      const char* themeName = getenv("XCURSOR_THEME");
   352  
   353      _glfw.wl.cursorTheme = wl_cursor_theme_load(themeName, cursorSize, _glfw.wl.shm);
   354      if (!_glfw.wl.cursorTheme)
   355      {
   356          _glfwInputError(GLFW_PLATFORM_ERROR,
   357                          "Wayland: Failed to load default cursor theme");
   358          return GLFW_FALSE;
   359      }
   360  
   361      // If this happens to be NULL, we just fallback to the scale=1 version.
   362      _glfw.wl.cursorThemeHiDPI =
   363          wl_cursor_theme_load(themeName, cursorSize * 2, _glfw.wl.shm);
   364  
   365      _glfw.wl.cursorSurface = wl_compositor_create_surface(_glfw.wl.compositor);
   366      _glfw.wl.cursorTimerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
   367      return GLFW_TRUE;
   368  }
   369  
   370  
   371  //////////////////////////////////////////////////////////////////////////
   372  //////                       GLFW platform API                      //////
   373  //////////////////////////////////////////////////////////////////////////
   374  
   375  GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform)
   376  {
   377      const _GLFWplatform wayland =
   378      {
   379          GLFW_PLATFORM_WAYLAND,
   380          _glfwInitWayland,
   381          _glfwTerminateWayland,
   382          _glfwGetCursorPosWayland,
   383          _glfwSetCursorPosWayland,
   384          _glfwSetCursorModeWayland,
   385          _glfwSetRawMouseMotionWayland,
   386          _glfwRawMouseMotionSupportedWayland,
   387          _glfwCreateCursorWayland,
   388          _glfwCreateStandardCursorWayland,
   389          _glfwDestroyCursorWayland,
   390          _glfwSetCursorWayland,
   391          _glfwGetScancodeNameWayland,
   392          _glfwGetKeyScancodeWayland,
   393          _glfwSetClipboardStringWayland,
   394          _glfwGetClipboardStringWayland,
   395  #if defined(__linux__)
   396          _glfwInitJoysticksLinux,
   397          _glfwTerminateJoysticksLinux,
   398          _glfwPollJoystickLinux,
   399          _glfwGetMappingNameLinux,
   400          _glfwUpdateGamepadGUIDLinux,
   401  #else
   402          _glfwInitJoysticksNull,
   403          _glfwTerminateJoysticksNull,
   404          _glfwPollJoystickNull,
   405          _glfwGetMappingNameNull,
   406          _glfwUpdateGamepadGUIDNull,
   407  #endif
   408          _glfwFreeMonitorWayland,
   409          _glfwGetMonitorPosWayland,
   410          _glfwGetMonitorContentScaleWayland,
   411          _glfwGetMonitorWorkareaWayland,
   412          _glfwGetVideoModesWayland,
   413          _glfwGetVideoModeWayland,
   414          _glfwGetGammaRampWayland,
   415          _glfwSetGammaRampWayland,
   416          _glfwCreateWindowWayland,
   417          _glfwDestroyWindowWayland,
   418          _glfwSetWindowTitleWayland,
   419          _glfwSetWindowIconWayland,
   420          _glfwGetWindowPosWayland,
   421          _glfwSetWindowPosWayland,
   422          _glfwGetWindowSizeWayland,
   423          _glfwSetWindowSizeWayland,
   424          _glfwSetWindowSizeLimitsWayland,
   425          _glfwSetWindowAspectRatioWayland,
   426          _glfwGetFramebufferSizeWayland,
   427          _glfwGetWindowFrameSizeWayland,
   428          _glfwGetWindowContentScaleWayland,
   429          _glfwIconifyWindowWayland,
   430          _glfwRestoreWindowWayland,
   431          _glfwMaximizeWindowWayland,
   432          _glfwShowWindowWayland,
   433          _glfwHideWindowWayland,
   434          _glfwRequestWindowAttentionWayland,
   435          _glfwFocusWindowWayland,
   436          _glfwSetWindowMonitorWayland,
   437          _glfwWindowFocusedWayland,
   438          _glfwWindowIconifiedWayland,
   439          _glfwWindowVisibleWayland,
   440          _glfwWindowMaximizedWayland,
   441          _glfwWindowHoveredWayland,
   442          _glfwFramebufferTransparentWayland,
   443          _glfwGetWindowOpacityWayland,
   444          _glfwSetWindowResizableWayland,
   445          _glfwSetWindowDecoratedWayland,
   446          _glfwSetWindowFloatingWayland,
   447          _glfwSetWindowOpacityWayland,
   448          _glfwSetWindowMousePassthroughWayland,
   449          _glfwPollEventsWayland,
   450          _glfwWaitEventsWayland,
   451          _glfwWaitEventsTimeoutWayland,
   452          _glfwPostEmptyEventWayland,
   453          _glfwGetEGLPlatformWayland,
   454          _glfwGetEGLNativeDisplayWayland,
   455          _glfwGetEGLNativeWindowWayland,
   456          _glfwGetRequiredInstanceExtensionsWayland,
   457          _glfwGetPhysicalDevicePresentationSupportWayland,
   458          _glfwCreateWindowSurfaceWayland,
   459      };
   460  
   461      void* module = _glfwPlatformLoadModule("libwayland-client.so.0");
   462      if (!module)
   463      {
   464          if (platformID == GLFW_PLATFORM_WAYLAND)
   465          {
   466              _glfwInputError(GLFW_PLATFORM_ERROR,
   467                              "Wayland: Failed to load libwayland-client");
   468          }
   469  
   470          return GLFW_FALSE;
   471      }
   472  
   473      PFN_wl_display_connect wl_display_connect = (PFN_wl_display_connect)
   474          _glfwPlatformGetModuleSymbol(module, "wl_display_connect");
   475      if (!wl_display_connect)
   476      {
   477          if (platformID == GLFW_PLATFORM_WAYLAND)
   478          {
   479              _glfwInputError(GLFW_PLATFORM_ERROR,
   480                              "Wayland: Failed to load libwayland-client entry point");
   481          }
   482  
   483          _glfwPlatformFreeModule(module);
   484          return GLFW_FALSE;
   485      }
   486  
   487      struct wl_display* display = wl_display_connect(NULL);
   488      if (!display)
   489      {
   490          if (platformID == GLFW_PLATFORM_WAYLAND)
   491              _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Failed to connect to display");
   492  
   493          _glfwPlatformFreeModule(module);
   494          return GLFW_FALSE;
   495      }
   496  
   497      _glfw.wl.display = display;
   498      _glfw.wl.client.handle = module;
   499  
   500      *platform = wayland;
   501      return GLFW_TRUE;
   502  }
   503  
   504  int _glfwInitWayland(void)
   505  {
   506      // These must be set before any failure checks
   507      _glfw.wl.keyRepeatTimerfd = -1;
   508      _glfw.wl.cursorTimerfd = -1;
   509  
   510      _glfw.wl.client.display_flush = (PFN_wl_display_flush)
   511          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_flush");
   512      _glfw.wl.client.display_cancel_read = (PFN_wl_display_cancel_read)
   513          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_cancel_read");
   514      _glfw.wl.client.display_dispatch_pending = (PFN_wl_display_dispatch_pending)
   515          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_dispatch_pending");
   516      _glfw.wl.client.display_read_events = (PFN_wl_display_read_events)
   517          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_read_events");
   518      _glfw.wl.client.display_disconnect = (PFN_wl_display_disconnect)
   519          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_disconnect");
   520      _glfw.wl.client.display_roundtrip = (PFN_wl_display_roundtrip)
   521          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_roundtrip");
   522      _glfw.wl.client.display_get_fd = (PFN_wl_display_get_fd)
   523          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_get_fd");
   524      _glfw.wl.client.display_prepare_read = (PFN_wl_display_prepare_read)
   525          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_display_prepare_read");
   526      _glfw.wl.client.proxy_marshal = (PFN_wl_proxy_marshal)
   527          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal");
   528      _glfw.wl.client.proxy_add_listener = (PFN_wl_proxy_add_listener)
   529          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_add_listener");
   530      _glfw.wl.client.proxy_destroy = (PFN_wl_proxy_destroy)
   531          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_destroy");
   532      _glfw.wl.client.proxy_marshal_constructor = (PFN_wl_proxy_marshal_constructor)
   533          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor");
   534      _glfw.wl.client.proxy_marshal_constructor_versioned = (PFN_wl_proxy_marshal_constructor_versioned)
   535          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_constructor_versioned");
   536      _glfw.wl.client.proxy_get_user_data = (PFN_wl_proxy_get_user_data)
   537          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_user_data");
   538      _glfw.wl.client.proxy_set_user_data = (PFN_wl_proxy_set_user_data)
   539          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_set_user_data");
   540      _glfw.wl.client.proxy_get_version = (PFN_wl_proxy_get_version)
   541          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_get_version");
   542      _glfw.wl.client.proxy_marshal_flags = (PFN_wl_proxy_marshal_flags)
   543          _glfwPlatformGetModuleSymbol(_glfw.wl.client.handle, "wl_proxy_marshal_flags");
   544  
   545      if (!_glfw.wl.client.display_flush ||
   546          !_glfw.wl.client.display_cancel_read ||
   547          !_glfw.wl.client.display_dispatch_pending ||
   548          !_glfw.wl.client.display_read_events ||
   549          !_glfw.wl.client.display_disconnect ||
   550          !_glfw.wl.client.display_roundtrip ||
   551          !_glfw.wl.client.display_get_fd ||
   552          !_glfw.wl.client.display_prepare_read ||
   553          !_glfw.wl.client.proxy_marshal ||
   554          !_glfw.wl.client.proxy_add_listener ||
   555          !_glfw.wl.client.proxy_destroy ||
   556          !_glfw.wl.client.proxy_marshal_constructor ||
   557          !_glfw.wl.client.proxy_marshal_constructor_versioned ||
   558          !_glfw.wl.client.proxy_get_user_data ||
   559          !_glfw.wl.client.proxy_set_user_data)
   560      {
   561          _glfwInputError(GLFW_PLATFORM_ERROR,
   562                          "Wayland: Failed to load libwayland-client entry point");
   563          return GLFW_FALSE;
   564      }
   565  
   566      _glfw.wl.cursor.handle = _glfwPlatformLoadModule("libwayland-cursor.so.0");
   567      if (!_glfw.wl.cursor.handle)
   568      {
   569          _glfwInputError(GLFW_PLATFORM_ERROR,
   570                          "Wayland: Failed to load libwayland-cursor");
   571          return GLFW_FALSE;
   572      }
   573  
   574      _glfw.wl.cursor.theme_load = (PFN_wl_cursor_theme_load)
   575          _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_load");
   576      _glfw.wl.cursor.theme_destroy = (PFN_wl_cursor_theme_destroy)
   577          _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_destroy");
   578      _glfw.wl.cursor.theme_get_cursor = (PFN_wl_cursor_theme_get_cursor)
   579          _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_theme_get_cursor");
   580      _glfw.wl.cursor.image_get_buffer = (PFN_wl_cursor_image_get_buffer)
   581          _glfwPlatformGetModuleSymbol(_glfw.wl.cursor.handle, "wl_cursor_image_get_buffer");
   582  
   583      _glfw.wl.egl.handle = _glfwPlatformLoadModule("libwayland-egl.so.1");
   584      if (!_glfw.wl.egl.handle)
   585      {
   586          _glfwInputError(GLFW_PLATFORM_ERROR,
   587                          "Wayland: Failed to load libwayland-egl");
   588          return GLFW_FALSE;
   589      }
   590  
   591      _glfw.wl.egl.window_create = (PFN_wl_egl_window_create)
   592          _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_create");
   593      _glfw.wl.egl.window_destroy = (PFN_wl_egl_window_destroy)
   594          _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_destroy");
   595      _glfw.wl.egl.window_resize = (PFN_wl_egl_window_resize)
   596          _glfwPlatformGetModuleSymbol(_glfw.wl.egl.handle, "wl_egl_window_resize");
   597  
   598      _glfw.wl.xkb.handle = _glfwPlatformLoadModule("libxkbcommon.so.0");
   599      if (!_glfw.wl.xkb.handle)
   600      {
   601          _glfwInputError(GLFW_PLATFORM_ERROR,
   602                          "Wayland: Failed to load libxkbcommon");
   603          return GLFW_FALSE;
   604      }
   605  
   606      _glfw.wl.xkb.context_new = (PFN_xkb_context_new)
   607          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_new");
   608      _glfw.wl.xkb.context_unref = (PFN_xkb_context_unref)
   609          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_context_unref");
   610      _glfw.wl.xkb.keymap_new_from_string = (PFN_xkb_keymap_new_from_string)
   611          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_new_from_string");
   612      _glfw.wl.xkb.keymap_unref = (PFN_xkb_keymap_unref)
   613          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_unref");
   614      _glfw.wl.xkb.keymap_mod_get_index = (PFN_xkb_keymap_mod_get_index)
   615          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_mod_get_index");
   616      _glfw.wl.xkb.keymap_key_repeats = (PFN_xkb_keymap_key_repeats)
   617          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_repeats");
   618      _glfw.wl.xkb.keymap_key_get_syms_by_level = (PFN_xkb_keymap_key_get_syms_by_level)
   619          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_keymap_key_get_syms_by_level");
   620      _glfw.wl.xkb.state_new = (PFN_xkb_state_new)
   621          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_new");
   622      _glfw.wl.xkb.state_unref = (PFN_xkb_state_unref)
   623          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_unref");
   624      _glfw.wl.xkb.state_key_get_syms = (PFN_xkb_state_key_get_syms)
   625          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_syms");
   626      _glfw.wl.xkb.state_update_mask = (PFN_xkb_state_update_mask)
   627          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_update_mask");
   628      _glfw.wl.xkb.state_key_get_layout = (PFN_xkb_state_key_get_layout)
   629          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_key_get_layout");
   630      _glfw.wl.xkb.state_mod_index_is_active = (PFN_xkb_state_mod_index_is_active)
   631          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_state_mod_index_is_active");
   632      _glfw.wl.xkb.compose_table_new_from_locale = (PFN_xkb_compose_table_new_from_locale)
   633          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_new_from_locale");
   634      _glfw.wl.xkb.compose_table_unref = (PFN_xkb_compose_table_unref)
   635          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_table_unref");
   636      _glfw.wl.xkb.compose_state_new = (PFN_xkb_compose_state_new)
   637          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_new");
   638      _glfw.wl.xkb.compose_state_unref = (PFN_xkb_compose_state_unref)
   639          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_unref");
   640      _glfw.wl.xkb.compose_state_feed = (PFN_xkb_compose_state_feed)
   641          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_feed");
   642      _glfw.wl.xkb.compose_state_get_status = (PFN_xkb_compose_state_get_status)
   643          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_status");
   644      _glfw.wl.xkb.compose_state_get_one_sym = (PFN_xkb_compose_state_get_one_sym)
   645          _glfwPlatformGetModuleSymbol(_glfw.wl.xkb.handle, "xkb_compose_state_get_one_sym");
   646  
   647      _glfw.wl.registry = wl_display_get_registry(_glfw.wl.display);
   648      wl_registry_add_listener(_glfw.wl.registry, &registryListener, NULL);
   649  
   650      createKeyTables();
   651  
   652      _glfw.wl.xkb.context = xkb_context_new(0);
   653      if (!_glfw.wl.xkb.context)
   654      {
   655          _glfwInputError(GLFW_PLATFORM_ERROR,
   656                          "Wayland: Failed to initialize xkb context");
   657          return GLFW_FALSE;
   658      }
   659  
   660      // Sync so we got all registry objects
   661      wl_display_roundtrip(_glfw.wl.display);
   662  
   663      // Sync so we got all initial output events
   664      wl_display_roundtrip(_glfw.wl.display);
   665  
   666  #ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
   667      if (_glfw.wl.seatVersion >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION)
   668      {
   669          _glfw.wl.keyRepeatTimerfd =
   670              timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
   671      }
   672  #endif
   673  
   674      if (!_glfw.wl.wmBase)
   675      {
   676          _glfwInputError(GLFW_PLATFORM_ERROR,
   677                          "Wayland: Failed to find xdg-shell in your compositor");
   678          return GLFW_FALSE;
   679      }
   680  
   681      if (!_glfw.wl.shm)
   682      {
   683          _glfwInputError(GLFW_PLATFORM_ERROR,
   684                          "Wayland: Failed to find wl_shm in your compositor");
   685          return GLFW_FALSE;
   686      }
   687  
   688      if (!loadCursorTheme())
   689          return GLFW_FALSE;
   690  
   691      if (_glfw.wl.seat && _glfw.wl.dataDeviceManager)
   692      {
   693          _glfw.wl.dataDevice =
   694              wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager,
   695                                                     _glfw.wl.seat);
   696          _glfwAddDataDeviceListenerWayland(_glfw.wl.dataDevice);
   697      }
   698  
   699      return GLFW_TRUE;
   700  }
   701  
   702  void _glfwTerminateWayland(void)
   703  {
   704      _glfwTerminateEGL();
   705      _glfwTerminateOSMesa();
   706  
   707      if (_glfw.wl.egl.handle)
   708      {
   709          _glfwPlatformFreeModule(_glfw.wl.egl.handle);
   710          _glfw.wl.egl.handle = NULL;
   711      }
   712  
   713      if (_glfw.wl.xkb.composeState)
   714          xkb_compose_state_unref(_glfw.wl.xkb.composeState);
   715      if (_glfw.wl.xkb.keymap)
   716          xkb_keymap_unref(_glfw.wl.xkb.keymap);
   717      if (_glfw.wl.xkb.state)
   718          xkb_state_unref(_glfw.wl.xkb.state);
   719      if (_glfw.wl.xkb.context)
   720          xkb_context_unref(_glfw.wl.xkb.context);
   721      if (_glfw.wl.xkb.handle)
   722      {
   723          _glfwPlatformFreeModule(_glfw.wl.xkb.handle);
   724          _glfw.wl.xkb.handle = NULL;
   725      }
   726  
   727      if (_glfw.wl.cursorTheme)
   728          wl_cursor_theme_destroy(_glfw.wl.cursorTheme);
   729      if (_glfw.wl.cursorThemeHiDPI)
   730          wl_cursor_theme_destroy(_glfw.wl.cursorThemeHiDPI);
   731      if (_glfw.wl.cursor.handle)
   732      {
   733          _glfwPlatformFreeModule(_glfw.wl.cursor.handle);
   734          _glfw.wl.cursor.handle = NULL;
   735      }
   736  
   737      for (unsigned int i = 0; i < _glfw.wl.offerCount; i++)
   738          wl_data_offer_destroy(_glfw.wl.offers[i].offer);
   739  
   740      _glfw_free(_glfw.wl.offers);
   741  
   742      if (_glfw.wl.cursorSurface)
   743          wl_surface_destroy(_glfw.wl.cursorSurface);
   744      if (_glfw.wl.subcompositor)
   745          wl_subcompositor_destroy(_glfw.wl.subcompositor);
   746      if (_glfw.wl.compositor)
   747          wl_compositor_destroy(_glfw.wl.compositor);
   748      if (_glfw.wl.shm)
   749          wl_shm_destroy(_glfw.wl.shm);
   750      if (_glfw.wl.viewporter)
   751          wp_viewporter_destroy(_glfw.wl.viewporter);
   752      if (_glfw.wl.decorationManager)
   753          zxdg_decoration_manager_v1_destroy(_glfw.wl.decorationManager);
   754      if (_glfw.wl.wmBase)
   755          xdg_wm_base_destroy(_glfw.wl.wmBase);
   756      if (_glfw.wl.selectionOffer)
   757          wl_data_offer_destroy(_glfw.wl.selectionOffer);
   758      if (_glfw.wl.dragOffer)
   759          wl_data_offer_destroy(_glfw.wl.dragOffer);
   760      if (_glfw.wl.selectionSource)
   761          wl_data_source_destroy(_glfw.wl.selectionSource);
   762      if (_glfw.wl.dataDevice)
   763          wl_data_device_destroy(_glfw.wl.dataDevice);
   764      if (_glfw.wl.dataDeviceManager)
   765          wl_data_device_manager_destroy(_glfw.wl.dataDeviceManager);
   766      if (_glfw.wl.pointer)
   767          wl_pointer_destroy(_glfw.wl.pointer);
   768      if (_glfw.wl.keyboard)
   769          wl_keyboard_destroy(_glfw.wl.keyboard);
   770      if (_glfw.wl.seat)
   771          wl_seat_destroy(_glfw.wl.seat);
   772      if (_glfw.wl.relativePointerManager)
   773          zwp_relative_pointer_manager_v1_destroy(_glfw.wl.relativePointerManager);
   774      if (_glfw.wl.pointerConstraints)
   775          zwp_pointer_constraints_v1_destroy(_glfw.wl.pointerConstraints);
   776      if (_glfw.wl.idleInhibitManager)
   777          zwp_idle_inhibit_manager_v1_destroy(_glfw.wl.idleInhibitManager);
   778      if (_glfw.wl.registry)
   779          wl_registry_destroy(_glfw.wl.registry);
   780      if (_glfw.wl.display)
   781      {
   782          wl_display_flush(_glfw.wl.display);
   783          wl_display_disconnect(_glfw.wl.display);
   784      }
   785  
   786      if (_glfw.wl.keyRepeatTimerfd >= 0)
   787          close(_glfw.wl.keyRepeatTimerfd);
   788      if (_glfw.wl.cursorTimerfd >= 0)
   789          close(_glfw.wl.cursorTimerfd);
   790  
   791      _glfw_free(_glfw.wl.clipboardString);
   792  }
   793