zorldo

Goofing around with Ebiten
git clone git://bsandro.tech/zorldo
Log | Files | Refs | README

wl_monitor.c (7384B)


      1 //========================================================================
      2 // GLFW 3.3 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 
     38 static void outputHandleGeometry(void* data,
     39                                  struct wl_output* output,
     40                                  int32_t x,
     41                                  int32_t y,
     42                                  int32_t physicalWidth,
     43                                  int32_t physicalHeight,
     44                                  int32_t subpixel,
     45                                  const char* make,
     46                                  const char* model,
     47                                  int32_t transform)
     48 {
     49     struct _GLFWmonitor *monitor = data;
     50     char name[1024];
     51 
     52     monitor->wl.x = x;
     53     monitor->wl.y = y;
     54     monitor->widthMM = physicalWidth;
     55     monitor->heightMM = physicalHeight;
     56 
     57     snprintf(name, sizeof(name), "%s %s", make, model);
     58     monitor->name = _glfw_strdup(name);
     59 }
     60 
     61 static void outputHandleMode(void* data,
     62                              struct wl_output* output,
     63                              uint32_t flags,
     64                              int32_t width,
     65                              int32_t height,
     66                              int32_t refresh)
     67 {
     68     struct _GLFWmonitor *monitor = data;
     69     GLFWvidmode mode;
     70 
     71     mode.width = width;
     72     mode.height = height;
     73     mode.redBits = 8;
     74     mode.greenBits = 8;
     75     mode.blueBits = 8;
     76     mode.refreshRate = (int) round(refresh / 1000.0);
     77 
     78     monitor->modeCount++;
     79     monitor->modes =
     80         realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
     81     monitor->modes[monitor->modeCount - 1] = mode;
     82 
     83     if (flags & WL_OUTPUT_MODE_CURRENT)
     84         monitor->wl.currentMode = monitor->modeCount - 1;
     85 }
     86 
     87 static void outputHandleDone(void* data, struct wl_output* output)
     88 {
     89     struct _GLFWmonitor *monitor = data;
     90 
     91     if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
     92     {
     93         // If Wayland does not provide a physical size, assume the default 96 DPI
     94         const GLFWvidmode* mode = &monitor->modes[monitor->wl.currentMode];
     95         monitor->widthMM  = (int) (mode->width * 25.4f / 96.f);
     96         monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
     97     }
     98 
     99     _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
    100 }
    101 
    102 static void outputHandleScale(void* data,
    103                               struct wl_output* output,
    104                               int32_t factor)
    105 {
    106     struct _GLFWmonitor *monitor = data;
    107 
    108     monitor->wl.scale = factor;
    109 }
    110 
    111 static const struct wl_output_listener outputListener = {
    112     outputHandleGeometry,
    113     outputHandleMode,
    114     outputHandleDone,
    115     outputHandleScale,
    116 };
    117 
    118 
    119 //////////////////////////////////////////////////////////////////////////
    120 //////                       GLFW internal API                      //////
    121 //////////////////////////////////////////////////////////////////////////
    122 
    123 void _glfwAddOutputWayland(uint32_t name, uint32_t version)
    124 {
    125     _GLFWmonitor *monitor;
    126     struct wl_output *output;
    127 
    128     if (version < 2)
    129     {
    130         _glfwInputError(GLFW_PLATFORM_ERROR,
    131                         "Wayland: Unsupported output interface version");
    132         return;
    133     }
    134 
    135     // The actual name of this output will be set in the geometry handler.
    136     monitor = _glfwAllocMonitor(NULL, 0, 0);
    137 
    138     output = wl_registry_bind(_glfw.wl.registry,
    139                               name,
    140                               &wl_output_interface,
    141                               2);
    142     if (!output)
    143     {
    144         _glfwFreeMonitor(monitor);
    145         return;
    146     }
    147 
    148     monitor->wl.scale = 1;
    149     monitor->wl.output = output;
    150     monitor->wl.name = name;
    151 
    152     wl_output_add_listener(output, &outputListener, monitor);
    153 }
    154 
    155 
    156 //////////////////////////////////////////////////////////////////////////
    157 //////                       GLFW platform API                      //////
    158 //////////////////////////////////////////////////////////////////////////
    159 
    160 void _glfwPlatformFreeMonitor(_GLFWmonitor* monitor)
    161 {
    162     if (monitor->wl.output)
    163         wl_output_destroy(monitor->wl.output);
    164 }
    165 
    166 void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
    167 {
    168     if (xpos)
    169         *xpos = monitor->wl.x;
    170     if (ypos)
    171         *ypos = monitor->wl.y;
    172 }
    173 
    174 void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
    175                                          float* xscale, float* yscale)
    176 {
    177     if (xscale)
    178         *xscale = (float) monitor->wl.scale;
    179     if (yscale)
    180         *yscale = (float) monitor->wl.scale;
    181 }
    182 
    183 void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
    184                                      int* xpos, int* ypos,
    185                                      int* width, int* height)
    186 {
    187     if (xpos)
    188         *xpos = monitor->wl.x;
    189     if (ypos)
    190         *ypos = monitor->wl.y;
    191     if (width)
    192         *width = monitor->modes[monitor->wl.currentMode].width;
    193     if (height)
    194         *height = monitor->modes[monitor->wl.currentMode].height;
    195 }
    196 
    197 GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
    198 {
    199     *found = monitor->modeCount;
    200     return monitor->modes;
    201 }
    202 
    203 void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
    204 {
    205     *mode = monitor->modes[monitor->wl.currentMode];
    206 }
    207 
    208 GLFWbool _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
    209 {
    210     _glfwInputError(GLFW_PLATFORM_ERROR,
    211                     "Wayland: Gamma ramp access is not available");
    212     return GLFW_FALSE;
    213 }
    214 
    215 void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor,
    216                                const GLFWgammaramp* ramp)
    217 {
    218     _glfwInputError(GLFW_PLATFORM_ERROR,
    219                     "Wayland: Gamma ramp access is not available");
    220 }
    221 
    222 
    223 //////////////////////////////////////////////////////////////////////////
    224 //////                        GLFW native API                       //////
    225 //////////////////////////////////////////////////////////////////////////
    226 
    227 GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
    228 {
    229     _GLFWmonitor* monitor = (_GLFWmonitor*) handle;
    230     _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
    231     return monitor->wl.output;
    232 }
    233