window.c (33265B)
1 //======================================================================== 2 // GLFW 3.4 - 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 = (_GLFWwindow*)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_WIN32_KEYBOARD_MENU: 367 _glfw.hints.window.win32.keymenu = value ? GLFW_TRUE : GLFW_FALSE; 368 return; 369 case GLFW_COCOA_GRAPHICS_SWITCHING: 370 _glfw.hints.context.nsgl.offline = value ? GLFW_TRUE : GLFW_FALSE; 371 return; 372 case GLFW_SCALE_TO_MONITOR: 373 _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; 374 return; 375 case GLFW_CENTER_CURSOR: 376 _glfw.hints.window.centerCursor = value ? GLFW_TRUE : GLFW_FALSE; 377 return; 378 case GLFW_FOCUS_ON_SHOW: 379 _glfw.hints.window.focusOnShow = value ? GLFW_TRUE : GLFW_FALSE; 380 return; 381 case GLFW_CLIENT_API: 382 _glfw.hints.context.client = value; 383 return; 384 case GLFW_CONTEXT_CREATION_API: 385 _glfw.hints.context.source = value; 386 return; 387 case GLFW_CONTEXT_VERSION_MAJOR: 388 _glfw.hints.context.major = value; 389 return; 390 case GLFW_CONTEXT_VERSION_MINOR: 391 _glfw.hints.context.minor = value; 392 return; 393 case GLFW_CONTEXT_ROBUSTNESS: 394 _glfw.hints.context.robustness = value; 395 return; 396 case GLFW_OPENGL_FORWARD_COMPAT: 397 _glfw.hints.context.forward = value ? GLFW_TRUE : GLFW_FALSE; 398 return; 399 case GLFW_OPENGL_DEBUG_CONTEXT: 400 _glfw.hints.context.debug = value ? GLFW_TRUE : GLFW_FALSE; 401 return; 402 case GLFW_CONTEXT_NO_ERROR: 403 _glfw.hints.context.noerror = value ? GLFW_TRUE : GLFW_FALSE; 404 return; 405 case GLFW_OPENGL_PROFILE: 406 _glfw.hints.context.profile = value; 407 return; 408 case GLFW_CONTEXT_RELEASE_BEHAVIOR: 409 _glfw.hints.context.release = value; 410 return; 411 case GLFW_REFRESH_RATE: 412 _glfw.hints.refreshRate = value; 413 return; 414 } 415 416 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint); 417 } 418 419 GLFWAPI void glfwWindowHintString(int hint, const char* value) 420 { 421 assert(value != NULL); 422 423 _GLFW_REQUIRE_INIT(); 424 425 switch (hint) 426 { 427 case GLFW_COCOA_FRAME_NAME: 428 strncpy(_glfw.hints.window.ns.frameName, value, 429 sizeof(_glfw.hints.window.ns.frameName) - 1); 430 return; 431 case GLFW_X11_CLASS_NAME: 432 strncpy(_glfw.hints.window.x11.className, value, 433 sizeof(_glfw.hints.window.x11.className) - 1); 434 return; 435 case GLFW_X11_INSTANCE_NAME: 436 strncpy(_glfw.hints.window.x11.instanceName, value, 437 sizeof(_glfw.hints.window.x11.instanceName) - 1); 438 return; 439 } 440 441 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint string 0x%08X", hint); 442 } 443 444 GLFWAPI void glfwDestroyWindow(GLFWwindow* handle) 445 { 446 _GLFWwindow* window = (_GLFWwindow*) handle; 447 448 _GLFW_REQUIRE_INIT(); 449 450 // Allow closing of NULL (to match the behavior of free) 451 if (window == NULL) 452 return; 453 454 // Clear all callbacks to avoid exposing a half torn-down window object 455 memset(&window->callbacks, 0, sizeof(window->callbacks)); 456 457 // The window's context must not be current on another thread when the 458 // window is destroyed 459 if (window == _glfwPlatformGetTls(&_glfw.contextSlot)) 460 glfwMakeContextCurrent(NULL); 461 462 _glfwPlatformDestroyWindow(window); 463 464 // Unlink window from global linked list 465 { 466 _GLFWwindow** prev = &_glfw.windowListHead; 467 468 while (*prev != window) 469 prev = &((*prev)->next); 470 471 *prev = window->next; 472 } 473 474 free(window); 475 } 476 477 GLFWAPI int glfwWindowShouldClose(GLFWwindow* handle) 478 { 479 _GLFWwindow* window = (_GLFWwindow*) handle; 480 assert(window != NULL); 481 482 _GLFW_REQUIRE_INIT_OR_RETURN(0); 483 return window->shouldClose; 484 } 485 486 GLFWAPI void glfwSetWindowShouldClose(GLFWwindow* handle, int value) 487 { 488 _GLFWwindow* window = (_GLFWwindow*) handle; 489 assert(window != NULL); 490 491 _GLFW_REQUIRE_INIT(); 492 window->shouldClose = value; 493 } 494 495 GLFWAPI void glfwSetWindowTitle(GLFWwindow* handle, const char* title) 496 { 497 _GLFWwindow* window = (_GLFWwindow*) handle; 498 assert(window != NULL); 499 assert(title != NULL); 500 501 _GLFW_REQUIRE_INIT(); 502 _glfwPlatformSetWindowTitle(window, title); 503 } 504 505 GLFWAPI void glfwSetWindowIcon(GLFWwindow* handle, 506 int count, const GLFWimage* images) 507 { 508 _GLFWwindow* window = (_GLFWwindow*) handle; 509 assert(window != NULL); 510 assert(count >= 0); 511 assert(count == 0 || images != NULL); 512 513 _GLFW_REQUIRE_INIT(); 514 _glfwPlatformSetWindowIcon(window, count, images); 515 } 516 517 GLFWAPI void glfwGetWindowPos(GLFWwindow* handle, int* xpos, int* ypos) 518 { 519 _GLFWwindow* window = (_GLFWwindow*) handle; 520 assert(window != NULL); 521 522 if (xpos) 523 *xpos = 0; 524 if (ypos) 525 *ypos = 0; 526 527 _GLFW_REQUIRE_INIT(); 528 _glfwPlatformGetWindowPos(window, xpos, ypos); 529 } 530 531 GLFWAPI void glfwSetWindowPos(GLFWwindow* handle, int xpos, int ypos) 532 { 533 _GLFWwindow* window = (_GLFWwindow*) handle; 534 assert(window != NULL); 535 536 _GLFW_REQUIRE_INIT(); 537 538 if (window->monitor) 539 return; 540 541 _glfwPlatformSetWindowPos(window, xpos, ypos); 542 } 543 544 GLFWAPI void glfwGetWindowSize(GLFWwindow* handle, int* width, int* height) 545 { 546 _GLFWwindow* window = (_GLFWwindow*) handle; 547 assert(window != NULL); 548 549 if (width) 550 *width = 0; 551 if (height) 552 *height = 0; 553 554 _GLFW_REQUIRE_INIT(); 555 _glfwPlatformGetWindowSize(window, width, height); 556 } 557 558 GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) 559 { 560 _GLFWwindow* window = (_GLFWwindow*) handle; 561 assert(window != NULL); 562 assert(width >= 0); 563 assert(height >= 0); 564 565 _GLFW_REQUIRE_INIT(); 566 567 window->videoMode.width = width; 568 window->videoMode.height = height; 569 570 _glfwPlatformSetWindowSize(window, width, height); 571 } 572 573 GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, 574 int minwidth, int minheight, 575 int maxwidth, int maxheight) 576 { 577 _GLFWwindow* window = (_GLFWwindow*) handle; 578 assert(window != NULL); 579 580 _GLFW_REQUIRE_INIT(); 581 582 if (minwidth != GLFW_DONT_CARE && minheight != GLFW_DONT_CARE) 583 { 584 if (minwidth < 0 || minheight < 0) 585 { 586 _glfwInputError(GLFW_INVALID_VALUE, 587 "Invalid window minimum size %ix%i", 588 minwidth, minheight); 589 return; 590 } 591 } 592 593 if (maxwidth != GLFW_DONT_CARE && maxheight != GLFW_DONT_CARE) 594 { 595 if (maxwidth < 0 || maxheight < 0 || 596 maxwidth < minwidth || maxheight < minheight) 597 { 598 _glfwInputError(GLFW_INVALID_VALUE, 599 "Invalid window maximum size %ix%i", 600 maxwidth, maxheight); 601 return; 602 } 603 } 604 605 window->minwidth = minwidth; 606 window->minheight = minheight; 607 window->maxwidth = maxwidth; 608 window->maxheight = maxheight; 609 610 if (window->monitor || !window->resizable) 611 return; 612 613 _glfwPlatformSetWindowSizeLimits(window, 614 minwidth, minheight, 615 maxwidth, maxheight); 616 } 617 618 GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) 619 { 620 _GLFWwindow* window = (_GLFWwindow*) handle; 621 assert(window != NULL); 622 assert(numer != 0); 623 assert(denom != 0); 624 625 _GLFW_REQUIRE_INIT(); 626 627 if (numer != GLFW_DONT_CARE && denom != GLFW_DONT_CARE) 628 { 629 if (numer <= 0 || denom <= 0) 630 { 631 _glfwInputError(GLFW_INVALID_VALUE, 632 "Invalid window aspect ratio %i:%i", 633 numer, denom); 634 return; 635 } 636 } 637 638 window->numer = numer; 639 window->denom = denom; 640 641 if (window->monitor || !window->resizable) 642 return; 643 644 _glfwPlatformSetWindowAspectRatio(window, numer, denom); 645 } 646 647 GLFWAPI void glfwGetFramebufferSize(GLFWwindow* handle, int* width, int* height) 648 { 649 _GLFWwindow* window = (_GLFWwindow*) handle; 650 assert(window != NULL); 651 652 if (width) 653 *width = 0; 654 if (height) 655 *height = 0; 656 657 _GLFW_REQUIRE_INIT(); 658 _glfwPlatformGetFramebufferSize(window, width, height); 659 } 660 661 GLFWAPI void glfwGetWindowFrameSize(GLFWwindow* handle, 662 int* left, int* top, 663 int* right, int* bottom) 664 { 665 _GLFWwindow* window = (_GLFWwindow*) handle; 666 assert(window != NULL); 667 668 if (left) 669 *left = 0; 670 if (top) 671 *top = 0; 672 if (right) 673 *right = 0; 674 if (bottom) 675 *bottom = 0; 676 677 _GLFW_REQUIRE_INIT(); 678 _glfwPlatformGetWindowFrameSize(window, left, top, right, bottom); 679 } 680 681 GLFWAPI void glfwGetWindowContentScale(GLFWwindow* handle, 682 float* xscale, float* yscale) 683 { 684 _GLFWwindow* window = (_GLFWwindow*) handle; 685 assert(window != NULL); 686 687 if (xscale) 688 *xscale = 0.f; 689 if (yscale) 690 *yscale = 0.f; 691 692 _GLFW_REQUIRE_INIT(); 693 _glfwPlatformGetWindowContentScale(window, xscale, yscale); 694 } 695 696 GLFWAPI float glfwGetWindowOpacity(GLFWwindow* handle) 697 { 698 _GLFWwindow* window = (_GLFWwindow*) handle; 699 assert(window != NULL); 700 701 _GLFW_REQUIRE_INIT_OR_RETURN(1.f); 702 return _glfwPlatformGetWindowOpacity(window); 703 } 704 705 GLFWAPI void glfwSetWindowOpacity(GLFWwindow* handle, float opacity) 706 { 707 _GLFWwindow* window = (_GLFWwindow*) handle; 708 assert(window != NULL); 709 assert(opacity == opacity); 710 assert(opacity >= 0.f); 711 assert(opacity <= 1.f); 712 713 _GLFW_REQUIRE_INIT(); 714 715 if (opacity != opacity || opacity < 0.f || opacity > 1.f) 716 { 717 _glfwInputError(GLFW_INVALID_VALUE, "Invalid window opacity %f", opacity); 718 return; 719 } 720 721 _glfwPlatformSetWindowOpacity(window, opacity); 722 } 723 724 GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) 725 { 726 _GLFWwindow* window = (_GLFWwindow*) handle; 727 assert(window != NULL); 728 729 _GLFW_REQUIRE_INIT(); 730 _glfwPlatformIconifyWindow(window); 731 } 732 733 GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) 734 { 735 _GLFWwindow* window = (_GLFWwindow*) handle; 736 assert(window != NULL); 737 738 _GLFW_REQUIRE_INIT(); 739 _glfwPlatformRestoreWindow(window); 740 } 741 742 GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) 743 { 744 _GLFWwindow* window = (_GLFWwindow*) handle; 745 assert(window != NULL); 746 747 _GLFW_REQUIRE_INIT(); 748 749 if (window->monitor) 750 return; 751 752 _glfwPlatformMaximizeWindow(window); 753 } 754 755 GLFWAPI void glfwShowWindow(GLFWwindow* handle) 756 { 757 _GLFWwindow* window = (_GLFWwindow*) handle; 758 assert(window != NULL); 759 760 _GLFW_REQUIRE_INIT(); 761 762 if (window->monitor) 763 return; 764 765 _glfwPlatformShowWindow(window); 766 767 if (window->focusOnShow) 768 _glfwPlatformFocusWindow(window); 769 } 770 771 GLFWAPI void glfwRequestWindowAttention(GLFWwindow* handle) 772 { 773 _GLFWwindow* window = (_GLFWwindow*) handle; 774 assert(window != NULL); 775 776 _GLFW_REQUIRE_INIT(); 777 778 _glfwPlatformRequestWindowAttention(window); 779 } 780 781 GLFWAPI void glfwHideWindow(GLFWwindow* handle) 782 { 783 _GLFWwindow* window = (_GLFWwindow*) handle; 784 assert(window != NULL); 785 786 _GLFW_REQUIRE_INIT(); 787 788 if (window->monitor) 789 return; 790 791 _glfwPlatformHideWindow(window); 792 } 793 794 GLFWAPI void glfwFocusWindow(GLFWwindow* handle) 795 { 796 _GLFWwindow* window = (_GLFWwindow*) handle; 797 assert(window != NULL); 798 799 _GLFW_REQUIRE_INIT(); 800 801 _glfwPlatformFocusWindow(window); 802 } 803 804 GLFWAPI int glfwGetWindowAttrib(GLFWwindow* handle, int attrib) 805 { 806 _GLFWwindow* window = (_GLFWwindow*) handle; 807 assert(window != NULL); 808 809 _GLFW_REQUIRE_INIT_OR_RETURN(0); 810 811 switch (attrib) 812 { 813 case GLFW_FOCUSED: 814 return _glfwPlatformWindowFocused(window); 815 case GLFW_ICONIFIED: 816 return _glfwPlatformWindowIconified(window); 817 case GLFW_VISIBLE: 818 return _glfwPlatformWindowVisible(window); 819 case GLFW_MAXIMIZED: 820 return _glfwPlatformWindowMaximized(window); 821 case GLFW_HOVERED: 822 return _glfwPlatformWindowHovered(window); 823 case GLFW_FOCUS_ON_SHOW: 824 return window->focusOnShow; 825 case GLFW_TRANSPARENT_FRAMEBUFFER: 826 return _glfwPlatformFramebufferTransparent(window); 827 case GLFW_RESIZABLE: 828 return window->resizable; 829 case GLFW_DECORATED: 830 return window->decorated; 831 case GLFW_FLOATING: 832 return window->floating; 833 case GLFW_AUTO_ICONIFY: 834 return window->autoIconify; 835 case GLFW_CLIENT_API: 836 return window->context.client; 837 case GLFW_CONTEXT_CREATION_API: 838 return window->context.source; 839 case GLFW_CONTEXT_VERSION_MAJOR: 840 return window->context.major; 841 case GLFW_CONTEXT_VERSION_MINOR: 842 return window->context.minor; 843 case GLFW_CONTEXT_REVISION: 844 return window->context.revision; 845 case GLFW_CONTEXT_ROBUSTNESS: 846 return window->context.robustness; 847 case GLFW_OPENGL_FORWARD_COMPAT: 848 return window->context.forward; 849 case GLFW_OPENGL_DEBUG_CONTEXT: 850 return window->context.debug; 851 case GLFW_OPENGL_PROFILE: 852 return window->context.profile; 853 case GLFW_CONTEXT_RELEASE_BEHAVIOR: 854 return window->context.release; 855 case GLFW_CONTEXT_NO_ERROR: 856 return window->context.noerror; 857 } 858 859 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); 860 return 0; 861 } 862 863 GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value) 864 { 865 _GLFWwindow* window = (_GLFWwindow*) handle; 866 assert(window != NULL); 867 868 _GLFW_REQUIRE_INIT(); 869 870 value = value ? GLFW_TRUE : GLFW_FALSE; 871 872 if (attrib == GLFW_AUTO_ICONIFY) 873 window->autoIconify = value; 874 else if (attrib == GLFW_RESIZABLE) 875 { 876 if (window->resizable == value) 877 return; 878 879 window->resizable = value; 880 if (!window->monitor) 881 _glfwPlatformSetWindowResizable(window, value); 882 } 883 else if (attrib == GLFW_DECORATED) 884 { 885 if (window->decorated == value) 886 return; 887 888 window->decorated = value; 889 if (!window->monitor) 890 _glfwPlatformSetWindowDecorated(window, value); 891 } 892 else if (attrib == GLFW_FLOATING) 893 { 894 if (window->floating == value) 895 return; 896 897 window->floating = value; 898 if (!window->monitor) 899 _glfwPlatformSetWindowFloating(window, value); 900 } 901 else if (attrib == GLFW_FOCUS_ON_SHOW) 902 window->focusOnShow = value; 903 else 904 _glfwInputError(GLFW_INVALID_ENUM, "Invalid window attribute 0x%08X", attrib); 905 } 906 907 GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) 908 { 909 _GLFWwindow* window = (_GLFWwindow*) handle; 910 assert(window != NULL); 911 912 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 913 return (GLFWmonitor*) window->monitor; 914 } 915 916 GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh, 917 GLFWmonitor* mh, 918 int xpos, int ypos, 919 int width, int height, 920 int refreshRate) 921 { 922 _GLFWwindow* window = (_GLFWwindow*) wh; 923 _GLFWmonitor* monitor = (_GLFWmonitor*) mh; 924 assert(window != NULL); 925 assert(width >= 0); 926 assert(height >= 0); 927 928 _GLFW_REQUIRE_INIT(); 929 930 if (width <= 0 || height <= 0) 931 { 932 _glfwInputError(GLFW_INVALID_VALUE, 933 "Invalid window size %ix%i", 934 width, height); 935 return; 936 } 937 938 if (refreshRate < 0 && refreshRate != GLFW_DONT_CARE) 939 { 940 _glfwInputError(GLFW_INVALID_VALUE, 941 "Invalid refresh rate %i", 942 refreshRate); 943 return; 944 } 945 946 window->videoMode.width = width; 947 window->videoMode.height = height; 948 window->videoMode.refreshRate = refreshRate; 949 950 _glfwPlatformSetWindowMonitor(window, monitor, 951 xpos, ypos, width, height, 952 refreshRate); 953 } 954 955 GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) 956 { 957 _GLFWwindow* window = (_GLFWwindow*) handle; 958 assert(window != NULL); 959 960 _GLFW_REQUIRE_INIT(); 961 window->userPointer = pointer; 962 } 963 964 GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* handle) 965 { 966 _GLFWwindow* window = (_GLFWwindow*) handle; 967 assert(window != NULL); 968 969 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 970 return window->userPointer; 971 } 972 973 GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* handle, 974 GLFWwindowposfun cbfun) 975 { 976 _GLFWwindow* window = (_GLFWwindow*) handle; 977 assert(window != NULL); 978 979 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 980 _GLFW_SWAP_POINTERS(GLFWwindowposfun, window->callbacks.pos, cbfun); 981 return cbfun; 982 } 983 984 GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* handle, 985 GLFWwindowsizefun cbfun) 986 { 987 _GLFWwindow* window = (_GLFWwindow*) handle; 988 assert(window != NULL); 989 990 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 991 _GLFW_SWAP_POINTERS(GLFWwindowsizefun, window->callbacks.size, cbfun); 992 return cbfun; 993 } 994 995 GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* handle, 996 GLFWwindowclosefun cbfun) 997 { 998 _GLFWwindow* window = (_GLFWwindow*) handle; 999 assert(window != NULL); 1000 1001 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1002 _GLFW_SWAP_POINTERS(GLFWwindowclosefun, window->callbacks.close, cbfun); 1003 return cbfun; 1004 } 1005 1006 GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* handle, 1007 GLFWwindowrefreshfun cbfun) 1008 { 1009 _GLFWwindow* window = (_GLFWwindow*) handle; 1010 assert(window != NULL); 1011 1012 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1013 _GLFW_SWAP_POINTERS(GLFWwindowrefreshfun, window->callbacks.refresh, cbfun); 1014 return cbfun; 1015 } 1016 1017 GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* handle, 1018 GLFWwindowfocusfun cbfun) 1019 { 1020 _GLFWwindow* window = (_GLFWwindow*) handle; 1021 assert(window != NULL); 1022 1023 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1024 _GLFW_SWAP_POINTERS(GLFWwindowfocusfun, window->callbacks.focus, cbfun); 1025 return cbfun; 1026 } 1027 1028 GLFWAPI GLFWwindowiconifyfun glfwSetWindowIconifyCallback(GLFWwindow* handle, 1029 GLFWwindowiconifyfun cbfun) 1030 { 1031 _GLFWwindow* window = (_GLFWwindow*) handle; 1032 assert(window != NULL); 1033 1034 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1035 _GLFW_SWAP_POINTERS(GLFWwindowiconifyfun, window->callbacks.iconify, cbfun); 1036 return cbfun; 1037 } 1038 1039 GLFWAPI GLFWwindowmaximizefun glfwSetWindowMaximizeCallback(GLFWwindow* handle, 1040 GLFWwindowmaximizefun cbfun) 1041 { 1042 _GLFWwindow* window = (_GLFWwindow*) handle; 1043 assert(window != NULL); 1044 1045 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1046 _GLFW_SWAP_POINTERS(GLFWwindowmaximizefun, window->callbacks.maximize, cbfun); 1047 return cbfun; 1048 } 1049 1050 GLFWAPI GLFWframebuffersizefun glfwSetFramebufferSizeCallback(GLFWwindow* handle, 1051 GLFWframebuffersizefun cbfun) 1052 { 1053 _GLFWwindow* window = (_GLFWwindow*) handle; 1054 assert(window != NULL); 1055 1056 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1057 _GLFW_SWAP_POINTERS(GLFWframebuffersizefun, window->callbacks.fbsize, cbfun); 1058 return cbfun; 1059 } 1060 1061 GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow* handle, 1062 GLFWwindowcontentscalefun cbfun) 1063 { 1064 _GLFWwindow* window = (_GLFWwindow*) handle; 1065 assert(window != NULL); 1066 1067 _GLFW_REQUIRE_INIT_OR_RETURN(NULL); 1068 _GLFW_SWAP_POINTERS(GLFWwindowcontentscalefun, window->callbacks.scale, cbfun); 1069 return cbfun; 1070 } 1071 1072 GLFWAPI void glfwPollEvents(void) 1073 { 1074 _GLFW_REQUIRE_INIT(); 1075 _glfwPlatformPollEvents(); 1076 } 1077 1078 GLFWAPI void glfwWaitEvents(void) 1079 { 1080 _GLFW_REQUIRE_INIT(); 1081 _glfwPlatformWaitEvents(); 1082 } 1083 1084 GLFWAPI void glfwWaitEventsTimeout(double timeout) 1085 { 1086 _GLFW_REQUIRE_INIT(); 1087 assert(timeout == timeout); 1088 assert(timeout >= 0.0); 1089 assert(timeout <= DBL_MAX); 1090 1091 if (timeout != timeout || timeout < 0.0 || timeout > DBL_MAX) 1092 { 1093 _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", timeout); 1094 return; 1095 } 1096 1097 _glfwPlatformWaitEventsTimeout(timeout); 1098 } 1099 1100 GLFWAPI void glfwPostEmptyEvent(void) 1101 { 1102 _GLFW_REQUIRE_INIT(); 1103 _glfwPlatformPostEmptyEvent(); 1104 }