github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/raylib/external/glfw/src/wl_monitor.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 <stdio.h>
    32  #include <stdlib.h>
    33  #include <string.h>
    34  #include <errno.h>
    35  #include <math.h>
    36  
    37  #include "wayland-client-protocol.h"
    38  
    39  
    40  static void outputHandleGeometry(void* userData,
    41                                   struct wl_output* output,
    42                                   int32_t x,
    43                                   int32_t y,
    44                                   int32_t physicalWidth,
    45                                   int32_t physicalHeight,
    46                                   int32_t subpixel,
    47                                   const char* make,
    48                                   const char* model,
    49                                   int32_t transform)
    50  {
    51      struct _GLFWmonitor* monitor = userData;
    52  
    53      monitor->wl.x = x;
    54      monitor->wl.y = y;
    55      monitor->widthMM = physicalWidth;
    56      monitor->heightMM = physicalHeight;
    57  
    58      if (strlen(monitor->name) == 0)
    59          snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
    60  }
    61  
    62  static void outputHandleMode(void* userData,
    63                               struct wl_output* output,
    64                               uint32_t flags,
    65                               int32_t width,
    66                               int32_t height,
    67                               int32_t refresh)
    68  {
    69      struct _GLFWmonitor* monitor = userData;
    70      GLFWvidmode mode;
    71  
    72      mode.width = width;
    73      mode.height = height;
    74      mode.redBits = 8;
    75      mode.greenBits = 8;
    76      mode.blueBits = 8;
    77      mode.refreshRate = (int) round(refresh / 1000.0);
    78  
    79      monitor->modeCount++;
    80      monitor->modes =
    81          _glfw_realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
    82      monitor->modes[monitor->modeCount - 1] = mode;
    83  
    84      if (flags & WL_OUTPUT_MODE_CURRENT)
    85          monitor->wl.currentMode = monitor->modeCount - 1;
    86  }
    87  
    88  static void outputHandleDone(void* userData, struct wl_output* output)
    89  {
    90      struct _GLFWmonitor* monitor = userData;
    91  
    92      if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
    93      {
    94          // If Wayland does not provide a physical size, assume the default 96 DPI
    95          const GLFWvidmode* mode = &monitor->modes[monitor->wl.currentMode];
    96          monitor->widthMM  = (int) (mode->width * 25.4f / 96.f);
    97          monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
    98      }
    99  
   100      for (int i = 0; i < _glfw.monitorCount; i++)
   101      {
   102          if (_glfw.monitors[i] == monitor)
   103              return;
   104      }
   105  
   106      _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
   107  }
   108  
   109  static void outputHandleScale(void* userData,
   110                                struct wl_output* output,
   111                                int32_t factor)
   112  {
   113      struct _GLFWmonitor* monitor = userData;
   114  
   115      monitor->wl.scale = factor;
   116  
   117      for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
   118      {
   119          for (int i = 0; i < window->wl.monitorsCount; i++)
   120          {
   121              if (window->wl.monitors[i] == monitor)
   122              {
   123                  _glfwUpdateContentScaleWayland(window);
   124                  break;
   125              }
   126          }
   127      }
   128  }
   129  
   130  #ifdef WL_OUTPUT_NAME_SINCE_VERSION
   131  
   132  void outputHandleName(void* userData, struct wl_output* wl_output, const char* name)
   133  {
   134      struct _GLFWmonitor* monitor = userData;
   135  
   136      strncpy(monitor->name, name, sizeof(monitor->name) - 1);
   137  }
   138  
   139  void outputHandleDescription(void* userData,
   140                               struct wl_output* wl_output,
   141                               const char* description)
   142  {
   143  }
   144  
   145  #endif // WL_OUTPUT_NAME_SINCE_VERSION
   146  
   147  static const struct wl_output_listener outputListener =
   148  {
   149      outputHandleGeometry,
   150      outputHandleMode,
   151      outputHandleDone,
   152      outputHandleScale,
   153  #ifdef WL_OUTPUT_NAME_SINCE_VERSION
   154      outputHandleName,
   155      outputHandleDescription,
   156  #endif
   157  };
   158  
   159  
   160  //////////////////////////////////////////////////////////////////////////
   161  //////                       GLFW internal API                      //////
   162  //////////////////////////////////////////////////////////////////////////
   163  
   164  void _glfwAddOutputWayland(uint32_t name, uint32_t version)
   165  {
   166      if (version < 2)
   167      {
   168          _glfwInputError(GLFW_PLATFORM_ERROR,
   169                          "Wayland: Unsupported output interface version");
   170          return;
   171      }
   172  
   173  #ifdef WL_OUTPUT_NAME_SINCE_VERSION
   174      version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);
   175  #else
   176      version = 2;
   177  #endif
   178  
   179      struct wl_output* output = wl_registry_bind(_glfw.wl.registry,
   180                                                  name,
   181                                                  &wl_output_interface,
   182                                                  version);
   183      if (!output)
   184          return;
   185  
   186      // The actual name of this output will be set in the geometry handler
   187      _GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
   188      monitor->wl.scale = 1;
   189      monitor->wl.output = output;
   190      monitor->wl.name = name;
   191  
   192      wl_output_add_listener(output, &outputListener, monitor);
   193  }
   194  
   195  
   196  //////////////////////////////////////////////////////////////////////////
   197  //////                       GLFW platform API                      //////
   198  //////////////////////////////////////////////////////////////////////////
   199  
   200  void _glfwFreeMonitorWayland(_GLFWmonitor* monitor)
   201  {
   202      if (monitor->wl.output)
   203          wl_output_destroy(monitor->wl.output);
   204  }
   205  
   206  void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos)
   207  {
   208      if (xpos)
   209          *xpos = monitor->wl.x;
   210      if (ypos)
   211          *ypos = monitor->wl.y;
   212  }
   213  
   214  void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor,
   215                                          float* xscale, float* yscale)
   216  {
   217      if (xscale)
   218          *xscale = (float) monitor->wl.scale;
   219      if (yscale)
   220          *yscale = (float) monitor->wl.scale;
   221  }
   222  
   223  void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor,
   224                                      int* xpos, int* ypos,
   225                                      int* width, int* height)
   226  {
   227      if (xpos)
   228          *xpos = monitor->wl.x;
   229      if (ypos)
   230          *ypos = monitor->wl.y;
   231      if (width)
   232          *width = monitor->modes[monitor->wl.currentMode].width;
   233      if (height)
   234          *height = monitor->modes[monitor->wl.currentMode].height;
   235  }
   236  
   237  GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* found)
   238  {
   239      *found = monitor->modeCount;
   240      return monitor->modes;
   241  }
   242  
   243  void _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode)
   244  {
   245      *mode = monitor->modes[monitor->wl.currentMode];
   246  }
   247  
   248  GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
   249  {
   250      _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
   251                      "Wayland: Gamma ramp access is not available");
   252      return GLFW_FALSE;
   253  }
   254  
   255  void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
   256  {
   257      _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
   258                      "Wayland: Gamma ramp access is not available");
   259  }
   260  
   261  
   262  //////////////////////////////////////////////////////////////////////////
   263  //////                        GLFW native API                       //////
   264  //////////////////////////////////////////////////////////////////////////
   265  
   266  GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
   267  {
   268      _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
   269      _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
   270      return monitor->wl.output;
   271  }
   272