window.c (32919B)
1 //======================================================================== 2 // GLFW 3.3 - www.glfw.org 3 //------------------------------------------------------------------------ 4 // Copyright (c) 2002-2006 Marcus Geelnard 5 // Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org> 6 // Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net> 7 // 8 // This software is provided 'as-is', without any express or implied 9 // warranty. In no event will the authors be held liable for any damages 10 // arising from the use of this software. 11 // 12 // Permission is granted to anyone to use this software for any purpose, 13 // including commercial applications, and to alter it and redistribute it 14 // freely, subject to the following restrictions: 15 // 16 // 1. The origin of this software must not be misrepresented; you must not 17 // claim that you wrote the original software. If you use this software 18 // in a product, an acknowledgment in the product documentation would 19 // be appreciated but is not required. 20 // 21 // 2. Altered source versions must be plainly marked as such, and must not 22 // be misrepresented as being the original software. 23 // 24 // 3. This notice may not be removed or altered from any source 25 // distribution. 26 // 27 //======================================================================== 28 // Please use C89 style variable declarations in this file because VS 2010 29 //======================================================================== 30 31 #include "internal.h" 32 33 #include <assert.h> 34 #include <string.h> 35 #include <stdlib.h> 36 #include <float.h> 37 38 39 ////////////////////////////////////////////////////////////////////////// 40 ////// GLFW event API ////// 41 ////////////////////////////////////////////////////////////////////////// 42 43 // Notifies shared code that a window has lost or received input focus 44 // 45 void _glfwInputWindowFocus(_GLFWwindow* window, GLFWbool focused) 46 { 47 if (window->callbacks.focus) 48 window->callbacks.focus((GLFWwindow*) window, focused); 49 50 if (!focused) 51 { 52 int key, button; 53 54 for (key = 0; key <= GLFW_KEY_LAST; key++) 55 { 56 if (window->keys[key] == GLFW_PRESS) 57 { 58 const int scancode = _glfwPlatformGetKeyScancode(key); 59 _glfwInputKey(window, key, scancode, GLFW_RELEASE, 0); 60 } 61 } 62 63 for (button = 0; button <= GLFW_MOUSE_BUTTON_LAST; button++) 64 { 65 if (window->mouseButtons[button] == GLFW_PRESS) 66 _glfwInputMouseClick(window, button, GLFW_RELEASE, 0); 67 } 68 } 69 } 70 71 // Notifies shared code that a window has moved 72 // The position is specified in content area relative screen coordinates 73 // 74 void _glfwInputWindowPos(_GLFWwindow* window, int x, int y) 75 { 76 if (window->callbacks.pos) 77 window->callbacks.pos((GLFWwindow*) window, x, y); 78 } 79 80 // Notifies shared code that a window has been resized 81 // The size is specified in screen coordinates 82 // 83 void _glfwInputWindowSize(_GLFWwindow* window, int width, int height) 84 { 85 if (window->callbacks.size) 86 window->callbacks.size((GLFWwindow*) window, width, height); 87 } 88 89 // Notifies shared code that a window has been iconified or restored 90 // 91 void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) 92 { 93 if (window->callbacks.iconify) 94 window->callbacks.iconify((GLFWwindow*) window, iconified); 95 } 96 97 // Notifies shared code that a window has been maximized or restored 98 // 99 void _glfwInputWindowMaximize(_GLFWwindow* window, GLFWbool maximized) 100 { 101 if (window->callbacks.maximize) 102 window->callbacks.maximize((GLFWwindow*) window, maximized); 103 } 104 105 // Notifies shared code that a window framebuffer has been resized 106 // The size is specified in pixels 107 // 108 void _glfwInputFramebufferSize(_GLFWwindow* window, int width, int height) 109 { 110 if (window->callbacks.fbsize) 111 window->callbacks.fbsize((GLFWwindow*) window, width, height); 112 } 113 114 // Notifies shared code that a window content scale has changed 115 // The scale is specified as the ratio between the current and default DPI 116 // 117 void _glfwInputWindowContentScale(_GLFWwindow* window, float xscale, float yscale) 118 { 119 if (window->callbacks.scale) 120 window->callbacks.scale((GLFWwindow*) window, xscale, yscale); 121 } 122 123 // Notifies shared code that the window contents needs updating 124 // 125 void _glfwInputWindowDamage(_GLFWwindow* window) 126 { 127 if (window->callbacks.refresh) 128 window->callbacks.refresh((GLFWwindow*) window); 129 } 130 131 // Notifies shared code that the user wishes to close a window 132 // 133 void _glfwInputWindowCloseRequest(_GLFWwindow* window) 134 { 135 window->shouldClose = GLFW_TRUE; 136 137 if (window->callbacks.close) 138 window->callbacks.close((GLFWwindow*) window); 139 } 140 141 // Notifies shared code that a window has changed its desired monitor 142 // 143 void _glfwInputWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor) 144 { 145 window->monitor = monitor; 146 } 147 148 ////////////////////////////////////////////////////////////////////////// 149 ////// GLFW public API ////// 150 ////////////////////////////////////////////////////////////////////////// 151 152 GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, 153 const char* title, 154 GLFWmonitor* monitor, 155 GLFWwindow* share) 156 { 157 _GLFWfbconfig fbconfig; 158 _GLFWctxconfig ctxconfig; 159 _GLFWwndconfig wndconfig; 160 _GLFWwindow* window; 161 162 assert(title != NULL); 163 assert(width >= 0); 164 assert(height >= 0); 165 166 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 167 168 if (width <= 0 || height <= 0) 169 { 170 _glfwInputError(GLFW_INVALID_VALUE, 171 "Invalid window size %ix%i", 172 width, height); 173 174 return NULL; 175 } 176 177 fbconfig = _glfw.hints.framebuffer; 178 ctxconfig = _glfw.hints.context; 179 wndconfig = _glfw.hints.window; 180 181 wndconfig.width = width; 182 wndconfig.height = height; 183 wndconfig.title = title; 184 ctxconfig.share = (_GLFWwindow*) share; 185 186 if (!_glfwIsValidContextConfig(&ctxconfig)) 187 return NULL; 188 189 window = calloc(1, sizeof(_GLFWwindow)); 190 window->next = _glfw.windowListHead; 191 _glfw.windowListHead = window; 192 193 window->videoMode.width = width; 194 window->videoMode.height = height; 195 window->videoMode.redBits = fbconfig.redBits; 196 window->videoMode.greenBits = fbconfig.greenBits; 197 window->videoMode.blueBits = fbconfig.blueBits; 198 window->videoMode.refreshRate = _glfw.hints.refreshRate; 199 200 window->monitor = (_GLFWmonitor*) monitor; 201 window->resizable = wndconfig.resizable; 202 window->decorated = wndconfig.decorated; 203 window->autoIconify = wndconfig.autoIconify; 204 window->floating = wndconfig.floating; 205 window->focusOnShow = wndconfig.focusOnShow; 206 window->cursorMode = GLFW_CURSOR_NORMAL; 207 208 window->minwidth = GLFW_DONT_CARE; 209 window->minheight = GLFW_DONT_CARE; 210 window->maxwidth = GLFW_DONT_CARE; 211 window->maxheight = GLFW_DONT_CARE; 212 window->numer = GLFW_DONT_CARE; 213 window->denom = GLFW_DONT_CARE; 214 215 // Open the actual window and create its context 216 if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig)) 217 { 218 glfwDestroyWindow((GLFWwindow*) window); 219 return NULL; 220 } 221 222 if (ctxconfig.client != GLFW_NO_API) 223 { 224 if (!_glfwRefreshContextAttribs(window, &ctxconfig)) 225 { 226 glfwDestroyWindow((GLFWwindow*) window); 227 return NULL; 228 } 229 } 230 231 if (window->monitor) 232 { 233 if (wndconfig.centerCursor) 234 _glfwCenterCursorInContentArea(window); 235 } 236 else 237 { 238 if (wndconfig.visible) 239 { 240 _glfwPlatformShowWindow(window); 241 if (wndconfig.focused) 242 _glfwPlatformFocusWindow(window); 243 } 244 } 245 246 return (GLFWwindow*) window; 247 } 248 249 void glfwDefaultWindowHints(void) 250 { 251 _GLFW_REQUIRE_INIT(); 252 253 // The default is OpenGL with minimum version 1.0 254 memset(&_glfw.hints.context, 0, sizeof(_glfw.hints.context)); 255 _glfw.hints.context.client = GLFW_OPENGL_API; 256 _glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API; 257 _glfw.hints.context.major = 1; 258 _glfw.hints.context.minor = 0; 259 260 // The default is a focused, visible, resizable window with decorations 261 memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window)); 262 _glfw.hints.window.resizable = GLFW_TRUE; 263 _glfw.hints.window.visible = GLFW_TRUE; 264 _glfw.hints.window.decorated = GLFW_TRUE; 265 _glfw.hints.window.focused = GLFW_TRUE; 266 _glfw.hints.window.autoIconify = GLFW_TRUE; 267 _glfw.hints.window.centerCursor = GLFW_TRUE; 268 _glfw.hints.window.focusOnShow = GLFW_TRUE; 269 270 // The default is 24 bits of color, 24 bits of depth and 8 bits of stencil, 271 // double buffered 272 memset(&_glfw.hints.framebuffer, 0, sizeof(_glfw.hints.framebuffer)); 273 _glfw.hints.framebuffer.redBits = 8; 274 _glfw.hints.framebuffer.greenBits = 8; 275 _glfw.hints.framebuffer.blueBits = 8; 276 _glfw.hints.framebuffer.alphaBits = 8; 277 _glfw.hints.framebuffer.depthBits = 24; 278 _glfw.hints.framebuffer.stencilBits = 8; 279 _glfw.hints.framebuffer.doublebuffer = GLFW_TRUE; 280 281 // The default is to select the highest available refresh rate 282 _glfw.hints.refreshRate = GLFW_DONT_CARE; 283 284 // The default is to use full Retina resolution framebuffers 285 _glfw.hints.window.ns.retina = GLFW_TRUE; 286 } 287 288 GLFWAPI void glfwWindowHint(int hint, int value) 289 { 290 _GLFW_REQUIRE_INIT(); 291 292 switch (hint) 293 { 294 case GLFW_RED_BITS: 295 _glfw.hints.framebuffer.redBits = value; 296 return; 297 case GLFW_GREEN_BITS: 298 _glfw.hints.framebuffer.greenBits = value; 299 return; 300 case GLFW_BLUE_BITS: 301 _glfw.hints.framebuffer.blueBits = value; 302 return; 303 case GLFW_ALPHA_BITS: 304 _glfw.hints.framebuffer.alphaBits = value; 305 return; 306 case GLFW_DEPTH_BITS: 307 _glfw.hints.framebuffer.depthBits = value; 308 return; 309 case GLFW_STENCIL_BITS: 310 _glfw.hints.framebuffer.stencilBits = value; 311 return; 312 case GLFW_ACCUM_RED_BITS: 313 _glfw.hints.framebuffer.accumRedBits = value; 314 return; 315 case GLFW_ACCUM_GREEN_BITS: 316 _glfw.hints.framebuffer.accumGreenBits = value; 317 return; 318 case GLFW_ACCUM_BLUE_BITS: 319 _glfw.hints.framebuffer.accumBlueBits = value; 320 return; 321 case GLFW_ACCUM_ALPHA_BITS: 322 _glfw.hints.framebuffer.accumAlphaBits = value; 323 return; 324 case GLFW_AUX_BUFFERS: 325 _glfw.hints.framebuffer.auxBuffers = value; 326 return; 327 case GLFW_STEREO: 328 _glfw.hints.framebuffer.stereo = value ? GLFW_TRUE : GLFW_FALSE; 329 return; 330 case GLFW_DOUBLEBUFFER: 331 _glfw.hints.framebuffer.doublebuffer = value ? GLFW_TRUE : GLFW_FALSE; 332 return; 333 case GLFW_TRANSPARENT_FRAMEBUFFER: 334 _glfw.hints.framebuffer.transparent = value ? GLFW_TRUE : GLFW_FALSE; 335 return; 336 case GLFW_SAMPLES: 337 _glfw.hints.framebuffer.samples = value; 338 return; 339 case GLFW_SRGB_CAPABLE: 340 _glfw.hints.framebuffer.sRGB = value ? GLFW_TRUE : GLFW_FALSE; 341 return; 342 case GLFW_RESIZABLE: 343 _glfw.hints.window.resizable = value ? GLFW_TRUE : GLFW_FALSE; 344 return; 345 case GLFW_DECORATED: 346 _glfw.hints.window.decorated = value ? GLFW_TRUE : GLFW_FALSE; 347 return; 348 case GLFW_FOCUSED: 349 _glfw.hints.window.focused = value ? GLFW_TRUE : GLFW_FALSE; 350 return; 351 case GLFW_AUTO_ICONIFY: 352 _glfw.hints.window.autoIconify = value ? GLFW_TRUE : GLFW_FALSE; 353 return; 354 case GLFW_FLOATING: 355 _glfw.hints.window.floating = value ? GLFW_TRUE : GLFW_FALSE; 356 return; 357 case GLFW_MAXIMIZED: 358 _glfw.hints.window.maximized = value ? GLFW_TRUE : GLFW_FALSE; 359 return; 360 case GLFW_VISIBLE: 361 _glfw.hints.window.visible = value ? GLFW_TRUE : GLFW_FALSE; 362 return; 363 case GLFW_COCOA_RETINA_FRAMEBUFFER: 364 _glfw.hints.window.ns.retina = value ? GLFW_TRUE : GLFW_FALSE; 365 return; 366 case GLFW_COCOA_GRAPHICS_SWITCHING: 367 _glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE; 368 return; 369 case GLFW_SCALE_TO_MONITOR: 370 _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; 371 return; 372 case GLFW_CENTER_CURSOR: 373 _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; 374 return; 375 case GLFW_FOCUS_ON_SHOW: 376 _glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE; 377 return; 378 case GLFW_CLIENT_API: 379 _glfw.hints.context.client = value; 380 return; 381 case GLFW_CONTEXT_CREATION_API: 382 _glfw.hints.context.source = value; 383 return; 384 case GLFW_CONTEXT_VERSION_MAJOR: 385 _glfw.hints.context.major = value; 386 return; 387 case GLFW_CONTEXT_VERSION_MINOR: 388 _glfw.hints.context.minor = value; 389 return; 390 case GLFW_CONTEXT_ROBUSTNESS: 391 _glfw.hints.context.robustness = value; 392 return; 393 case GLFW_OPENGL_FORWARD_COMPAT: 394 _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE; 395 return; 396 case GLFW_OPENGL_DEBUG_CONTEXT: 397 _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE; 398 return; 399 case GLFW_CONTEXT_NO_ERROR: 400 _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE; 401 return; 402 case GLFW_OPENGL_PROFILE: 403 _glfw.hints.context.profile = value; 404 return; 405 case GLFW_CONTEXT_RELEASE_BEHAVIOR: 406 _glfw.hints.context.release = value; 407 return; 408 case GLFW_REFRESH_RATE: 409 _glfw.hints.refreshRate = value; 410 return; 411 } 412 413 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint); 414 } 415 416 GLFWAPI void glfwWindowHintString(int hint, const char* value) 417 { 418 assert(value != NULL); 419 420 _GLFW_REQUIRE_INIT(); 421 422 switch (hint) 423 { 424 case GLFW_COCOA_FRAME_NAME: 425 strncpy(_glfw.hints.window.ns.frameName, value, 426 sizeof(_glfw.hints.window.ns.frameName) - 1); 427 return; 428 case GLFW_X11_CLASS_NAME: 429 strncpy(_glfw.hints.window.x11.className, value, 430 sizeof(_glfw.hints.window.x11.className) - 1); 431 return; 432 case GLFW_X11_INSTANCE_NAME: 433 strncpy(_glfw.hints.window.x11.instanceName, value, 434 sizeof(_glfw.hints.window.x11.instanceName) - 1); 435 return; 436 } 437 438 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint string 0x%08X", hint); 439 } 440 441 GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) 442 { 443 _GLFWwindow* window = (_GLFWwindow*) handle; 444 445 _GLFW_REQUIRE_INIT(); 446 447 // Allow closing of NULL (to match the behavior of free) 448 if (window == NULL) 449 return; 450 451 // Clear all callbacks to avoid exposing a half torn-down window object 452 memset(&window->callbacks, 0, sizeof(window->callbacks)); 453 454 // The window's context must not be current on another thread when the 455 // window is destroyed 456 if (window == _glfwPlatformGetTls(&_glfw.contextSlot)) 457 glfwMakeContextCurrent(NULL); 458 459 _glfwPlatformDestroyWindow(window); 460 461 // Unlink window from global linked list 462 { 463 _GLFWwindow** prev = &_glfw.windowListHead; 464 465 while (*prev != window) 466 prev = &((*prev)->next); 467 468 *prev = window->next; 469 } 470 471 free(window); 472 } 473 474 GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) 475 { 476 _GLFWwindow* window = (_GLFWwindow*) handle; 477 assert(window != NULL); 478 479 _GLFW_REQUIRE_INIT_OR_RETURN(0); 480 return window->shouldClose; 481 } 482 483 GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) 484 { 485 _GLFWwindow* window = (_GLFWwindow*) handle; 486 assert(window != NULL); 487 488 _GLFW_REQUIRE_INIT(); 489 window->shouldClose = value; 490 } 491 492 GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) 493 { 494 _GLFWwindow* window = (_GLFWwindow*) handle; 495 assert(window != NULL); 496 assert(title != NULL); 497 498 _GLFW_REQUIRE_INIT(); 499 _glfwPlatformSetWindowTitle(window, title); 500 } 501 502 GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, 503 int count, const GLFWimage* images) 504 { 505 _GLFWwindow* window = (_GLFWwindow*) handle; 506 assert(window != NULL); 507 assert(count >= 0); 508 assert(count == 0 || images != NULL); 509 510 _GLFW_REQUIRE_INIT(); 511 _glfwPlatformSetWindowIcon(window, count, images); 512 } 513 514 GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) 515 { 516 _GLFWwindow* window = (_GLFWwindow*) handle; 517 assert(window != NULL); 518 519 if (xpos) 520 *xpos = 0; 521 if (ypos) 522 *ypos = 0; 523 524 _GLFW_REQUIRE_INIT(); 525 _glfwPlatformGetWindowPos(window, xpos, ypos); 526 } 527 528 GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) 529 { 530 _GLFWwindow* window = (_GLFWwindow*) handle; 531 assert(window != NULL); 532 533 _GLFW_REQUIRE_INIT(); 534 535 if (window->monitor) 536 return; 537 538 _glfwPlatformSetWindowPos(window, xpos, ypos); 539 } 540 541 GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) 542 { 543 _GLFWwindow* window = (_GLFWwindow*) handle; 544 assert(window != NULL); 545 546 if (width) 547 *width = 0; 548 if (height) 549 *height = 0; 550 551 _GLFW_REQUIRE_INIT(); 552 _glfwPlatformGetWindowSize(window, width, height); 553 } 554 555 GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) 556 { 557 _GLFWwindow* window = (_GLFWwindow*) handle; 558 assert(window != NULL); 559 assert(width >= 0); 560 assert(height >= 0); 561 562 _GLFW_REQUIRE_INIT(); 563 564 window->videoMode.width = width; 565 window->videoMode.height = height; 566 567 _glfwPlatformSetWindowSize(window, width, height); 568 } 569 570 GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, 571 int minwidth, int minheight, 572 int maxwidth, int maxheight) 573 { 574 _GLFWwindow* window = (_GLFWwindow*) handle; 575 assert(window != NULL); 576 577 _GLFW_REQUIRE_INIT(); 578 579 if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE) 580 { 581 if (minwidth < 0 || minheight < 0) 582 { 583 _glfwInputError(GLFW_INVALID_VALUE, 584 "Invalid window minimum size %ix%i", 585 minwidth, minheight); 586 return; 587 } 588 } 589 590 if (maxwidth != GLFW_DONT_CARE && maxheight != GLFW_DONT_CARE) 591 { 592 if (maxwidth < 0 || maxheight < 0 || 593 maxwidth < minwidth || maxheight < minheight) 594 { 595 _glfwInputError(GLFW_INVALID_VALUE, 596 "Invalid window maximum size %ix%i", 597 maxwidth, maxheight); 598 return; 599 } 600 } 601 602 window->minwidth = minwidth; 603 window->minheight = minheight; 604 window->maxwidth = maxwidth; 605 window->maxheight = maxheight; 606 607 if (window->monitor || !window->resizable) 608 return; 609 610 _glfwPlatformSetWindowSizeLimits(window, 611 minwidth, minheight, 612 maxwidth, maxheight); 613 } 614 615 GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) 616 { 617 _GLFWwindow* window = (_GLFWwindow*) handle; 618 assert(window != NULL); 619 assert(numer != 0); 620 assert(denom != 0); 621 622 _GLFW_REQUIRE_INIT(); 623 624 if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) 625 { 626 if (numer <= 0 || denom <= 0) 627 { 628 _glfwInputError(GLFW_INVALID_VALUE, 629 "Invalid window aspect ratio %i:%i", 630 numer, denom); 631 return; 632 } 633 } 634 635 window->numer = numer; 636 window->denom = denom; 637 638 if (window->monitor || !window->resizable) 639 return; 640 641 _glfwPlatformSetWindowAspectRatio(window, numer, denom); 642 } 643 644 GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) 645 { 646 _GLFWwindow* window = (_GLFWwindow*) handle; 647 assert(window != NULL); 648 649 if (width) 650 *width = 0; 651 if (height) 652 *height = 0; 653 654 _GLFW_REQUIRE_INIT(); 655 _glfwPlatformGetFramebufferSize(window, width, height); 656 } 657 658 GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, 659 int* left, int* top, 660 int* right, int* bottom) 661 { 662 _GLFWwindow* window = (_GLFWwindow*) handle; 663 assert(window != NULL); 664 665 if (left) 666 *left = 0; 667 if (top) 668 *top = 0; 669 if (right) 670 *right = 0; 671 if (bottom) 672 *bottom = 0; 673 674 _GLFW_REQUIRE_INIT(); 675 _glfwPlatformGetWindowFrameSize(window, left, top, right, bottom); 676 } 677 678 GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle, 679 float* xscale, float* yscale) 680 { 681 _GLFWwindow* window = (_GLFWwindow*) handle; 682 assert(window != NULL); 683 684 if (xscale) 685 *xscale = 0.f; 686 if (yscale) 687 *yscale = 0.f; 688 689 _GLFW_REQUIRE_INIT(); 690 _glfwPlatformGetWindowContentScale(window, xscale, yscale); 691 } 692 693 GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) 694 { 695 _GLFWwindow* window = (_GLFWwindow*) handle; 696 assert(window != NULL); 697 698 _GLFW_REQUIRE_INIT_OR_RETURN(1.f); 699 return _glfwPlatformGetWindowOpacity(window); 700 } 701 702 GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) 703 { 704 _GLFWwindow* window = (_GLFWwindow*) handle; 705 assert(window != NULL); 706 assert(opacity == opacity); 707 assert(opacity >= 0.f); 708 assert(opacity <= 1.f); 709 710 _GLFW_REQUIRE_INIT(); 711 712 if (opacity != opacity || opacity < 0.f || opacity > 1.f) 713 { 714 _glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity); 715 return; 716 } 717 718 _glfwPlatformSetWindowOpacity(window, opacity); 719 } 720 721 GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) 722 { 723 _GLFWwindow* window = (_GLFWwindow*) handle; 724 assert(window != NULL); 725 726 _GLFW_REQUIRE_INIT(); 727 _glfwPlatformIconifyWindow(window); 728 } 729 730 GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) 731 { 732 _GLFWwindow* window = (_GLFWwindow*) handle; 733 assert(window != NULL); 734 735 _GLFW_REQUIRE_INIT(); 736 _glfwPlatformRestoreWindow(window); 737 } 738 739 GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) 740 { 741 _GLFWwindow* window = (_GLFWwindow*) handle; 742 assert(window != NULL); 743 744 _GLFW_REQUIRE_INIT(); 745 746 if (window->monitor) 747 return; 748 749 _glfwPlatformMaximizeWindow(window); 750 } 751 752 GLFWAPI void glfwShowWindow(GLFWwindow* handle) 753 { 754 _GLFWwindow* window = (_GLFWwindow*) handle; 755 assert(window != NULL); 756 757 _GLFW_REQUIRE_INIT(); 758 759 if (window->monitor) 760 return; 761 762 _glfwPlatformShowWindow(window); 763 764 if (window->focusOnShow) 765 _glfwPlatformFocusWindow(window); 766 } 767 768 GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) 769 { 770 _GLFWwindow* window = (_GLFWwindow*) handle; 771 assert(window != NULL); 772 773 _GLFW_REQUIRE_INIT(); 774 775 _glfwPlatformRequestWindowAttention(window); 776 } 777 778 GLFWAPI void glfwHideWindow(GLFWwindow* handle) 779 { 780 _GLFWwindow* window = (_GLFWwindow*) handle; 781 assert(window != NULL); 782 783 _GLFW_REQUIRE_INIT(); 784 785 if (window->monitor) 786 return; 787 788 _glfwPlatformHideWindow(window); 789 } 790 791 GLFWAPI void glfwFocusWindow(GLFWwindow* handle) 792 { 793 _GLFWwindow* window = (_GLFWwindow*) handle; 794 assert(window != NULL); 795 796 _GLFW_REQUIRE_INIT(); 797 798 _glfwPlatformFocusWindow(window); 799 } 800 801 GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) 802 { 803 _GLFWwindow* window = (_GLFWwindow*) handle; 804 assert(window != NULL); 805 806 _GLFW_REQUIRE_INIT_OR_RETURN(0); 807 808 switch (attrib) 809 { 810 case GLFW_FOCUSED: 811 return _glfwPlatformWindowFocused(window); 812 case GLFW_ICONIFIED: 813 return _glfwPlatformWindowIconified(window); 814 case GLFW_VISIBLE: 815 return _glfwPlatformWindowVisible(window); 816 case GLFW_MAXIMIZED: 817 return _glfwPlatformWindowMaximized(window); 818 case GLFW_HOVERED: 819 return _glfwPlatformWindowHovered(window); 820 case GLFW_FOCUS_ON_SHOW: 821 return window->focusOnShow; 822 case GLFW_TRANSPARENT_FRAMEBUFFER: 823 return _glfwPlatformFramebufferTransparent(window); 824 case GLFW_RESIZABLE: 825 return window->resizable; 826 case GLFW_DECORATED: 827 return window->decorated; 828 case GLFW_FLOATING: 829 return window->floating; 830 case GLFW_AUTO_ICONIFY: 831 return window->autoIconify; 832 case GLFW_CLIENT_API: 833 return window->context.client; 834 case GLFW_CONTEXT_CREATION_API: 835 return window->context.source; 836 case GLFW_CONTEXT_VERSION_MAJOR: 837 return window->context.major; 838 case GLFW_CONTEXT_VERSION_MINOR: 839 return window->context.minor; 840 case GLFW_CONTEXT_REVISION: 841 return window->context.revision; 842 case GLFW_CONTEXT_ROBUSTNESS: 843 return window->context.robustness; 844 case GLFW_OPENGL_FORWARD_COMPAT: 845 return window->context.forward; 846 case GLFW_OPENGL_DEBUG_CONTEXT: 847 return window->context.debug; 848 case GLFW_OPENGL_PROFILE: 849 return window->context.profile; 850 case GLFW_CONTEXT_RELEASE_BEHAVIOR: 851 return window->context.release; 852 case GLFW_CONTEXT_NO_ERROR: 853 return window->context.noerror; 854 } 855 856 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); 857 return 0; 858 } 859 860 GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) 861 { 862 _GLFWwindow* window = (_GLFWwindow*) handle; 863 assert(window != NULL); 864 865 _GLFW_REQUIRE_INIT(); 866 867 value = value ? GLFW_TRUE : GLFW_FALSE; 868 869 if (attrib == GLFW_AUTO_ICONIFY) 870 window->autoIconify = value; 871 else if (attrib == GLFW_RESIZABLE) 872 { 873 if (window->resizable == value) 874 return; 875 876 window->resizable = value; 877 if (!window->monitor) 878 _glfwPlatformSetWindowResizable(window, value); 879 } 880 else if (attrib == GLFW_DECORATED) 881 { 882 if (window->decorated == value) 883 return; 884 885 window->decorated = value; 886 if (!window->monitor) 887 _glfwPlatformSetWindowDecorated(window, value); 888 } 889 else if (attrib == GLFW_FLOATING) 890 { 891 if (window->floating == value) 892 return; 893 894 window->floating = value; 895 if (!window->monitor) 896 _glfwPlatformSetWindowFloating(window, value); 897 } 898 else if (attrib == GLFW_FOCUS_ON_SHOW) 899 window->focusOnShow = value; 900 else 901 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); 902 } 903 904 GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) 905 { 906 _GLFWwindow* window = (_GLFWwindow*) handle; 907 assert(window != NULL); 908 909 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 910 return (GLFWmonitor*) window->monitor; 911 } 912 913 GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh, 914 GLFWmonitor* mh, 915 int xpos, int ypos, 916 int width, int height, 917 int refreshRate) 918 { 919 _GLFWwindow* window = (_GLFWwindow*) wh; 920 _GLFWmonitor* monitor = (_GLFWmonitor*) mh; 921 assert(window != NULL); 922 assert(width >= 0); 923 assert(height >= 0); 924 925 _GLFW_REQUIRE_INIT(); 926 927 if (width <= 0 || height <= 0) 928 { 929 _glfwInputError(GLFW_INVALID_VALUE, 930 "Invalid window size %ix%i", 931 width, height); 932 return; 933 } 934 935 if (refreshRate < 0 && refreshRate != GLFW_DONT_CARE) 936 { 937 _glfwInputError(GLFW_INVALID_VALUE, 938 "Invalid refresh rate %i", 939 refreshRate); 940 return; 941 } 942 943 window->videoMode.width = width; 944 window->videoMode.height = height; 945 window->videoMode.refreshRate = refreshRate; 946 947 _glfwPlatformSetWindowMonitor(window, monitor, 948 xpos, ypos, width, height, 949 refreshRate); 950 } 951 952 GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) 953 { 954 _GLFWwindow* window = (_GLFWwindow*) handle; 955 assert(window != NULL); 956 957 _GLFW_REQUIRE_INIT(); 958 window->userPointer = pointer; 959 } 960 961 GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) 962 { 963 _GLFWwindow* window = (_GLFWwindow*) handle; 964 assert(window != NULL); 965 966 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 967 return window->userPointer; 968 } 969 970 GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, 971 GLFWwindowposfun cbfun) 972 { 973 _GLFWwindow* window = (_GLFWwindow*) handle; 974 assert(window != NULL); 975 976 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 977 _GLFW_SWAP_POINTERS(window->callbacks.pos, cbfun); 978 return cbfun; 979 } 980 981 GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, 982 GLFWwindowsizefun cbfun) 983 { 984 _GLFWwindow* window = (_GLFWwindow*) handle; 985 assert(window != NULL); 986 987 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 988 _GLFW_SWAP_POINTERS(window->callbacks.size, cbfun); 989 return cbfun; 990 } 991 992 GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, 993 GLFWwindowclosefun cbfun) 994 { 995 _GLFWwindow* window = (_GLFWwindow*) handle; 996 assert(window != NULL); 997 998 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 999 _GLFW_SWAP_POINTERS(window->callbacks.close, cbfun); 1000 return cbfun; 1001 } 1002 1003 GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, 1004 GLFWwindowrefreshfun cbfun) 1005 { 1006 _GLFWwindow* window = (_GLFWwindow*) handle; 1007 assert(window != NULL); 1008 1009 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1010 _GLFW_SWAP_POINTERS(window->callbacks.refresh, cbfun); 1011 return cbfun; 1012 } 1013 1014 GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, 1015 GLFWwindowfocusfun cbfun) 1016 { 1017 _GLFWwindow* window = (_GLFWwindow*) handle; 1018 assert(window != NULL); 1019 1020 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1021 _GLFW_SWAP_POINTERS(window->callbacks.focus, cbfun); 1022 return cbfun; 1023 } 1024 1025 GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, 1026 GLFWwindowiconifyfun cbfun) 1027 { 1028 _GLFWwindow* window = (_GLFWwindow*) handle; 1029 assert(window != NULL); 1030 1031 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1032 _GLFW_SWAP_POINTERS(window->callbacks.iconify, cbfun); 1033 return cbfun; 1034 } 1035 1036 GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle, 1037 GLFWwindowmaximizefun cbfun) 1038 { 1039 _GLFWwindow* window = (_GLFWwindow*) handle; 1040 assert(window != NULL); 1041 1042 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1043 _GLFW_SWAP_POINTERS(window->callbacks.maximize, cbfun); 1044 return cbfun; 1045 } 1046 1047 GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle, 1048 GLFWframebuffersizefun cbfun) 1049 { 1050 _GLFWwindow* window = (_GLFWwindow*) handle; 1051 assert(window != NULL); 1052 1053 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1054 _GLFW_SWAP_POINTERS(window->callbacks.fbsize, cbfun); 1055 return cbfun; 1056 } 1057 1058 GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle, 1059 GLFWwindowcontentscalefun cbfun) 1060 { 1061 _GLFWwindow* window = (_GLFWwindow*) handle; 1062 assert(window != NULL); 1063 1064 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1065 _GLFW_SWAP_POINTERS(window->callbacks.scale, cbfun); 1066 return cbfun; 1067 } 1068 1069 GLFWAPI void glfwPollEvents(void) 1070 { 1071 _GLFW_REQUIRE_INIT(); 1072 _glfwPlatformPollEvents(); 1073 } 1074 1075 GLFWAPI void glfwWaitEvents(void) 1076 { 1077 _GLFW_REQUIRE_INIT(); 1078 _glfwPlatformWaitEvents(); 1079 } 1080 1081 GLFWAPI void glfwWaitEventsTimeout(double timeout) 1082 { 1083 _GLFW_REQUIRE_INIT(); 1084 assert(timeout == timeout); 1085 assert(timeout >= 0.0); 1086 assert(timeout <= DBL_MAX); 1087 1088 if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX) 1089 { 1090 _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout); 1091 return; 1092 } 1093 1094 _glfwPlatformWaitEventsTimeout(timeout); 1095 } 1096 1097 GLFWAPI void glfwPostEmptyEvent(void) 1098 { 1099 _GLFW_REQUIRE_INIT(); 1100 _glfwPlatformPostEmptyEvent(); 1101 } 1102