Blender  V3.3
GHOST_System.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include "GHOST_System.h"
9 
10 #include <chrono>
11 #include <cstdio> /* just for printf */
12 
13 #include "GHOST_DisplayManager.h"
14 #include "GHOST_EventManager.h"
15 #include "GHOST_TimerManager.h"
16 #include "GHOST_TimerTask.h"
17 #include "GHOST_WindowManager.h"
18 
19 #ifdef WITH_INPUT_NDOF
20 # include "GHOST_NDOFManager.h"
21 #endif
22 
24  : m_nativePixel(false),
25  m_windowFocus(true),
26  m_displayManager(nullptr),
27  m_timerManager(nullptr),
28  m_windowManager(nullptr),
29  m_eventManager(nullptr),
30 #ifdef WITH_INPUT_NDOF
31  m_ndofManager(0),
32 #endif
33  m_multitouchGestures(true),
34  m_tabletAPI(GHOST_kTabletAutomatic),
35  m_is_debug_enabled(false)
36 {
37 }
38 
40 {
41  exit();
42 }
43 
45 {
46  return std::chrono::duration_cast<std::chrono::milliseconds>(
47  std::chrono::steady_clock::now().time_since_epoch())
48  .count();
49 }
50 
52  uint64_t interval,
53  GHOST_TimerProcPtr timerProc,
54  GHOST_TUserDataPtr userData)
55 {
56  uint64_t millis = getMilliSeconds();
57  GHOST_TimerTask *timer = new GHOST_TimerTask(millis + delay, interval, timerProc, userData);
58  if (timer) {
59  if (m_timerManager->addTimer(timer) == GHOST_kSuccess) {
60  /* Check to see whether we need to fire the timer right away. */
61  m_timerManager->fireTimers(millis);
62  }
63  else {
64  delete timer;
65  timer = nullptr;
66  }
67  }
68  return timer;
69 }
70 
72 {
74  if (timerTask) {
75  success = m_timerManager->removeTimer((GHOST_TimerTask *)timerTask);
76  }
77  return success;
78 }
79 
81 {
82  GHOST_TSuccess success;
83 
84  /*
85  * Remove all pending events for the window.
86  */
87  if (m_windowManager->getWindowFound(window)) {
89  }
90  if (window == m_windowManager->getFullScreenWindow()) {
91  success = endFullScreen();
92  }
93  else {
94  if (m_windowManager->getWindowFound(window)) {
95  success = m_windowManager->removeWindow(window);
96  if (success) {
97  delete window;
98  }
99  }
100  else {
101  success = GHOST_kFailure;
102  }
103  }
104  return success;
105 }
106 
108 {
109  return m_windowManager->getWindowFound(window);
110 }
111 
113  GHOST_IWindow **window,
114  const bool stereoVisual,
115  const bool alphaBackground)
116 {
117  GHOST_TSuccess success = GHOST_kFailure;
118  GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager");
119  if (m_displayManager) {
120  if (!m_windowManager->getFullScreen()) {
123 
124  // GHOST_PRINT("GHOST_System::beginFullScreen(): activating new display settings\n");
126  setting);
127  if (success == GHOST_kSuccess) {
128  // GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n");
129  success = createFullScreenWindow(
130  (GHOST_Window **)window, setting, stereoVisual, alphaBackground);
131  if (success == GHOST_kSuccess) {
132  m_windowManager->beginFullScreen(*window, stereoVisual);
133  }
134  else {
137  }
138  }
139  }
140  }
141  if (success == GHOST_kFailure) {
142  GHOST_PRINT("GHOST_System::beginFullScreen(): could not enter full-screen mode\n");
143  }
144  return success;
145 }
146 
148  GHOST_IWindow ** /*window*/)
149 {
150  GHOST_TSuccess success = GHOST_kFailure;
151  GHOST_ASSERT(m_windowManager, "GHOST_System::updateFullScreen(): invalid window manager");
152  if (m_displayManager) {
155  setting);
156  }
157  }
158 
159  return success;
160 }
161 
163 {
164  GHOST_TSuccess success = GHOST_kFailure;
165  GHOST_ASSERT(m_windowManager, "GHOST_System::endFullScreen(): invalid window manager");
167  // GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
168  // GHOST_PRINT("GHOST_System::endFullScreen(): leaving window manager full-screen mode\n");
169  success = m_windowManager->endFullScreen();
170  GHOST_ASSERT(m_displayManager, "GHOST_System::endFullScreen(): invalid display manager");
171  // GHOST_PRINT("GHOST_System::endFullScreen(): leaving full-screen mode\n");
174  }
175  else {
176  success = GHOST_kFailure;
177  }
178  return success;
179 }
180 
182 {
183  bool fullScreen;
184  if (m_windowManager) {
185  fullScreen = m_windowManager->getFullScreen();
186  }
187  else {
188  fullScreen = false;
189  }
190  return fullScreen;
191 }
192 
194 {
195  /* TODO: This solution should follow the order of the activated windows (Z-order).
196  * It is imperfect but usable in most cases. */
197  for (GHOST_IWindow *iwindow : m_windowManager->getWindows()) {
198  if (iwindow->getState() == GHOST_kWindowStateMinimized) {
199  continue;
200  }
201 
203  iwindow->getClientBounds(bounds);
204  if (bounds.isInside(x, y)) {
205  return iwindow;
206  }
207  }
208 
209  return nullptr;
210 }
211 
213 {
214 #ifdef WITH_INPUT_NDOF
215  /* NDOF Motion event is sent only once per dispatch, so do it now: */
216  if (m_ndofManager) {
217  m_ndofManager->sendMotionEvent();
218  }
219 #endif
220 
221  if (m_eventManager) {
223  }
224 
226 }
227 
229 {
230  GHOST_TSuccess success;
231  if (m_eventManager) {
232  success = m_eventManager->addConsumer(consumer);
233  }
234  else {
235  success = GHOST_kFailure;
236  }
237  return success;
238 }
239 
241 {
242  GHOST_TSuccess success;
243  if (m_eventManager) {
244  success = m_eventManager->removeConsumer(consumer);
245  }
246  else {
247  success = GHOST_kFailure;
248  }
249  return success;
250 }
251 
253 {
254  GHOST_TSuccess success;
255  if (m_eventManager) {
256  success = m_eventManager->pushEvent(event);
257  }
258  else {
259  success = GHOST_kFailure;
260  }
261  return success;
262 }
263 
265  int32_t &x,
266  int32_t &y) const
267 {
268  /* Sub-classes that can implement this directly should do so. */
269  int32_t screen_x, screen_y;
270  GHOST_TSuccess success = getCursorPosition(screen_x, screen_y);
271  if (success == GHOST_kSuccess) {
272  window->screenToClient(screen_x, screen_y, x, y);
273  }
274  return success;
275 }
276 
278  int32_t x,
279  int32_t y)
280 {
281  /* Sub-classes that can implement this directly should do so. */
282  int32_t screen_x, screen_y;
283  window->clientToScreen(x, y, screen_x, screen_y);
284  return setCursorPosition(screen_x, screen_y);
285 }
286 
288 {
289  GHOST_ModifierKeys keys;
290  /* Get the state of all modifier keys. */
291  GHOST_TSuccess success = getModifierKeys(keys);
292  if (success) {
293  /* Isolate the state of the key requested. */
294  isDown = keys.get(mask);
295  }
296  return success;
297 }
298 
300 {
301  GHOST_Buttons buttons;
302  /* Get the state of all mouse buttons. */
303  GHOST_TSuccess success = getButtons(buttons);
304  if (success) {
305  /* Isolate the state of the mouse button requested. */
306  isDown = buttons.get(mask);
307  }
308  return success;
309 }
310 
312 {
313  m_multitouchGestures = use;
314 }
315 
317 {
318  m_tabletAPI = api;
319 }
320 
322 {
323  return m_tabletAPI;
324 }
325 
326 #ifdef WITH_INPUT_NDOF
327 void GHOST_System::setNDOFDeadZone(float deadzone)
328 {
329  if (this->m_ndofManager) {
330  this->m_ndofManager->setDeadZone(deadzone);
331  }
332 }
333 #endif
334 
336 {
340 
341 #ifdef WITH_GHOST_DEBUG
342  if (m_eventManager) {
343  m_eventPrinter = new GHOST_EventPrinter();
344  m_eventManager->addConsumer(m_eventPrinter);
345  }
346 #endif /* WITH_GHOST_DEBUG */
347 
349  return GHOST_kSuccess;
350  }
351  return GHOST_kFailure;
352 }
353 
355 {
356  if (getFullScreen()) {
357  endFullScreen();
358  }
359 
360  delete m_displayManager;
361  m_displayManager = nullptr;
362 
363  delete m_windowManager;
364  m_windowManager = nullptr;
365 
366  delete m_timerManager;
367  m_timerManager = nullptr;
368 
369  delete m_eventManager;
370  m_eventManager = nullptr;
371 
372 #ifdef WITH_INPUT_NDOF
373  delete m_ndofManager;
374  m_ndofManager = nullptr;
375 #endif
376 
377  return GHOST_kSuccess;
378 }
379 
381  const GHOST_DisplaySetting &settings,
382  const bool stereoVisual,
383  const bool alphaBackground)
384 {
385  GHOST_GLSettings glSettings = {0};
386 
387  if (stereoVisual) {
388  glSettings.flags |= GHOST_glStereoVisual;
389  }
390  if (alphaBackground) {
391  glSettings.flags |= GHOST_glAlphaBackground;
392  }
393 
394  /* NOTE: don't use #getCurrentDisplaySetting() because on X11 we may
395  * be zoomed in and the desktop may be bigger than the viewport. */
397  "GHOST_System::createFullScreenWindow(): invalid display manager");
398  // GHOST_PRINT("GHOST_System::createFullScreenWindow(): creating full-screen window\n");
399  *window = (GHOST_Window *)createWindow("",
400  0,
401  0,
402  settings.xPixels,
403  settings.yPixels,
406  glSettings,
407  true /* exclusive */);
408  return (*window == nullptr) ? GHOST_kFailure : GHOST_kSuccess;
409 }
410 
412 {
413  m_nativePixel = true;
414  return true;
415 }
416 
417 void GHOST_System::useWindowFocus(const bool use_focus)
418 {
419  m_windowFocus = use_focus;
420 }
421 
423 {
424  return true;
425 }
426 
428 {
429  return true;
430 }
431 
433 {
435 }
436 
438 {
439  return m_is_debug_enabled;
440 }
#define GHOST_ASSERT(x, info)
Definition: GHOST_Debug.h:54
#define GHOST_PRINT(x)
Definition: GHOST_Debug.h:35
@ GHOST_kWindowStateMinimized
Definition: GHOST_Types.h:132
@ GHOST_kWindowStateNormal
Definition: GHOST_Types.h:130
void * GHOST_TUserDataPtr
Definition: GHOST_Types.h:72
@ GHOST_kDebugDefault
Definition: GHOST_Types.h:586
@ GHOST_glAlphaBackground
Definition: GHOST_Types.h:64
@ GHOST_glStereoVisual
Definition: GHOST_Types.h:62
void(* GHOST_TimerProcPtr)(struct GHOST_TimerTaskHandle__ *task, uint64_t time)
Definition: GHOST_Types.h:614
@ GHOST_kDrawingContextTypeOpenGL
Definition: GHOST_Types.h:150
GHOST_TModifierKey
Definition: GHOST_Types.h:118
GHOST_TSuccess
Definition: GHOST_Types.h:74
@ GHOST_kFailure
Definition: GHOST_Types.h:74
@ GHOST_kSuccess
Definition: GHOST_Types.h:74
GHOST_TButton
Definition: GHOST_Types.h:156
GHOST_TTabletAPI
Definition: GHOST_Types.h:89
@ GHOST_kTabletAutomatic
Definition: GHOST_Types.h:90
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
virtual GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting)
virtual GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const
void removeWindowEvents(GHOST_IWindow *window)
GHOST_TSuccess addConsumer(GHOST_IEventConsumer *consumer)
GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer)
GHOST_TSuccess pushEvent(GHOST_IEvent *event)
virtual GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const =0
virtual GHOST_IWindow * createWindow(const char *title, int32_t left, int32_t top, uint32_t width, uint32_t height, GHOST_TWindowState state, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings, const bool exclusive=false, const bool is_dialog=false, const GHOST_IWindow *parentWindow=NULL)=0
virtual GHOST_TSuccess setCursorPosition(int32_t x, int32_t y)=0
virtual void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const =0
virtual void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const =0
virtual uint64_t getMilliSeconds() const
GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, const GHOST_DisplaySetting &settings, const bool stereoVisual, const bool alphaBackground=0)
virtual GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const =0
GHOST_DisplaySetting m_preFullScreenSetting
Definition: GHOST_System.h:411
void useWindowFocus(const bool use_focus)
GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask)
GHOST_TTabletAPI getTabletAPI(void)
GHOST_TSuccess endFullScreen(void)
virtual bool isDebugEnabled()
virtual ~GHOST_System()
virtual GHOST_TSuccess exit()
bool m_multitouchGestures
Definition: GHOST_System.h:414
virtual GHOST_TSuccess init()
virtual void setTabletAPI(GHOST_TTabletAPI api)
bool supportsWindowPosition(void)
bool m_windowFocus
Definition: GHOST_System.h:162
GHOST_TSuccess getButtonState(GHOST_TButton mask, bool &isDown) const
GHOST_TSuccess getModifierKeyState(GHOST_TModifierKey mask, bool &isDown) const
GHOST_TSuccess disposeWindow(GHOST_IWindow *window)
bool useNativePixel(void)
GHOST_IWindow * getWindowUnderCursor(int32_t x, int32_t y)
void setMultitouchGestures(const bool use)
GHOST_WindowManager * m_windowManager
Definition: GHOST_System.h:395
virtual void initDebug(GHOST_Debug debug)
GHOST_TSuccess getCursorPositionClientRelative(const GHOST_IWindow *window, int32_t &x, int32_t &y) const
void dispatchEvents()
bool validWindow(GHOST_IWindow *window)
GHOST_ITimerTask * installTimer(uint64_t delay, uint64_t interval, GHOST_TimerProcPtr timerProc, GHOST_TUserDataPtr userData=NULL)
GHOST_TSuccess pushEvent(GHOST_IEvent *event)
GHOST_TimerManager * m_timerManager
Definition: GHOST_System.h:392
GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer)
GHOST_TSuccess setCursorPositionClientRelative(GHOST_IWindow *window, int32_t x, int32_t y)
GHOST_DisplayManager * m_displayManager
Definition: GHOST_System.h:389
bool m_nativePixel
Definition: GHOST_System.h:152
bool supportsCursorWarp(void)
GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window, const bool stereoVisual, const bool alphaBackground)
GHOST_TTabletAPI m_tabletAPI
Definition: GHOST_System.h:417
bool m_is_debug_enabled
Definition: GHOST_System.h:419
GHOST_EventManager * m_eventManager
Definition: GHOST_System.h:398
virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const =0
GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window)
bool getFullScreen(void)
GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer)
bool fireTimers(uint64_t time)
GHOST_TSuccess removeTimer(GHOST_TimerTask *timer)
GHOST_TSuccess addTimer(GHOST_TimerTask *timer)
GHOST_TSuccess endFullScreen(void)
bool getFullScreen(void) const
GHOST_TSuccess removeWindow(const GHOST_IWindow *window)
const std::vector< GHOST_IWindow * > & getWindows() const
GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual)
bool getWindowFound(const GHOST_IWindow *window) const
GHOST_IWindow * getFullScreenWindow(void) const
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
signed int int32_t
Definition: stdint.h:77
unsigned __int64 uint64_t
Definition: stdint.h:90
bool get(GHOST_TButton mask) const
bool get(GHOST_TModifierKey mask) const