1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
20 /** \file
21  * \ingroup GHOST
22  *
23  * C Api for GHOST
24  */
25 
26 #include <stdlib.h>
27 #include <string.h>
28 
29 #include "GHOST_C-api.h"
30 #include "GHOST_IEvent.h"
31 #include "GHOST_IEventConsumer.h"
32 #include "GHOST_ISystem.h"
33 #include "intern/GHOST_Debug.h"
34 #ifdef WITH_XR_OPENXR
35 #  include "GHOST_IXrContext.h"
36 #endif
37 #include "intern/GHOST_CallbackEventConsumer.h"
38 #include "intern/GHOST_XrException.h"
39 
GHOST_CreateSystem(void)40 GHOST_SystemHandle GHOST_CreateSystem(void)
41 {
42   GHOST_ISystem::createSystem();
43   GHOST_ISystem *system = GHOST_ISystem::getSystem();
44 
45   return (GHOST_SystemHandle)system;
46 }
47 
GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle,int is_debug_enabled)48 void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, int is_debug_enabled)
49 {
50   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
51 
52   system->initDebug(is_debug_enabled);
53 }
54 
GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)55 GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle)
56 {
57   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
58 
59   return system->disposeSystem();
60 }
61 
GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle,const char * title,const char * message,const char * help_label,const char * continue_label,const char * link,GHOST_DialogOptions dialog_options)62 void GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle,
63                           const char *title,
64                           const char *message,
65                           const char *help_label,
66                           const char *continue_label,
67                           const char *link,
68                           GHOST_DialogOptions dialog_options)
69 {
70   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
71   system->showMessageBox(title, message, help_label, continue_label, link, dialog_options);
72 }
73 
GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback,GHOST_TUserDataPtr userdata)74 GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback,
75                                                     GHOST_TUserDataPtr userdata)
76 {
77   return (GHOST_EventConsumerHandle) new GHOST_CallbackEventConsumer(eventCallback, userdata);
78 }
79 
GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhandle)80 GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhandle)
81 {
82   delete ((GHOST_CallbackEventConsumer *)consumerhandle);
83   return GHOST_kSuccess;
84 }
85 
GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle)86 GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle)
87 {
88   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
89 
90   return system->getMilliSeconds();
91 }
92 
GHOST_InstallTimer(GHOST_SystemHandle systemhandle,GHOST_TUns64 delay,GHOST_TUns64 interval,GHOST_TimerProcPtr timerproc,GHOST_TUserDataPtr userdata)93 GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle,
94                                          GHOST_TUns64 delay,
95                                          GHOST_TUns64 interval,
96                                          GHOST_TimerProcPtr timerproc,
97                                          GHOST_TUserDataPtr userdata)
98 {
99   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
100 
101   return (GHOST_TimerTaskHandle)system->installTimer(delay, interval, timerproc, userdata);
102 }
103 
GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,GHOST_TimerTaskHandle timertaskhandle)104 GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
105                                  GHOST_TimerTaskHandle timertaskhandle)
106 {
107   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
108   GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
109 
110   return system->removeTimer(timertask);
111 }
112 
GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle)113 GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle)
114 {
115   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
116 
117   return system->getNumDisplays();
118 }
119 
GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,GHOST_TUns32 * width,GHOST_TUns32 * height)120 void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
121                                     GHOST_TUns32 *width,
122                                     GHOST_TUns32 *height)
123 {
124   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
125 
126   system->getMainDisplayDimensions(*width, *height);
127 }
128 
GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,GHOST_TUns32 * width,GHOST_TUns32 * height)129 void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
130                                    GHOST_TUns32 *width,
131                                    GHOST_TUns32 *height)
132 {
133   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
134 
135   system->getAllDisplayDimensions(*width, *height);
136 }
137 
GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,GHOST_GLSettings glSettings)138 GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle,
139                                               GHOST_GLSettings glSettings)
140 {
141   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
142 
143   return (GHOST_ContextHandle)system->createOffscreenContext(glSettings);
144 }
145 
GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,GHOST_ContextHandle contexthandle)146 GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle,
147                                           GHOST_ContextHandle contexthandle)
148 {
149   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
150   GHOST_IContext *context = (GHOST_IContext *)contexthandle;
151 
152   return system->disposeContext(context);
153 }
154 
GHOST_CreateWindow(GHOST_SystemHandle systemhandle,const char * title,GHOST_TInt32 left,GHOST_TInt32 top,GHOST_TUns32 width,GHOST_TUns32 height,GHOST_TWindowState state,GHOST_TDrawingContextType type,GHOST_GLSettings glSettings)155 GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
156                                       const char *title,
157                                       GHOST_TInt32 left,
158                                       GHOST_TInt32 top,
159                                       GHOST_TUns32 width,
160                                       GHOST_TUns32 height,
161                                       GHOST_TWindowState state,
162                                       GHOST_TDrawingContextType type,
163                                       GHOST_GLSettings glSettings)
164 {
165   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
166 
167   return (GHOST_WindowHandle)system->createWindow(
168       title, left, top, width, height, state, type, glSettings, false, false);
169 }
170 
GHOST_CreateDialogWindow(GHOST_SystemHandle systemhandle,GHOST_WindowHandle parent_windowhandle,const char * title,GHOST_TInt32 left,GHOST_TInt32 top,GHOST_TUns32 width,GHOST_TUns32 height,GHOST_TWindowState state,GHOST_TDrawingContextType type,GHOST_GLSettings glSettings)171 GHOST_WindowHandle GHOST_CreateDialogWindow(GHOST_SystemHandle systemhandle,
172                                             GHOST_WindowHandle parent_windowhandle,
173                                             const char *title,
174                                             GHOST_TInt32 left,
175                                             GHOST_TInt32 top,
176                                             GHOST_TUns32 width,
177                                             GHOST_TUns32 height,
178                                             GHOST_TWindowState state,
179                                             GHOST_TDrawingContextType type,
180                                             GHOST_GLSettings glSettings)
181 {
182   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
183 
184   return (GHOST_WindowHandle)system->createWindow(title,
185                                                   left,
186                                                   top,
187                                                   width,
188                                                   height,
189                                                   state,
190                                                   type,
191                                                   glSettings,
192                                                   false,
193                                                   true,
194                                                   (GHOST_IWindow *)parent_windowhandle);
195 }
196 
GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)197 GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
198 {
199   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
200 
201   return window->getUserData();
202 }
GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle,GHOST_TUserDataPtr userdata)203 void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata)
204 {
205   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
206 
207   window->setUserData(userdata);
208 }
209 
GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle)210 int GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle)
211 {
212   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
213 
214   return (int)window->isDialog();
215 }
216 
GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,GHOST_WindowHandle windowhandle)217 GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle,
218                                    GHOST_WindowHandle windowhandle)
219 {
220   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
221   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
222 
223   return system->disposeWindow(window);
224 }
225 
GHOST_ValidWindow(GHOST_SystemHandle systemhandle,GHOST_WindowHandle windowhandle)226 int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle)
227 {
228   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
229   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
230 
231   return (int)system->validWindow(window);
232 }
233 
GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,GHOST_DisplaySetting * setting,const int stereoVisual)234 GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle,
235                                          GHOST_DisplaySetting *setting,
236                                          const int stereoVisual)
237 {
238   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
239   GHOST_IWindow *window = NULL;
240   bool bstereoVisual;
241 
242   if (stereoVisual)
243     bstereoVisual = true;
244   else
245     bstereoVisual = false;
246 
247   system->beginFullScreen(*setting, &window, bstereoVisual);
248 
249   return (GHOST_WindowHandle)window;
250 }
251 
GHOST_EndFullScreen(GHOST_SystemHandle systemhandle)252 GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle)
253 {
254   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
255 
256   return system->endFullScreen();
257 }
258 
GHOST_GetFullScreen(GHOST_SystemHandle systemhandle)259 int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle)
260 {
261   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
262 
263   return (int)system->getFullScreen();
264 }
265 
GHOST_ProcessEvents(GHOST_SystemHandle systemhandle,int waitForEvent)266 int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent)
267 {
268   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
269 
270   return (int)system->processEvents(waitForEvent ? true : false);
271 }
272 
GHOST_DispatchEvents(GHOST_SystemHandle systemhandle)273 void GHOST_DispatchEvents(GHOST_SystemHandle systemhandle)
274 {
275   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
276 
277   system->dispatchEvents();
278 }
279 
GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle,GHOST_EventConsumerHandle consumerhandle)280 GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle,
281                                       GHOST_EventConsumerHandle consumerhandle)
282 {
283   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
284 
285   return system->addEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle);
286 }
287 
GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle,GHOST_EventConsumerHandle consumerhandle)288 GHOST_TSuccess GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle,
289                                          GHOST_EventConsumerHandle consumerhandle)
290 {
291   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
292 
293   return system->removeEventConsumer((GHOST_CallbackEventConsumer *)consumerhandle);
294 }
295 
GHOST_SetProgressBar(GHOST_WindowHandle windowhandle,float progress)296 GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, float progress)
297 {
298   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
299 
300   return window->setProgressBar(progress);
301 }
302 
GHOST_EndProgressBar(GHOST_WindowHandle windowhandle)303 GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle)
304 {
305   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
306 
307   return window->endProgressBar();
308 }
309 
GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)310 GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)
311 {
312   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
313 
314   return window->getCursorShape();
315 }
316 
GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,GHOST_TStandardCursor cursorshape)317 GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle,
318                                     GHOST_TStandardCursor cursorshape)
319 {
320   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
321 
322   return window->setCursorShape(cursorshape);
323 }
324 
GHOST_HasCursorShape(GHOST_WindowHandle windowhandle,GHOST_TStandardCursor cursorshape)325 GHOST_TSuccess GHOST_HasCursorShape(GHOST_WindowHandle windowhandle,
326                                     GHOST_TStandardCursor cursorshape)
327 {
328   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
329 
330   return window->hasCursorShape(cursorshape);
331 }
332 
GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,GHOST_TUns8 * bitmap,GHOST_TUns8 * mask,int sizex,int sizey,int hotX,int hotY,GHOST_TUns8 canInvertColor)333 GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle,
334                                           GHOST_TUns8 *bitmap,
335                                           GHOST_TUns8 *mask,
336                                           int sizex,
337                                           int sizey,
338                                           int hotX,
339                                           int hotY,
340                                           GHOST_TUns8 canInvertColor)
341 {
342   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
343 
344   return window->setCustomCursorShape(bitmap, mask, sizex, sizey, hotX, hotY, canInvertColor);
345 }
346 
GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)347 int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)
348 {
349   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
350 
351   return (int)window->getCursorVisibility();
352 }
353 
GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle,int visible)354 GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible)
355 {
356   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
357 
358   return window->setCursorVisibility(visible ? true : false);
359 }
360 
GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle,GHOST_TInt32 * x,GHOST_TInt32 * y)361 GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle,
362                                        GHOST_TInt32 *x,
363                                        GHOST_TInt32 *y)
364 {
365   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
366 
367   return system->getCursorPosition(*x, *y);
368 }
369 
GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,GHOST_TInt32 x,GHOST_TInt32 y)370 GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
371                                        GHOST_TInt32 x,
372                                        GHOST_TInt32 y)
373 {
374   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
375 
376   return system->setCursorPosition(x, y);
377 }
378 
GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,GHOST_TGrabCursorMode mode,GHOST_TAxisFlag wrap_axis,int bounds[4],const int mouse_ungrab_xy[2])379 GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
380                                    GHOST_TGrabCursorMode mode,
381                                    GHOST_TAxisFlag wrap_axis,
382                                    int bounds[4],
383                                    const int mouse_ungrab_xy[2])
384 {
385   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
386   GHOST_Rect bounds_rect;
387   GHOST_TInt32 mouse_xy[2];
388 
389   if (bounds) {
390     bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]);
391   }
392   if (mouse_ungrab_xy) {
393     mouse_xy[0] = mouse_ungrab_xy[0];
394     mouse_xy[1] = mouse_ungrab_xy[1];
395   }
396 
397   return window->setCursorGrab(
398       mode, wrap_axis, bounds ? &bounds_rect : NULL, mouse_ungrab_xy ? mouse_xy : NULL);
399 }
400 
GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,GHOST_TModifierKeyMask mask,int * isDown)401 GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
402                                          GHOST_TModifierKeyMask mask,
403                                          int *isDown)
404 {
405   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
406   GHOST_TSuccess result;
407   bool isdown = false;
408 
409   result = system->getModifierKeyState(mask, isdown);
410   *isDown = (int)isdown;
411 
412   return result;
413 }
414 
GHOST_GetButtonState(GHOST_SystemHandle systemhandle,GHOST_TButtonMask mask,int * isDown)415 GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
416                                     GHOST_TButtonMask mask,
417                                     int *isDown)
418 {
419   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
420   GHOST_TSuccess result;
421   bool isdown = false;
422 
423   result = system->getButtonState(mask, isdown);
424   *isDown = (int)isdown;
425 
426   return result;
427 }
428 
429 #ifdef WITH_INPUT_NDOF
GHOST_setNDOFDeadZone(float deadzone)430 void GHOST_setNDOFDeadZone(float deadzone)
431 {
432   GHOST_ISystem *system = GHOST_ISystem::getSystem();
433   system->setNDOFDeadZone(deadzone);
434 }
435 #endif
436 
GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle,GHOST_TInt8 canAccept)437 void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, GHOST_TInt8 canAccept)
438 {
439   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
440 
441   window->setAcceptDragOperation(canAccept);
442 }
443 
GHOST_GetEventType(GHOST_EventHandle eventhandle)444 GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle)
445 {
446   GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
447 
448   return event->getType();
449 }
450 
GHOST_GetEventTime(GHOST_EventHandle eventhandle)451 GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle)
452 {
453   GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
454 
455   return event->getTime();
456 }
457 
GHOST_GetEventWindow(GHOST_EventHandle eventhandle)458 GHOST_WindowHandle GHOST_GetEventWindow(GHOST_EventHandle eventhandle)
459 {
460   GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
461 
462   return (GHOST_WindowHandle)event->getWindow();
463 }
464 
GHOST_GetEventData(GHOST_EventHandle eventhandle)465 GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle)
466 {
467   GHOST_IEvent *event = (GHOST_IEvent *)eventhandle;
468 
469   return event->getData();
470 }
471 
GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle)472 GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle)
473 {
474   GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
475 
476   return timertask->getTimerProc();
477 }
478 
GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle,GHOST_TimerProcPtr timerproc)479 void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle, GHOST_TimerProcPtr timerproc)
480 {
481   GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
482 
483   timertask->setTimerProc(timerproc);
484 }
485 
GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle)486 GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle)
487 {
488   GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
489 
490   return timertask->getUserData();
491 }
492 
GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle,GHOST_TUserDataPtr userdata)493 void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, GHOST_TUserDataPtr userdata)
494 {
495   GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
496 
497   timertask->setUserData(userdata);
498 }
499 
GHOST_GetValid(GHOST_WindowHandle windowhandle)500 int GHOST_GetValid(GHOST_WindowHandle windowhandle)
501 {
502   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
503 
504   return (int)window->getValid();
505 }
506 
GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle)507 GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle)
508 {
509   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
510 
511   return window->getDrawingContextType();
512 }
513 
GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle,GHOST_TDrawingContextType type)514 GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle,
515                                            GHOST_TDrawingContextType type)
516 {
517   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
518 
519   return window->setDrawingContextType(type);
520 }
521 
GHOST_SetTitle(GHOST_WindowHandle windowhandle,const char * title)522 void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title)
523 {
524   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
525 
526   window->setTitle(title);
527 }
528 
GHOST_GetTitle(GHOST_WindowHandle windowhandle)529 char *GHOST_GetTitle(GHOST_WindowHandle windowhandle)
530 {
531   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
532   std::string title = window->getTitle();
533 
534   char *ctitle = (char *)malloc(title.size() + 1);
535 
536   if (ctitle == NULL) {
537     return NULL;
538   }
539 
540   strcpy(ctitle, title.c_str());
541 
542   return ctitle;
543 }
544 
GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)545 GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
546 {
547   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
548   GHOST_Rect *rectangle = NULL;
549 
550   rectangle = new GHOST_Rect();
551   window->getWindowBounds(*rectangle);
552 
553   return (GHOST_RectangleHandle)rectangle;
554 }
555 
GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)556 GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)
557 {
558   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
559   GHOST_Rect *rectangle = NULL;
560 
561   rectangle = new GHOST_Rect();
562   window->getClientBounds(*rectangle);
563 
564   return (GHOST_RectangleHandle)rectangle;
565 }
566 
GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle)567 void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle)
568 {
569   delete (GHOST_Rect *)rectanglehandle;
570 }
571 
GHOST_SetClientWidth(GHOST_WindowHandle windowhandle,GHOST_TUns32 width)572 GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width)
573 {
574   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
575 
576   return window->setClientWidth(width);
577 }
578 
GHOST_SetClientHeight(GHOST_WindowHandle windowhandle,GHOST_TUns32 height)579 GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height)
580 {
581   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
582 
583   return window->setClientHeight(height);
584 }
585 
GHOST_SetClientSize(GHOST_WindowHandle windowhandle,GHOST_TUns32 width,GHOST_TUns32 height)586 GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle,
587                                    GHOST_TUns32 width,
588                                    GHOST_TUns32 height)
589 {
590   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
591 
592   return window->setClientSize(width, height);
593 }
594 
GHOST_ScreenToClient(GHOST_WindowHandle windowhandle,GHOST_TInt32 inX,GHOST_TInt32 inY,GHOST_TInt32 * outX,GHOST_TInt32 * outY)595 void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle,
596                           GHOST_TInt32 inX,
597                           GHOST_TInt32 inY,
598                           GHOST_TInt32 *outX,
599                           GHOST_TInt32 *outY)
600 {
601   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
602 
603   window->screenToClient(inX, inY, *outX, *outY);
604 }
605 
GHOST_ClientToScreen(GHOST_WindowHandle windowhandle,GHOST_TInt32 inX,GHOST_TInt32 inY,GHOST_TInt32 * outX,GHOST_TInt32 * outY)606 void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle,
607                           GHOST_TInt32 inX,
608                           GHOST_TInt32 inY,
609                           GHOST_TInt32 *outX,
610                           GHOST_TInt32 *outY)
611 {
612   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
613 
614   window->clientToScreen(inX, inY, *outX, *outY);
615 }
616 
GHOST_GetWindowState(GHOST_WindowHandle windowhandle)617 GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle)
618 {
619   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
620 
621   return window->getState();
622 }
623 
GHOST_SetWindowState(GHOST_WindowHandle windowhandle,GHOST_TWindowState state)624 GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, GHOST_TWindowState state)
625 {
626   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
627 
628   return window->setState(state);
629 }
630 
GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle,GHOST_TUns8 isUnsavedChanges)631 GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle,
632                                             GHOST_TUns8 isUnsavedChanges)
633 {
634   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
635 
636   return window->setModifiedState(isUnsavedChanges);
637 }
638 
GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle,GHOST_TWindowOrder order)639 GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle, GHOST_TWindowOrder order)
640 {
641   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
642 
643   return window->setOrder(order);
644 }
645 
GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle)646 GHOST_TSuccess GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle)
647 {
648   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
649 
650   return window->swapBuffers();
651 }
652 
GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle,int interval)653 GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int interval)
654 {
655   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
656 
657   return window->setSwapInterval(interval);
658 }
659 
GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle,int * intervalOut)660 GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int *intervalOut)
661 {
662   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
663 
664   return window->getSwapInterval(*intervalOut);
665 }
666 
GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle)667 GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle)
668 {
669   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
670 
671   return window->activateDrawingContext();
672 }
673 
GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)674 GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle)
675 {
676   GHOST_IContext *context = (GHOST_IContext *)contexthandle;
677   if (context) {
678     return context->activateDrawingContext();
679   }
680   else {
681     GHOST_PRINTF("%s: Context not valid\n", __func__);
682     return GHOST_kFailure;
683   }
684 }
685 
GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle)686 GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle)
687 {
688   GHOST_IContext *context = (GHOST_IContext *)contexthandle;
689 
690   return context->releaseDrawingContext();
691 }
692 
GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle)693 unsigned int GHOST_GetContextDefaultOpenGLFramebuffer(GHOST_ContextHandle contexthandle)
694 {
695   GHOST_IContext *context = (GHOST_IContext *)contexthandle;
696 
697   return context->getDefaultFramebuffer();
698 }
699 
GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)700 unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windowhandle)
701 {
702   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
703 
704   return window->getDefaultFramebuffer();
705 }
706 
GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)707 GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle)
708 {
709   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
710 
711   return window->invalidate();
712 }
713 
GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle,GHOST_TTabletAPI api)714 void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
715 {
716   GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
717   system->setTabletAPI(api);
718 }
719 
GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)720 GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)
721 {
722   return ((GHOST_Rect *)rectanglehandle)->getWidth();
723 }
724 
GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle)725 GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle)
726 {
727   return ((GHOST_Rect *)rectanglehandle)->getHeight();
728 }
729 
GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_TInt32 * l,GHOST_TInt32 * t,GHOST_TInt32 * r,GHOST_TInt32 * b)730 void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle,
731                         GHOST_TInt32 *l,
732                         GHOST_TInt32 *t,
733                         GHOST_TInt32 *r,
734                         GHOST_TInt32 *b)
735 {
736   GHOST_Rect *rect = (GHOST_Rect *)rectanglehandle;
737 
738   *l = rect->m_l;
739   *t = rect->m_t;
740   *r = rect->m_r;
741   *b = rect->m_b;
742 }
743 
GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_TInt32 l,GHOST_TInt32 t,GHOST_TInt32 r,GHOST_TInt32 b)744 void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle,
745                         GHOST_TInt32 l,
746                         GHOST_TInt32 t,
747                         GHOST_TInt32 r,
748                         GHOST_TInt32 b)
749 {
750   ((GHOST_Rect *)rectanglehandle)->set(l, t, r, b);
751 }
752 
GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehandle)753 GHOST_TSuccess GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehandle)
754 {
755   GHOST_TSuccess result = GHOST_kFailure;
756 
757   if (((GHOST_Rect *)rectanglehandle)->isEmpty())
758     result = GHOST_kSuccess;
759 
760   return result;
761 }
762 
GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle)763 GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle)
764 {
765   GHOST_TSuccess result = GHOST_kFailure;
766 
767   if (((GHOST_Rect *)rectanglehandle)->isValid())
768     result = GHOST_kSuccess;
769 
770   return result;
771 }
772 
GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_TInt32 i)773 void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i)
774 {
775   ((GHOST_Rect *)rectanglehandle)->inset(i);
776 }
777 
GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_RectangleHandle anotherrectanglehandle)778 void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle,
779                           GHOST_RectangleHandle anotherrectanglehandle)
780 {
781   ((GHOST_Rect *)rectanglehandle)->unionRect(*(GHOST_Rect *)anotherrectanglehandle);
782 }
783 
GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_TInt32 x,GHOST_TInt32 y)784 void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle,
785                                GHOST_TInt32 x,
786                                GHOST_TInt32 y)
787 {
788   ((GHOST_Rect *)rectanglehandle)->unionPoint(x, y);
789 }
790 
GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_TInt32 x,GHOST_TInt32 y)791 GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle,
792                                        GHOST_TInt32 x,
793                                        GHOST_TInt32 y)
794 {
795   GHOST_TSuccess result = GHOST_kFailure;
796 
797   if (((GHOST_Rect *)rectanglehandle)->isInside(x, y))
798     result = GHOST_kSuccess;
799 
800   return result;
801 }
802 
GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle,GHOST_RectangleHandle anotherrectanglehandle)803 GHOST_TVisibility GHOST_GetRectangleVisibility(GHOST_RectangleHandle rectanglehandle,
804                                                GHOST_RectangleHandle anotherrectanglehandle)
805 {
806   GHOST_TVisibility visible = GHOST_kNotVisible;
807 
808   visible = ((GHOST_Rect *)rectanglehandle)->getVisibility(*(GHOST_Rect *)anotherrectanglehandle);
809 
810   return visible;
811 }
812 
GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_TInt32 cx,GHOST_TInt32 cy)813 void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle,
814                               GHOST_TInt32 cx,
815                               GHOST_TInt32 cy)
816 {
817   ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy);
818 }
819 
GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle,GHOST_TInt32 cx,GHOST_TInt32 cy,GHOST_TInt32 w,GHOST_TInt32 h)820 void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle,
821                               GHOST_TInt32 cx,
822                               GHOST_TInt32 cy,
823                               GHOST_TInt32 w,
824                               GHOST_TInt32 h)
825 {
826   ((GHOST_Rect *)rectanglehandle)->setCenter(cx, cy, w, h);
827 }
828 
GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,GHOST_RectangleHandle anotherrectanglehandle)829 GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
830                                    GHOST_RectangleHandle anotherrectanglehandle)
831 {
832   GHOST_TSuccess result = GHOST_kFailure;
833 
834   if (((GHOST_Rect *)rectanglehandle)->clip(*(GHOST_Rect *)anotherrectanglehandle))
835     result = GHOST_kSuccess;
836 
837   return result;
838 }
839 
GHOST_getClipboard(int selection)840 GHOST_TUns8 *GHOST_getClipboard(int selection)
841 {
842   GHOST_ISystem *system = GHOST_ISystem::getSystem();
843   return system->getClipboard(selection);
844 }
845 
GHOST_putClipboard(GHOST_TInt8 * buffer,int selection)846 void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection)
847 {
848   GHOST_ISystem *system = GHOST_ISystem::getSystem();
849   system->putClipboard(buffer, selection);
850 }
851 
GHOST_toggleConsole(int action)852 int GHOST_toggleConsole(int action)
853 {
854   GHOST_ISystem *system = GHOST_ISystem::getSystem();
855   return system->toggleConsole(action);
856 }
857 
GHOST_UseNativePixels(void)858 int GHOST_UseNativePixels(void)
859 {
860   GHOST_ISystem *system = GHOST_ISystem::getSystem();
861   return system->useNativePixel();
862 }
863 
GHOST_UseWindowFocus(int use_focus)864 void GHOST_UseWindowFocus(int use_focus)
865 {
866   GHOST_ISystem *system = GHOST_ISystem::getSystem();
867   return system->useWindowFocus(use_focus);
868 }
869 
GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle)870 float GHOST_GetNativePixelSize(GHOST_WindowHandle windowhandle)
871 {
872   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
873   if (window)
874     return window->getNativePixelSize();
875   return 1.0f;
876 }
877 
GHOST_GetDPIHint(GHOST_WindowHandle windowhandle)878 GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle)
879 {
880   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
881   return window->getDPIHint();
882 }
883 
884 #ifdef WITH_INPUT_IME
885 
GHOST_BeginIME(GHOST_WindowHandle windowhandle,GHOST_TInt32 x,GHOST_TInt32 y,GHOST_TInt32 w,GHOST_TInt32 h,int complete)886 void GHOST_BeginIME(GHOST_WindowHandle windowhandle,
887                     GHOST_TInt32 x,
888                     GHOST_TInt32 y,
889                     GHOST_TInt32 w,
890                     GHOST_TInt32 h,
891                     int complete)
892 {
893   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
894   window->beginIME(x, y, w, h, complete);
895 }
896 
GHOST_EndIME(GHOST_WindowHandle windowhandle)897 void GHOST_EndIME(GHOST_WindowHandle windowhandle)
898 {
899   GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
900   window->endIME();
901 }
902 
903 #endif /* WITH_INPUT_IME */
904 
905 #ifdef WITH_XR_OPENXR
906 
907 #  define GHOST_XR_CAPI_CALL(call, ctx) \
908     try { \
909       call; \
910     } \
911     catch (GHOST_XrException & e) { \
912       (ctx)->dispatchErrorMessage(&e); \
913     }
914 
915 #  define GHOST_XR_CAPI_CALL_RET(call, ctx) \
916     try { \
917       return call; \
918     } \
919     catch (GHOST_XrException & e) { \
920       (ctx)->dispatchErrorMessage(&e); \
921     }
922 
GHOST_XrSessionStart(GHOST_XrContextHandle xr_contexthandle,const GHOST_XrSessionBeginInfo * begin_info)923 void GHOST_XrSessionStart(GHOST_XrContextHandle xr_contexthandle,
924                           const GHOST_XrSessionBeginInfo *begin_info)
925 {
926   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
927   GHOST_XR_CAPI_CALL(xr_context->startSession(begin_info), xr_context);
928 }
929 
GHOST_XrSessionEnd(GHOST_XrContextHandle xr_contexthandle)930 void GHOST_XrSessionEnd(GHOST_XrContextHandle xr_contexthandle)
931 {
932   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
933   GHOST_XR_CAPI_CALL(xr_context->endSession(), xr_context);
934 }
935 
GHOST_XrSessionDrawViews(GHOST_XrContextHandle xr_contexthandle,void * draw_customdata)936 void GHOST_XrSessionDrawViews(GHOST_XrContextHandle xr_contexthandle, void *draw_customdata)
937 {
938   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
939   GHOST_XR_CAPI_CALL(xr_context->drawSessionViews(draw_customdata), xr_context);
940 }
941 
GHOST_XrSessionIsRunning(const GHOST_XrContextHandle xr_contexthandle)942 int GHOST_XrSessionIsRunning(const GHOST_XrContextHandle xr_contexthandle)
943 {
944   const GHOST_IXrContext *xr_context = (const GHOST_IXrContext *)xr_contexthandle;
945   GHOST_XR_CAPI_CALL_RET(xr_context->isSessionRunning(), xr_context);
946   return 0; /* Only reached if exception is thrown. */
947 }
948 
GHOST_XrGraphicsContextBindFuncs(GHOST_XrContextHandle xr_contexthandle,GHOST_XrGraphicsContextBindFn bind_fn,GHOST_XrGraphicsContextUnbindFn unbind_fn)949 void GHOST_XrGraphicsContextBindFuncs(GHOST_XrContextHandle xr_contexthandle,
950                                       GHOST_XrGraphicsContextBindFn bind_fn,
951                                       GHOST_XrGraphicsContextUnbindFn unbind_fn)
952 {
953   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
954   GHOST_XR_CAPI_CALL(xr_context->setGraphicsContextBindFuncs(bind_fn, unbind_fn), xr_context);
955 }
956 
GHOST_XrDrawViewFunc(GHOST_XrContextHandle xr_contexthandle,GHOST_XrDrawViewFn draw_view_fn)957 void GHOST_XrDrawViewFunc(GHOST_XrContextHandle xr_contexthandle, GHOST_XrDrawViewFn draw_view_fn)
958 {
959   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
960   GHOST_XR_CAPI_CALL(xr_context->setDrawViewFunc(draw_view_fn), xr_context);
961 }
962 
GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_contexthandle)963 int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_contexthandle)
964 {
965   GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
966 
967   GHOST_XR_CAPI_CALL_RET(xr_context->needsUpsideDownDrawing(), xr_context);
968   return 0; /* Only reached if exception is thrown. */
969 }
970 
971 #endif
972