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