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