1 | //======================================================================== |
2 | // GLFW 3.4 - www.glfw.org |
3 | //------------------------------------------------------------------------ |
4 | // Copyright (c) 2016 Google Inc. |
5 | // Copyright (c) 2016-2019 Camilla Löwy <[email protected]> |
6 | // |
7 | // This software is provided 'as-is', without any express or implied |
8 | // warranty. In no event will the authors be held liable for any damages |
9 | // arising from the use of this software. |
10 | // |
11 | // Permission is granted to anyone to use this software for any purpose, |
12 | // including commercial applications, and to alter it and redistribute it |
13 | // freely, subject to the following restrictions: |
14 | // |
15 | // 1. The origin of this software must not be misrepresented; you must not |
16 | // claim that you wrote the original software. If you use this software |
17 | // in a product, an acknowledgment in the product documentation would |
18 | // be appreciated but is not required. |
19 | // |
20 | // 2. Altered source versions must be plainly marked as such, and must not |
21 | // be misrepresented as being the original software. |
22 | // |
23 | // 3. This notice may not be removed or altered from any source |
24 | // distribution. |
25 | // |
26 | //======================================================================== |
27 | // It is fine to use C99 in this file because it will not be built with VS |
28 | //======================================================================== |
29 | |
30 | #include "internal.h" |
31 | |
32 | #include <stdlib.h> |
33 | |
34 | static void applySizeLimits(_GLFWwindow* window, int* width, int* height) |
35 | { |
36 | if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE) |
37 | { |
38 | const float ratio = (float) window->numer / (float) window->denom; |
39 | *height = (int) (*width / ratio); |
40 | } |
41 | |
42 | if (window->minwidth != GLFW_DONT_CARE && *width < window->minwidth) |
43 | *width = window->minwidth; |
44 | else if (window->maxwidth != GLFW_DONT_CARE && *width > window->maxwidth) |
45 | *width = window->maxwidth; |
46 | |
47 | if (window->minheight != GLFW_DONT_CARE && *height < window->minheight) |
48 | *height = window->minheight; |
49 | else if (window->maxheight != GLFW_DONT_CARE && *height > window->maxheight) |
50 | *height = window->maxheight; |
51 | } |
52 | |
53 | static void fitToMonitor(_GLFWwindow* window) |
54 | { |
55 | GLFWvidmode mode; |
56 | _glfwGetVideoModeNull(window->monitor, &mode); |
57 | _glfwGetMonitorPosNull(window->monitor, |
58 | &window->null.xpos, |
59 | &window->null.ypos); |
60 | window->null.width = mode.width; |
61 | window->null.height = mode.height; |
62 | } |
63 | |
64 | static void acquireMonitor(_GLFWwindow* window) |
65 | { |
66 | _glfwInputMonitorWindow(window->monitor, window); |
67 | } |
68 | |
69 | static void releaseMonitor(_GLFWwindow* window) |
70 | { |
71 | if (window->monitor->window != window) |
72 | return; |
73 | |
74 | _glfwInputMonitorWindow(window->monitor, NULL); |
75 | } |
76 | |
77 | static int createNativeWindow(_GLFWwindow* window, |
78 | const _GLFWwndconfig* wndconfig, |
79 | const _GLFWfbconfig* fbconfig) |
80 | { |
81 | if (window->monitor) |
82 | fitToMonitor(window); |
83 | else |
84 | { |
85 | window->null.xpos = 17; |
86 | window->null.ypos = 17; |
87 | window->null.width = wndconfig->width; |
88 | window->null.height = wndconfig->height; |
89 | } |
90 | |
91 | window->null.visible = wndconfig->visible; |
92 | window->null.decorated = wndconfig->decorated; |
93 | window->null.maximized = wndconfig->maximized; |
94 | window->null.floating = wndconfig->floating; |
95 | window->null.transparent = fbconfig->transparent; |
96 | window->null.opacity = 1.f; |
97 | |
98 | return GLFW_TRUE; |
99 | } |
100 | |
101 | |
102 | ////////////////////////////////////////////////////////////////////////// |
103 | ////// GLFW platform API ////// |
104 | ////////////////////////////////////////////////////////////////////////// |
105 | |
106 | int _glfwCreateWindowNull(_GLFWwindow* window, |
107 | const _GLFWwndconfig* wndconfig, |
108 | const _GLFWctxconfig* ctxconfig, |
109 | const _GLFWfbconfig* fbconfig) |
110 | { |
111 | if (!createNativeWindow(window, wndconfig, fbconfig)) |
112 | return GLFW_FALSE; |
113 | |
114 | if (ctxconfig->client != GLFW_NO_API) |
115 | { |
116 | if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API || |
117 | ctxconfig->source == GLFW_OSMESA_CONTEXT_API) |
118 | { |
119 | if (!_glfwInitOSMesa()) |
120 | return GLFW_FALSE; |
121 | if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) |
122 | return GLFW_FALSE; |
123 | } |
124 | else if (ctxconfig->source == GLFW_EGL_CONTEXT_API) |
125 | { |
126 | if (!_glfwInitEGL()) |
127 | return GLFW_FALSE; |
128 | if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) |
129 | return GLFW_FALSE; |
130 | } |
131 | } |
132 | |
133 | if (window->monitor) |
134 | { |
135 | _glfwShowWindowNull(window); |
136 | _glfwFocusWindowNull(window); |
137 | acquireMonitor(window); |
138 | } |
139 | |
140 | return GLFW_TRUE; |
141 | } |
142 | |
143 | void _glfwDestroyWindowNull(_GLFWwindow* window) |
144 | { |
145 | if (window->monitor) |
146 | releaseMonitor(window); |
147 | |
148 | if (_glfw.null.focusedWindow == window) |
149 | _glfw.null.focusedWindow = NULL; |
150 | |
151 | if (window->context.destroy) |
152 | window->context.destroy(window); |
153 | } |
154 | |
155 | void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title) |
156 | { |
157 | } |
158 | |
159 | void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images) |
160 | { |
161 | } |
162 | |
163 | void _glfwSetWindowMonitorNull(_GLFWwindow* window, |
164 | _GLFWmonitor* monitor, |
165 | int xpos, int ypos, |
166 | int width, int height, |
167 | int refreshRate) |
168 | { |
169 | if (window->monitor == monitor) |
170 | { |
171 | if (!monitor) |
172 | { |
173 | _glfwSetWindowPosNull(window, xpos, ypos); |
174 | _glfwSetWindowSizeNull(window, width, height); |
175 | } |
176 | |
177 | return; |
178 | } |
179 | |
180 | if (window->monitor) |
181 | releaseMonitor(window); |
182 | |
183 | _glfwInputWindowMonitor(window, monitor); |
184 | |
185 | if (window->monitor) |
186 | { |
187 | window->null.visible = GLFW_TRUE; |
188 | acquireMonitor(window); |
189 | fitToMonitor(window); |
190 | } |
191 | else |
192 | { |
193 | _glfwSetWindowPosNull(window, xpos, ypos); |
194 | _glfwSetWindowSizeNull(window, width, height); |
195 | } |
196 | } |
197 | |
198 | void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos) |
199 | { |
200 | if (xpos) |
201 | *xpos = window->null.xpos; |
202 | if (ypos) |
203 | *ypos = window->null.ypos; |
204 | } |
205 | |
206 | void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos) |
207 | { |
208 | if (window->monitor) |
209 | return; |
210 | |
211 | if (window->null.xpos != xpos || window->null.ypos != ypos) |
212 | { |
213 | window->null.xpos = xpos; |
214 | window->null.ypos = ypos; |
215 | _glfwInputWindowPos(window, xpos, ypos); |
216 | } |
217 | } |
218 | |
219 | void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height) |
220 | { |
221 | if (width) |
222 | *width = window->null.width; |
223 | if (height) |
224 | *height = window->null.height; |
225 | } |
226 | |
227 | void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height) |
228 | { |
229 | if (window->monitor) |
230 | return; |
231 | |
232 | if (window->null.width != width || window->null.height != height) |
233 | { |
234 | window->null.width = width; |
235 | window->null.height = height; |
236 | _glfwInputWindowSize(window, width, height); |
237 | _glfwInputFramebufferSize(window, width, height); |
238 | } |
239 | } |
240 | |
241 | void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window, |
242 | int minwidth, int minheight, |
243 | int maxwidth, int maxheight) |
244 | { |
245 | int width = window->null.width; |
246 | int height = window->null.height; |
247 | applySizeLimits(window, &width, &height); |
248 | _glfwSetWindowSizeNull(window, width, height); |
249 | } |
250 | |
251 | void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d) |
252 | { |
253 | int width = window->null.width; |
254 | int height = window->null.height; |
255 | applySizeLimits(window, &width, &height); |
256 | _glfwSetWindowSizeNull(window, width, height); |
257 | } |
258 | |
259 | void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height) |
260 | { |
261 | if (width) |
262 | *width = window->null.width; |
263 | if (height) |
264 | *height = window->null.height; |
265 | } |
266 | |
267 | void _glfwGetWindowFrameSizeNull(_GLFWwindow* window, |
268 | int* left, int* top, |
269 | int* right, int* bottom) |
270 | { |
271 | if (window->null.decorated && !window->monitor) |
272 | { |
273 | if (left) |
274 | *left = 1; |
275 | if (top) |
276 | *top = 10; |
277 | if (right) |
278 | *right = 1; |
279 | if (bottom) |
280 | *bottom = 1; |
281 | } |
282 | else |
283 | { |
284 | if (left) |
285 | *left = 0; |
286 | if (top) |
287 | *top = 0; |
288 | if (right) |
289 | *right = 0; |
290 | if (bottom) |
291 | *bottom = 0; |
292 | } |
293 | } |
294 | |
295 | void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale) |
296 | { |
297 | if (xscale) |
298 | *xscale = 1.f; |
299 | if (yscale) |
300 | *yscale = 1.f; |
301 | } |
302 | |
303 | void _glfwIconifyWindowNull(_GLFWwindow* window) |
304 | { |
305 | if (_glfw.null.focusedWindow == window) |
306 | { |
307 | _glfw.null.focusedWindow = NULL; |
308 | _glfwInputWindowFocus(window, GLFW_FALSE); |
309 | } |
310 | |
311 | if (!window->null.iconified) |
312 | { |
313 | window->null.iconified = GLFW_TRUE; |
314 | _glfwInputWindowIconify(window, GLFW_TRUE); |
315 | |
316 | if (window->monitor) |
317 | releaseMonitor(window); |
318 | } |
319 | } |
320 | |
321 | void _glfwRestoreWindowNull(_GLFWwindow* window) |
322 | { |
323 | if (window->null.iconified) |
324 | { |
325 | window->null.iconified = GLFW_FALSE; |
326 | _glfwInputWindowIconify(window, GLFW_FALSE); |
327 | |
328 | if (window->monitor) |
329 | acquireMonitor(window); |
330 | } |
331 | else if (window->null.maximized) |
332 | { |
333 | window->null.maximized = GLFW_FALSE; |
334 | _glfwInputWindowMaximize(window, GLFW_FALSE); |
335 | } |
336 | } |
337 | |
338 | void _glfwMaximizeWindowNull(_GLFWwindow* window) |
339 | { |
340 | if (!window->null.maximized) |
341 | { |
342 | window->null.maximized = GLFW_TRUE; |
343 | _glfwInputWindowMaximize(window, GLFW_TRUE); |
344 | } |
345 | } |
346 | |
347 | int _glfwWindowMaximizedNull(_GLFWwindow* window) |
348 | { |
349 | return window->null.maximized; |
350 | } |
351 | |
352 | int _glfwWindowHoveredNull(_GLFWwindow* window) |
353 | { |
354 | return _glfw.null.xcursor >= window->null.xpos && |
355 | _glfw.null.ycursor >= window->null.ypos && |
356 | _glfw.null.xcursor <= window->null.xpos + window->null.width - 1 && |
357 | _glfw.null.ycursor <= window->null.ypos + window->null.height - 1; |
358 | } |
359 | |
360 | int _glfwFramebufferTransparentNull(_GLFWwindow* window) |
361 | { |
362 | return window->null.transparent; |
363 | } |
364 | |
365 | void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled) |
366 | { |
367 | window->null.resizable = enabled; |
368 | } |
369 | |
370 | void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled) |
371 | { |
372 | window->null.decorated = enabled; |
373 | } |
374 | |
375 | void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled) |
376 | { |
377 | window->null.floating = enabled; |
378 | } |
379 | |
380 | void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled) |
381 | { |
382 | } |
383 | |
384 | float _glfwGetWindowOpacityNull(_GLFWwindow* window) |
385 | { |
386 | return window->null.opacity; |
387 | } |
388 | |
389 | void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity) |
390 | { |
391 | window->null.opacity = opacity; |
392 | } |
393 | |
394 | void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled) |
395 | { |
396 | } |
397 | |
398 | GLFWbool _glfwRawMouseMotionSupportedNull(void) |
399 | { |
400 | return GLFW_TRUE; |
401 | } |
402 | |
403 | void _glfwShowWindowNull(_GLFWwindow* window) |
404 | { |
405 | window->null.visible = GLFW_TRUE; |
406 | } |
407 | |
408 | void _glfwRequestWindowAttentionNull(_GLFWwindow* window) |
409 | { |
410 | } |
411 | |
412 | void _glfwHideWindowNull(_GLFWwindow* window) |
413 | { |
414 | if (_glfw.null.focusedWindow == window) |
415 | { |
416 | _glfw.null.focusedWindow = NULL; |
417 | _glfwInputWindowFocus(window, GLFW_FALSE); |
418 | } |
419 | |
420 | window->null.visible = GLFW_FALSE; |
421 | } |
422 | |
423 | void _glfwFocusWindowNull(_GLFWwindow* window) |
424 | { |
425 | _GLFWwindow* previous; |
426 | |
427 | if (_glfw.null.focusedWindow == window) |
428 | return; |
429 | |
430 | if (!window->null.visible) |
431 | return; |
432 | |
433 | previous = _glfw.null.focusedWindow; |
434 | _glfw.null.focusedWindow = window; |
435 | |
436 | if (previous) |
437 | { |
438 | _glfwInputWindowFocus(previous, GLFW_FALSE); |
439 | if (previous->monitor && previous->autoIconify) |
440 | _glfwIconifyWindowNull(previous); |
441 | } |
442 | |
443 | _glfwInputWindowFocus(window, GLFW_TRUE); |
444 | } |
445 | |
446 | int _glfwWindowFocusedNull(_GLFWwindow* window) |
447 | { |
448 | return _glfw.null.focusedWindow == window; |
449 | } |
450 | |
451 | int _glfwWindowIconifiedNull(_GLFWwindow* window) |
452 | { |
453 | return window->null.iconified; |
454 | } |
455 | |
456 | int _glfwWindowVisibleNull(_GLFWwindow* window) |
457 | { |
458 | return window->null.visible; |
459 | } |
460 | |
461 | void _glfwPollEventsNull(void) |
462 | { |
463 | } |
464 | |
465 | void _glfwWaitEventsNull(void) |
466 | { |
467 | } |
468 | |
469 | void _glfwWaitEventsTimeoutNull(double timeout) |
470 | { |
471 | } |
472 | |
473 | void _glfwPostEmptyEventNull(void) |
474 | { |
475 | } |
476 | |
477 | void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos) |
478 | { |
479 | if (xpos) |
480 | *xpos = _glfw.null.xcursor - window->null.xpos; |
481 | if (ypos) |
482 | *ypos = _glfw.null.ycursor - window->null.ypos; |
483 | } |
484 | |
485 | void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y) |
486 | { |
487 | _glfw.null.xcursor = window->null.xpos + (int) x; |
488 | _glfw.null.ycursor = window->null.ypos + (int) y; |
489 | } |
490 | |
491 | void _glfwSetCursorModeNull(_GLFWwindow* window, int mode) |
492 | { |
493 | } |
494 | |
495 | int _glfwCreateCursorNull(_GLFWcursor* cursor, |
496 | const GLFWimage* image, |
497 | int xhot, int yhot) |
498 | { |
499 | return GLFW_TRUE; |
500 | } |
501 | |
502 | int _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape) |
503 | { |
504 | return GLFW_TRUE; |
505 | } |
506 | |
507 | void _glfwDestroyCursorNull(_GLFWcursor* cursor) |
508 | { |
509 | } |
510 | |
511 | void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor) |
512 | { |
513 | } |
514 | |
515 | void _glfwSetClipboardStringNull(const char* string) |
516 | { |
517 | char* copy = _glfw_strdup(string); |
518 | _glfw_free(_glfw.null.clipboardString); |
519 | _glfw.null.clipboardString = copy; |
520 | } |
521 | |
522 | const char* _glfwGetClipboardStringNull(void) |
523 | { |
524 | return _glfw.null.clipboardString; |
525 | } |
526 | |
527 | EGLenum _glfwGetEGLPlatformNull(EGLint** attribs) |
528 | { |
529 | return 0; |
530 | } |
531 | |
532 | EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void) |
533 | { |
534 | return 0; |
535 | } |
536 | |
537 | EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window) |
538 | { |
539 | return 0; |
540 | } |
541 | |
542 | const char* (int scancode) |
543 | { |
544 | if (scancode < GLFW_KEY_SPACE || scancode > GLFW_KEY_LAST) |
545 | { |
546 | _glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i" , scancode); |
547 | return NULL; |
548 | } |
549 | |
550 | switch (scancode) |
551 | { |
552 | case GLFW_KEY_APOSTROPHE: |
553 | return "'" ; |
554 | case GLFW_KEY_COMMA: |
555 | return "," ; |
556 | case GLFW_KEY_MINUS: |
557 | case GLFW_KEY_KP_SUBTRACT: |
558 | return "-" ; |
559 | case GLFW_KEY_PERIOD: |
560 | case GLFW_KEY_KP_DECIMAL: |
561 | return "." ; |
562 | case GLFW_KEY_SLASH: |
563 | case GLFW_KEY_KP_DIVIDE: |
564 | return "/" ; |
565 | case GLFW_KEY_SEMICOLON: |
566 | return ";" ; |
567 | case GLFW_KEY_EQUAL: |
568 | case GLFW_KEY_KP_EQUAL: |
569 | return "=" ; |
570 | case GLFW_KEY_LEFT_BRACKET: |
571 | return "[" ; |
572 | case GLFW_KEY_RIGHT_BRACKET: |
573 | return "]" ; |
574 | case GLFW_KEY_KP_MULTIPLY: |
575 | return "*" ; |
576 | case GLFW_KEY_KP_ADD: |
577 | return "+" ; |
578 | case GLFW_KEY_BACKSLASH: |
579 | case GLFW_KEY_WORLD_1: |
580 | case GLFW_KEY_WORLD_2: |
581 | return "\\" ; |
582 | case GLFW_KEY_0: |
583 | case GLFW_KEY_KP_0: |
584 | return "0" ; |
585 | case GLFW_KEY_1: |
586 | case GLFW_KEY_KP_1: |
587 | return "1" ; |
588 | case GLFW_KEY_2: |
589 | case GLFW_KEY_KP_2: |
590 | return "2" ; |
591 | case GLFW_KEY_3: |
592 | case GLFW_KEY_KP_3: |
593 | return "3" ; |
594 | case GLFW_KEY_4: |
595 | case GLFW_KEY_KP_4: |
596 | return "4" ; |
597 | case GLFW_KEY_5: |
598 | case GLFW_KEY_KP_5: |
599 | return "5" ; |
600 | case GLFW_KEY_6: |
601 | case GLFW_KEY_KP_6: |
602 | return "6" ; |
603 | case GLFW_KEY_7: |
604 | case GLFW_KEY_KP_7: |
605 | return "7" ; |
606 | case GLFW_KEY_8: |
607 | case GLFW_KEY_KP_8: |
608 | return "8" ; |
609 | case GLFW_KEY_9: |
610 | case GLFW_KEY_KP_9: |
611 | return "9" ; |
612 | case GLFW_KEY_A: |
613 | return "a" ; |
614 | case GLFW_KEY_B: |
615 | return "b" ; |
616 | case GLFW_KEY_C: |
617 | return "c" ; |
618 | case GLFW_KEY_D: |
619 | return "d" ; |
620 | case GLFW_KEY_E: |
621 | return "e" ; |
622 | case GLFW_KEY_F: |
623 | return "f" ; |
624 | case GLFW_KEY_G: |
625 | return "g" ; |
626 | case GLFW_KEY_H: |
627 | return "h" ; |
628 | case GLFW_KEY_I: |
629 | return "i" ; |
630 | case GLFW_KEY_J: |
631 | return "j" ; |
632 | case GLFW_KEY_K: |
633 | return "k" ; |
634 | case GLFW_KEY_L: |
635 | return "l" ; |
636 | case GLFW_KEY_M: |
637 | return "m" ; |
638 | case GLFW_KEY_N: |
639 | return "n" ; |
640 | case GLFW_KEY_O: |
641 | return "o" ; |
642 | case GLFW_KEY_P: |
643 | return "p" ; |
644 | case GLFW_KEY_Q: |
645 | return "q" ; |
646 | case GLFW_KEY_R: |
647 | return "r" ; |
648 | case GLFW_KEY_S: |
649 | return "s" ; |
650 | case GLFW_KEY_T: |
651 | return "t" ; |
652 | case GLFW_KEY_U: |
653 | return "u" ; |
654 | case GLFW_KEY_V: |
655 | return "v" ; |
656 | case GLFW_KEY_W: |
657 | return "w" ; |
658 | case GLFW_KEY_X: |
659 | return "x" ; |
660 | case GLFW_KEY_Y: |
661 | return "y" ; |
662 | case GLFW_KEY_Z: |
663 | return "z" ; |
664 | } |
665 | |
666 | return NULL; |
667 | } |
668 | |
669 | int _glfwGetKeyScancodeNull(int key) |
670 | { |
671 | return key; |
672 | } |
673 | |
674 | void _glfwGetRequiredInstanceExtensionsNull(char** extensions) |
675 | { |
676 | } |
677 | |
678 | int _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, |
679 | VkPhysicalDevice device, |
680 | uint32_t queuefamily) |
681 | { |
682 | return GLFW_FALSE; |
683 | } |
684 | |
685 | VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, |
686 | _GLFWwindow* window, |
687 | const VkAllocationCallbacks* allocator, |
688 | VkSurfaceKHR* surface) |
689 | { |
690 | // This seems like the most appropriate error to return here |
691 | return VK_ERROR_EXTENSION_NOT_PRESENT; |
692 | } |
693 | |
694 | |