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 | |
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 | |
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 | |
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 | |
83 | void _glfwInputWindowIconify(_GLFWwindow* window, GLFWbool iconified) |
84 | { |
85 | if (window->callbacks.iconify) |
86 | window->callbacks.iconify((GLFWwindow*) window, iconified); |
87 | } |
88 | |
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 | |
95 | void _glfwInputWindowDamage(_GLFWwindow* window) |
96 | { |
97 | if (window->callbacks.refresh) |
98 | window->callbacks.refresh((GLFWwindow*) window); |
99 | } |
100 | |
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 | |
109 | void _glfwInputWindowMonitorChange(_GLFWwindow* window, _GLFWmonitor* monitor) |
110 | { |
111 | window->monitor = monitor; |
112 | } |
113 | |
114 | |
115 | ////////////////////////////////////////////////////////////////////////// |
116 | ////// GLFW public API ////// |
117 | ////////////////////////////////////////////////////////////////////////// |
118 | |
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.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 | |
231 | void 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 | |
264 | GLFWAPI 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 | |
375 | GLFWAPI 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 | |
408 | GLFWAPI 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 | |
417 | GLFWAPI 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 | |
426 | GLFWAPI 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 | |
437 | GLFWAPI 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 | |
449 | GLFWAPI 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 | |
463 | GLFWAPI 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 | |
476 | GLFWAPI 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 | |
490 | GLFWAPI 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 | |
503 | GLFWAPI 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 | |
548 | GLFWAPI 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 | |
575 | GLFWAPI 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 | |
589 | GLFWAPI 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 | |
609 | GLFWAPI void glfwIconifyWindow(GLFWwindow* handle) |
610 | { |
611 | _GLFWwindow* window = (_GLFWwindow*) handle; |
612 | assert(window != NULL); |
613 | |
614 | _GLFW_REQUIRE_INIT(); |
615 | _glfwPlatformIconifyWindow(window); |
616 | } |
617 | |
618 | GLFWAPI void glfwRestoreWindow(GLFWwindow* handle) |
619 | { |
620 | _GLFWwindow* window = (_GLFWwindow*) handle; |
621 | assert(window != NULL); |
622 | |
623 | _GLFW_REQUIRE_INIT(); |
624 | _glfwPlatformRestoreWindow(window); |
625 | } |
626 | |
627 | GLFWAPI void glfwMaximizeWindow(GLFWwindow* handle) |
628 | { |
629 | _GLFWwindow* window = (_GLFWwindow*) handle; |
630 | _GLFW_REQUIRE_INIT(); |
631 | _glfwPlatformMaximizeWindow(window); |
632 | } |
633 | |
634 | GLFWAPI 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 | |
648 | GLFWAPI 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 | |
661 | GLFWAPI 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 | |
671 | GLFWAPI 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 | |
722 | GLFWAPI 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 | |
731 | GLFWAPI 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 | |
768 | GLFWAPI 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 | |
777 | GLFWAPI 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 | |
786 | GLFWAPI 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 | |
797 | GLFWAPI 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 | |
808 | GLFWAPI 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 | |
819 | GLFWAPI 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 | |
830 | GLFWAPI 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 | |
841 | GLFWAPI 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 | |
852 | GLFWAPI 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 | |
863 | GLFWAPI void glfwPollEvents(void) |
864 | { |
865 | _GLFW_REQUIRE_INIT(); |
866 | _glfwPlatformPollEvents(); |
867 | } |
868 | |
869 | GLFWAPI void glfwWaitEvents(void) |
870 | { |
871 | _GLFW_REQUIRE_INIT(); |
872 | |
873 | if (!_glfw.windowListHead) |
874 | return; |
875 | |
876 | _glfwPlatformWaitEvents(); |
877 | } |
878 | |
879 | GLFWAPI 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 | |
892 | GLFWAPI void glfwPostEmptyEvent(void) |
893 | { |
894 | _GLFW_REQUIRE_INIT(); |
895 | |
896 | if (!_glfw.windowListHead) |
897 | return; |
898 | |
899 | _glfwPlatformPostEmptyEvent(); |
900 | } |
901 | |
902 | |