diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-07-12 17:17:54 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-07-12 17:17:54 +0400 |
commit | f7b9418d25a2fdbead0d21a53bf56b0199fb45f9 (patch) | |
tree | 3e5ed573143e281932a47db9a567fa23b7cfefa4 /intern | |
parent | b90535cc334bb8ae3a51f8023732b8c786019ac7 (diff) |
build option to use SDL 1.3 for GHOST rather then X11/Win32/Cocoa api's,
This opens up the option for blender to be more easily ported to other devices, OS's.
TODO
- continuous grab.
- text glitch with multiple windows (was a bug in X11 too for a while, will check on this)
Diffstat (limited to 'intern')
-rw-r--r-- | intern/ghost/CMakeLists.txt | 30 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_DisplayManagerSDL.cpp | 93 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_DisplayManagerSDL.h | 69 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_ISystem.cpp | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_NDOFManager.cpp | 2 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemSDL.cpp | 500 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemSDL.h | 121 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowSDL.cpp | 608 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowSDL.h | 128 |
9 files changed, 1548 insertions, 7 deletions
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 922f6918392..30f5b176532 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -89,13 +89,27 @@ set(SRC intern/GHOST_WindowManager.h ) -if(WITH_HEADLESS) - list(APPEND SRC - intern/GHOST_DisplayManagerNULL.h - intern/GHOST_SystemNULL.h - intern/GHOST_WindowNULL.h - ) - add_definitions(-DWITH_HEADLESS) +if(WITH_HEADLESS OR WITH_SDL_GHOST) + if(WITH_HEADLESS) + list(APPEND SRC + intern/GHOST_DisplayManagerNULL.h + intern/GHOST_SystemNULL.h + intern/GHOST_WindowNULL.h + ) + add_definitions(-DWITH_HEADLESS) + else() + list(APPEND SRC + intern/GHOST_DisplayManagerSDL.cpp + intern/GHOST_SystemSDL.cpp + intern/GHOST_WindowSDL.cpp + + intern/GHOST_DisplayManagerSDL.h + intern/GHOST_SystemSDL.h + intern/GHOST_WindowSDL.h + ) + add_definitions(-DWITH_SDL_GHOST) + endif() + # ack, this is still system dependant if(APPLE) @@ -124,6 +138,8 @@ if(WITH_HEADLESS) ) endif() + list(APPEND INC_SYS ${SDL_INCLUDE_DIR}) + elseif(APPLE) if(WITH_COCOA) list(APPEND SRC diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp new file mode 100644 index 00000000000..ed37fa1dd0f --- /dev/null +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.cpp @@ -0,0 +1,93 @@ +/* + * $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_DisplayManagerSDL.cpp + * \ingroup GHOST + */ + +#include "GHOST_SystemSDL.h" +#include "GHOST_DisplayManagerSDL.h" + +GHOST_DisplayManagerSDL::GHOST_DisplayManagerSDL(GHOST_SystemSDL *system) + : + GHOST_DisplayManager(), + m_system(system) +{ + /* do nothing */ +} + +GHOST_TSuccess +GHOST_DisplayManagerSDL::getNumDisplays(GHOST_TUns8& numDisplays) +{ + numDisplays= SDL_GetNumVideoDisplays(); + return GHOST_kSuccess; +} + + +GHOST_TSuccess GHOST_DisplayManagerSDL::getNumDisplaySettings(GHOST_TUns8 display, + GHOST_TInt32& numSettings) +{ + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + numSettings= GHOST_TInt32(1); + return GHOST_kSuccess; +} + +GHOST_TSuccess +GHOST_DisplayManagerSDL::getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting& setting) +{ + + GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n"); + GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n"); + SDL_DisplayMode mode; + + SDL_GetDesktopDisplayMode(display, &mode); + + setting.xPixels= mode.w; + setting.yPixels= mode.h; + setting.bpp= SDL_BYTESPERPIXEL(mode.format); + /* assume 60 when unset */ + setting.frequency= mode.refresh_rate ? mode.refresh_rate : 60; + + return GHOST_kSuccess; +} + +GHOST_TSuccess +GHOST_DisplayManagerSDL::getCurrentDisplaySetting(GHOST_TUns8 display, + GHOST_DisplaySetting& setting) +{ + return getDisplaySetting(display,GHOST_TInt32(0),setting); +} + +GHOST_TSuccess +GHOST_DisplayManagerSDL:: setCurrentDisplaySetting(GHOST_TUns8 display, + const GHOST_DisplaySetting& setting) +{ + // This is never going to work robustly in X + // but it's currently part of the full screen interface + + // we fudge it for now. + + return GHOST_kSuccess; +} diff --git a/intern/ghost/intern/GHOST_DisplayManagerSDL.h b/intern/ghost/intern/GHOST_DisplayManagerSDL.h new file mode 100644 index 00000000000..5019d1b1351 --- /dev/null +++ b/intern/ghost/intern/GHOST_DisplayManagerSDL.h @@ -0,0 +1,69 @@ +/* + * $Id: GHOST_DisplayManagerSDL.h 37194 2011-06-05 00:10:20Z gsrb3d $ + * ***** 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_DisplayManagerSDL.h + * \ingroup GHOST + * Declaration of GHOST_DisplayManagerSDL class. + */ + +#ifndef _GHOST_DISPLAY_MANAGER_SDL_H_ +#define _GHOST_DISPLAY_MANAGER_SDL_H_ + +#include "GHOST_DisplayManager.h" + +extern "C" { + #include "SDL.h" +} + +class GHOST_SystemSDL; + +class GHOST_DisplayManagerSDL : public GHOST_DisplayManager +{ +public: + GHOST_DisplayManagerSDL(GHOST_SystemSDL *system); + + GHOST_TSuccess + getNumDisplays(GHOST_TUns8& numDisplays); + + GHOST_TSuccess + getNumDisplaySettings(GHOST_TUns8 display, + GHOST_TInt32& numSettings); + + GHOST_TSuccess + getDisplaySetting(GHOST_TUns8 display, + GHOST_TInt32 index, + GHOST_DisplaySetting& setting); + + GHOST_TSuccess + getCurrentDisplaySetting(GHOST_TUns8 display, + GHOST_DisplaySetting& setting); + + GHOST_TSuccess + setCurrentDisplaySetting(GHOST_TUns8 display, + const GHOST_DisplaySetting& setting); + +private : + GHOST_SystemSDL * m_system; +}; + +#endif /* _GHOST_DISPLAY_MANAGER_SDL_H_ */ diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp index 7f170d2e876..2cb82ffd7c2 100644 --- a/intern/ghost/intern/GHOST_ISystem.cpp +++ b/intern/ghost/intern/GHOST_ISystem.cpp @@ -43,6 +43,8 @@ #ifdef WITH_HEADLESS # include "GHOST_SystemNULL.h" +#elif defined(WITH_SDL_GHOST) +# include "GHOST_SystemSDL.h" #elif defined(WIN32) # include "GHOST_SystemWin32.h" #else @@ -67,6 +69,8 @@ GHOST_TSuccess GHOST_ISystem::createSystem() if (!m_system) { #ifdef WITH_HEADLESS m_system = new GHOST_SystemNULL(); +#elif defined(WITH_SDL_GHOST) + m_system = new GHOST_SystemSDL(); #elif defined(WIN32) m_system = new GHOST_SystemWin32 (); #else diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index 7721b1708f9..30f0de1e646 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -85,6 +85,8 @@ GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window, /* do nothing */ #elif defined(_WIN32) || defined(__APPLE__) m_DeviceHandle = ndofDeviceOpen((void *)¤tNdofValues); + #elif defined(WITH_SDL_GHOST) + /* do nothing */ #else GHOST_SystemX11 *sys; sys = static_cast<GHOST_SystemX11*>(GHOST_ISystem::getSystem()); diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp new file mode 100644 index 00000000000..33dcbc01307 --- /dev/null +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -0,0 +1,500 @@ +/* + * $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; + GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); + assert(window != NULL); + + g_event= new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, sdl_sub_evt.x, sdl_sub_evt.y); + 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 xi, yi; + SDL_GetMouseState(&xi, &yi); + x= xi; + y= yi; + return GHOST_kSuccess; +} + +GHOST_TSuccess +GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x, + GHOST_TInt32 y) +{ + // SDL_SendMouseMotion(SDL, SDL_FALSE, x, y); // NOT EXPOSED + SDL_WarpMouseInWindow(NULL, x, y); + 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 */ +} diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h new file mode 100644 index 00000000000..7aea1b6694a --- /dev/null +++ b/intern/ghost/intern/GHOST_SystemSDL.h @@ -0,0 +1,121 @@ +/* + * $Id: GHOST_SystemSDL.h 37194 2011-06-05 00:10:20Z gsrb3d $ + * ***** 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.h + * \ingroup GHOST + * Declaration of GHOST_SystemSDL class. + */ + +#ifndef _GHOST_SYSTEM_SDL_H_ +#define _GHOST_SYSTEM_SDL_H_ + +#include "GHOST_System.h" +#include "../GHOST_Types.h" +#include "GHOST_DisplayManagerSDL.h" +#include "GHOST_TimerManager.h" +#include "GHOST_WindowSDL.h" +#include "GHOST_Event.h" + +extern "C" { + #include "SDL.h" +} + +class GHOST_WindowSDL; + + +class GHOST_SystemSDL : public GHOST_System { +public: + + void addDirtyWindow(GHOST_WindowSDL *bad_wind); + + GHOST_SystemSDL(); + ~GHOST_SystemSDL(); + + bool + processEvents(bool waitForEvent); + + int + toggleConsole(int action) { return 0; } + + GHOST_TSuccess + getModifierKeys(GHOST_ModifierKeys& keys) const; + + GHOST_TSuccess + getButtons(GHOST_Buttons& buttons) const; + + GHOST_TUns8 * + getClipboard(bool selection) const; + + void + putClipboard(GHOST_TInt8 *buffer, bool selection) const; + + GHOST_TUns64 + getMilliSeconds(); + + GHOST_TUns8 + getNumDisplays() const; + + GHOST_TSuccess + getCursorPosition(GHOST_TInt32& x, + GHOST_TInt32& y) const; + + GHOST_TSuccess + setCursorPosition(GHOST_TInt32 x, + GHOST_TInt32 y); + + void + getMainDisplayDimensions(GHOST_TUns32& width, + GHOST_TUns32& height) const; + +private: + + GHOST_TSuccess + init(); + + GHOST_IWindow * + 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 + ); + + /* SDL spesific */ + GHOST_WindowSDL * findGhostWindow(SDL_Window *sdl_win); + + bool + generateWindowExposeEvents(); + + void + processEvent(SDL_Event *sdl_event); + + /// The vector of windows that need to be updated. + std::vector<GHOST_WindowSDL *> m_dirty_windows; +}; + +#endif diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp new file mode 100644 index 00000000000..9d4263f6311 --- /dev/null +++ b/intern/ghost/intern/GHOST_WindowSDL.cpp @@ -0,0 +1,608 @@ +/* + * $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_WindowSDL.cpp + * \ingroup GHOST + */ + +#include "GHOST_WindowSDL.h" +#include "SDL_mouse.h" +#include <assert.h> + +static SDL_GLContext s_firstContext= NULL; + +GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system, + const STR_String& title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + const GHOST_TEmbedderWindowID parentWindow, + GHOST_TDrawingContextType type, + const bool stereoVisual, + const GHOST_TUns16 numOfAASamples + ) + : + GHOST_Window(width,height,state,type,stereoVisual,numOfAASamples), + m_system (system), + m_invalid_window(false), + m_sdl_custom_cursor(NULL) +{ + m_sdl_win= SDL_CreateWindow(title, + 10, + 10, + width, + height, + SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN); + + //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); + + m_sdl_glcontext= SDL_GL_CreateContext(m_sdl_win); + + //fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n", + // theEvent->error_code, theEvent->request_code) ; + + setTitle(title); +} + +GHOST_WindowSDL::~GHOST_WindowSDL() +{ + if(m_sdl_custom_cursor) { + SDL_FreeCursor(m_sdl_custom_cursor); + } + + if (m_sdl_glcontext != s_firstContext) { + SDL_GL_DeleteContext(m_sdl_glcontext); + } + + SDL_DestroyWindow(m_sdl_win); +} + + +GHOST_TSuccess +GHOST_WindowSDL::installDrawingContext(GHOST_TDrawingContextType type) +{ + // only support openGL for now. + GHOST_TSuccess success; + switch (type) { + case GHOST_kDrawingContextTypeOpenGL: + m_sdl_glcontext= SDL_GL_CreateContext(m_sdl_win); + + if (m_sdl_glcontext != NULL) { + if (!s_firstContext) { + s_firstContext= m_sdl_glcontext; + } + + success= (SDL_GL_MakeCurrent(m_sdl_win, m_sdl_glcontext) < 0) ? + GHOST_kFailure : GHOST_kSuccess; + } + else { + success= GHOST_kFailure; + } + + break; + + case GHOST_kDrawingContextTypeNone: + success= GHOST_kSuccess; + break; + + default: + success= GHOST_kFailure; + } + return success; +} + + +GHOST_TSuccess +GHOST_WindowSDL::invalidate(void) +{ + // So the idea of this function is to generate an expose event + // for the window. + // Unfortunately X does not handle expose events for you and + // it is the client's job to refresh the dirty part of the window. + // We need to queue up invalidate calls and generate GHOST events + // for them in the system. + + // We implement this by setting a boolean in this class to concatenate + // all such calls into a single event for this window. + + // At the same time we queue the dirty windows in the system class + // and generate events for them at the next processEvents call. + + if (m_invalid_window == false) { + m_system->addDirtyWindow(this); + m_invalid_window= true; + } + + return GHOST_kSuccess; +} + + +GHOST_TSuccess +GHOST_WindowSDL::swapBuffers() +{ + if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) { + SDL_GL_SwapWindow(m_sdl_win); + return GHOST_kSuccess; + } + else { + return GHOST_kFailure; + } +} + + +GHOST_TSuccess +GHOST_WindowSDL::activateDrawingContext() +{ + if (m_sdl_glcontext !=NULL) { + int status=SDL_GL_MakeCurrent(m_sdl_win, m_sdl_glcontext); + (void)status; + return GHOST_kSuccess; + } + return GHOST_kFailure; +} + + +GHOST_TSuccess +GHOST_WindowSDL::removeDrawingContext() +{ + GHOST_TSuccess success; + + if (m_sdl_glcontext != NULL) { + SDL_GL_DeleteContext(m_sdl_glcontext); + success= GHOST_kSuccess; + } + else { + success= GHOST_kFailure; + } + return success; +} + + +GHOST_TSuccess +GHOST_WindowSDL::setState(GHOST_TWindowState state) +{ + switch(state) { + case GHOST_kWindowStateNormal: + SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); + SDL_RestoreWindow(m_sdl_win); + break; + case GHOST_kWindowStateMaximized: + SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); + SDL_MaximizeWindow(m_sdl_win); + break; + case GHOST_kWindowStateMinimized: + SDL_MinimizeWindow(m_sdl_win); + break; + case GHOST_kWindowStateFullScreen: + SDL_SetWindowFullscreen(m_sdl_win, SDL_TRUE); + break; + default: + break; + } + + return GHOST_kSuccess; +} + + +GHOST_TWindowState +GHOST_WindowSDL::getState() const +{ + Uint32 flags= SDL_GetWindowFlags(m_sdl_win); + + if(flags & SDL_WINDOW_FULLSCREEN) return GHOST_kWindowStateFullScreen; + else if(flags & SDL_WINDOW_MAXIMIZED) return GHOST_kWindowStateMaximized; + else if(flags & SDL_WINDOW_MINIMIZED) return GHOST_kWindowStateMinimized; + return GHOST_kWindowStateNormal; +} + + +void +GHOST_WindowSDL::setTitle(const STR_String& title) +{ + SDL_SetWindowTitle(m_sdl_win, title.ReadPtr()); +} + + +void +GHOST_WindowSDL::getTitle(STR_String& title) const +{ + title= SDL_GetWindowTitle(m_sdl_win); +} + + +void +GHOST_WindowSDL::getWindowBounds(GHOST_Rect& bounds) const +{ + getClientBounds(bounds); +} + + +void +GHOST_WindowSDL::getClientBounds(GHOST_Rect& bounds) const +{ + int x, y, w, h; + SDL_GetWindowSize(m_sdl_win, &w, &h); + SDL_GetWindowPosition(m_sdl_win, &x, &y); + + bounds.m_l= x; + bounds.m_r= x + w; + bounds.m_t= y; + bounds.m_b= y + h; +} + +GHOST_TSuccess +GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width) +{ + int height; + SDL_GetWindowSize(m_sdl_win, NULL, &height); + SDL_SetWindowSize(m_sdl_win, width, height); + return GHOST_kSuccess; +} + +GHOST_TSuccess +GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height) +{ + int width; + SDL_GetWindowSize(m_sdl_win, &width, NULL); + SDL_SetWindowSize(m_sdl_win, width, height); + return GHOST_kSuccess; +} + +GHOST_TSuccess +GHOST_WindowSDL::setClientSize(GHOST_TUns32 width, + GHOST_TUns32 height) +{ + SDL_SetWindowSize(m_sdl_win, width, height); + return GHOST_kSuccess; +} + + +/* mouse cursor */ +static unsigned char sdl_std_cursor_mask_xterm[]= {0xef,0x01,0xff,0x01,0xff,0x01,0x7c,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x38,0x00,0x7c,0x00,0xff,0x01,0xff,0x01,0xef,0x01,}; +static unsigned char sdl_std_cursor_xterm[]= {0x00,0x77,0x00,0x1c,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x1c,0x00,0x77,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_xterm 9 +#define sdl_std_cursor_HEIGHT_xterm 16 +#define sdl_std_cursor_HOT_X_xterm -3 +#define sdl_std_cursor_HOT_Y_xterm -7 + +static unsigned char sdl_std_cursor_mask_watch[]= {0xfc,0x0f,0xfc,0x0f,0xfc,0x0f,0xfe,0x1f,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfe,0x1f,0xfc,0x0f,0xfc,0x0f,0xfc,0x0f,}; +static unsigned char sdl_std_cursor_watch[]= {0xf8,0x07,0xf8,0x07,0xf8,0x07,0xfc,0x0f,0x86,0x18,0x83,0x30,0x81,0xe0,0xc1,0xe1,0xc1,0xe1,0x21,0xe0,0x13,0x30,0x06,0x18,0xfc,0x0f,0xf8,0x07,0xf8,0x07,0xf8,0x07,}; +#define sdl_std_cursor_WIDTH_watch 16 +#define sdl_std_cursor_HEIGHT_watch 16 +#define sdl_std_cursor_HOT_X_watch -15 +#define sdl_std_cursor_HOT_Y_watch -7 + +static unsigned char sdl_std_cursor_mask_umbrella[]= {0xe8,0x76,0xfb,0xdf,0xfd,0x3f,0xfe,0xff,0xff,0x3f,0xff,0xff,0xcf,0x79,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x07,0xc0,0x07,0xc0,0x07,0xc0,0x07,0x80,0x03,}; +static unsigned char sdl_std_cursor_umbrella[]= {0x88,0x04,0x20,0x0a,0xc9,0x32,0xf2,0x09,0x4c,0x06,0x43,0x18,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x01,0x40,0x01,0x80,0x00,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_umbrella 16 +#define sdl_std_cursor_HEIGHT_umbrella 16 +#define sdl_std_cursor_HOT_X_umbrella -7 +#define sdl_std_cursor_HOT_Y_umbrella -12 + +static unsigned char sdl_std_cursor_mask_top_side[]= {0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xc0,0x01,0xe0,0x03,0xf0,0x07,0xf8,0x0f,0xdc,0x1d,0xcc,0x19,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,}; +static unsigned char sdl_std_cursor_top_side[]= {0xff,0x1f,0xff,0x1f,0x00,0x00,0x40,0x00,0xe0,0x00,0x50,0x01,0x48,0x02,0x44,0x04,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_top_side 15 +#define sdl_std_cursor_HEIGHT_top_side 16 +#define sdl_std_cursor_HOT_X_top_side -6 +#define sdl_std_cursor_HOT_Y_top_side -14 + +static unsigned char sdl_std_cursor_mask_top_right_corner[]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf0,0xfc,0xf7,0xfc,0xf7,0xfc,0xf7,0xc0,0xf7,0xe0,0xf7,0x70,0xf7,0x38,0xf7,0x1c,0xf7,0x0c,0xf7,0x00,0xf0,0x00,0xf0,}; +static unsigned char sdl_std_cursor_top_right_corner[]= {0xff,0x3f,0xff,0x3f,0x00,0x30,0x00,0x30,0x00,0x30,0xfc,0x31,0x80,0x31,0x40,0x31,0x20,0x31,0x10,0x31,0x08,0x31,0x04,0x31,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_top_right_corner 16 +#define sdl_std_cursor_HEIGHT_top_right_corner 16 +#define sdl_std_cursor_HOT_X_top_right_corner -13 +#define sdl_std_cursor_HOT_Y_top_right_corner -14 + +static unsigned char sdl_std_cursor_mask_top_left_corner[]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0xef,0x3f,0xef,0x3f,0xef,0x3f,0xef,0x03,0xef,0x07,0xef,0x0e,0xef,0x1c,0xef,0x38,0xef,0x30,0x0f,0x00,0x0f,0x00,}; +static unsigned char sdl_std_cursor_top_left_corner[]= {0xff,0x3f,0xff,0x3f,0x03,0x00,0x03,0x00,0x03,0x00,0xe3,0x0f,0x63,0x00,0xa3,0x00,0x23,0x01,0x23,0x02,0x23,0x04,0x23,0x08,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_top_left_corner 16 +#define sdl_std_cursor_HEIGHT_top_left_corner 16 +#define sdl_std_cursor_HOT_X_top_left_corner 0 +#define sdl_std_cursor_HOT_Y_top_left_corner -14 + +static unsigned char sdl_std_cursor_mask_spraycan[]= {0x00,0x0c,0x18,0x0d,0x7c,0x0d,0x7c,0x0d,0x7e,0x0d,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,0xff,0x00,}; +static unsigned char sdl_std_cursor_spraycan[]= {0x00,0x06,0x80,0x00,0x2c,0x06,0x9e,0x00,0x16,0x06,0x3f,0x00,0x21,0x00,0x27,0x00,0x25,0x00,0x27,0x00,0x25,0x00,0x27,0x00,0x27,0x00,0x21,0x00,0x21,0x00,0x3f,0x00,}; +#define sdl_std_cursor_WIDTH_spraycan 12 +#define sdl_std_cursor_HEIGHT_spraycan 16 +#define sdl_std_cursor_HOT_X_spraycan -9 +#define sdl_std_cursor_HOT_Y_spraycan -14 + +static unsigned char sdl_std_cursor_mask_sb_v_double_arrow[]= {0x38,0x00,0x7c,0x00,0xfe,0x00,0xff,0x01,0xff,0x01,0x7c,0x00,0x7c,0x00,0x7c,0x00,0x7c,0x00,0x7c,0x00,0xff,0x01,0xff,0x01,0xfe,0x00,0x7c,0x00,0x38,0x00,}; +static unsigned char sdl_std_cursor_sb_v_double_arrow[]= {0x10,0x00,0x38,0x00,0x7c,0x00,0xfe,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0x28,0x00,0xfe,0x00,0x7c,0x00,0x38,0x00,0x10,0x00,}; +#define sdl_std_cursor_WIDTH_sb_v_double_arrow 9 +#define sdl_std_cursor_HEIGHT_sb_v_double_arrow 15 +#define sdl_std_cursor_HOT_X_sb_v_double_arrow -3 +#define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8 + +static unsigned char sdl_std_cursor_mask_sb_h_double_arrow[]= {0x18,0x0c,0x1c,0x1c,0xfe,0x3f,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xfe,0x3f,0x1c,0x1c,0x18,0x0c,}; +static unsigned char sdl_std_cursor_sb_h_double_arrow[]= {0x00,0x00,0x08,0x08,0x0c,0x18,0xfe,0x3f,0x0f,0x78,0xfe,0x3f,0x0c,0x18,0x08,0x08,0x00,0x00}; +#define sdl_std_cursor_WIDTH_sb_h_double_arrow 15 +#define sdl_std_cursor_HEIGHT_sb_h_double_arrow 9 +#define sdl_std_cursor_HOT_X_sb_h_double_arrow -7 +#define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4 + +static unsigned char sdl_std_cursor_mask_right_side[]= {0x00,0xf0,0x00,0xf0,0xc0,0xf0,0xc0,0xf1,0x80,0xf3,0x00,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xf7,0x80,0xf3,0xc0,0xf1,0xc0,0xf0,0x00,0xf0,0x00,0xf0,}; +static unsigned char sdl_std_cursor_right_side[]= {0x00,0x30,0x00,0x30,0x40,0x30,0x80,0x30,0x00,0x31,0x00,0x32,0xff,0x37,0x00,0x32,0x00,0x31,0x80,0x30,0x40,0x30,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_right_side 16 +#define sdl_std_cursor_HEIGHT_right_side 15 +#define sdl_std_cursor_HOT_X_right_side -13 +#define sdl_std_cursor_HOT_Y_right_side -7 + +static unsigned char sdl_std_cursor_mask_right_ptr[]= {0x00,0x03,0x80,0x03,0xc0,0x03,0xe0,0x03,0xf0,0x03,0xf8,0x03,0xfc,0x03,0xfe,0x03,0xff,0x03,0xff,0x03,0xf8,0x03,0xbc,0x03,0x3c,0x03,0x1e,0x00,0x1e,0x00,0x0c,0x00,}; +static unsigned char sdl_std_cursor_right_ptr[]= {0x00,0x80,0x00,0xc0,0x00,0xe0,0x00,0xf0,0x00,0xf8,0x00,0xfc,0x00,0xfe,0x00,0xff,0x00,0xf8,0x00,0xd8,0x00,0x8c,0x00,0x0c,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_right_ptr 10 +#define sdl_std_cursor_HEIGHT_right_ptr 16 +#define sdl_std_cursor_HOT_X_right_ptr -7 +#define sdl_std_cursor_HOT_Y_right_ptr -14 + +static unsigned char sdl_std_cursor_mask_question_arrow[]= {0xf8,0x00,0xfc,0x01,0xfe,0x03,0xff,0x07,0x8f,0x07,0x9f,0x07,0xde,0x07,0xfc,0x03,0xf8,0x01,0xf8,0x00,0xf8,0x00,0xfc,0x01,0xfe,0x03,0xfc,0x01,0xf8,0x00,0x70,0x00,}; +static unsigned char sdl_std_cursor_question_arrow[]= {0x7c,0x00,0xfe,0x00,0xc7,0x01,0x83,0x01,0x87,0x01,0xc6,0x01,0xe0,0x00,0x78,0x00,0x38,0x00,0x28,0x00,0x28,0x00,0xee,0x00,0x6c,0x00,0x38,0x00,0x10,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_question_arrow 11 +#define sdl_std_cursor_HEIGHT_question_arrow 16 +#define sdl_std_cursor_HOT_X_question_arrow -4 +#define sdl_std_cursor_HOT_Y_question_arrow -8 + +static unsigned char sdl_std_cursor_mask_pirate[]= {0xf0,0x03,0xf8,0x07,0xfc,0x0f,0xfe,0x1f,0xfe,0x1f,0xfc,0x0f,0xf8,0x07,0xf1,0x83,0xf1,0xe3,0xf3,0xf3,0xef,0x39,0x1e,0x1e,0xe0,0x01,0xfe,0xc7,0xff,0xff,0x0f,0x7c,}; +static unsigned char sdl_std_cursor_pirate[]= {0xe0,0x01,0xf0,0x03,0xf8,0x07,0xcc,0x0c,0xcc,0x0c,0xf8,0x07,0xf0,0x03,0xe0,0x01,0xe1,0x21,0xe1,0x61,0xc2,0x10,0x1c,0x0e,0xe0,0x01,0xf8,0x47,0x0f,0x7c,0x01,0x20,}; +#define sdl_std_cursor_WIDTH_pirate 16 +#define sdl_std_cursor_HEIGHT_pirate 16 +#define sdl_std_cursor_HOT_X_pirate -7 +#define sdl_std_cursor_HOT_Y_pirate -4 + +static unsigned char sdl_std_cursor_mask_left_side[]= {0x0f,0x00,0x0f,0x00,0x0f,0x03,0x8f,0x03,0xcf,0x01,0xef,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0x00,0xcf,0x01,0x8f,0x03,0x0f,0x03,0x0f,0x00,0x0f,0x00,}; +static unsigned char sdl_std_cursor_left_side[]= {0x03,0x00,0x03,0x00,0x83,0x00,0x43,0x00,0x23,0x00,0x13,0x00,0xfb,0x3f,0x13,0x00,0x23,0x00,0x43,0x00,0x83,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_left_side 16 +#define sdl_std_cursor_HEIGHT_left_side 15 +#define sdl_std_cursor_HOT_X_left_side 0 +#define sdl_std_cursor_HOT_Y_left_side -7 + +static unsigned char sdl_std_cursor_mask_left_ptr[]= {0x03,0x00,0x07,0x00,0x0f,0x00,0x1f,0x00,0x3f,0x00,0x7f,0x00,0xff,0x00,0xff,0x01,0xff,0x03,0xff,0x03,0x7f,0x00,0xf7,0x00,0xf3,0x00,0xe0,0x01,0xe0,0x01,0xc0,0x00,}; +static unsigned char sdl_std_cursor_left_ptr[]= {0x00,0x00,0x02,0x00,0x06,0x00,0x0e,0x00,0x1e,0x00,0x3e,0x00,0x7e,0x00,0xfe,0x00,0xfe,0x00,0x3e,0x00,0x36,0x00,0x62,0x00,0x60,0x00,0xc0,0x00,0xc0,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_left_ptr 10 +#define sdl_std_cursor_HEIGHT_left_ptr 16 +#define sdl_std_cursor_HOT_X_left_ptr -8 +#define sdl_std_cursor_HOT_Y_left_ptr -14 + +static unsigned char sdl_std_cursor_mask_exchange[]= {0xe3,0x07,0xf7,0x0f,0xff,0x1f,0xff,0x3f,0x3f,0x38,0xff,0x30,0xff,0x00,0xff,0x00,0x00,0xff,0x00,0xff,0x0c,0xfe,0x1c,0xfc,0xfc,0xff,0xf8,0xff,0xf0,0xef,0xe0,0xc7,}; +static unsigned char sdl_std_cursor_exchange[]= {0xf1,0x03,0xfb,0x07,0x1f,0x0c,0x09,0x08,0x19,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x00,0x26,0x04,0x24,0x0c,0x3e,0xf8,0x37,0xf0,0x23,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_exchange 16 +#define sdl_std_cursor_HEIGHT_exchange 16 +#define sdl_std_cursor_HOT_X_exchange -6 +#define sdl_std_cursor_HOT_Y_exchange -8 + +static unsigned char sdl_std_cursor_mask_crosshair[]= {0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,}; +static unsigned char sdl_std_cursor_crosshair[]= {0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x7f,0xff,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_crosshair 16 +#define sdl_std_cursor_HEIGHT_crosshair 16 +#define sdl_std_cursor_HOT_X_crosshair -7 +#define sdl_std_cursor_HOT_Y_crosshair -8 + +static unsigned char sdl_std_cursor_mask_bottom_side[]= {0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xc0,0x01,0xcc,0x19,0xdc,0x1d,0xf8,0x0f,0xf0,0x07,0xe0,0x03,0xc0,0x01,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0x7f,}; +static unsigned char sdl_std_cursor_bottom_side[]= {0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x44,0x04,0x48,0x02,0x50,0x01,0xe0,0x00,0x40,0x00,0x00,0x00,0xff,0x1f,0xff,0x1f,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_bottom_side 15 +#define sdl_std_cursor_HEIGHT_bottom_side 16 +#define sdl_std_cursor_HOT_X_bottom_side -6 +#define sdl_std_cursor_HOT_Y_bottom_side -1 + +static unsigned char sdl_std_cursor_mask_bottom_right_corner[]= {0x00,0xf0,0x00,0xf0,0x0c,0xf7,0x1c,0xf7,0x38,0xf7,0x70,0xf7,0xe0,0xf7,0xc0,0xf7,0xfc,0xf7,0xfc,0xf7,0xfc,0xf7,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,}; +static unsigned char sdl_std_cursor_bottom_right_corner[]= {0x00,0x30,0x00,0x30,0x04,0x31,0x08,0x31,0x10,0x31,0x20,0x31,0x40,0x31,0x80,0x31,0xfc,0x31,0x00,0x30,0x00,0x30,0x00,0x30,0xff,0x3f,0xff,0x3f,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_bottom_right_corner 16 +#define sdl_std_cursor_HEIGHT_bottom_right_corner 16 +#define sdl_std_cursor_HOT_X_bottom_right_corner -13 +#define sdl_std_cursor_HOT_Y_bottom_right_corner -1 + +static unsigned char sdl_std_cursor_mask_bottom_left_corner[]= {0x0f,0x00,0x0f,0x00,0xef,0x30,0xef,0x38,0xef,0x1c,0xef,0x0e,0xef,0x07,0xef,0x03,0xef,0x3f,0xef,0x3f,0xef,0x3f,0x0f,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,}; +static unsigned char sdl_std_cursor_bottom_left_corner[]= {0x03,0x00,0x03,0x00,0x23,0x08,0x23,0x04,0x23,0x02,0x23,0x01,0xa3,0x00,0x63,0x00,0xe3,0x0f,0x03,0x00,0x03,0x00,0x03,0x00,0xff,0x3f,0xff,0x3f,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_bottom_left_corner 16 +#define sdl_std_cursor_HEIGHT_bottom_left_corner 16 +#define sdl_std_cursor_HOT_X_bottom_left_corner 0 +#define sdl_std_cursor_HOT_Y_bottom_left_corner -1 + +static unsigned char sdl_std_cursor_mask_arrow[]= {0x00,0xe0,0x00,0xf8,0x00,0xfe,0x80,0x7f,0xe0,0x7f,0xf8,0x3f,0xfc,0x3f,0xfc,0x1f,0xe0,0x1f,0xf0,0x0f,0xf8,0x0f,0x7c,0x07,0x3e,0x07,0x1f,0x02,0x0e,0x00,0x04,0x00,}; +static unsigned char sdl_std_cursor_arrow[]= {0x00,0x30,0x00,0x3c,0x00,0x1f,0xc0,0x1f,0xf0,0x0f,0xfc,0x0f,0xc0,0x07,0xe0,0x07,0x70,0x03,0x38,0x03,0x1c,0x01,0x0e,0x01,0x07,0x00,0x02,0x00,0x00,0x00,0x00,0x00,}; +#define sdl_std_cursor_WIDTH_arrow 16 +#define sdl_std_cursor_HEIGHT_arrow 16 +#define sdl_std_cursor_HOT_X_arrow -13 +#define sdl_std_cursor_HOT_Y_arrow -14 +/* end cursor data */ + + +static SDL_Cursor *sdl_std_cursor_array[(int)GHOST_kStandardCursorNumCursors]= {0}; + +/* utility function mostly a copy of SDL_CreateCursor but allows us to change + * color and supports blenders flipped bits */ +static SDL_Cursor * +sdl_ghost_CreateCursor(const Uint8 *data, + const Uint8 *mask, + int w, + int h, + int hot_x, + int hot_y) +{ + SDL_Surface *surface; + SDL_Cursor *cursor; + int x, y; + Uint32 *pixel; + Uint8 datab= 0, maskb= 0; + const Uint32 black= 0xFF000000; + const Uint32 white= 0xFFFFFFFF; + const Uint32 transparent= 0x00000000; + + /* Make sure the width is a multiple of 8 */ + w= ((w + 7) & ~7); + + /* Create the surface from a bitmap */ + surface= SDL_CreateRGBSurface(0, w, h, 32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); + if (!surface) { + return NULL; + } + for (y= 0; y < h; ++y) { + pixel= (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch); + for (x= 0; x < w; ++x) { + if ((x % 8) == 0) { + datab= *data++; + maskb= *mask++; + + /* reverse bit order */ + datab= (datab * 0x0202020202ULL & 0x010884422010ULL) % 1023; + maskb= (maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023; + } + if (maskb & 0x80) { + *pixel++= (datab & 0x80) ? white : black; + } + else { + *pixel++= (datab & 0x80) ? white : transparent; + } + datab <<= 1; + maskb <<= 1; + } + } + + cursor= SDL_CreateColorCursor(surface, hot_x, hot_y); + + SDL_FreeSurface(surface); + + return cursor; +} + +/* TODO, this is currently never freed but it wont leak either. */ +static void sdl_cursor_init(void) +{ + +#define DEF_CURSOR(name, ind) \ + assert(\ + (\ + sdl_std_cursor_array[(int)ind]= \ + sdl_ghost_CreateCursor(sdl_std_cursor_##name, \ + sdl_std_cursor_mask_##name, \ + sdl_std_cursor_WIDTH_##name, \ + sdl_std_cursor_HEIGHT_##name, \ + (sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \ + (sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1) \ + ) != NULL) \ + + + DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault); + DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow); + DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow); + DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo); // TODO, replace this one. + DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy); + DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp); + DEF_CURSOR(exchange, GHOST_kStandardCursorCycle); + DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray); + DEF_CURSOR(watch, GHOST_kStandardCursorWait); + DEF_CURSOR(xterm, GHOST_kStandardCursorText); + DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair); + DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown); + DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight); + DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide); + DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide); + DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide); + DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide); + DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner); + DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner); + DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner); + DEF_CURSOR(bottom_left_corner , GHOST_kStandardCursorBottomLeftCorner); + DEF_CURSOR(arrow , GHOST_kStandardCursorCopy); + //DEF_CURSOR(arrow, GHOST_kStandardCursorCustom); + DEF_CURSOR(arrow, GHOST_kStandardCursorPencil); + +#undef DEF_CURSOR + +} + + + +GHOST_TSuccess +GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode) +{ + return GHOST_kSuccess; +} + + +GHOST_TSuccess +GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape) +{ + if(sdl_std_cursor_array[0] == NULL) { + sdl_cursor_init(); + } + + SDL_SetCursor(sdl_std_cursor_array[(int)shape]); + return GHOST_kSuccess; +} + + +GHOST_TSuccess +GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], + GHOST_TUns8 mask[16][2], + int hotX, + int hotY) +{ + return setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, + (GHOST_TUns8 *)mask, + 16, 16, + hotX, hotY, + 0, 1); +} + + +GHOST_TSuccess +GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, + GHOST_TUns8 *mask, + int sizex, int sizey, + int hotX, int hotY, + int fg_color, int bg_color) +{ + if(m_sdl_custom_cursor) { + SDL_FreeCursor(m_sdl_custom_cursor); + } + + m_sdl_custom_cursor= sdl_ghost_CreateCursor((const Uint8 *)bitmap, + (const Uint8 *)mask, + sizex, sizex, + hotX, hotY); + + SDL_SetCursor(m_sdl_custom_cursor); + return GHOST_kSuccess; +} + + +GHOST_TSuccess +GHOST_WindowSDL::setWindowCursorVisibility(bool visible) +{ + SDL_ShowCursor(visible); + return GHOST_kSuccess; +} diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h new file mode 100644 index 00000000000..12ff0266e8c --- /dev/null +++ b/intern/ghost/intern/GHOST_WindowSDL.h @@ -0,0 +1,128 @@ +/* + * $Id: GHOST_WindowSDL.h 38022 2011-07-01 15:15:22Z campbellbarton $ + * ***** 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_WindowSDL.h + * \ingroup GHOST + * Declaration of GHOST_WindowSDL class. + */ + +#ifndef _GHOST_WINDOWSDL_H_ +#define _GHOST_WINDOWSDL_H_ + +#include "GHOST_Window.h" +#include "GHOST_SystemSDL.h" +#include <map> + +extern "C" { + #include "SDL.h" +} + +class STR_String; + +class GHOST_WindowSDL : public GHOST_Window +{ +private : + GHOST_SystemSDL * m_system; + bool m_invalid_window; + + SDL_Window * m_sdl_win; + SDL_GLContext m_sdl_glcontext; + SDL_Cursor * m_sdl_custom_cursor; + +public: + + const GHOST_TabletData* GetTabletData() { return NULL; } + + GHOST_WindowSDL(GHOST_SystemSDL *system, + const STR_String& title, + GHOST_TInt32 left, + GHOST_TInt32 top, + GHOST_TUns32 width, + GHOST_TUns32 height, + GHOST_TWindowState state, + const GHOST_TEmbedderWindowID parentWindow, + GHOST_TDrawingContextType type, + const bool stereoVisual, + const GHOST_TUns16 numOfAASamples + ); + + ~GHOST_WindowSDL(); + + /* SDL spesific */ + SDL_Window * + getSDLWindow( + ){ + return m_sdl_win; + } + + + GHOST_TSuccess invalidate(void); + + /** + * called by the X11 system implementation when expose events + * for the window have been pushed onto the GHOST queue + */ + + void validate() + { + m_invalid_window = false; + } + + bool getValid( ) const + { + return (m_sdl_win != NULL); + } + +protected: + GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type); + GHOST_TSuccess removeDrawingContext(); + + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); + GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape); + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY); + GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color); + GHOST_TSuccess setWindowCursorVisibility(bool visible); + + void setTitle(const STR_String& title); + void getTitle(STR_String& title) const; + void getWindowBounds( GHOST_Rect& bounds ) const; + void getClientBounds( GHOST_Rect& bounds ) const; + GHOST_TSuccess setClientWidth(GHOST_TUns32 width); + GHOST_TSuccess setClientHeight(GHOST_TUns32 height); + GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); + + /* TODO */ + void screenToClient( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; } + void clientToScreen( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const { outX = inX; outY = inY; } + + GHOST_TSuccess swapBuffers(); + GHOST_TSuccess activateDrawingContext(); + GHOST_TSuccess setState(GHOST_TWindowState state); + GHOST_TWindowState getState() const; + + GHOST_TSuccess setOrder(GHOST_TWindowOrder order) { return GHOST_kSuccess; } // TODO + +}; + + +#endif // _GHOST_WINDOWSDL_H_ |