github.com/Konstantin8105/c4go@v0.0.0-20240505174241-768bb1c65a51/tests/raylib/external/glfw/src/window.c (about)

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