volviewer

Volumetric Data Toy Viewer
git clone anongit@rnpnr.xyz:volviewer.git
Log | Files | Refs | Feed | LICENSE

wl_monitor.c (8627B)


      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 
     27 #include "internal.h"
     28 
     29 #if defined(_GLFW_WAYLAND)
     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 (size_t i = 0; i < window->wl.outputScaleCount; i++)
    120         {
    121             if (window->wl.outputScales[i].output == monitor->wl.output)
    122             {
    123                 window->wl.outputScales[i].factor = monitor->wl.scale;
    124                 _glfwUpdateBufferScaleFromOutputsWayland(window);
    125                 break;
    126             }
    127         }
    128     }
    129 }
    130 
    131 void outputHandleName(void* userData, struct wl_output* wl_output, const char* name)
    132 {
    133     struct _GLFWmonitor* monitor = userData;
    134 
    135     strncpy(monitor->name, name, sizeof(monitor->name) - 1);
    136 }
    137 
    138 void outputHandleDescription(void* userData,
    139                              struct wl_output* wl_output,
    140                              const char* description)
    141 {
    142 }
    143 
    144 static const struct wl_output_listener outputListener =
    145 {
    146     outputHandleGeometry,
    147     outputHandleMode,
    148     outputHandleDone,
    149     outputHandleScale,
    150     outputHandleName,
    151     outputHandleDescription,
    152 };
    153 
    154 
    155 //////////////////////////////////////////////////////////////////////////
    156 //////                       GLFW internal API                      //////
    157 //////////////////////////////////////////////////////////////////////////
    158 
    159 void _glfwAddOutputWayland(uint32_t name, uint32_t version)
    160 {
    161     if (version < 2)
    162     {
    163         _glfwInputError(GLFW_PLATFORM_ERROR,
    164                         "Wayland: Unsupported output interface version");
    165         return;
    166     }
    167 
    168     version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);
    169 
    170     struct wl_output* output = wl_registry_bind(_glfw.wl.registry,
    171                                                 name,
    172                                                 &wl_output_interface,
    173                                                 version);
    174     if (!output)
    175         return;
    176 
    177     // The actual name of this output will be set in the geometry handler
    178     _GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
    179     monitor->wl.scale = 1;
    180     monitor->wl.output = output;
    181     monitor->wl.name = name;
    182 
    183     wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag);
    184     wl_output_add_listener(output, &outputListener, monitor);
    185 }
    186 
    187 
    188 //////////////////////////////////////////////////////////////////////////
    189 //////                       GLFW platform API                      //////
    190 //////////////////////////////////////////////////////////////////////////
    191 
    192 void _glfwFreeMonitorWayland(_GLFWmonitor* monitor)
    193 {
    194     if (monitor->wl.output)
    195         wl_output_destroy(monitor->wl.output);
    196 }
    197 
    198 void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos)
    199 {
    200     if (xpos)
    201         *xpos = monitor->wl.x;
    202     if (ypos)
    203         *ypos = monitor->wl.y;
    204 }
    205 
    206 void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor,
    207                                         float* xscale, float* yscale)
    208 {
    209     if (xscale)
    210         *xscale = (float) monitor->wl.scale;
    211     if (yscale)
    212         *yscale = (float) monitor->wl.scale;
    213 }
    214 
    215 void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor,
    216                                     int* xpos, int* ypos,
    217                                     int* width, int* height)
    218 {
    219     if (xpos)
    220         *xpos = monitor->wl.x;
    221     if (ypos)
    222         *ypos = monitor->wl.y;
    223     if (width)
    224         *width = monitor->modes[monitor->wl.currentMode].width;
    225     if (height)
    226         *height = monitor->modes[monitor->wl.currentMode].height;
    227 }
    228 
    229 GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* found)
    230 {
    231     *found = monitor->modeCount;
    232     return monitor->modes;
    233 }
    234 
    235 GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode)
    236 {
    237     *mode = monitor->modes[monitor->wl.currentMode];
    238     return GLFW_TRUE;
    239 }
    240 
    241 GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
    242 {
    243     _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
    244                     "Wayland: Gamma ramp access is not available");
    245     return GLFW_FALSE;
    246 }
    247 
    248 void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
    249 {
    250     _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
    251                     "Wayland: Gamma ramp access is not available");
    252 }
    253 
    254 
    255 //////////////////////////////////////////////////////////////////////////
    256 //////                        GLFW native API                       //////
    257 //////////////////////////////////////////////////////////////////////////
    258 
    259 GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
    260 {
    261     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
    262     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
    263 
    264     if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
    265     {
    266         _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Wayland: Platform not initialized");
    267         return NULL;
    268     }
    269 
    270     return monitor->wl.output;
    271 }
    272 
    273 #endif // _GLFW_WAYLAND
    274