medfall

A super great game engine
Log | Files | Refs

window.cc (29566B)


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