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