2
* ***** BEGIN GPL LICENSE BLOCK *****
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
* Contributor(s): Campbell Barton
20
* ***** END GPL LICENSE BLOCK *****
23
/** \file ghost/intern/GHOST_SystemSDL.cpp
29
#include "GHOST_SystemSDL.h"
31
#include "GHOST_WindowManager.h"
33
#include "GHOST_EventCursor.h"
34
#include "GHOST_EventKey.h"
35
#include "GHOST_EventButton.h"
36
#include "GHOST_EventWheel.h"
38
GHOST_SystemSDL::GHOST_SystemSDL()
42
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) {
43
printf ("Error initializing SDL: %s\n", SDL_GetError());
46
/* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */
47
/* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */
48
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
49
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
50
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
51
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
52
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
53
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
56
GHOST_SystemSDL::~GHOST_SystemSDL()
62
GHOST_SystemSDL::createWindow(const STR_String& title,
67
GHOST_TWindowState state,
68
GHOST_TDrawingContextType type,
70
const GHOST_TUns16 numOfAASamples,
71
const GHOST_TEmbedderWindowID parentWindow
74
GHOST_WindowSDL *window= NULL;
76
window= new GHOST_WindowSDL (this, title, left, top, width, height, state, parentWindow, type, stereoVisual, 1);
79
if (GHOST_kWindowStateFullScreen == state) {
80
SDL_Window *sdl_win = window->getSDLWindow();
83
static_cast<GHOST_DisplayManagerSDL *> (m_displayManager)->getCurrentDisplayModeSDL(mode);
85
SDL_SetWindowDisplayMode(sdl_win, &mode);
86
SDL_ShowWindow(sdl_win);
87
SDL_SetWindowFullscreen(sdl_win, SDL_TRUE);
90
if (window->getValid()) {
91
m_windowManager->addWindow(window);
92
pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
103
GHOST_SystemSDL::init() {
104
GHOST_TSuccess success = GHOST_System::init();
107
m_displayManager = new GHOST_DisplayManagerSDL(this);
109
if (m_displayManager) {
110
return GHOST_kSuccess;
114
return GHOST_kFailure;
118
GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32& width,
119
GHOST_TUns32& height) const
121
SDL_DisplayMode mode;
122
SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */
128
GHOST_SystemSDL::getNumDisplays() const
130
return SDL_GetNumVideoDisplays();
134
GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const
136
SDL_Keymod mod= SDL_GetModState();
138
keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0);
139
keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0);
140
keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0);
141
keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
142
keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
143
keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
144
keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI|KMOD_RGUI)) != 0);
146
return GHOST_kSuccess;
149
#define GXMAP(k,x,y) case x: k= y; break;
152
convertSDLKey(SDL_Scancode key)
156
if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
157
type= GHOST_TKey( key - SDL_SCANCODE_A + int(GHOST_kKeyA));
158
} else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
159
type= (key == SDL_SCANCODE_0) ? GHOST_kKey0 : GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1));
160
} else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
161
type= GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
162
} else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
163
type= GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13));
166
/* TODO SDL_SCANCODE_NONUSBACKSLASH */
168
GXMAP(type,SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace);
169
GXMAP(type,SDL_SCANCODE_TAB, GHOST_kKeyTab);
170
GXMAP(type,SDL_SCANCODE_RETURN, GHOST_kKeyEnter);
171
GXMAP(type,SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc);
172
GXMAP(type,SDL_SCANCODE_SPACE, GHOST_kKeySpace);
174
GXMAP(type,SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon);
175
GXMAP(type,SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod);
176
GXMAP(type,SDL_SCANCODE_COMMA, GHOST_kKeyComma);
177
GXMAP(type,SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote);
178
GXMAP(type,SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave);
179
GXMAP(type,SDL_SCANCODE_MINUS, GHOST_kKeyMinus);
180
GXMAP(type,SDL_SCANCODE_EQUALS, GHOST_kKeyEqual);
182
GXMAP(type,SDL_SCANCODE_SLASH, GHOST_kKeySlash);
183
GXMAP(type,SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash);
184
GXMAP(type,SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual);
185
GXMAP(type,SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket);
186
GXMAP(type,SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket);
187
GXMAP(type,SDL_SCANCODE_PAUSE, GHOST_kKeyPause);
189
GXMAP(type,SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift);
190
GXMAP(type,SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift);
191
GXMAP(type,SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl);
192
GXMAP(type,SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
193
GXMAP(type,SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
194
GXMAP(type,SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
195
GXMAP(type,SDL_SCANCODE_LGUI, GHOST_kKeyOS);
196
GXMAP(type,SDL_SCANCODE_RGUI, GHOST_kKeyOS);
198
GXMAP(type,SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
199
GXMAP(type,SDL_SCANCODE_DELETE, GHOST_kKeyDelete);
200
GXMAP(type,SDL_SCANCODE_HOME, GHOST_kKeyHome);
201
GXMAP(type,SDL_SCANCODE_END, GHOST_kKeyEnd);
202
GXMAP(type,SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage);
203
GXMAP(type,SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage);
205
GXMAP(type,SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow);
206
GXMAP(type,SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow);
207
GXMAP(type,SDL_SCANCODE_UP, GHOST_kKeyUpArrow);
208
GXMAP(type,SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow);
210
GXMAP(type,SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock);
211
GXMAP(type,SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock);
212
GXMAP(type,SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock);
213
GXMAP(type,SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen);
217
/* note, sdl defines a bunch of kp defines I never saw before like
218
* SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */
219
GXMAP(type,SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0);
220
GXMAP(type,SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1);
221
GXMAP(type,SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2);
222
GXMAP(type,SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3);
223
GXMAP(type,SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4);
224
GXMAP(type,SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5);
225
GXMAP(type,SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6);
226
GXMAP(type,SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7);
227
GXMAP(type,SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8);
228
GXMAP(type,SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9);
229
GXMAP(type,SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod);
231
GXMAP(type,SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter);
232
GXMAP(type,SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus);
233
GXMAP(type,SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus);
234
GXMAP(type,SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk);
235
GXMAP(type,SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash);
237
/* Media keys in some keyboards and laptops with XFree86/Xorg */
238
GXMAP(type,SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay);
239
GXMAP(type,SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop);
240
GXMAP(type,SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst);
241
// GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
242
GXMAP(type,SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
246
type= GHOST_kKeyUnknown;
257
GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
259
GHOST_Event * g_event= NULL;
261
switch(sdl_event->type) {
262
case SDL_WINDOWEVENT:
264
SDL_WindowEvent &sdl_sub_evt= sdl_event->window;
265
GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
266
//assert(window != NULL); // can be NULL on close window.
268
switch (sdl_sub_evt.event) {
269
case SDL_WINDOWEVENT_EXPOSED:
270
g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
272
case SDL_WINDOWEVENT_RESIZED:
273
g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
275
case SDL_WINDOWEVENT_MOVED:
276
g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window);
278
case SDL_WINDOWEVENT_FOCUS_GAINED:
279
g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window);
281
case SDL_WINDOWEVENT_FOCUS_LOST:
282
g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window);
284
case SDL_WINDOWEVENT_CLOSE:
285
g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
291
g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL);
294
case SDL_MOUSEMOTION:
296
SDL_MouseMotionEvent &sdl_sub_evt= sdl_event->motion;
297
SDL_Window *sdl_win= SDL_GetWindowFromID(sdl_sub_evt.windowID);
298
GHOST_WindowSDL *window= findGhostWindow(sdl_win);
299
assert(window != NULL);
302
SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
304
GHOST_TInt32 x_root= sdl_sub_evt.x + x_win;
305
GHOST_TInt32 y_root= sdl_sub_evt.y + y_win;
308
if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
310
GHOST_TInt32 x_new= x_root;
311
GHOST_TInt32 y_new= y_root;
312
GHOST_TInt32 x_accum, y_accum;
315
/* fallback to window bounds */
316
if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
317
window->getClientBounds(bounds);
319
/* could also clamp to screen bounds
320
* wrap with a window outside the view will fail atm */
321
bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
322
window->getCursorGrabAccum(x_accum, y_accum);
324
// cant use setCursorPosition because the mouse may have no focus!
325
if(x_new != x_root || y_new != y_root) {
326
if (1 ) { //xme.time > m_last_warp) {
327
/* when wrapping we don't need to add an event because the
328
* setCursorPosition call will cause a new event after */
329
SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */
330
window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new));
331
// m_last_warp= lastEventTime(xme.time);
333
// setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
334
SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
337
g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new);
340
g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum);
346
g_event= new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root);
350
case SDL_MOUSEBUTTONUP:
351
case SDL_MOUSEBUTTONDOWN:
353
SDL_MouseButtonEvent &sdl_sub_evt= sdl_event->button;
354
GHOST_TButtonMask gbmask= GHOST_kButtonMaskLeft;
355
GHOST_TEventType type= (sdl_sub_evt.state==SDL_PRESSED) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp;
357
GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
358
assert(window != NULL);
360
/* process rest of normal mouse buttons */
361
if(sdl_sub_evt.button == SDL_BUTTON_LEFT)
362
gbmask= GHOST_kButtonMaskLeft;
363
else if(sdl_sub_evt.button == SDL_BUTTON_MIDDLE)
364
gbmask= GHOST_kButtonMaskMiddle;
365
else if(sdl_sub_evt.button == SDL_BUTTON_RIGHT)
366
gbmask= GHOST_kButtonMaskRight;
367
/* these buttons are untested! */
368
else if(sdl_sub_evt.button == SDL_BUTTON_X1)
369
gbmask= GHOST_kButtonMaskButton4;
370
else if(sdl_sub_evt.button == SDL_BUTTON_X2)
371
gbmask= GHOST_kButtonMaskButton5;
375
g_event= new GHOST_EventButton(getMilliSeconds(), type, window, gbmask);
380
SDL_MouseWheelEvent &sdl_sub_evt= sdl_event->wheel;
381
GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
382
assert(window != NULL);
383
g_event= new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y);
389
SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key;
390
SDL_Keycode sym= sdl_sub_evt.keysym.sym;
391
GHOST_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
393
GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
394
assert(window != NULL);
396
GHOST_TKey gkey= convertSDLKey(sdl_sub_evt.keysym.scancode);
397
/* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */
398
/* printf("%d\n", sym); */
401
case SDLK_KP_DIVIDE: sym= '/'; break;
402
case SDLK_KP_MULTIPLY: sym= '*'; break;
403
case SDLK_KP_MINUS: sym= '-'; break;
404
case SDLK_KP_PLUS: sym= '+'; break;
405
case SDLK_KP_1: sym= '1'; break;
406
case SDLK_KP_2: sym= '2'; break;
407
case SDLK_KP_3: sym= '3'; break;
408
case SDLK_KP_4: sym= '4'; break;
409
case SDLK_KP_5: sym= '5'; break;
410
case SDLK_KP_6: sym= '6'; break;
411
case SDLK_KP_7: sym= '7'; break;
412
case SDLK_KP_8: sym= '8'; break;
413
case SDLK_KP_9: sym= '9'; break;
414
case SDLK_KP_0: sym= '0'; break;
415
case SDLK_KP_PERIOD: sym= '.'; break;
416
default: sym= 0; break;
420
if(sdl_sub_evt.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT)) {
421
/* lame US keyboard assumptions */
422
if(sym >= 'a' && sym <= ('a' + 32)) {
427
case '`': sym= '~'; break;
428
case '1': sym= '!'; break;
429
case '2': sym= '@'; break;
430
case '3': sym= '#'; break;
431
case '4': sym= '$'; break;
432
case '5': sym= '%'; break;
433
case '6': sym= '^'; break;
434
case '7': sym= '&'; break;
435
case '8': sym= '*'; break;
436
case '9': sym= '('; break;
437
case '0': sym= ')'; break;
438
case '-': sym= '_'; break;
439
case '=': sym= '+'; break;
440
case '[': sym= '{'; break;
441
case ']': sym= '}'; break;
442
case '\\': sym= '|'; break;
443
case ';': sym= ':'; break;
444
case '\'': sym= '"'; break;
445
case ',': sym= '<'; break;
446
case '.': sym= '>'; break;
447
case '/': sym= '?'; break;
454
g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL);
465
GHOST_SystemSDL::getCursorPosition(GHOST_TInt32& x,
466
GHOST_TInt32& y) const
469
SDL_Window *win= SDL_GetMouseFocus();
470
SDL_GetWindowPosition(win, &x_win, &y_win);
473
SDL_GetMouseState(&xi, &yi);
477
return GHOST_kSuccess;
481
GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x,
485
SDL_Window *win= SDL_GetMouseFocus();
486
SDL_GetWindowPosition(win, &x_win, &y_win);
488
SDL_WarpMouseInWindow(win, x - x_win, y - y_win);
489
return GHOST_kSuccess;
493
GHOST_SystemSDL::generateWindowExposeEvents()
495
std::vector<GHOST_WindowSDL *>::iterator w_start= m_dirty_windows.begin();
496
std::vector<GHOST_WindowSDL *>::const_iterator w_end= m_dirty_windows.end();
497
bool anyProcessed= false;
499
for (;w_start != w_end; ++w_start) {
500
GHOST_Event * g_event= new
503
GHOST_kEventWindowUpdate,
507
(*w_start)->validate();
510
printf("Expose events pushed\n");
516
m_dirty_windows.clear();
522
GHOST_SystemSDL::processEvents(bool waitForEvent)
524
// Get all the current events -- translate them into
525
// ghost events and call base class pushEvent() method.
527
bool anyProcessed= false;
530
GHOST_TimerManager* timerMgr= getTimerManager();
532
if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
533
GHOST_TUns64 next= timerMgr->nextFireTime();
535
if (next==GHOST_kFireTimeNever) {
536
SDL_WaitEventTimeout(NULL, -1);
537
//SleepTillEvent(m_display, -1);
539
GHOST_TInt64 maxSleep= next - getMilliSeconds();
542
SDL_WaitEventTimeout(NULL, next - getMilliSeconds());
543
// SleepTillEvent(m_display, next - getMilliSeconds()); // X11
548
if (timerMgr->fireTimers(getMilliSeconds())) {
553
while (SDL_PollEvent(&sdl_event)) {
554
processEvent(&sdl_event);
558
if (generateWindowExposeEvents()) {
561
} while (waitForEvent && !anyProcessed);
568
GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
570
if (sdl_win == NULL) return NULL;
572
// It is not entirely safe to do this as the backptr may point
573
// to a window that has recently been removed.
574
// We should always check the window manager's list of windows
575
// and only process events on these windows.
577
std::vector<GHOST_IWindow *> & win_vec= m_windowManager->getWindows();
579
std::vector<GHOST_IWindow *>::iterator win_it= win_vec.begin();
580
std::vector<GHOST_IWindow *>::const_iterator win_end= win_vec.end();
582
for (; win_it != win_end; ++win_it) {
583
GHOST_WindowSDL * window= static_cast<GHOST_WindowSDL *>(*win_it);
584
if (window->getSDLWindow() == sdl_win) {
593
GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind)
595
GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
597
m_dirty_windows.push_back(bad_wind);
601
GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons& buttons) const
603
Uint8 state= SDL_GetMouseState(NULL, NULL);
604
buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0);
605
buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0);
606
buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0);
608
return GHOST_kSuccess;
612
GHOST_SystemSDL::getClipboard(bool selection) const
614
return (GHOST_TUns8 *)SDL_GetClipboardText();
618
GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const
620
SDL_SetClipboardText(buffer);
624
GHOST_SystemSDL::getMilliSeconds()
626
return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */