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