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