Blender  V2.93
GHOST_SystemSDL.cpp
Go to the documentation of this file.
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 
21 #include <assert.h>
22 
23 #include "GHOST_ContextSDL.h"
24 #include "GHOST_SystemSDL.h"
25 #include "GHOST_WindowSDL.h"
26 
27 #include "GHOST_WindowManager.h"
28 
29 #include "GHOST_EventButton.h"
30 #include "GHOST_EventCursor.h"
31 #include "GHOST_EventKey.h"
32 #include "GHOST_EventWheel.h"
33 
35 {
36  if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) {
37  printf("Error initializing SDL: %s\n", SDL_GetError());
38  }
39 
40  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
41  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
42  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
43  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
44  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
45 }
46 
48 {
49  SDL_Quit();
50 }
51 
52 GHOST_IWindow *GHOST_SystemSDL::createWindow(const char *title,
59  GHOST_GLSettings glSettings,
60  const bool exclusive,
61  const bool /* is_dialog */,
62  const GHOST_IWindow *parentWindow)
63 {
64  GHOST_WindowSDL *window = NULL;
65 
66  window = new GHOST_WindowSDL(this,
67  title,
68  left,
69  top,
70  width,
71  height,
72  state,
73  type,
74  ((glSettings.flags & GHOST_glStereoVisual) != 0),
75  exclusive,
76  parentWindow);
77 
78  if (window) {
80  SDL_Window *sdl_win = window->getSDLWindow();
81  SDL_DisplayMode mode;
82 
83  static_cast<GHOST_DisplayManagerSDL *>(m_displayManager)->getCurrentDisplayModeSDL(mode);
84 
85  SDL_SetWindowDisplayMode(sdl_win, &mode);
86  SDL_ShowWindow(sdl_win);
87  SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
88  }
89 
90  if (window->getValid()) {
91  m_windowManager->addWindow(window);
93  }
94  else {
95  delete window;
96  window = NULL;
97  }
98  }
99  return window;
100 }
101 
102 GHOST_TSuccess GHOST_SystemSDL::init()
103 {
105 
106  if (success) {
108 
109  if (m_displayManager) {
110  return GHOST_kSuccess;
111  }
112  }
113 
114  return GHOST_kFailure;
115 }
116 
122 {
123  SDL_DisplayMode mode;
124  SDL_GetDesktopDisplayMode(0, &mode); /* note, always 0 display */
125  width = mode.w;
126  height = mode.h;
127 }
128 
130 {
131  SDL_DisplayMode mode;
132  SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */
133  width = mode.w;
134  height = mode.h;
135 }
136 
138 {
139  return SDL_GetNumVideoDisplays();
140 }
141 
143 {
145  NULL,
146  0, // profile bit
147  3,
148  3,
151 
152  if (context->initializeDrawingContext())
153  return context;
154  else
155  delete context;
156 
157  return NULL;
158 }
159 
161 {
162  delete context;
163 
164  return GHOST_kSuccess;
165 }
166 
168 {
169  SDL_Keymod mod = SDL_GetModState();
170 
171  keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0);
172  keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0);
173  keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0);
174  keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
175  keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
176  keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
177  keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0);
178 
179  return GHOST_kSuccess;
180 }
181 
182 #define GXMAP(k, x, y) \
183  case x: \
184  k = y; \
185  break
186 
187 static GHOST_TKey convertSDLKey(SDL_Scancode key)
188 {
190 
191  if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
192  type = GHOST_TKey(key - SDL_SCANCODE_A + int(GHOST_kKeyA));
193  }
194  else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
195  type = (key == SDL_SCANCODE_0) ? GHOST_kKey0 :
196  GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1));
197  }
198  else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
199  type = GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
200  }
201  else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
202  type = GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13));
203  }
204  else {
205  switch (key) {
206  /* TODO SDL_SCANCODE_NONUSBACKSLASH */
207 
208  GXMAP(type, SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace);
209  GXMAP(type, SDL_SCANCODE_TAB, GHOST_kKeyTab);
210  GXMAP(type, SDL_SCANCODE_RETURN, GHOST_kKeyEnter);
211  GXMAP(type, SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc);
212  GXMAP(type, SDL_SCANCODE_SPACE, GHOST_kKeySpace);
213 
214  GXMAP(type, SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon);
215  GXMAP(type, SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod);
216  GXMAP(type, SDL_SCANCODE_COMMA, GHOST_kKeyComma);
217  GXMAP(type, SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote);
218  GXMAP(type, SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave);
219  GXMAP(type, SDL_SCANCODE_MINUS, GHOST_kKeyMinus);
220  GXMAP(type, SDL_SCANCODE_EQUALS, GHOST_kKeyEqual);
221 
222  GXMAP(type, SDL_SCANCODE_SLASH, GHOST_kKeySlash);
223  GXMAP(type, SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash);
224  GXMAP(type, SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual);
225  GXMAP(type, SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket);
226  GXMAP(type, SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket);
227  GXMAP(type, SDL_SCANCODE_PAUSE, GHOST_kKeyPause);
228 
229  GXMAP(type, SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift);
230  GXMAP(type, SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift);
231  GXMAP(type, SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl);
232  GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
233  GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
234  GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
235  GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS);
236  GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS);
237  GXMAP(type, SDL_SCANCODE_APPLICATION, GHOST_kKeyApp);
238 
239  GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
240  GXMAP(type, SDL_SCANCODE_DELETE, GHOST_kKeyDelete);
241  GXMAP(type, SDL_SCANCODE_HOME, GHOST_kKeyHome);
242  GXMAP(type, SDL_SCANCODE_END, GHOST_kKeyEnd);
243  GXMAP(type, SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage);
244  GXMAP(type, SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage);
245 
246  GXMAP(type, SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow);
247  GXMAP(type, SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow);
248  GXMAP(type, SDL_SCANCODE_UP, GHOST_kKeyUpArrow);
249  GXMAP(type, SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow);
250 
251  GXMAP(type, SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock);
252  GXMAP(type, SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock);
253  GXMAP(type, SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock);
254  GXMAP(type, SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen);
255 
256  /* keypad events */
257 
258  /* NOTE: SDL defines a bunch of key-pad identifiers that aren't supported by GHOST,
259  * such as #SDL_SCANCODE_KP_PERCENT, #SDL_SCANCODE_KP_XOR. */
260  GXMAP(type, SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0);
261  GXMAP(type, SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1);
262  GXMAP(type, SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2);
263  GXMAP(type, SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3);
264  GXMAP(type, SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4);
265  GXMAP(type, SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5);
266  GXMAP(type, SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6);
267  GXMAP(type, SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7);
268  GXMAP(type, SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8);
269  GXMAP(type, SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9);
270  GXMAP(type, SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod);
271 
272  GXMAP(type, SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter);
273  GXMAP(type, SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus);
274  GXMAP(type, SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus);
275  GXMAP(type, SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk);
276  GXMAP(type, SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash);
277 
278  /* Media keys in some keyboards and laptops with XFree86/Xorg */
279  GXMAP(type, SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay);
280  GXMAP(type, SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop);
281  GXMAP(type, SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst);
282  // GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
283  GXMAP(type, SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
284 
285  default:
286  printf("Unknown\n");
288  break;
289  }
290  }
291 
292  return type;
293 }
294 #undef GXMAP
295 
300 static SDL_Window *SDL_GetWindowFromID_fallback(Uint32 id)
301 {
302  SDL_Window *sdl_win = SDL_GetWindowFromID(id);
303  if (sdl_win == NULL) {
304  sdl_win = SDL_GL_GetCurrentWindow();
305  }
306  return sdl_win;
307 }
308 
309 void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
310 {
311  GHOST_Event *g_event = NULL;
312 
313  switch (sdl_event->type) {
314  case SDL_WINDOWEVENT: {
315  SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
316  GHOST_WindowSDL *window = findGhostWindow(
317  SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
318  // assert(window != NULL); // can be NULL on close window.
319 
320  switch (sdl_sub_evt.event) {
321  case SDL_WINDOWEVENT_EXPOSED:
322  g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
323  break;
324  case SDL_WINDOWEVENT_RESIZED:
325  g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
326  break;
327  case SDL_WINDOWEVENT_MOVED:
328  g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window);
329  break;
330  case SDL_WINDOWEVENT_FOCUS_GAINED:
331  g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window);
332  break;
333  case SDL_WINDOWEVENT_FOCUS_LOST:
334  g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window);
335  break;
336  case SDL_WINDOWEVENT_CLOSE:
337  g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
338  break;
339  }
340 
341  break;
342  }
343 
344  case SDL_QUIT: {
346  g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventQuitRequest, window);
347  break;
348  }
349 
350  case SDL_MOUSEMOTION: {
351  SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion;
352  SDL_Window *sdl_win = SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID);
353  GHOST_WindowSDL *window = findGhostWindow(sdl_win);
354  assert(window != NULL);
355 
356  int x_win, y_win;
357  SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
358 
359  GHOST_TInt32 x_root = sdl_sub_evt.x + x_win;
360  GHOST_TInt32 y_root = sdl_sub_evt.y + y_win;
361 
362 #if 0
363  if (window->getCursorGrabMode() != GHOST_kGrabDisable &&
364  window->getCursorGrabMode() != GHOST_kGrabNormal) {
365  GHOST_TInt32 x_new = x_root;
366  GHOST_TInt32 y_new = y_root;
367  GHOST_TInt32 x_accum, y_accum;
369 
370  /* fallback to window bounds */
371  if (window->getCursorGrabBounds(bounds) == GHOST_kFailure)
372  window->getClientBounds(bounds);
373 
374  /* Could also clamp to screen bounds wrap with a window outside the view will fail atm.
375  * Use offset of 8 in case the window is at screen bounds. */
376  bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis());
377  window->getCursorGrabAccum(x_accum, y_accum);
378 
379  // cant use setCursorPosition because the mouse may have no focus!
380  if (x_new != x_root || y_new != y_root) {
381  if (1) { //xme.time > m_last_warp) {
382  /* when wrapping we don't need to add an event because the
383  * setCursorPosition call will cause a new event after */
384  SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */
385  window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new));
386  // m_last_warp= lastEventTime(xme.time);
387  }
388  else {
389  // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
390  SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
391  }
392 
393  g_event = new GHOST_EventCursor(getMilliSeconds(),
395  window,
396  x_new,
397  y_new,
399  }
400  else {
401  g_event = new GHOST_EventCursor(getMilliSeconds(),
403  window,
404  x_root + x_accum,
405  y_root + y_accum,
407  }
408  }
409  else
410 #endif
411  {
412  g_event = new GHOST_EventCursor(getMilliSeconds(),
414  window,
415  x_root,
416  y_root,
418  }
419  break;
420  }
421  case SDL_MOUSEBUTTONUP:
422  case SDL_MOUSEBUTTONDOWN: {
423  SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button;
425  GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventButtonDown :
427 
428  GHOST_WindowSDL *window = findGhostWindow(
429  SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
430  assert(window != NULL);
431 
432  /* process rest of normal mouse buttons */
433  if (sdl_sub_evt.button == SDL_BUTTON_LEFT)
434  gbmask = GHOST_kButtonMaskLeft;
435  else if (sdl_sub_evt.button == SDL_BUTTON_MIDDLE)
436  gbmask = GHOST_kButtonMaskMiddle;
437  else if (sdl_sub_evt.button == SDL_BUTTON_RIGHT)
438  gbmask = GHOST_kButtonMaskRight;
439  /* these buttons are untested! */
440  else if (sdl_sub_evt.button == SDL_BUTTON_X1)
441  gbmask = GHOST_kButtonMaskButton4;
442  else if (sdl_sub_evt.button == SDL_BUTTON_X2)
443  gbmask = GHOST_kButtonMaskButton5;
444  else
445  break;
446 
447  g_event = new GHOST_EventButton(
448  getMilliSeconds(), type, window, gbmask, GHOST_TABLET_DATA_NONE);
449  break;
450  }
451  case SDL_MOUSEWHEEL: {
452  SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel;
453  GHOST_WindowSDL *window = findGhostWindow(
454  SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
455  assert(window != NULL);
456  g_event = new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y);
457  break;
458  }
459  case SDL_KEYDOWN:
460  case SDL_KEYUP: {
461  SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key;
462  SDL_Keycode sym = sdl_sub_evt.keysym.sym;
463  GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown :
465 
466  GHOST_WindowSDL *window = findGhostWindow(
467  SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
468  assert(window != NULL);
469 
470  GHOST_TKey gkey = convertSDLKey(sdl_sub_evt.keysym.scancode);
471  /* note, the sdl_sub_evt.keysym.sym is truncated,
472  * for unicode support ghost has to be modified */
473  /* printf("%d\n", sym); */
474  if (sym > 127) {
475  switch (sym) {
476  case SDLK_KP_DIVIDE:
477  sym = '/';
478  break;
479  case SDLK_KP_MULTIPLY:
480  sym = '*';
481  break;
482  case SDLK_KP_MINUS:
483  sym = '-';
484  break;
485  case SDLK_KP_PLUS:
486  sym = '+';
487  break;
488  case SDLK_KP_1:
489  sym = '1';
490  break;
491  case SDLK_KP_2:
492  sym = '2';
493  break;
494  case SDLK_KP_3:
495  sym = '3';
496  break;
497  case SDLK_KP_4:
498  sym = '4';
499  break;
500  case SDLK_KP_5:
501  sym = '5';
502  break;
503  case SDLK_KP_6:
504  sym = '6';
505  break;
506  case SDLK_KP_7:
507  sym = '7';
508  break;
509  case SDLK_KP_8:
510  sym = '8';
511  break;
512  case SDLK_KP_9:
513  sym = '9';
514  break;
515  case SDLK_KP_0:
516  sym = '0';
517  break;
518  case SDLK_KP_PERIOD:
519  sym = '.';
520  break;
521  default:
522  sym = 0;
523  break;
524  }
525  }
526  else {
527  if (sdl_sub_evt.keysym.mod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
528  /* lame US keyboard assumptions */
529  if (sym >= 'a' && sym <= ('a' + 32)) {
530  sym -= 32;
531  }
532  else {
533  switch (sym) {
534  case '`':
535  sym = '~';
536  break;
537  case '1':
538  sym = '!';
539  break;
540  case '2':
541  sym = '@';
542  break;
543  case '3':
544  sym = '#';
545  break;
546  case '4':
547  sym = '$';
548  break;
549  case '5':
550  sym = '%';
551  break;
552  case '6':
553  sym = '^';
554  break;
555  case '7':
556  sym = '&';
557  break;
558  case '8':
559  sym = '*';
560  break;
561  case '9':
562  sym = '(';
563  break;
564  case '0':
565  sym = ')';
566  break;
567  case '-':
568  sym = '_';
569  break;
570  case '=':
571  sym = '+';
572  break;
573  case '[':
574  sym = '{';
575  break;
576  case ']':
577  sym = '}';
578  break;
579  case '\\':
580  sym = '|';
581  break;
582  case ';':
583  sym = ':';
584  break;
585  case '\'':
586  sym = '"';
587  break;
588  case ',':
589  sym = '<';
590  break;
591  case '.':
592  sym = '>';
593  break;
594  case '/':
595  sym = '?';
596  break;
597  default:
598  break;
599  }
600  }
601  }
602  }
603 
604  g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL, false);
605  break;
606  }
607  }
608 
609  if (g_event) {
610  pushEvent(g_event);
611  }
612 }
613 
615 {
616  int x_win, y_win;
617  SDL_Window *win = SDL_GetMouseFocus();
618  SDL_GetWindowPosition(win, &x_win, &y_win);
619 
620  int xi, yi;
621  SDL_GetMouseState(&xi, &yi);
622  x = xi + x_win;
623  y = yi + x_win;
624 
625  return GHOST_kSuccess;
626 }
627 
629 {
630  int x_win, y_win;
631  SDL_Window *win = SDL_GetMouseFocus();
632  SDL_GetWindowPosition(win, &x_win, &y_win);
633 
634  SDL_WarpMouseInWindow(win, x - x_win, y - y_win);
635  return GHOST_kSuccess;
636 }
637 
638 bool GHOST_SystemSDL::generateWindowExposeEvents()
639 {
640  std::vector<GHOST_WindowSDL *>::iterator w_start = m_dirty_windows.begin();
641  std::vector<GHOST_WindowSDL *>::const_iterator w_end = m_dirty_windows.end();
642  bool anyProcessed = false;
643 
644  for (; w_start != w_end; ++w_start) {
646 
647  (*w_start)->validate();
648 
649  if (g_event) {
650  // printf("Expose events pushed\n");
651  pushEvent(g_event);
652  anyProcessed = true;
653  }
654  }
655 
656  m_dirty_windows.clear();
657  return anyProcessed;
658 }
659 
660 bool GHOST_SystemSDL::processEvents(bool waitForEvent)
661 {
662  // Get all the current events -- translate them into
663  // ghost events and call base class pushEvent() method.
664 
665  bool anyProcessed = false;
666 
667  do {
668  GHOST_TimerManager *timerMgr = getTimerManager();
669 
670  if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
671  GHOST_TUns64 next = timerMgr->nextFireTime();
672 
673  if (next == GHOST_kFireTimeNever) {
674  SDL_WaitEventTimeout(NULL, -1);
675  // SleepTillEvent(m_display, -1);
676  }
677  else {
678  GHOST_TInt64 maxSleep = next - getMilliSeconds();
679 
680  if (maxSleep >= 0) {
681  SDL_WaitEventTimeout(NULL, next - getMilliSeconds());
682  // SleepTillEvent(m_display, next - getMilliSeconds()); // X11
683  }
684  }
685  }
686 
687  if (timerMgr->fireTimers(getMilliSeconds())) {
688  anyProcessed = true;
689  }
690 
691  SDL_Event sdl_event;
692  while (SDL_PollEvent(&sdl_event)) {
693  processEvent(&sdl_event);
694  anyProcessed = true;
695  }
696 
697  if (generateWindowExposeEvents()) {
698  anyProcessed = true;
699  }
700  } while (waitForEvent && !anyProcessed);
701 
702  return anyProcessed;
703 }
704 
705 GHOST_WindowSDL *GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
706 {
707  if (sdl_win == NULL)
708  return NULL;
709 
710  // It is not entirely safe to do this as the backptr may point
711  // to a window that has recently been removed.
712  // We should always check the window manager's list of windows
713  // and only process events on these windows.
714 
715  const std::vector<GHOST_IWindow *> &win_vec = m_windowManager->getWindows();
716 
717  std::vector<GHOST_IWindow *>::const_iterator win_it = win_vec.begin();
718  std::vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
719 
720  for (; win_it != win_end; ++win_it) {
721  GHOST_WindowSDL *window = static_cast<GHOST_WindowSDL *>(*win_it);
722  if (window->getSDLWindow() == sdl_win) {
723  return window;
724  }
725  }
726  return NULL;
727 }
728 
730 {
731  GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
732 
733  m_dirty_windows.push_back(bad_wind);
734 }
735 
737 {
738  Uint8 state = SDL_GetMouseState(NULL, NULL);
739  buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0);
740  buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0);
741  buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0);
742 
743  return GHOST_kSuccess;
744 }
745 
747 {
748  return (GHOST_TUns8 *)SDL_GetClipboardText();
749 }
750 
752 {
753  SDL_SetClipboardText(buffer);
754 }
755 
757 {
758  return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */
759 }
#define GHOST_OPENGL_SDL_RESET_NOTIFICATION_STRATEGY
#define GHOST_OPENGL_SDL_CONTEXT_FLAGS
#define GHOST_ASSERT(x, info)
Definition: GHOST_Debug.h:79
static SDL_Window * SDL_GetWindowFromID_fallback(Uint32 id)
static GHOST_TKey convertSDLKey(SDL_Scancode key)
#define GXMAP(k, x, y)
GHOST_TWindowState
Definition: GHOST_Types.h:144
@ GHOST_kWindowStateFullScreen
Definition: GHOST_Types.h:148
unsigned int GHOST_TUns32
Definition: GHOST_Types.h:64
unsigned long long GHOST_TUns64
Definition: GHOST_Types.h:86
GHOST_TEventType
Definition: GHOST_Types.h:177
@ GHOST_kEventWindowClose
Definition: GHOST_Types.h:197
@ GHOST_kEventWindowMove
Definition: GHOST_Types.h:202
@ GHOST_kEventWindowSize
Definition: GHOST_Types.h:201
@ GHOST_kEventCursorMove
Definition: GHOST_Types.h:180
@ GHOST_kEventButtonUp
Mouse button event.
Definition: GHOST_Types.h:182
@ GHOST_kEventWindowActivate
Definition: GHOST_Types.h:198
@ GHOST_kEventWindowUpdate
Definition: GHOST_Types.h:200
@ GHOST_kEventWindowDeactivate
Definition: GHOST_Types.h:199
@ GHOST_kEventButtonDown
Mouse move event.
Definition: GHOST_Types.h:181
@ GHOST_kEventKeyDown
Trackpad event.
Definition: GHOST_Types.h:191
@ GHOST_kEventKeyUp
Definition: GHOST_Types.h:192
@ GHOST_kEventQuitRequest
Definition: GHOST_Types.h:195
static const GHOST_TabletData GHOST_TABLET_DATA_NONE
Definition: GHOST_Types.h:119
int GHOST_TInt32
Definition: GHOST_Types.h:63
@ GHOST_glStereoVisual
Definition: GHOST_Types.h:71
GHOST_TKey
Definition: GHOST_Types.h:267
@ GHOST_kKeyInsert
Definition: GHOST_Types.h:354
@ GHOST_kKeySemicolon
Definition: GHOST_Types.h:296
@ GHOST_kKeyMediaPlay
Definition: GHOST_Types.h:406
@ GHOST_kKeyQuote
Definition: GHOST_Types.h:277
@ GHOST_kKeyNumpad3
Definition: GHOST_Types.h:365
@ GHOST_kKeyAccentGrave
Definition: GHOST_Types.h:330
@ GHOST_kKeyNumpad1
Definition: GHOST_Types.h:363
@ GHOST_kKeyLeftAlt
Definition: GHOST_Types.h:336
@ GHOST_kKeyRightShift
Definition: GHOST_Types.h:333
@ GHOST_kKeyNumLock
Definition: GHOST_Types.h:343
@ GHOST_kKeyEnter
Definition: GHOST_Types.h:273
@ GHOST_kKeyNumpadSlash
Definition: GHOST_Types.h:377
@ GHOST_kKeyRightArrow
Definition: GHOST_Types.h:347
@ GHOST_kKeyF13
Definition: GHOST_Types.h:392
@ GHOST_kKeyNumpad4
Definition: GHOST_Types.h:366
@ GHOST_kKeyPause
Definition: GHOST_Types.h:352
@ GHOST_kKeyCapsLock
Definition: GHOST_Types.h:342
@ GHOST_kKeyApp
Definition: GHOST_Types.h:340
@ GHOST_kKeyMinus
Definition: GHOST_Types.h:279
@ GHOST_kKeyMediaStop
Definition: GHOST_Types.h:407
@ GHOST_kKeyBackSpace
Definition: GHOST_Types.h:269
@ GHOST_kKey0
Definition: GHOST_Types.h:285
@ GHOST_kKeyDownPage
Definition: GHOST_Types.h:359
@ GHOST_kKeyDownArrow
Definition: GHOST_Types.h:349
@ GHOST_kKeyNumpadPeriod
Definition: GHOST_Types.h:372
@ GHOST_kKeyF1
Definition: GHOST_Types.h:380
@ GHOST_kKeyNumpadAsterisk
Definition: GHOST_Types.h:376
@ GHOST_kKeyPrintScreen
Definition: GHOST_Types.h:351
@ GHOST_kKeyLeftControl
Definition: GHOST_Types.h:334
@ GHOST_kKeyLeftBracket
Definition: GHOST_Types.h:327
@ GHOST_kKey1
Definition: GHOST_Types.h:286
@ GHOST_kKeyTab
Definition: GHOST_Types.h:270
@ GHOST_kKeyComma
Definition: GHOST_Types.h:278
@ GHOST_kKeyRightBracket
Definition: GHOST_Types.h:328
@ GHOST_kKeyBackslash
Definition: GHOST_Types.h:329
@ GHOST_kKeyOS
Definition: GHOST_Types.h:338
@ GHOST_kKeyNumpad2
Definition: GHOST_Types.h:364
@ GHOST_kKeyRightAlt
Definition: GHOST_Types.h:337
@ GHOST_kKeyPeriod
Definition: GHOST_Types.h:281
@ GHOST_kKeyNumpadPlus
Definition: GHOST_Types.h:374
@ GHOST_kKeyUpPage
Definition: GHOST_Types.h:358
@ GHOST_kKeyNumpad5
Definition: GHOST_Types.h:367
@ GHOST_kKeyLeftArrow
Definition: GHOST_Types.h:346
@ GHOST_kKeyEqual
Definition: GHOST_Types.h:297
@ GHOST_kKeyHome
Definition: GHOST_Types.h:356
@ GHOST_kKeyNumpad6
Definition: GHOST_Types.h:368
@ GHOST_kKeyNumpad8
Definition: GHOST_Types.h:370
@ GHOST_kKeyNumpad9
Definition: GHOST_Types.h:371
@ GHOST_kKeyEnd
Definition: GHOST_Types.h:357
@ GHOST_kKeyUpArrow
Definition: GHOST_Types.h:348
@ GHOST_kKeyDelete
Definition: GHOST_Types.h:355
@ GHOST_kKeyNumpad0
Definition: GHOST_Types.h:362
@ GHOST_kKeyA
Definition: GHOST_Types.h:300
@ GHOST_kKeyMediaFirst
Definition: GHOST_Types.h:408
@ GHOST_kKeyNumpad7
Definition: GHOST_Types.h:369
@ GHOST_kKeyRightControl
Definition: GHOST_Types.h:335
@ GHOST_kKeyEsc
Definition: GHOST_Types.h:275
@ GHOST_kKeyUnknown
Definition: GHOST_Types.h:268
@ GHOST_kKeyScrollLock
Definition: GHOST_Types.h:344
@ GHOST_kKeySlash
Definition: GHOST_Types.h:282
@ GHOST_kKeyNumpadEnter
Definition: GHOST_Types.h:373
@ GHOST_kKeyNumpadMinus
Definition: GHOST_Types.h:375
@ GHOST_kKeyLeftShift
Definition: GHOST_Types.h:332
@ GHOST_kKeyMediaLast
Definition: GHOST_Types.h:409
@ GHOST_kKeySpace
Definition: GHOST_Types.h:276
GHOST_TDrawingContextType
Definition: GHOST_Types.h:156
GHOST_TButtonMask
Definition: GHOST_Types.h:164
@ GHOST_kButtonMaskRight
Definition: GHOST_Types.h:168
@ GHOST_kButtonMaskButton4
Definition: GHOST_Types.h:169
@ GHOST_kButtonMaskLeft
Definition: GHOST_Types.h:166
@ GHOST_kButtonMaskButton5
Definition: GHOST_Types.h:170
@ GHOST_kButtonMaskMiddle
Definition: GHOST_Types.h:167
char GHOST_TInt8
Definition: GHOST_Types.h:59
GHOST_TSuccess
Definition: GHOST_Types.h:91
@ GHOST_kFailure
Definition: GHOST_Types.h:91
@ GHOST_kSuccess
Definition: GHOST_Types.h:91
@ GHOST_kFireTimeNever
Definition: GHOST_Types.h:131
@ GHOST_kModifierKeyRightControl
Definition: GHOST_Types.h:139
@ GHOST_kModifierKeyLeftControl
Definition: GHOST_Types.h:138
@ GHOST_kModifierKeyRightAlt
Definition: GHOST_Types.h:137
@ GHOST_kModifierKeyOS
Definition: GHOST_Types.h:140
@ GHOST_kModifierKeyRightShift
Definition: GHOST_Types.h:135
@ GHOST_kModifierKeyLeftAlt
Definition: GHOST_Types.h:136
@ GHOST_kModifierKeyLeftShift
Definition: GHOST_Types.h:134
@ GHOST_kGrabDisable
Definition: GHOST_Types.h:414
@ GHOST_kGrabNormal
Definition: GHOST_Types.h:416
unsigned char GHOST_TUns8
Definition: GHOST_Types.h:60
long long GHOST_TInt64
Definition: GHOST_Types.h:85
_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 GLsizei width
_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 type
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_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
_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 GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble top
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
GHOST_TUns64 getMilliSeconds()
GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
bool processEvents(bool waitForEvent)
GHOST_IContext * createOffscreenContext(GHOST_GLSettings glSettings)
GHOST_TSuccess disposeContext(GHOST_IContext *context)
void putClipboard(GHOST_TInt8 *buffer, bool selection) const
void addDirtyWindow(GHOST_WindowSDL *bad_wind)
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const
GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const
GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const
GHOST_TUns8 * getClipboard(bool selection) const
void getMainDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
void getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 &height) const
GHOST_TUns8 getNumDisplays() const
virtual GHOST_TSuccess init()
GHOST_TimerManager * getTimerManager() const
Definition: GHOST_System.h:407
GHOST_WindowManager * m_windowManager
Definition: GHOST_System.h:383
GHOST_TSuccess pushEvent(GHOST_IEvent *event)
GHOST_DisplayManager * m_displayManager
Definition: GHOST_System.h:377
GHOST_TUns64 nextFireTime()
bool fireTimers(GHOST_TUns64 time)
GHOST_TSuccess addWindow(GHOST_IWindow *window)
GHOST_IWindow * getActiveWindow(void) const
const std::vector< GHOST_IWindow * > & getWindows() const
bool getValid() const
void getClientBounds(GHOST_Rect &bounds) const
SDL_Window * getSDLWindow()
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds)
GHOST_TAxisFlag getCursorGrabAxis() const
Definition: GHOST_Window.h:430
void setCursorGrabAccum(GHOST_TInt32 x, GHOST_TInt32 y)
Definition: GHOST_Window.h:447
GHOST_TGrabCursorMode getCursorGrabMode() const
Definition: GHOST_Window.h:420
void getCursorGrabAccum(GHOST_TInt32 &x, GHOST_TInt32 &y) const
Definition: GHOST_Window.h:441
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
static ulong * next
static ulong state[N]
static int left
struct SELECTID_Context context
Definition: select_engine.c:47
void set(GHOST_TButtonMask mask, bool down)
void set(GHOST_TModifierKeyMask mask, bool down)
ccl_device_inline int mod(int x, int m)
Definition: util_math.h:405