Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/ghost/intern/GHOST_SystemSDL.cpp')
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp555
1 files changed, 555 insertions, 0 deletions
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
new file mode 100644
index 00000000000..2c61acc2d93
--- /dev/null
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -0,0 +1,555 @@
+/*
+ * $Id$
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file ghost/intern/GHOST_SystemSDL.cpp
+ * \ingroup GHOST
+ */
+
+#include <assert.h>
+
+#include "GHOST_SystemSDL.h"
+
+#include "GHOST_WindowManager.h"
+
+#include "GHOST_EventCursor.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_EventButton.h"
+#include "GHOST_EventWheel.h"
+
+GHOST_SystemSDL::GHOST_SystemSDL()
+ :
+ GHOST_System()
+{
+ if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) {
+ printf ("Error initializing SDL: %s\n", SDL_GetError());
+ }
+
+ /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */
+ /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+}
+
+GHOST_SystemSDL::~GHOST_SystemSDL()
+{
+ SDL_Quit();
+}
+
+GHOST_IWindow *
+GHOST_SystemSDL::createWindow(const STR_String& title,
+ GHOST_TInt32 left,
+ GHOST_TInt32 top,
+ GHOST_TUns32 width,
+ GHOST_TUns32 height,
+ GHOST_TWindowState state,
+ GHOST_TDrawingContextType type,
+ bool stereoVisual,
+ const GHOST_TUns16 numOfAASamples,
+ const GHOST_TEmbedderWindowID parentWindow
+ )
+{
+ GHOST_WindowSDL *window= NULL;
+
+ window= new GHOST_WindowSDL (this, title, left, top, width, height, state, parentWindow, type, stereoVisual, 1);
+
+ if (window) {
+ if (window->getValid()) {
+ m_windowManager->addWindow(window);
+ pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+ }
+ else {
+ delete window;
+ window= NULL;
+ }
+ }
+ return window;
+}
+
+GHOST_TSuccess
+GHOST_SystemSDL::init() {
+ GHOST_TSuccess success = GHOST_System::init();
+
+ if (success) {
+ m_displayManager = new GHOST_DisplayManagerSDL(this);
+
+ if (m_displayManager) {
+ return GHOST_kSuccess;
+ }
+ }
+
+ return GHOST_kFailure;
+}
+
+void
+GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32& width,
+ GHOST_TUns32& height) const
+{
+ SDL_DisplayMode mode;
+ SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */
+ width= mode.w;
+ height= mode.h;
+}
+
+GHOST_TUns8
+GHOST_SystemSDL::getNumDisplays() const
+{
+ return SDL_GetNumVideoDisplays();
+}
+
+GHOST_TSuccess
+GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const
+{
+ SDL_Keymod mod= SDL_GetModState();
+
+ keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0);
+ keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0);
+ keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0);
+ keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
+ keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
+ keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
+ keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI|KMOD_RGUI)) != 0);
+
+ return GHOST_kSuccess;
+}
+
+#define GXMAP(k,x,y) case x: k= y; break;
+
+static GHOST_TKey
+convertSDLKey(SDL_Scancode key)
+{
+ GHOST_TKey type;
+
+ if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) {
+ type= GHOST_TKey( key - SDL_SCANCODE_A + int(GHOST_kKeyA));
+ } else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) {
+ type= GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey0));
+ } else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) {
+ type= GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1));
+ } else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) {
+ type= GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13));
+ } else {
+ switch(key) {
+ /* TODO SDL_SCANCODE_NONUSBACKSLASH */
+
+ GXMAP(type,SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace);
+ GXMAP(type,SDL_SCANCODE_TAB, GHOST_kKeyTab);
+ GXMAP(type,SDL_SCANCODE_RETURN, GHOST_kKeyEnter);
+ GXMAP(type,SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc);
+ GXMAP(type,SDL_SCANCODE_SPACE, GHOST_kKeySpace);
+
+ GXMAP(type,SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon);
+ GXMAP(type,SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod);
+ GXMAP(type,SDL_SCANCODE_COMMA, GHOST_kKeyComma);
+ GXMAP(type,SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote);
+ GXMAP(type,SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave);
+ GXMAP(type,SDL_SCANCODE_MINUS, GHOST_kKeyMinus);
+ GXMAP(type,SDL_SCANCODE_SLASH, GHOST_kKeySlash);
+ GXMAP(type,SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash);
+ GXMAP(type,SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual);
+ GXMAP(type,SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket);
+ GXMAP(type,SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket);
+ GXMAP(type,SDL_SCANCODE_PAUSE, GHOST_kKeyPause);
+
+ GXMAP(type,SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift);
+ GXMAP(type,SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift);
+ GXMAP(type,SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl);
+ GXMAP(type,SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
+ GXMAP(type,SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
+ GXMAP(type,SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
+ GXMAP(type,SDL_SCANCODE_RGUI, GHOST_kKeyOS);
+
+ GXMAP(type,SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
+ GXMAP(type,SDL_SCANCODE_DELETE, GHOST_kKeyDelete);
+ GXMAP(type,SDL_SCANCODE_HOME, GHOST_kKeyHome);
+ GXMAP(type,SDL_SCANCODE_END, GHOST_kKeyEnd);
+ GXMAP(type,SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage);
+ GXMAP(type,SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage);
+
+ GXMAP(type,SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow);
+ GXMAP(type,SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow);
+ GXMAP(type,SDL_SCANCODE_UP, GHOST_kKeyUpArrow);
+ GXMAP(type,SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow);
+
+ GXMAP(type,SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock);
+ GXMAP(type,SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock);
+ GXMAP(type,SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock);
+
+ /* keypad events */
+
+ /* note, sdl defines a bunch of kp defines I never saw before like
+ * SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */
+ GXMAP(type,SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0);
+ GXMAP(type,SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1);
+ GXMAP(type,SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2);
+ GXMAP(type,SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3);
+ GXMAP(type,SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4);
+ GXMAP(type,SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5);
+ GXMAP(type,SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6);
+ GXMAP(type,SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7);
+ GXMAP(type,SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8);
+ GXMAP(type,SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9);
+ GXMAP(type,SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod);
+
+ GXMAP(type,SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter);
+ GXMAP(type,SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus);
+ GXMAP(type,SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus);
+ GXMAP(type,SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk);
+ GXMAP(type,SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash);
+
+ /* Media keys in some keyboards and laptops with XFree86/Xorg */
+ GXMAP(type,SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay);
+ GXMAP(type,SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop);
+ GXMAP(type,SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst);
+ // GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst);
+ GXMAP(type,SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast);
+
+ default:
+ type= GHOST_kKeyUnknown;
+ break;
+ }
+ }
+
+ return type;
+}
+#undef GXMAP
+
+
+void
+GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
+{
+ GHOST_Event * g_event= NULL;
+
+ switch(sdl_event->type) {
+ case SDL_WINDOWEVENT:
+ {
+ SDL_WindowEvent &sdl_sub_evt= sdl_event->window;
+ GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
+ //assert(window != NULL); // can be NULL on close window.
+
+ switch (sdl_sub_evt.event) {
+ case SDL_WINDOWEVENT_EXPOSED:
+ g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
+ break;
+ case SDL_WINDOWEVENT_RESIZED:
+ g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
+ break;
+ case SDL_WINDOWEVENT_MOVED:
+ g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window);
+ break;
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window);
+ break;
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window);
+ break;
+ case SDL_WINDOWEVENT_CLOSE:
+ g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
+ break;
+ }
+ }
+ break;
+ case SDL_QUIT:
+ g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL);
+ break;
+
+ case SDL_MOUSEMOTION:
+ {
+ SDL_MouseMotionEvent &sdl_sub_evt= sdl_event->motion;
+ SDL_Window *sdl_win= SDL_GetWindowFromID(sdl_sub_evt.windowID);
+ GHOST_WindowSDL *window= findGhostWindow(sdl_win);
+ assert(window != NULL);
+
+ int x_win, y_win;
+ SDL_GetWindowPosition(sdl_win, &x_win, &y_win);
+
+ GHOST_TInt32 x_root= sdl_sub_evt.x + x_win;
+ GHOST_TInt32 y_root= sdl_sub_evt.y + y_win;
+
+#if 0
+ if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal)
+ {
+ GHOST_TInt32 x_new= x_root;
+ GHOST_TInt32 y_new= y_root;
+ GHOST_TInt32 x_accum, y_accum;
+ GHOST_Rect bounds;
+
+ /* fallback to window bounds */
+ if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
+ window->getClientBounds(bounds);
+
+ /* could also clamp to screen bounds
+ * wrap with a window outside the view will fail atm */
+ bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */
+ window->getCursorGrabAccum(x_accum, y_accum);
+
+ // cant use setCursorPosition because the mouse may have no focus!
+ if(x_new != x_root || y_new != y_root) {
+ if (1 ) { //xme.time > m_last_warp) {
+ /* when wrapping we don't need to add an event because the
+ * setCursorPosition call will cause a new event after */
+ SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */
+ window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new));
+ // m_last_warp= lastEventTime(xme.time);
+ } else {
+ // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */
+ SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
+ }
+
+ g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new);
+ }
+ else {
+ g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum);
+ }
+ }
+ else
+#endif
+ {
+ g_event= new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root);
+ }
+ break;
+ }
+ case SDL_MOUSEBUTTONUP:
+ case SDL_MOUSEBUTTONDOWN:
+ {
+ SDL_MouseButtonEvent &sdl_sub_evt= sdl_event->button;
+ GHOST_TButtonMask gbmask= GHOST_kButtonMaskLeft;
+ GHOST_TEventType type= (sdl_sub_evt.state==SDL_PRESSED) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp;
+
+ GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
+ assert(window != NULL);
+
+ /* process rest of normal mouse buttons */
+ if(sdl_sub_evt.button == SDL_BUTTON_LEFT)
+ gbmask= GHOST_kButtonMaskLeft;
+ else if(sdl_sub_evt.button == SDL_BUTTON_MIDDLE)
+ gbmask= GHOST_kButtonMaskMiddle;
+ else if(sdl_sub_evt.button == SDL_BUTTON_RIGHT)
+ gbmask= GHOST_kButtonMaskRight;
+ /* these buttons are untested! */
+ else if(sdl_sub_evt.button == SDL_BUTTON_X1)
+ gbmask= GHOST_kButtonMaskButton4;
+ else if(sdl_sub_evt.button == SDL_BUTTON_X2)
+ gbmask= GHOST_kButtonMaskButton5;
+ else
+ break;
+
+ g_event= new GHOST_EventButton(getMilliSeconds(), type, window, gbmask);
+ break;
+ }
+ case SDL_MOUSEWHEEL:
+ {
+ SDL_MouseWheelEvent &sdl_sub_evt= sdl_event->wheel;
+ GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
+ assert(window != NULL);
+ g_event= new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y);
+ }
+ break;
+ case SDL_KEYDOWN:
+ case SDL_KEYUP:
+ {
+ SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key;
+ GHOST_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp;
+
+ GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID));
+ assert(window != NULL);
+
+ GHOST_TKey gkey= convertSDLKey(sdl_sub_evt.keysym.scancode);
+ /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */
+ g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sdl_sub_evt.keysym.sym);
+ }
+ break;
+ }
+
+ if (g_event) {
+ pushEvent(g_event);
+ }
+}
+
+GHOST_TSuccess
+GHOST_SystemSDL::getCursorPosition(GHOST_TInt32& x,
+ GHOST_TInt32& y) const
+{
+ int x_win, y_win;
+ SDL_Window *win= SDL_GetMouseFocus();
+ SDL_GetWindowPosition(win, &x_win, &y_win);
+
+ int xi, yi;
+ SDL_GetMouseState(&xi, &yi);
+ x= xi + x_win;
+ y= yi + x_win;
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TSuccess
+GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x,
+ GHOST_TInt32 y)
+{
+ int x_win, y_win;
+ SDL_Window *win= SDL_GetMouseFocus();
+ SDL_GetWindowPosition(win, &x_win, &y_win);
+
+ SDL_WarpMouseInWindow(win, x - x_win, y - y_win);
+ return GHOST_kSuccess;
+}
+
+bool
+GHOST_SystemSDL::generateWindowExposeEvents()
+{
+ vector<GHOST_WindowSDL *>::iterator w_start= m_dirty_windows.begin();
+ vector<GHOST_WindowSDL *>::const_iterator w_end= m_dirty_windows.end();
+ bool anyProcessed= false;
+
+ for (;w_start != w_end; ++w_start) {
+ GHOST_Event * g_event= new
+ GHOST_Event(
+ getMilliSeconds(),
+ GHOST_kEventWindowUpdate,
+ *w_start
+ );
+
+ (*w_start)->validate();
+
+ if (g_event) {
+ printf("Expose events pushed\n");
+ pushEvent(g_event);
+ anyProcessed= true;
+ }
+ }
+
+ m_dirty_windows.clear();
+ return anyProcessed;
+}
+
+
+bool
+GHOST_SystemSDL::processEvents(bool waitForEvent)
+{
+ // Get all the current events -- translate them into
+ // ghost events and call base class pushEvent() method.
+
+ bool anyProcessed= false;
+
+ do {
+ GHOST_TimerManager* timerMgr= getTimerManager();
+
+ if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) {
+ GHOST_TUns64 next= timerMgr->nextFireTime();
+
+ if (next==GHOST_kFireTimeNever) {
+ SDL_WaitEventTimeout(NULL, -1);
+ //SleepTillEvent(m_display, -1);
+ } else {
+ GHOST_TInt64 maxSleep= next - getMilliSeconds();
+
+ if(maxSleep >= 0) {
+ SDL_WaitEventTimeout(NULL, next - getMilliSeconds());
+ // SleepTillEvent(m_display, next - getMilliSeconds()); // X11
+ }
+ }
+ }
+
+ if (timerMgr->fireTimers(getMilliSeconds())) {
+ anyProcessed= true;
+ }
+
+ SDL_Event sdl_event;
+ while (SDL_PollEvent(&sdl_event)) {
+ processEvent(&sdl_event);
+ anyProcessed= true;
+ }
+
+ if (generateWindowExposeEvents()) {
+ anyProcessed= true;
+ }
+ } while (waitForEvent && !anyProcessed);
+
+ return anyProcessed;
+}
+
+
+GHOST_WindowSDL *
+GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
+{
+ if (sdl_win == NULL) return NULL;
+
+ // It is not entirely safe to do this as the backptr may point
+ // to a window that has recently been removed.
+ // We should always check the window manager's list of windows
+ // and only process events on these windows.
+
+ vector<GHOST_IWindow *> & win_vec= m_windowManager->getWindows();
+
+ vector<GHOST_IWindow *>::iterator win_it= win_vec.begin();
+ vector<GHOST_IWindow *>::const_iterator win_end= win_vec.end();
+
+ for (; win_it != win_end; ++win_it) {
+ GHOST_WindowSDL * window= static_cast<GHOST_WindowSDL *>(*win_it);
+ if (window->getSDLWindow() == sdl_win) {
+ return window;
+ }
+ }
+ return NULL;
+}
+
+
+void
+GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind)
+{
+ GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)");
+
+ m_dirty_windows.push_back(bad_wind);
+}
+
+
+GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons& buttons) const
+{
+ Uint8 state= SDL_GetMouseState(NULL, NULL);
+ buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0);
+ buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0);
+ buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0);
+
+ return GHOST_kSuccess;
+}
+
+GHOST_TUns8 *
+GHOST_SystemSDL::getClipboard(bool selection) const
+{
+ return (GHOST_TUns8 *)SDL_GetClipboardText();
+}
+
+void
+GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const
+{
+ SDL_SetClipboardText(buffer);
+}
+
+GHOST_TUns64
+GHOST_SystemSDL::getMilliSeconds()
+{
+ return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */
+}