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  * %Main interface file for C++ Api with declaration of GHOST_ISystem interface
23  * class.
24  * Contains the doxygen documentation main page.
25  */
26 
27 #pragma once
28 
29 #include <stdlib.h>
30 
31 #include "GHOST_IContext.h"
32 #include "GHOST_ITimerTask.h"
33 #include "GHOST_IWindow.h"
34 #include "GHOST_Types.h"
35 
36 class GHOST_IEventConsumer;
37 
38 /**
39  * \page GHOSTPage GHOST
40  *
41  * \section intro Introduction
42  *
43  * GHOST is yet another acronym. It stands for "Generic Handy Operating System
44  * Toolkit". It has been created to replace the OpenGL utility tool kit
45  * <a href="http://www.opengl.org/resources/libraries/glut/">GLUT</a>.
46  * GLUT was used in <a href="http://www.blender3d.com">Blender</a> until the
47  * point that Blender needed to be ported to Apple's Mac OSX. Blender needed a
48  * number of modifications in GLUT to work but the GLUT sources for OSX were
49  * unavailable at the time. The decision was made to build our own replacement
50  * for GLUT. In those days, NaN Technologies BV was the company that developed
51  * Blender.
52  * <br><br>
53  * Enough history. What does GHOST have to offer?<br>
54  * In short: everything that Blender needed from GLUT to run on all its supported
55  * operating systems and some extra's.
56  * This includes :
57  *
58  * - Time(r) management.
59  * - Display/window management (windows are only created on the main display).
60  * - Event management.
61  * - Cursor shape management (no custom cursors for now).
62  * - Access to the state of the mouse buttons and the keyboard.
63  * - Menus for windows with events generated when they are accessed (this is
64  *   work in progress).
65  * - Video mode switching.
66  * - Copy/Paste buffers.
67  * - System paths.
68  *
69  * Font management has been moved to a separate library.
70  *
71  * \section platforms Platforms
72  *
73  * GHOST supports the following platforms:
74  *
75  * - OSX Cocoa.
76  * - Windows.
77  * - X11.
78  * - SDL2 (experimental).
79  * - NULL (headless mode).
80  *
81  * \section Building GHOST
82  *
83  * GHOST is not build standalone however there are tests in intern/ghost/test
84  *
85  * \section interface Interface
86  * GHOST has two programming interfaces:
87  *
88  * - The C-API. For programs written in C.
89  * - The C++-API. For programs written in C++.
90  *
91  * GHOST itself is written in C++ and the C-API is a wrapper around the C++
92  * API.
93  *
94  * \subsection cplusplus_api The C++ API consists of the following files:
95  *
96  * - GHOST_IEvent.h
97  * - GHOST_IEventConsumer.h
98  * - GHOST_ISystem.h
99  * - GHOST_ITimerTask.h
100  * - GHOST_IWindow.h
101  * - GHOST_Rect.h
102  * - GHOST_Types.h
103  *
104  * For an example of using the C++-API, have a look at the GHOST_C-Test.cpp
105  * program in the ?/ghost/test/gears/ directory.
106  *
107  * \subsection c_api The C-API
108  * To use GHOST in programs written in C, include the file GHOST_C-API.h in
109  * your program. This file includes the GHOST_Types.h file for all GHOST types
110  * and defines functions that give you access to the same functionality present
111  * in the C++ API.<br>
112  * For an example of using the C-API, have a look at the GHOST_C-Test.c program
113  * in the ?/ghost/test/gears/ directory.
114  *
115  * \section work Work in progress
116  * \todo write WIP section
117  */
118 
119 /** \interface GHOST_ISystem
120  * Interface for classes that provide access to the operating system.
121  * There should be only one system class in an application.
122  * Therefore, the routines to create and dispose the system are static.
123  * Provides:
124  *  -# Time(r) management.
125  *  -# Display/window management (windows are only created on the main display).
126  *  -# Event management.
127  *  -# Cursor shape management (no custom cursors for now).
128  *  -# Access to the state of the mouse buttons and the keyboard.
129  *  -# Menus for windows with events generated when they are accessed (this is
130  *     work in progress).
131  */
132 class GHOST_ISystem {
133  public:
134   /**
135    * Creates the one and only system.
136    * \return An indication of success.
137    */
138   static GHOST_TSuccess createSystem();
139 
140   /**
141    * Disposes the one and only system.
142    * \return An indication of success.
143    */
144   static GHOST_TSuccess disposeSystem();
145 
146   /**
147    * Returns a pointer to the one and only system (nil if it hasn't been created).
148    * \return A pointer to the system.
149    */
150   static GHOST_ISystem *getSystem();
151 
152  protected:
153   /**
154    * Constructor.
155    * Protected default constructor to force use of static createSystem member.
156    */
GHOST_ISystem()157   GHOST_ISystem()
158   {
159   }
160 
161   /**
162    * Destructor.
163    * Protected default constructor to force use of static dispose member.
164    */
~GHOST_ISystem()165   virtual ~GHOST_ISystem()
166   {
167   }
168 
169  public:
170   /***************************************************************************************
171    * Time(r) functionality
172    ***************************************************************************************/
173 
174   /**
175    * Returns the system time.
176    * Returns the number of milliseconds since the start of the system process.
177    * Based on ANSI clock() routine.
178    * \return The number of milliseconds.
179    */
180   virtual GHOST_TUns64 getMilliSeconds() const = 0;
181 
182   /**
183    * Installs a timer.
184    * Note that, on most operating systems, messages need to be processed in order
185    * for the timer callbacks to be invoked.
186    * \param delay     The time to wait for the first call to the timerProc (in milliseconds)
187    * \param interval  The interval between calls to the timerProc (in milliseconds)
188    * \param timerProc The callback invoked when the interval expires,
189    * \param userData  Placeholder for user data.
190    * \return A timer task (0 if timer task installation failed).
191    */
192   virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
193                                          GHOST_TUns64 interval,
194                                          GHOST_TimerProcPtr timerProc,
195                                          GHOST_TUserDataPtr userData = NULL) = 0;
196 
197   /**
198    * Removes a timer.
199    * \param timerTask Timer task to be removed.
200    * \return Indication of success.
201    */
202   virtual GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask) = 0;
203 
204   /***************************************************************************************
205    * Display/window management functionality
206    ***************************************************************************************/
207 
208   /**
209    * Returns the number of displays on this system.
210    * \return The number of displays.
211    */
212   virtual GHOST_TUns8 getNumDisplays() const = 0;
213 
214   /**
215    * Returns the dimensions of the main display on this system.
216    * \return The dimension of the main display.
217    */
218   virtual void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const = 0;
219 
220   /**
221    * Returns the combine dimensions of all monitors.
222    * \return The dimension of the workspace.
223    */
224   virtual void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const = 0;
225 
226   /**
227    * Create a new window.
228    * The new window is added to the list of windows managed.
229    * Never explicitly delete the window, use disposeWindow() instead.
230    * \param title: The name of the window
231    * (displayed in the title bar of the window if the OS supports it).
232    * \param left: The coordinate of the left edge of the window.
233    * \param top: The coordinate of the top edge of the window.
234    * \param width: The width the window.
235    * \param height: The height the window.
236    * \param state: The state of the window when opened.
237    * \param type: The type of drawing context installed in this window.
238    * \param glSettings: Misc OpenGL settings.
239    * \param exclusive: Use to show the window on top and ignore others (used full-screen).
240    * \param is_dialog: Stay on top of parent window, no icon in taskbar, can't be minimized.
241    * \param parentWindow: Parent (embedder) window
242    * \return The new window (or 0 if creation failed).
243    */
244   virtual GHOST_IWindow *createWindow(const char *title,
245                                       GHOST_TInt32 left,
246                                       GHOST_TInt32 top,
247                                       GHOST_TUns32 width,
248                                       GHOST_TUns32 height,
249                                       GHOST_TWindowState state,
250                                       GHOST_TDrawingContextType type,
251                                       GHOST_GLSettings glSettings,
252                                       const bool exclusive = false,
253                                       const bool is_dialog = false,
254                                       const GHOST_IWindow *parentWindow = NULL) = 0;
255 
256   /**
257    * Dispose a window.
258    * \param   window Pointer to the window to be disposed.
259    * \return  Indication of success.
260    */
261   virtual GHOST_TSuccess disposeWindow(GHOST_IWindow *window) = 0;
262 
263   /**
264    * Create a new offscreen context.
265    * Never explicitly delete the context, use disposeContext() instead.
266    * \return  The new context (or 0 if creation failed).
267    */
268   virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0;
269 
270   /**
271    * Dispose of a context.
272    * \param   context Pointer to the context to be disposed.
273    * \return  Indication of success.
274    */
275   virtual GHOST_TSuccess disposeContext(GHOST_IContext *context) = 0;
276 
277   /**
278    * Returns whether a window is valid.
279    * \param   window Pointer to the window to be checked.
280    * \return  Indication of validity.
281    */
282   virtual bool validWindow(GHOST_IWindow *window) = 0;
283 
284   /**
285    * Begins full screen mode.
286    * \param setting   The new setting of the display.
287    * \param window    Window displayed in full screen.
288    *                  This window is invalid after full screen has been ended.
289    * \return  Indication of success.
290    */
291   virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting,
292                                          GHOST_IWindow **window,
293                                          const bool stereoVisual,
294                                          const bool alphaBackground = 0) = 0;
295 
296   /**
297    * Updates the resolution while in fullscreen mode.
298    * \param setting   The new setting of the display.
299    * \param window    Window displayed in full screen.
300    *
301    * \return  Indication of success.
302    */
303   virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting,
304                                           GHOST_IWindow **window) = 0;
305 
306   /**
307    * Ends full screen mode.
308    * \return  Indication of success.
309    */
310   virtual GHOST_TSuccess endFullScreen(void) = 0;
311 
312   /**
313    * Returns current full screen mode status.
314    * \return The current status.
315    */
316   virtual bool getFullScreen(void) = 0;
317 
318   /**
319    * Native pixel size support (MacBook 'retina').
320    */
321   virtual bool useNativePixel(void) = 0;
322 
323   /**
324    * Focus window after opening, or put them in the background.
325    */
326   virtual void useWindowFocus(const bool use_focus) = 0;
327 
328   /***************************************************************************************
329    * Event management functionality
330    ***************************************************************************************/
331 
332   /**
333    * Retrieves events from the system and stores them in the queue.
334    * \param waitForEvent Flag to wait for an event (or return immediately).
335    * \return Indication of the presence of events.
336    */
337   virtual bool processEvents(bool waitForEvent) = 0;
338 
339   /**
340    * Retrieves events from the queue and send them to the event consumers.
341    */
342   virtual void dispatchEvents() = 0;
343 
344   /**
345    * Adds the given event consumer to our list.
346    * \param consumer The event consumer to add.
347    * \return Indication of success.
348    */
349   virtual GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer) = 0;
350 
351   /**
352    * Removes the given event consumer to our list.
353    * \param consumer The event consumer to remove.
354    * \return Indication of success.
355    */
356   virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer) = 0;
357 
358   /***************************************************************************************
359    * Cursor management functionality
360    ***************************************************************************************/
361 
362   /**
363    * Returns the current location of the cursor (location in screen coordinates)
364    * \param x         The x-coordinate of the cursor.
365    * \param y         The y-coordinate of the cursor.
366    * \return          Indication of success.
367    */
368   virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const = 0;
369 
370   /**
371    * Updates the location of the cursor (location in screen coordinates).
372    * Not all operating systems allow the cursor to be moved (without the input device being moved).
373    * \param x         The x-coordinate of the cursor.
374    * \param y         The y-coordinate of the cursor.
375    * \return          Indication of success.
376    */
377   virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) = 0;
378 
379   /***************************************************************************************
380    * Access to mouse button and keyboard states.
381    ***************************************************************************************/
382 
383   /**
384    * Returns the state of a modifier key (outside the message queue).
385    * \param mask      The modifier key state to retrieve.
386    * \param isDown    The state of a modifier key (true == pressed).
387    * \return          Indication of success.
388    */
389   virtual GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool &isDown) const = 0;
390 
391   /**
392    * Returns the state of a mouse button (outside the message queue).
393    * \param mask      The button state to retrieve.
394    * \param isDown    Button state.
395    * \return          Indication of success.
396    */
397   virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool &isDown) const = 0;
398 
399   /**
400    * Set which tablet API to use. Only affects Windows, other platforms have a single API.
401    * \param api Enum indicating which API to use.
402    */
403   virtual void setTabletAPI(GHOST_TTabletAPI api) = 0;
404 
405 #ifdef WITH_INPUT_NDOF
406   /**
407    * Sets 3D mouse deadzone
408    * \param deadzone: Dead-zone of the 3D mouse (both for rotation and pan) relative to full range
409    */
410   virtual void setNDOFDeadZone(float deadzone) = 0;
411 #endif
412 
413   /**
414    * Toggles console
415    * \param action
416    * - 0: Hides
417    * - 1: Shows
418    * - 2: Toggles
419    * - 3: Hides if it runs not from  command line
420    * - *: Does nothing
421    * \return current status (1 -visible, 0 - hidden)
422    */
423   virtual int toggleConsole(int action) = 0;
424 
425   /***************************************************************************************
426    * Access to clipboard.
427    ***************************************************************************************/
428 
429   /**
430    * Returns the selection buffer
431    * \return "unsigned char" from X11 XA_CUT_BUFFER0 buffer
432    *
433    */
434   virtual GHOST_TUns8 *getClipboard(bool selection) const = 0;
435 
436   /**
437    * Put data to the Clipboard
438    */
439   virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0;
440 
441   /***************************************************************************************
442    * System Message Box.
443    ***************************************************************************************/
444 
445   /**
446    * Show a system message box
447    *
448    * \param title                   The title of the message box
449    * \param message                 The message to display
450    * \param help_label              Help button label
451    * \param continue_label          Continue button label
452    * \param link                    An optional hyperlink
453    * \param dialog_options Options  how to display the message
454    */
455   virtual GHOST_TSuccess showMessageBox(const char * /*title*/,
456                                         const char * /*message*/,
457                                         const char * /*help_label*/,
458                                         const char * /*continue_label*/,
459                                         const char * /*link*/,
460                                         GHOST_DialogOptions /*dialog_options*/) const = 0;
461 
462   /***************************************************************************************
463    * Debugging
464    ***************************************************************************************/
465 
466   /**
467    * Specify whether debug messages are to be shown.
468    */
469   virtual void initDebug(bool is_debug_enabled) = 0;
470 
471   /**
472    * Check whether debug messages are to be shown.
473    */
474   virtual bool isDebugEnabled() = 0;
475 
476  protected:
477   /**
478    * Initialize the system.
479    * \return Indication of success.
480    */
481   virtual GHOST_TSuccess init() = 0;
482 
483   /**
484    * Shut the system down.
485    * \return Indication of success.
486    */
487   virtual GHOST_TSuccess exit() = 0;
488 
489   /** The one and only system */
490   static GHOST_ISystem *m_system;
491 
492 #ifdef WITH_CXX_GUARDEDALLOC
493   MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_ISystem")
494 #endif
495 };
496