Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * Contributor(s): Campbell Barton 00019 * 00020 * ***** END GPL LICENSE BLOCK ***** 00021 */ 00022 00027 #include <assert.h> 00028 00029 #include "GHOST_SystemSDL.h" 00030 00031 #include "GHOST_WindowManager.h" 00032 00033 #include "GHOST_EventCursor.h" 00034 #include "GHOST_EventKey.h" 00035 #include "GHOST_EventButton.h" 00036 #include "GHOST_EventWheel.h" 00037 00038 GHOST_SystemSDL::GHOST_SystemSDL() 00039 : 00040 GHOST_System() 00041 { 00042 if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) != 0) { 00043 printf ("Error initializing SDL: %s\n", SDL_GetError()); 00044 } 00045 00046 /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); */ 00047 /* SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); */ 00048 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 00049 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 00050 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 00051 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 00052 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 00053 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); 00054 } 00055 00056 GHOST_SystemSDL::~GHOST_SystemSDL() 00057 { 00058 SDL_Quit(); 00059 } 00060 00061 GHOST_IWindow * 00062 GHOST_SystemSDL::createWindow(const STR_String& title, 00063 GHOST_TInt32 left, 00064 GHOST_TInt32 top, 00065 GHOST_TUns32 width, 00066 GHOST_TUns32 height, 00067 GHOST_TWindowState state, 00068 GHOST_TDrawingContextType type, 00069 bool stereoVisual, 00070 const GHOST_TUns16 numOfAASamples, 00071 const GHOST_TEmbedderWindowID parentWindow 00072 ) 00073 { 00074 GHOST_WindowSDL *window= NULL; 00075 00076 window= new GHOST_WindowSDL (this, title, left, top, width, height, state, parentWindow, type, stereoVisual, 1); 00077 00078 if (window) { 00079 if (window->getValid()) { 00080 m_windowManager->addWindow(window); 00081 pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window)); 00082 } 00083 else { 00084 delete window; 00085 window= NULL; 00086 } 00087 } 00088 return window; 00089 } 00090 00091 GHOST_TSuccess 00092 GHOST_SystemSDL::init() { 00093 GHOST_TSuccess success = GHOST_System::init(); 00094 00095 if (success) { 00096 m_displayManager = new GHOST_DisplayManagerSDL(this); 00097 00098 if (m_displayManager) { 00099 return GHOST_kSuccess; 00100 } 00101 } 00102 00103 return GHOST_kFailure; 00104 } 00105 00106 void 00107 GHOST_SystemSDL::getMainDisplayDimensions(GHOST_TUns32& width, 00108 GHOST_TUns32& height) const 00109 { 00110 SDL_DisplayMode mode; 00111 SDL_GetCurrentDisplayMode(0, &mode); /* note, always 0 display */ 00112 width= mode.w; 00113 height= mode.h; 00114 } 00115 00116 GHOST_TUns8 00117 GHOST_SystemSDL::getNumDisplays() const 00118 { 00119 return SDL_GetNumVideoDisplays(); 00120 } 00121 00122 GHOST_TSuccess 00123 GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys& keys) const 00124 { 00125 SDL_Keymod mod= SDL_GetModState(); 00126 00127 keys.set(GHOST_kModifierKeyLeftShift, (mod & KMOD_LSHIFT) != 0); 00128 keys.set(GHOST_kModifierKeyRightShift, (mod & KMOD_RSHIFT) != 0); 00129 keys.set(GHOST_kModifierKeyLeftControl, (mod & KMOD_LCTRL) != 0); 00130 keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0); 00131 keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0); 00132 keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0); 00133 keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI|KMOD_RGUI)) != 0); 00134 00135 return GHOST_kSuccess; 00136 } 00137 00138 #define GXMAP(k,x,y) case x: k= y; break; 00139 00140 static GHOST_TKey 00141 convertSDLKey(SDL_Scancode key) 00142 { 00143 GHOST_TKey type; 00144 00145 if ((key >= SDL_SCANCODE_A) && (key <= SDL_SCANCODE_Z)) { 00146 type= GHOST_TKey( key - SDL_SCANCODE_A + int(GHOST_kKeyA)); 00147 } else if ((key >= SDL_SCANCODE_1) && (key <= SDL_SCANCODE_0)) { 00148 type= (key == SDL_SCANCODE_0) ? GHOST_kKey0 : GHOST_TKey(key - SDL_SCANCODE_1 + int(GHOST_kKey1)); 00149 } else if ((key >= SDL_SCANCODE_F1) && (key <= SDL_SCANCODE_F12)) { 00150 type= GHOST_TKey(key - SDL_SCANCODE_F1 + int(GHOST_kKeyF1)); 00151 } else if ((key >= SDL_SCANCODE_F13) && (key <= SDL_SCANCODE_F24)) { 00152 type= GHOST_TKey(key - SDL_SCANCODE_F13 + int(GHOST_kKeyF13)); 00153 } else { 00154 switch(key) { 00155 /* TODO SDL_SCANCODE_NONUSBACKSLASH */ 00156 00157 GXMAP(type,SDL_SCANCODE_BACKSPACE, GHOST_kKeyBackSpace); 00158 GXMAP(type,SDL_SCANCODE_TAB, GHOST_kKeyTab); 00159 GXMAP(type,SDL_SCANCODE_RETURN, GHOST_kKeyEnter); 00160 GXMAP(type,SDL_SCANCODE_ESCAPE, GHOST_kKeyEsc); 00161 GXMAP(type,SDL_SCANCODE_SPACE, GHOST_kKeySpace); 00162 00163 GXMAP(type,SDL_SCANCODE_SEMICOLON, GHOST_kKeySemicolon); 00164 GXMAP(type,SDL_SCANCODE_PERIOD, GHOST_kKeyPeriod); 00165 GXMAP(type,SDL_SCANCODE_COMMA, GHOST_kKeyComma); 00166 GXMAP(type,SDL_SCANCODE_APOSTROPHE, GHOST_kKeyQuote); 00167 GXMAP(type,SDL_SCANCODE_GRAVE, GHOST_kKeyAccentGrave); 00168 GXMAP(type,SDL_SCANCODE_MINUS, GHOST_kKeyMinus); 00169 GXMAP(type,SDL_SCANCODE_EQUALS, GHOST_kKeyEqual); 00170 00171 GXMAP(type,SDL_SCANCODE_SLASH, GHOST_kKeySlash); 00172 GXMAP(type,SDL_SCANCODE_BACKSLASH, GHOST_kKeyBackslash); 00173 GXMAP(type,SDL_SCANCODE_KP_EQUALS, GHOST_kKeyEqual); 00174 GXMAP(type,SDL_SCANCODE_LEFTBRACKET, GHOST_kKeyLeftBracket); 00175 GXMAP(type,SDL_SCANCODE_RIGHTBRACKET, GHOST_kKeyRightBracket); 00176 GXMAP(type,SDL_SCANCODE_PAUSE, GHOST_kKeyPause); 00177 00178 GXMAP(type,SDL_SCANCODE_LSHIFT, GHOST_kKeyLeftShift); 00179 GXMAP(type,SDL_SCANCODE_RSHIFT, GHOST_kKeyRightShift); 00180 GXMAP(type,SDL_SCANCODE_LCTRL, GHOST_kKeyLeftControl); 00181 GXMAP(type,SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl); 00182 GXMAP(type,SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt); 00183 GXMAP(type,SDL_SCANCODE_RALT, GHOST_kKeyRightAlt); 00184 GXMAP(type,SDL_SCANCODE_LGUI, GHOST_kKeyOS); 00185 GXMAP(type,SDL_SCANCODE_RGUI, GHOST_kKeyOS); 00186 00187 GXMAP(type,SDL_SCANCODE_INSERT, GHOST_kKeyInsert); 00188 GXMAP(type,SDL_SCANCODE_DELETE, GHOST_kKeyDelete); 00189 GXMAP(type,SDL_SCANCODE_HOME, GHOST_kKeyHome); 00190 GXMAP(type,SDL_SCANCODE_END, GHOST_kKeyEnd); 00191 GXMAP(type,SDL_SCANCODE_PAGEUP, GHOST_kKeyUpPage); 00192 GXMAP(type,SDL_SCANCODE_PAGEDOWN, GHOST_kKeyDownPage); 00193 00194 GXMAP(type,SDL_SCANCODE_LEFT, GHOST_kKeyLeftArrow); 00195 GXMAP(type,SDL_SCANCODE_RIGHT, GHOST_kKeyRightArrow); 00196 GXMAP(type,SDL_SCANCODE_UP, GHOST_kKeyUpArrow); 00197 GXMAP(type,SDL_SCANCODE_DOWN, GHOST_kKeyDownArrow); 00198 00199 GXMAP(type,SDL_SCANCODE_CAPSLOCK, GHOST_kKeyCapsLock); 00200 GXMAP(type,SDL_SCANCODE_SCROLLLOCK, GHOST_kKeyScrollLock); 00201 GXMAP(type,SDL_SCANCODE_NUMLOCKCLEAR, GHOST_kKeyNumLock); 00202 GXMAP(type,SDL_SCANCODE_PRINTSCREEN, GHOST_kKeyPrintScreen); 00203 00204 /* keypad events */ 00205 00206 /* note, sdl defines a bunch of kp defines I never saw before like 00207 * SDL_SCANCODE_KP_PERCENT, SDL_SCANCODE_KP_XOR - campbell */ 00208 GXMAP(type,SDL_SCANCODE_KP_0, GHOST_kKeyNumpad0); 00209 GXMAP(type,SDL_SCANCODE_KP_1, GHOST_kKeyNumpad1); 00210 GXMAP(type,SDL_SCANCODE_KP_2, GHOST_kKeyNumpad2); 00211 GXMAP(type,SDL_SCANCODE_KP_3, GHOST_kKeyNumpad3); 00212 GXMAP(type,SDL_SCANCODE_KP_4, GHOST_kKeyNumpad4); 00213 GXMAP(type,SDL_SCANCODE_KP_5, GHOST_kKeyNumpad5); 00214 GXMAP(type,SDL_SCANCODE_KP_6, GHOST_kKeyNumpad6); 00215 GXMAP(type,SDL_SCANCODE_KP_7, GHOST_kKeyNumpad7); 00216 GXMAP(type,SDL_SCANCODE_KP_8, GHOST_kKeyNumpad8); 00217 GXMAP(type,SDL_SCANCODE_KP_9, GHOST_kKeyNumpad9); 00218 GXMAP(type,SDL_SCANCODE_KP_PERIOD, GHOST_kKeyNumpadPeriod); 00219 00220 GXMAP(type,SDL_SCANCODE_KP_ENTER, GHOST_kKeyNumpadEnter); 00221 GXMAP(type,SDL_SCANCODE_KP_PLUS, GHOST_kKeyNumpadPlus); 00222 GXMAP(type,SDL_SCANCODE_KP_MINUS, GHOST_kKeyNumpadMinus); 00223 GXMAP(type,SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk); 00224 GXMAP(type,SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash); 00225 00226 /* Media keys in some keyboards and laptops with XFree86/Xorg */ 00227 GXMAP(type,SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay); 00228 GXMAP(type,SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop); 00229 GXMAP(type,SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst); 00230 // GXMAP(type,XF86XK_AudioRewind, GHOST_kKeyMediaFirst); 00231 GXMAP(type,SDL_SCANCODE_AUDIONEXT, GHOST_kKeyMediaLast); 00232 00233 default: 00234 printf("Unknown\n"); 00235 type= GHOST_kKeyUnknown; 00236 break; 00237 } 00238 } 00239 00240 return type; 00241 } 00242 #undef GXMAP 00243 00244 00245 void 00246 GHOST_SystemSDL::processEvent(SDL_Event *sdl_event) 00247 { 00248 GHOST_Event * g_event= NULL; 00249 00250 switch(sdl_event->type) { 00251 case SDL_WINDOWEVENT: 00252 { 00253 SDL_WindowEvent &sdl_sub_evt= sdl_event->window; 00254 GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); 00255 //assert(window != NULL); // can be NULL on close window. 00256 00257 switch (sdl_sub_evt.event) { 00258 case SDL_WINDOWEVENT_EXPOSED: 00259 g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window); 00260 break; 00261 case SDL_WINDOWEVENT_RESIZED: 00262 g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window); 00263 break; 00264 case SDL_WINDOWEVENT_MOVED: 00265 g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window); 00266 break; 00267 case SDL_WINDOWEVENT_FOCUS_GAINED: 00268 g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window); 00269 break; 00270 case SDL_WINDOWEVENT_FOCUS_LOST: 00271 g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window); 00272 break; 00273 case SDL_WINDOWEVENT_CLOSE: 00274 g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window); 00275 break; 00276 } 00277 } 00278 break; 00279 case SDL_QUIT: 00280 g_event= new GHOST_Event(getMilliSeconds(), GHOST_kEventQuit, NULL); 00281 break; 00282 00283 case SDL_MOUSEMOTION: 00284 { 00285 SDL_MouseMotionEvent &sdl_sub_evt= sdl_event->motion; 00286 SDL_Window *sdl_win= SDL_GetWindowFromID(sdl_sub_evt.windowID); 00287 GHOST_WindowSDL *window= findGhostWindow(sdl_win); 00288 assert(window != NULL); 00289 00290 int x_win, y_win; 00291 SDL_GetWindowPosition(sdl_win, &x_win, &y_win); 00292 00293 GHOST_TInt32 x_root= sdl_sub_evt.x + x_win; 00294 GHOST_TInt32 y_root= sdl_sub_evt.y + y_win; 00295 00296 #if 0 00297 if(window->getCursorGrabMode() != GHOST_kGrabDisable && window->getCursorGrabMode() != GHOST_kGrabNormal) 00298 { 00299 GHOST_TInt32 x_new= x_root; 00300 GHOST_TInt32 y_new= y_root; 00301 GHOST_TInt32 x_accum, y_accum; 00302 GHOST_Rect bounds; 00303 00304 /* fallback to window bounds */ 00305 if(window->getCursorGrabBounds(bounds)==GHOST_kFailure) 00306 window->getClientBounds(bounds); 00307 00308 /* could also clamp to screen bounds 00309 * wrap with a window outside the view will fail atm */ 00310 bounds.wrapPoint(x_new, y_new, 8); /* offset of one incase blender is at screen bounds */ 00311 window->getCursorGrabAccum(x_accum, y_accum); 00312 00313 // cant use setCursorPosition because the mouse may have no focus! 00314 if(x_new != x_root || y_new != y_root) { 00315 if (1 ) { //xme.time > m_last_warp) { 00316 /* when wrapping we don't need to add an event because the 00317 * setCursorPosition call will cause a new event after */ 00318 SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); /* wrap */ 00319 window->setCursorGrabAccum(x_accum + (x_root - x_new), y_accum + (y_root - y_new)); 00320 // m_last_warp= lastEventTime(xme.time); 00321 } else { 00322 // setCursorPosition(x_new, y_new); /* wrap but don't accumulate */ 00323 SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win); 00324 } 00325 00326 g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_new, y_new); 00327 } 00328 else { 00329 g_event = new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root + x_accum, y_root + y_accum); 00330 } 00331 } 00332 else 00333 #endif 00334 { 00335 g_event= new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x_root, y_root); 00336 } 00337 break; 00338 } 00339 case SDL_MOUSEBUTTONUP: 00340 case SDL_MOUSEBUTTONDOWN: 00341 { 00342 SDL_MouseButtonEvent &sdl_sub_evt= sdl_event->button; 00343 GHOST_TButtonMask gbmask= GHOST_kButtonMaskLeft; 00344 GHOST_TEventType type= (sdl_sub_evt.state==SDL_PRESSED) ? GHOST_kEventButtonDown : GHOST_kEventButtonUp; 00345 00346 GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); 00347 assert(window != NULL); 00348 00349 /* process rest of normal mouse buttons */ 00350 if(sdl_sub_evt.button == SDL_BUTTON_LEFT) 00351 gbmask= GHOST_kButtonMaskLeft; 00352 else if(sdl_sub_evt.button == SDL_BUTTON_MIDDLE) 00353 gbmask= GHOST_kButtonMaskMiddle; 00354 else if(sdl_sub_evt.button == SDL_BUTTON_RIGHT) 00355 gbmask= GHOST_kButtonMaskRight; 00356 /* these buttons are untested! */ 00357 else if(sdl_sub_evt.button == SDL_BUTTON_X1) 00358 gbmask= GHOST_kButtonMaskButton4; 00359 else if(sdl_sub_evt.button == SDL_BUTTON_X2) 00360 gbmask= GHOST_kButtonMaskButton5; 00361 else 00362 break; 00363 00364 g_event= new GHOST_EventButton(getMilliSeconds(), type, window, gbmask); 00365 break; 00366 } 00367 case SDL_MOUSEWHEEL: 00368 { 00369 SDL_MouseWheelEvent &sdl_sub_evt= sdl_event->wheel; 00370 GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); 00371 assert(window != NULL); 00372 g_event= new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y); 00373 } 00374 break; 00375 case SDL_KEYDOWN: 00376 case SDL_KEYUP: 00377 { 00378 SDL_KeyboardEvent &sdl_sub_evt= sdl_event->key; 00379 SDL_Keycode sym= sdl_sub_evt.keysym.sym; 00380 GHOST_TEventType type= (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp; 00381 00382 GHOST_WindowSDL *window= findGhostWindow(SDL_GetWindowFromID(sdl_sub_evt.windowID)); 00383 assert(window != NULL); 00384 00385 GHOST_TKey gkey= convertSDLKey(sdl_sub_evt.keysym.scancode); 00386 /* note, the sdl_sub_evt.keysym.sym is truncated, for unicode support ghost has to be modified */ 00387 /* printf("%d\n", sym); */ 00388 if(sym > 127) { 00389 switch(sym) { 00390 case SDLK_KP_DIVIDE: sym= '/'; break; 00391 case SDLK_KP_MULTIPLY: sym= '*'; break; 00392 case SDLK_KP_MINUS: sym= '-'; break; 00393 case SDLK_KP_PLUS: sym= '+'; break; 00394 case SDLK_KP_1: sym= '1'; break; 00395 case SDLK_KP_2: sym= '2'; break; 00396 case SDLK_KP_3: sym= '3'; break; 00397 case SDLK_KP_4: sym= '4'; break; 00398 case SDLK_KP_5: sym= '5'; break; 00399 case SDLK_KP_6: sym= '6'; break; 00400 case SDLK_KP_7: sym= '7'; break; 00401 case SDLK_KP_8: sym= '8'; break; 00402 case SDLK_KP_9: sym= '9'; break; 00403 case SDLK_KP_0: sym= '0'; break; 00404 case SDLK_KP_PERIOD: sym= '.'; break; 00405 default: sym= 0; break; 00406 } 00407 } 00408 else { 00409 if(sdl_sub_evt.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT)) { 00410 /* lame US keyboard assumptions */ 00411 if(sym >= 'a' && sym <= ('a' + 32)) { 00412 sym -= 32; 00413 } 00414 else { 00415 switch(sym) { 00416 case '`': sym= '~'; break; 00417 case '1': sym= '!'; break; 00418 case '2': sym= '@'; break; 00419 case '3': sym= '#'; break; 00420 case '4': sym= '$'; break; 00421 case '5': sym= '%'; break; 00422 case '6': sym= '^'; break; 00423 case '7': sym= '&'; break; 00424 case '8': sym= '*'; break; 00425 case '9': sym= '('; break; 00426 case '0': sym= ')'; break; 00427 case '-': sym= '_'; break; 00428 case '=': sym= '+'; break; 00429 case '[': sym= '{'; break; 00430 case ']': sym= '}'; break; 00431 case '\\': sym= '|'; break; 00432 case ';': sym= ':'; break; 00433 case '\'': sym= '"'; break; 00434 case ',': sym= '<'; break; 00435 case '.': sym= '>'; break; 00436 case '/': sym= '?'; break; 00437 default: break; 00438 } 00439 } 00440 } 00441 } 00442 00443 g_event= new GHOST_EventKey(getMilliSeconds(), type, window, gkey, sym, NULL); 00444 } 00445 break; 00446 } 00447 00448 if (g_event) { 00449 pushEvent(g_event); 00450 } 00451 } 00452 00453 GHOST_TSuccess 00454 GHOST_SystemSDL::getCursorPosition(GHOST_TInt32& x, 00455 GHOST_TInt32& y) const 00456 { 00457 int x_win, y_win; 00458 SDL_Window *win= SDL_GetMouseFocus(); 00459 SDL_GetWindowPosition(win, &x_win, &y_win); 00460 00461 int xi, yi; 00462 SDL_GetMouseState(&xi, &yi); 00463 x= xi + x_win; 00464 y= yi + x_win; 00465 00466 return GHOST_kSuccess; 00467 } 00468 00469 GHOST_TSuccess 00470 GHOST_SystemSDL::setCursorPosition(GHOST_TInt32 x, 00471 GHOST_TInt32 y) 00472 { 00473 int x_win, y_win; 00474 SDL_Window *win= SDL_GetMouseFocus(); 00475 SDL_GetWindowPosition(win, &x_win, &y_win); 00476 00477 SDL_WarpMouseInWindow(win, x - x_win, y - y_win); 00478 return GHOST_kSuccess; 00479 } 00480 00481 bool 00482 GHOST_SystemSDL::generateWindowExposeEvents() 00483 { 00484 vector<GHOST_WindowSDL *>::iterator w_start= m_dirty_windows.begin(); 00485 vector<GHOST_WindowSDL *>::const_iterator w_end= m_dirty_windows.end(); 00486 bool anyProcessed= false; 00487 00488 for (;w_start != w_end; ++w_start) { 00489 GHOST_Event * g_event= new 00490 GHOST_Event( 00491 getMilliSeconds(), 00492 GHOST_kEventWindowUpdate, 00493 *w_start 00494 ); 00495 00496 (*w_start)->validate(); 00497 00498 if (g_event) { 00499 printf("Expose events pushed\n"); 00500 pushEvent(g_event); 00501 anyProcessed= true; 00502 } 00503 } 00504 00505 m_dirty_windows.clear(); 00506 return anyProcessed; 00507 } 00508 00509 00510 bool 00511 GHOST_SystemSDL::processEvents(bool waitForEvent) 00512 { 00513 // Get all the current events -- translate them into 00514 // ghost events and call base class pushEvent() method. 00515 00516 bool anyProcessed= false; 00517 00518 do { 00519 GHOST_TimerManager* timerMgr= getTimerManager(); 00520 00521 if (waitForEvent && m_dirty_windows.empty() && !SDL_HasEvents(SDL_FIRSTEVENT, SDL_LASTEVENT)) { 00522 GHOST_TUns64 next= timerMgr->nextFireTime(); 00523 00524 if (next==GHOST_kFireTimeNever) { 00525 SDL_WaitEventTimeout(NULL, -1); 00526 //SleepTillEvent(m_display, -1); 00527 } else { 00528 GHOST_TInt64 maxSleep= next - getMilliSeconds(); 00529 00530 if(maxSleep >= 0) { 00531 SDL_WaitEventTimeout(NULL, next - getMilliSeconds()); 00532 // SleepTillEvent(m_display, next - getMilliSeconds()); // X11 00533 } 00534 } 00535 } 00536 00537 if (timerMgr->fireTimers(getMilliSeconds())) { 00538 anyProcessed= true; 00539 } 00540 00541 SDL_Event sdl_event; 00542 while (SDL_PollEvent(&sdl_event)) { 00543 processEvent(&sdl_event); 00544 anyProcessed= true; 00545 } 00546 00547 if (generateWindowExposeEvents()) { 00548 anyProcessed= true; 00549 } 00550 } while (waitForEvent && !anyProcessed); 00551 00552 return anyProcessed; 00553 } 00554 00555 00556 GHOST_WindowSDL * 00557 GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win) 00558 { 00559 if (sdl_win == NULL) return NULL; 00560 00561 // It is not entirely safe to do this as the backptr may point 00562 // to a window that has recently been removed. 00563 // We should always check the window manager's list of windows 00564 // and only process events on these windows. 00565 00566 vector<GHOST_IWindow *> & win_vec= m_windowManager->getWindows(); 00567 00568 vector<GHOST_IWindow *>::iterator win_it= win_vec.begin(); 00569 vector<GHOST_IWindow *>::const_iterator win_end= win_vec.end(); 00570 00571 for (; win_it != win_end; ++win_it) { 00572 GHOST_WindowSDL * window= static_cast<GHOST_WindowSDL *>(*win_it); 00573 if (window->getSDLWindow() == sdl_win) { 00574 return window; 00575 } 00576 } 00577 return NULL; 00578 } 00579 00580 00581 void 00582 GHOST_SystemSDL::addDirtyWindow(GHOST_WindowSDL *bad_wind) 00583 { 00584 GHOST_ASSERT((bad_wind != NULL), "addDirtyWindow() NULL ptr trapped (window)"); 00585 00586 m_dirty_windows.push_back(bad_wind); 00587 } 00588 00589 00590 GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons& buttons) const 00591 { 00592 Uint8 state= SDL_GetMouseState(NULL, NULL); 00593 buttons.set(GHOST_kButtonMaskLeft, (state & SDL_BUTTON_LMASK) != 0); 00594 buttons.set(GHOST_kButtonMaskMiddle, (state & SDL_BUTTON_MMASK) != 0); 00595 buttons.set(GHOST_kButtonMaskRight, (state & SDL_BUTTON_RMASK) != 0); 00596 00597 return GHOST_kSuccess; 00598 } 00599 00600 GHOST_TUns8 * 00601 GHOST_SystemSDL::getClipboard(bool selection) const 00602 { 00603 return (GHOST_TUns8 *)SDL_GetClipboardText(); 00604 } 00605 00606 void 00607 GHOST_SystemSDL::putClipboard(GHOST_TInt8 *buffer, bool selection) const 00608 { 00609 SDL_SetClipboardText(buffer); 00610 } 00611 00612 GHOST_TUns64 00613 GHOST_SystemSDL::getMilliSeconds() 00614 { 00615 return GHOST_TUns64(SDL_GetTicks()); /* note, 32 -> 64bits */ 00616 }