ScrapExplorer - monitor.c

Home / ext / glfw / src Lines: 1 | Size: 15201 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1//======================================================================== 2// GLFW 3.5 - www.glfw.org 3//------------------------------------------------------------------------ 4// Copyright (c) 2002-2006 Marcus Geelnard 5// Copyright (c) 2006-2019 Camilla Löwy <[email protected]> 6// 7// This software is provided 'as-is', without any express or implied 8// warranty. In no event will the authors be held liable for any damages 9// arising from the use of this software. 10// 11// Permission is granted to anyone to use this software for any purpose, 12// including commercial applications, and to alter it and redistribute it 13// freely, subject to the following restrictions: 14// 15// 1. The origin of this software must not be misrepresented; you must not 16// claim that you wrote the original software. If you use this software 17// in a product, an acknowledgment in the product documentation would 18// be appreciated but is not required. 19// 20// 2. Altered source versions must be plainly marked as such, and must not 21// be misrepresented as being the original software. 22// 23// 3. This notice may not be removed or altered from any source 24// distribution. 25// 26//======================================================================== 27 28#include "internal.h" 29 30#include <assert.h> 31#include <math.h> 32#include <float.h> 33#include <string.h> 34#include <stdlib.h> 35#include <limits.h> 36 37 38// Lexically compare video modes, used by qsort 39// 40static int compareVideoModes(const void* fp, const void* sp) 41{ 42 const GLFWvidmode* fm = fp; 43 const GLFWvidmode* sm = sp; 44 const int fbpp = fm->redBits + fm->greenBits + fm->blueBits; 45 const int sbpp = sm->redBits + sm->greenBits + sm->blueBits; 46 const int farea = fm->width * fm->height; 47 const int sarea = sm->width * sm->height; 48 49 // First sort on color bits per pixel 50 if (fbpp != sbpp) 51 return fbpp - sbpp; 52 53 // Then sort on screen area 54 if (farea != sarea) 55 return farea - sarea; 56 57 // Then sort on width 58 if (fm->width != sm->width) 59 return fm->width - sm->width; 60 61 // Lastly sort on refresh rate 62 return fm->refreshRate - sm->refreshRate; 63} 64 65// Retrieves the available modes for the specified monitor 66// 67static GLFWbool refreshVideoModes(_GLFWmonitor* monitor) 68{ 69 int modeCount; 70 GLFWvidmode* modes; 71 72 if (monitor->modes) 73 return GLFW_TRUE; 74 75 modes = _glfw.platform.getVideoModes(monitor, &modeCount); 76 if (!modes) 77 return GLFW_FALSE; 78 79 qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes); 80 81 _glfw_free(monitor->modes); 82 monitor->modes = modes; 83 monitor->modeCount = modeCount; 84 85 return GLFW_TRUE; 86} 87 88 89////////////////////////////////////////////////////////////////////////// 90////// GLFW event API ////// 91////////////////////////////////////////////////////////////////////////// 92 93// Notifies shared code of a monitor connection or disconnection 94// 95void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement) 96{ 97 assert(monitor != NULL); 98 assert(action == GLFW_CONNECTED || action == GLFW_DISCONNECTED); 99 assert(placement == _GLFW_INSERT_FIRST || placement == _GLFW_INSERT_LAST); 100 101 if (action == GLFW_CONNECTED) 102 { 103 _glfw.monitorCount++; 104 _glfw.monitors = 105 _glfw_realloc(_glfw.monitors, 106 sizeof(_GLFWmonitor*) * _glfw.monitorCount); 107 108 if (placement == _GLFW_INSERT_FIRST) 109 { 110 memmove(_glfw.monitors + 1, 111 _glfw.monitors, 112 ((size_t) _glfw.monitorCount - 1) * sizeof(_GLFWmonitor*)); 113 _glfw.monitors[0] = monitor; 114 } 115 else 116 _glfw.monitors[_glfw.monitorCount - 1] = monitor; 117 } 118 else if (action == GLFW_DISCONNECTED) 119 { 120 int i; 121 _GLFWwindow* window; 122 123 for (window = _glfw.windowListHead; window; window = window->next) 124 { 125 if (window->monitor == monitor) 126 { 127 int width, height, xoff, yoff; 128 _glfw.platform.getWindowSize(window, &width, &height); 129 _glfw.platform.setWindowMonitor(window, NULL, 0, 0, width, height, 0); 130 _glfw.platform.getWindowFrameSize(window, &xoff, &yoff, NULL, NULL); 131 _glfw.platform.setWindowPos(window, xoff, yoff); 132 } 133 } 134 135 for (i = 0; i < _glfw.monitorCount; i++) 136 { 137 if (_glfw.monitors[i] == monitor) 138 { 139 _glfw.monitorCount--; 140 memmove(_glfw.monitors + i, 141 _glfw.monitors + i + 1, 142 ((size_t) _glfw.monitorCount - i) * sizeof(_GLFWmonitor*)); 143 break; 144 } 145 } 146 } 147 148 if (_glfw.callbacks.monitor) 149 _glfw.callbacks.monitor((GLFWmonitor*) monitor, action); 150 151 if (action == GLFW_DISCONNECTED) 152 _glfwFreeMonitor(monitor); 153} 154 155// Notifies shared code that a full screen window has acquired or released 156// a monitor 157// 158void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window) 159{ 160 assert(monitor != NULL); 161 monitor->window = window; 162} 163 164 165////////////////////////////////////////////////////////////////////////// 166////// GLFW internal API ////// 167////////////////////////////////////////////////////////////////////////// 168 169// Allocates and returns a monitor object with the specified name and dimensions 170// 171_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM) 172{ 173 _GLFWmonitor* monitor = _glfw_calloc(1, sizeof(_GLFWmonitor)); 174 monitor->widthMM = widthMM; 175 monitor->heightMM = heightMM; 176 177 strncpy(monitor->name, name, sizeof(monitor->name) - 1); 178 179 return monitor; 180} 181 182// Frees a monitor object and any data associated with it 183// 184void _glfwFreeMonitor(_GLFWmonitor* monitor) 185{ 186 if (monitor == NULL) 187 return; 188 189 _glfw.platform.freeMonitor(monitor); 190 191 _glfwFreeGammaArrays(&monitor->originalRamp); 192 _glfwFreeGammaArrays(&monitor->currentRamp); 193 194 _glfw_free(monitor->modes); 195 _glfw_free(monitor); 196} 197 198// Allocates red, green and blue value arrays of the specified size 199// 200void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size) 201{ 202 ramp->red = _glfw_calloc(size, sizeof(unsigned short)); 203 ramp->green = _glfw_calloc(size, sizeof(unsigned short)); 204 ramp->blue = _glfw_calloc(size, sizeof(unsigned short)); 205 ramp->size = size; 206} 207 208// Frees the red, green and blue value arrays and clears the struct 209// 210void _glfwFreeGammaArrays(GLFWgammaramp* ramp) 211{ 212 _glfw_free(ramp->red); 213 _glfw_free(ramp->green); 214 _glfw_free(ramp->blue); 215 216 memset(ramp, 0, sizeof(GLFWgammaramp)); 217} 218 219// Chooses the video mode most closely matching the desired one 220// 221const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor, 222 const GLFWvidmode* desired) 223{ 224 int i; 225 unsigned int sizeDiff, leastSizeDiff = UINT_MAX; 226 unsigned int rateDiff, leastRateDiff = UINT_MAX; 227 unsigned int colorDiff, leastColorDiff = UINT_MAX; 228 const GLFWvidmode* current; 229 const GLFWvidmode* closest = NULL; 230 231 if (!refreshVideoModes(monitor)) 232 return NULL; 233 234 for (i = 0; i < monitor->modeCount; i++) 235 { 236 current = monitor->modes + i; 237 238 colorDiff = 0; 239 240 if (desired->redBits != GLFW_DONT_CARE) 241 colorDiff += abs(current->redBits - desired->redBits); 242 if (desired->greenBits != GLFW_DONT_CARE) 243 colorDiff += abs(current->greenBits - desired->greenBits); 244 if (desired->blueBits != GLFW_DONT_CARE) 245 colorDiff += abs(current->blueBits - desired->blueBits); 246 247 sizeDiff = abs((current->width - desired->width) * 248 (current->width - desired->width) + 249 (current->height - desired->height) * 250 (current->height - desired->height)); 251 252 if (desired->refreshRate != GLFW_DONT_CARE) 253 rateDiff = abs(current->refreshRate - desired->refreshRate); 254 else 255 rateDiff = UINT_MAX - current->refreshRate; 256 257 if ((colorDiff < leastColorDiff) || 258 (colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) || 259 (colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff)) 260 { 261 closest = current; 262 leastSizeDiff = sizeDiff; 263 leastRateDiff = rateDiff; 264 leastColorDiff = colorDiff; 265 } 266 } 267 268 return closest; 269} 270 271// Performs lexical comparison between two @ref GLFWvidmode structures 272// 273int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm) 274{ 275 return compareVideoModes(fm, sm); 276} 277 278// Splits a color depth into red, green and blue bit depths 279// 280void _glfwSplitBPP(int bpp, int* red, int* green, int* blue) 281{ 282 int delta; 283 284 // We assume that by 32 the user really meant 24 285 if (bpp == 32) 286 bpp = 24; 287 288 // Convert "bits per pixel" to red, green & blue sizes 289 290 *red = *green = *blue = bpp / 3; 291 delta = bpp - (*red * 3); 292 if (delta >= 1) 293 *green = *green + 1; 294 295 if (delta == 2) 296 *red = *red + 1; 297} 298 299 300////////////////////////////////////////////////////////////////////////// 301////// GLFW public API ////// 302////////////////////////////////////////////////////////////////////////// 303 304GLFWAPI GLFWmonitor** glfwGetMonitors(int* count) 305{ 306 assert(count != NULL); 307 308 *count = 0; 309 310 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 311 312 *count = _glfw.monitorCount; 313 return (GLFWmonitor**) _glfw.monitors; 314} 315 316GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void) 317{ 318 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 319 320 if (!_glfw.monitorCount) 321 return NULL; 322 323 return (GLFWmonitor*) _glfw.monitors[0]; 324} 325 326GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos) 327{ 328 if (xpos) 329 *xpos = 0; 330 if (ypos) 331 *ypos = 0; 332 333 _GLFW_REQUIRE_INIT(); 334 335 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 336 assert(monitor != NULL); 337 338 _glfw.platform.getMonitorPos(monitor, xpos, ypos); 339} 340 341GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle, 342 int* xpos, int* ypos, 343 int* width, int* height) 344{ 345 if (xpos) 346 *xpos = 0; 347 if (ypos) 348 *ypos = 0; 349 if (width) 350 *width = 0; 351 if (height) 352 *height = 0; 353 354 _GLFW_REQUIRE_INIT(); 355 356 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 357 assert(monitor != NULL); 358 359 _glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height); 360} 361 362GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM) 363{ 364 if (widthMM) 365 *widthMM = 0; 366 if (heightMM) 367 *heightMM = 0; 368 369 _GLFW_REQUIRE_INIT(); 370 371 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 372 assert(monitor != NULL); 373 374 if (widthMM) 375 *widthMM = monitor->widthMM; 376 if (heightMM) 377 *heightMM = monitor->heightMM; 378} 379 380GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle, 381 float* xscale, float* yscale) 382{ 383 if (xscale) 384 *xscale = 0.f; 385 if (yscale) 386 *yscale = 0.f; 387 388 _GLFW_REQUIRE_INIT(); 389 390 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 391 assert(monitor != NULL); 392 393 _glfw.platform.getMonitorContentScale(monitor, xscale, yscale); 394} 395 396GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle) 397{ 398 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 399 400 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 401 assert(monitor != NULL); 402 403 return monitor->name; 404} 405 406GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer) 407{ 408 _GLFW_REQUIRE_INIT(); 409 410 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 411 assert(monitor != NULL); 412 413 monitor->userPointer = pointer; 414} 415 416GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle) 417{ 418 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 419 420 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 421 assert(monitor != NULL); 422 423 return monitor->userPointer; 424} 425 426GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun) 427{ 428 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 429 _GLFW_SWAP(GLFWmonitorfun, _glfw.callbacks.monitor, cbfun); 430 return cbfun; 431} 432 433GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count) 434{ 435 assert(count != NULL); 436 437 *count = 0; 438 439 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 440 441 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 442 assert(monitor != NULL); 443 444 if (!refreshVideoModes(monitor)) 445 return NULL; 446 447 *count = monitor->modeCount; 448 return monitor->modes; 449} 450 451GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) 452{ 453 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 454 455 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 456 assert(monitor != NULL); 457 458 if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode)) 459 return NULL; 460 461 return &monitor->currentMode; 462} 463 464GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) 465{ 466 unsigned int i; 467 unsigned short* values; 468 GLFWgammaramp ramp; 469 const GLFWgammaramp* original; 470 assert(gamma > 0.f); 471 assert(gamma <= FLT_MAX); 472 473 _GLFW_REQUIRE_INIT(); 474 475 assert(handle != NULL); 476 477 if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX) 478 { 479 _glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma); 480 return; 481 } 482 483 original = glfwGetGammaRamp(handle); 484 if (!original) 485 return; 486 487 values = _glfw_calloc(original->size, sizeof(unsigned short)); 488 489 for (i = 0; i < original->size; i++) 490 { 491 float value; 492 493 // Calculate intensity 494 value = i / (float) (original->size - 1); 495 // Apply gamma curve 496 value = powf(value, 1.f / gamma) * 65535.f + 0.5f; 497 // Clamp to value range 498 value = fminf(value, 65535.f); 499 500 values[i] = (unsigned short) value; 501 } 502 503 ramp.red = values; 504 ramp.green = values; 505 ramp.blue = values; 506 ramp.size = original->size; 507 508 glfwSetGammaRamp(handle, &ramp); 509 _glfw_free(values); 510} 511 512GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle) 513{ 514 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 515 516 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 517 assert(monitor != NULL); 518 519 _glfwFreeGammaArrays(&monitor->currentRamp); 520 if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp)) 521 return NULL; 522 523 return &monitor->currentRamp; 524} 525 526GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp) 527{ 528 assert(ramp != NULL); 529 assert(ramp->size > 0); 530 assert(ramp->red != NULL); 531 assert(ramp->green != NULL); 532 assert(ramp->blue != NULL); 533 534 _GLFW_REQUIRE_INIT(); 535 536 _GLFWmonitor* monitor = (_GLFWmonitor*) handle; 537 assert(monitor != NULL); 538 539 if (ramp->size <= 0) 540 { 541 _glfwInputError(GLFW_INVALID_VALUE, 542 "Invalid gamma ramp size %i", 543 ramp->size); 544 return; 545 } 546 547 if (!monitor->originalRamp.size) 548 { 549 if (!_glfw.platform.getGammaRamp(monitor, &monitor->originalRamp)) 550 return; 551 } 552 553 _glfw.platform.setGammaRamp(monitor, ramp); 554} 555 556
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.