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 //
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
28 #include "internal.h"
29
30 #include <assert.h>
31 #include <float.h>
32 #include <stdlib.h>
33
34 // Internal key state used for sticky keys
35 #define _GLFW_STICK 3
36
37
38 //////////////////////////////////////////////////////////////////////////
39 ////// GLFW event API //////
40 //////////////////////////////////////////////////////////////////////////
41
_glfwInputKey(_GLFWwindow * window,int key,int scancode,int action,int mods)42 void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods)
43 {
44 if (key >= 0 && key <= GLFW_KEY_LAST)
45 {
46 GLFWbool repeated = GLFW_FALSE;
47
48 if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
49 return;
50
51 if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
52 repeated = GLFW_TRUE;
53
54 if (action == GLFW_RELEASE && window->stickyKeys)
55 window->keys[key] = _GLFW_STICK;
56 else
57 window->keys[key] = (char) action;
58
59 if (repeated)
60 action = GLFW_REPEAT;
61 }
62
63 if (window->callbacks.key)
64 window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods);
65 }
66
_glfwInputChar(_GLFWwindow * window,unsigned int codepoint,int mods,GLFWbool plain)67 void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain)
68 {
69 if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
70 return;
71
72 if (window->callbacks.charmods)
73 window->callbacks.charmods((GLFWwindow*) window, codepoint, mods);
74
75 if (plain)
76 {
77 if (window->callbacks.character)
78 window->callbacks.character((GLFWwindow*) window, codepoint);
79 }
80 }
81
_glfwInputScroll(_GLFWwindow * window,double xoffset,double yoffset)82 void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
83 {
84 if (window->callbacks.scroll)
85 window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
86 }
87
_glfwInputMouseClick(_GLFWwindow * window,int button,int action,int mods)88 void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
89 {
90 if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
91 return;
92
93 // Register mouse button action
94 if (action == GLFW_RELEASE && window->stickyMouseButtons)
95 window->mouseButtons[button] = _GLFW_STICK;
96 else
97 window->mouseButtons[button] = (char) action;
98
99 if (window->callbacks.mouseButton)
100 window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
101 }
102
_glfwInputCursorPos(_GLFWwindow * window,double xpos,double ypos)103 void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
104 {
105 if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
106 return;
107
108 window->virtualCursorPosX = xpos;
109 window->virtualCursorPosY = ypos;
110
111 if (window->callbacks.cursorPos)
112 window->callbacks.cursorPos((GLFWwindow*) window, xpos, ypos);
113 }
114
_glfwInputCursorEnter(_GLFWwindow * window,GLFWbool entered)115 void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
116 {
117 if (window->callbacks.cursorEnter)
118 window->callbacks.cursorEnter((GLFWwindow*) window, entered);
119 }
120
_glfwInputDrop(_GLFWwindow * window,int count,const char ** paths)121 void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
122 {
123 if (window->callbacks.drop)
124 window->callbacks.drop((GLFWwindow*) window, count, paths);
125 }
126
_glfwInputJoystickChange(int joy,int event)127 void _glfwInputJoystickChange(int joy, int event)
128 {
129 if (_glfw.callbacks.joystick)
130 _glfw.callbacks.joystick(joy, event);
131 }
132
133
134 //////////////////////////////////////////////////////////////////////////
135 ////// GLFW internal API //////
136 //////////////////////////////////////////////////////////////////////////
137
_glfwIsPrintable(int key)138 GLFWbool _glfwIsPrintable(int key)
139 {
140 return (key >= GLFW_KEY_APOSTROPHE && key <= GLFW_KEY_WORLD_2) ||
141 (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD) ||
142 key == GLFW_KEY_KP_EQUAL;
143 }
144
145
146 //////////////////////////////////////////////////////////////////////////
147 ////// GLFW public API //////
148 //////////////////////////////////////////////////////////////////////////
149
glfwGetInputMode(GLFWwindow * handle,int mode)150 GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
151 {
152 _GLFWwindow* window = (_GLFWwindow*) handle;
153 assert(window != NULL);
154
155 _GLFW_REQUIRE_INIT_OR_RETURN(0);
156
157 switch (mode)
158 {
159 case GLFW_CURSOR:
160 return window->cursorMode;
161 case GLFW_STICKY_KEYS:
162 return window->stickyKeys;
163 case GLFW_STICKY_MOUSE_BUTTONS:
164 return window->stickyMouseButtons;
165 default:
166 _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode);
167 return 0;
168 }
169 }
170
glfwSetInputMode(GLFWwindow * handle,int mode,int value)171 GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
172 {
173 _GLFWwindow* window = (_GLFWwindow*) handle;
174 assert(window != NULL);
175
176 _GLFW_REQUIRE_INIT();
177
178 switch (mode)
179 {
180 case GLFW_CURSOR:
181 {
182 if (value != GLFW_CURSOR_NORMAL &&
183 value != GLFW_CURSOR_HIDDEN &&
184 value != GLFW_CURSOR_DISABLED)
185 {
186 _glfwInputError(GLFW_INVALID_ENUM,
187 "Invalid cursor mode %i",
188 value);
189 return;
190 }
191
192 if (window->cursorMode == value)
193 return;
194
195 window->cursorMode = value;
196
197 _glfwPlatformGetCursorPos(window,
198 &window->virtualCursorPosX,
199 &window->virtualCursorPosY);
200
201 if (_glfwPlatformWindowFocused(window))
202 _glfwPlatformSetCursorMode(window, value);
203
204 return;
205 }
206
207 case GLFW_STICKY_KEYS:
208 {
209 if (window->stickyKeys == value)
210 return;
211
212 if (!value)
213 {
214 int i;
215
216 // Release all sticky keys
217 for (i = 0; i <= GLFW_KEY_LAST; i++)
218 {
219 if (window->keys[i] == _GLFW_STICK)
220 window->keys[i] = GLFW_RELEASE;
221 }
222 }
223
224 window->stickyKeys = value ? GLFW_TRUE : GLFW_FALSE;
225 return;
226 }
227
228 case GLFW_STICKY_MOUSE_BUTTONS:
229 {
230 if (window->stickyMouseButtons == value)
231 return;
232
233 if (!value)
234 {
235 int i;
236
237 // Release all sticky mouse buttons
238 for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
239 {
240 if (window->mouseButtons[i] == _GLFW_STICK)
241 window->mouseButtons[i] = GLFW_RELEASE;
242 }
243 }
244
245 window->stickyMouseButtons = value ? GLFW_TRUE : GLFW_FALSE;
246 return;
247 }
248 }
249
250 _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode %i", mode);
251 }
252
glfwGetKeyName(int key,int scancode)253 GLFWAPI const char* glfwGetKeyName(int key, int scancode)
254 {
255 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
256 return _glfwPlatformGetKeyName(key, scancode);
257 }
258
glfwGetKey(GLFWwindow * handle,int key)259 GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
260 {
261 _GLFWwindow* window = (_GLFWwindow*) handle;
262 assert(window != NULL);
263
264 _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
265
266 if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
267 {
268 _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
269 return GLFW_RELEASE;
270 }
271
272 if (window->keys[key] == _GLFW_STICK)
273 {
274 // Sticky mode: release key now
275 window->keys[key] = GLFW_RELEASE;
276 return GLFW_PRESS;
277 }
278
279 return (int) window->keys[key];
280 }
281
glfwGetMouseButton(GLFWwindow * handle,int button)282 GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
283 {
284 _GLFWwindow* window = (_GLFWwindow*) handle;
285 assert(window != NULL);
286
287 _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
288
289 if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST)
290 {
291 _glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button);
292 return GLFW_RELEASE;
293 }
294
295 if (window->mouseButtons[button] == _GLFW_STICK)
296 {
297 // Sticky mode: release mouse button now
298 window->mouseButtons[button] = GLFW_RELEASE;
299 return GLFW_PRESS;
300 }
301
302 return (int) window->mouseButtons[button];
303 }
304
glfwGetCursorPos(GLFWwindow * handle,double * xpos,double * ypos)305 GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
306 {
307 _GLFWwindow* window = (_GLFWwindow*) handle;
308 assert(window != NULL);
309
310 if (xpos)
311 *xpos = 0;
312 if (ypos)
313 *ypos = 0;
314
315 _GLFW_REQUIRE_INIT();
316
317 if (window->cursorMode == GLFW_CURSOR_DISABLED)
318 {
319 if (xpos)
320 *xpos = window->virtualCursorPosX;
321 if (ypos)
322 *ypos = window->virtualCursorPosY;
323 }
324 else
325 _glfwPlatformGetCursorPos(window, xpos, ypos);
326 }
327
glfwSetCursorPos(GLFWwindow * handle,double xpos,double ypos)328 GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
329 {
330 _GLFWwindow* window = (_GLFWwindow*) handle;
331 assert(window != NULL);
332
333 _GLFW_REQUIRE_INIT();
334
335 if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
336 ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)
337 {
338 _glfwInputError(GLFW_INVALID_VALUE,
339 "Invalid cursor position %f %f",
340 xpos, ypos);
341 return;
342 }
343
344 if (!_glfwPlatformWindowFocused(window))
345 return;
346
347 if (window->cursorMode == GLFW_CURSOR_DISABLED)
348 {
349 // Only update the accumulated position if the cursor is disabled
350 window->virtualCursorPosX = xpos;
351 window->virtualCursorPosY = ypos;
352 }
353 else
354 {
355 // Update system cursor position
356 _glfwPlatformSetCursorPos(window, xpos, ypos);
357 }
358 }
359
glfwCreateCursor(const GLFWimage * image,int xhot,int yhot)360 GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
361 {
362 _GLFWcursor* cursor;
363
364 assert(image != NULL);
365
366 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
367
368 cursor = calloc(1, sizeof(_GLFWcursor));
369 cursor->next = _glfw.cursorListHead;
370 _glfw.cursorListHead = cursor;
371
372 if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot))
373 {
374 glfwDestroyCursor((GLFWcursor*) cursor);
375 return NULL;
376 }
377
378 return (GLFWcursor*) cursor;
379 }
380
glfwCreateStandardCursor(int shape)381 GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
382 {
383 _GLFWcursor* cursor;
384
385 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
386
387 if (shape != GLFW_ARROW_CURSOR &&
388 shape != GLFW_IBEAM_CURSOR &&
389 shape != GLFW_CROSSHAIR_CURSOR &&
390 shape != GLFW_HAND_CURSOR &&
391 shape != GLFW_HRESIZE_CURSOR &&
392 shape != GLFW_VRESIZE_CURSOR)
393 {
394 _glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor %i", shape);
395 return NULL;
396 }
397
398 cursor = calloc(1, sizeof(_GLFWcursor));
399 cursor->next = _glfw.cursorListHead;
400 _glfw.cursorListHead = cursor;
401
402 if (!_glfwPlatformCreateStandardCursor(cursor, shape))
403 {
404 glfwDestroyCursor((GLFWcursor*) cursor);
405 return NULL;
406 }
407
408 return (GLFWcursor*) cursor;
409 }
410
glfwDestroyCursor(GLFWcursor * handle)411 GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
412 {
413 _GLFWcursor* cursor = (_GLFWcursor*) handle;
414
415 _GLFW_REQUIRE_INIT();
416
417 if (cursor == NULL)
418 return;
419
420 // Make sure the cursor is not being used by any window
421 {
422 _GLFWwindow* window;
423
424 for (window = _glfw.windowListHead; window; window = window->next)
425 {
426 if (window->cursor == cursor)
427 glfwSetCursor((GLFWwindow*) window, NULL);
428 }
429 }
430
431 _glfwPlatformDestroyCursor(cursor);
432
433 // Unlink cursor from global linked list
434 {
435 _GLFWcursor** prev = &_glfw.cursorListHead;
436
437 while (*prev != cursor)
438 prev = &((*prev)->next);
439
440 *prev = cursor->next;
441 }
442
443 free(cursor);
444 }
445
glfwSetCursor(GLFWwindow * windowHandle,GLFWcursor * cursorHandle)446 GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
447 {
448 _GLFWwindow* window = (_GLFWwindow*) windowHandle;
449 _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
450 assert(window != NULL);
451
452 _GLFW_REQUIRE_INIT();
453
454 window->cursor = cursor;
455
456 _glfwPlatformSetCursor(window, cursor);
457 }
458
glfwSetKeyCallback(GLFWwindow * handle,GLFWkeyfun cbfun)459 GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
460 {
461 _GLFWwindow* window = (_GLFWwindow*) handle;
462 assert(window != NULL);
463
464 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
465 _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);
466 return cbfun;
467 }
468
glfwSetCharCallback(GLFWwindow * handle,GLFWcharfun cbfun)469 GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
470 {
471 _GLFWwindow* window = (_GLFWwindow*) handle;
472 assert(window != NULL);
473
474 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
475 _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);
476 return cbfun;
477 }
478
glfwSetCharModsCallback(GLFWwindow * handle,GLFWcharmodsfun cbfun)479 GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
480 {
481 _GLFWwindow* window = (_GLFWwindow*) handle;
482 assert(window != NULL);
483
484 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
485 _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);
486 return cbfun;
487 }
488
glfwSetMouseButtonCallback(GLFWwindow * handle,GLFWmousebuttonfun cbfun)489 GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
490 GLFWmousebuttonfun cbfun)
491 {
492 _GLFWwindow* window = (_GLFWwindow*) handle;
493 assert(window != NULL);
494
495 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
496 _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);
497 return cbfun;
498 }
499
glfwSetCursorPosCallback(GLFWwindow * handle,GLFWcursorposfun cbfun)500 GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
501 GLFWcursorposfun cbfun)
502 {
503 _GLFWwindow* window = (_GLFWwindow*) handle;
504 assert(window != NULL);
505
506 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
507 _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);
508 return cbfun;
509 }
510
glfwSetCursorEnterCallback(GLFWwindow * handle,GLFWcursorenterfun cbfun)511 GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
512 GLFWcursorenterfun cbfun)
513 {
514 _GLFWwindow* window = (_GLFWwindow*) handle;
515 assert(window != NULL);
516
517 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
518 _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);
519 return cbfun;
520 }
521
glfwSetScrollCallback(GLFWwindow * handle,GLFWscrollfun cbfun)522 GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
523 GLFWscrollfun cbfun)
524 {
525 _GLFWwindow* window = (_GLFWwindow*) handle;
526 assert(window != NULL);
527
528 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
529 _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);
530 return cbfun;
531 }
532
glfwSetDropCallback(GLFWwindow * handle,GLFWdropfun cbfun)533 GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
534 {
535 _GLFWwindow* window = (_GLFWwindow*) handle;
536 assert(window != NULL);
537
538 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
539 _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
540 return cbfun;
541 }
542
glfwJoystickPresent(int joy)543 GLFWAPI int glfwJoystickPresent(int joy)
544 {
545 _GLFW_REQUIRE_INIT_OR_RETURN(0);
546
547 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
548 {
549 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);
550 return 0;
551 }
552
553 return _glfwPlatformJoystickPresent(joy);
554 }
555
glfwGetJoystickAxes(int joy,int * count)556 GLFWAPI const float* glfwGetJoystickAxes(int joy, int* count)
557 {
558 assert(count != NULL);
559 *count = 0;
560
561 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
562
563 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
564 {
565 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);
566 return NULL;
567 }
568
569 return _glfwPlatformGetJoystickAxes(joy, count);
570 }
571
glfwGetJoystickButtons(int joy,int * count)572 GLFWAPI const unsigned char* glfwGetJoystickButtons(int joy, int* count)
573 {
574 assert(count != NULL);
575 *count = 0;
576
577 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
578
579 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
580 {
581 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);
582 return NULL;
583 }
584
585 return _glfwPlatformGetJoystickButtons(joy, count);
586 }
587
glfwGetJoystickName(int joy)588 GLFWAPI const char* glfwGetJoystickName(int joy)
589 {
590 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
591
592 if (joy < 0 || joy > GLFW_JOYSTICK_LAST)
593 {
594 _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick %i", joy);
595 return NULL;
596 }
597
598 return _glfwPlatformGetJoystickName(joy);
599 }
600
glfwSetJoystickCallback(GLFWjoystickfun cbfun)601 GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
602 {
603 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
604 _GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
605 return cbfun;
606 }
607
glfwSetClipboardString(GLFWwindow * handle,const char * string)608 GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
609 {
610 _GLFWwindow* window = (_GLFWwindow*) handle;
611 assert(window != NULL);
612 assert(string != NULL);
613
614 _GLFW_REQUIRE_INIT();
615 _glfwPlatformSetClipboardString(window, string);
616 }
617
glfwGetClipboardString(GLFWwindow * handle)618 GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
619 {
620 _GLFWwindow* window = (_GLFWwindow*) handle;
621 assert(window != NULL);
622
623 _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
624 return _glfwPlatformGetClipboardString(window);
625 }
626
glfwGetTime(void)627 GLFWAPI double glfwGetTime(void)
628 {
629 _GLFW_REQUIRE_INIT_OR_RETURN(0.0);
630 return (double) (_glfwPlatformGetTimerValue() - _glfw.timerOffset) /
631 _glfwPlatformGetTimerFrequency();
632 }
633
glfwSetTime(double time)634 GLFWAPI void glfwSetTime(double time)
635 {
636 _GLFW_REQUIRE_INIT();
637
638 if (time != time || time < 0.0 || time > 18446744073.0)
639 {
640 _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", time);
641 return;
642 }
643
644 _glfw.timerOffset = _glfwPlatformGetTimerValue() -
645 (uint64_t) (time * _glfwPlatformGetTimerFrequency());
646 }
647
glfwGetTimerValue(void)648 GLFWAPI uint64_t glfwGetTimerValue(void)
649 {
650 _GLFW_REQUIRE_INIT_OR_RETURN(0);
651 return _glfwPlatformGetTimerValue();
652 }
653
glfwGetTimerFrequency(void)654 GLFWAPI uint64_t glfwGetTimerFrequency(void)
655 {
656 _GLFW_REQUIRE_INIT_OR_RETURN(0);
657 return _glfwPlatformGetTimerFrequency();
658 }
659
660