|
Blender
V2.59
|
00001 /* 00002 * $Id: GHOST_WindowSDL.cpp 38349 2011-07-13 00:49:22Z gsrb3d $ 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 "GHOST_WindowSDL.h" 00029 #include "SDL_mouse.h" 00030 #include <assert.h> 00031 00032 static SDL_GLContext s_firstContext= NULL; 00033 00034 GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system, 00035 const STR_String& title, 00036 GHOST_TInt32 left, 00037 GHOST_TInt32 top, 00038 GHOST_TUns32 width, 00039 GHOST_TUns32 height, 00040 GHOST_TWindowState state, 00041 const GHOST_TEmbedderWindowID parentWindow, 00042 GHOST_TDrawingContextType type, 00043 const bool stereoVisual, 00044 const GHOST_TUns16 numOfAASamples 00045 ) 00046 : 00047 GHOST_Window(width,height,state,type,stereoVisual,numOfAASamples), 00048 m_system (system), 00049 m_invalid_window(false), 00050 m_sdl_custom_cursor(NULL) 00051 { 00052 m_sdl_win= SDL_CreateWindow(title, 00053 left, 00054 top, 00055 width, 00056 height, 00057 SDL_WINDOW_RESIZABLE|SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN); 00058 00059 //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); 00060 //SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); 00061 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 00062 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 00063 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 00064 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 00065 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 00066 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); 00067 00068 m_sdl_glcontext= SDL_GL_CreateContext(m_sdl_win); 00069 00070 //fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n", 00071 // theEvent->error_code, theEvent->request_code) ; 00072 00073 setTitle(title); 00074 } 00075 00076 GHOST_WindowSDL::~GHOST_WindowSDL() 00077 { 00078 if(m_sdl_custom_cursor) { 00079 SDL_FreeCursor(m_sdl_custom_cursor); 00080 } 00081 00082 if (m_sdl_glcontext != s_firstContext) { 00083 SDL_GL_DeleteContext(m_sdl_glcontext); 00084 } 00085 00086 SDL_DestroyWindow(m_sdl_win); 00087 } 00088 00089 00090 GHOST_TSuccess 00091 GHOST_WindowSDL::installDrawingContext(GHOST_TDrawingContextType type) 00092 { 00093 // only support openGL for now. 00094 GHOST_TSuccess success; 00095 switch (type) { 00096 case GHOST_kDrawingContextTypeOpenGL: 00097 m_sdl_glcontext= SDL_GL_CreateContext(m_sdl_win); 00098 00099 if (m_sdl_glcontext != NULL) { 00100 if (!s_firstContext) { 00101 s_firstContext= m_sdl_glcontext; 00102 } 00103 00104 success= (SDL_GL_MakeCurrent(m_sdl_win, m_sdl_glcontext) < 0) ? 00105 GHOST_kFailure : GHOST_kSuccess; 00106 } 00107 else { 00108 success= GHOST_kFailure; 00109 } 00110 00111 break; 00112 00113 case GHOST_kDrawingContextTypeNone: 00114 success= GHOST_kSuccess; 00115 break; 00116 00117 default: 00118 success= GHOST_kFailure; 00119 } 00120 return success; 00121 } 00122 00123 00124 GHOST_TSuccess 00125 GHOST_WindowSDL::invalidate(void) 00126 { 00127 // So the idea of this function is to generate an expose event 00128 // for the window. 00129 // Unfortunately X does not handle expose events for you and 00130 // it is the client's job to refresh the dirty part of the window. 00131 // We need to queue up invalidate calls and generate GHOST events 00132 // for them in the system. 00133 00134 // We implement this by setting a boolean in this class to concatenate 00135 // all such calls into a single event for this window. 00136 00137 // At the same time we queue the dirty windows in the system class 00138 // and generate events for them at the next processEvents call. 00139 00140 if (m_invalid_window == false) { 00141 m_system->addDirtyWindow(this); 00142 m_invalid_window= true; 00143 } 00144 00145 return GHOST_kSuccess; 00146 } 00147 00148 00149 GHOST_TSuccess 00150 GHOST_WindowSDL::swapBuffers() 00151 { 00152 if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) { 00153 SDL_GL_SwapWindow(m_sdl_win); 00154 return GHOST_kSuccess; 00155 } 00156 else { 00157 return GHOST_kFailure; 00158 } 00159 } 00160 00161 00162 GHOST_TSuccess 00163 GHOST_WindowSDL::activateDrawingContext() 00164 { 00165 if (m_sdl_glcontext !=NULL) { 00166 int status=SDL_GL_MakeCurrent(m_sdl_win, m_sdl_glcontext); 00167 (void)status; 00168 return GHOST_kSuccess; 00169 } 00170 return GHOST_kFailure; 00171 } 00172 00173 00174 GHOST_TSuccess 00175 GHOST_WindowSDL::removeDrawingContext() 00176 { 00177 GHOST_TSuccess success; 00178 00179 if (m_sdl_glcontext != NULL) { 00180 SDL_GL_DeleteContext(m_sdl_glcontext); 00181 success= GHOST_kSuccess; 00182 } 00183 else { 00184 success= GHOST_kFailure; 00185 } 00186 return success; 00187 } 00188 00189 00190 GHOST_TSuccess 00191 GHOST_WindowSDL::setState(GHOST_TWindowState state) 00192 { 00193 switch(state) { 00194 case GHOST_kWindowStateNormal: 00195 SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); 00196 SDL_RestoreWindow(m_sdl_win); 00197 break; 00198 case GHOST_kWindowStateMaximized: 00199 SDL_SetWindowFullscreen(m_sdl_win, SDL_FALSE); 00200 SDL_MaximizeWindow(m_sdl_win); 00201 break; 00202 case GHOST_kWindowStateMinimized: 00203 SDL_MinimizeWindow(m_sdl_win); 00204 break; 00205 case GHOST_kWindowStateFullScreen: 00206 SDL_SetWindowFullscreen(m_sdl_win, SDL_TRUE); 00207 break; 00208 default: 00209 break; 00210 } 00211 00212 return GHOST_kSuccess; 00213 } 00214 00215 00216 GHOST_TWindowState 00217 GHOST_WindowSDL::getState() const 00218 { 00219 Uint32 flags= SDL_GetWindowFlags(m_sdl_win); 00220 00221 if(flags & SDL_WINDOW_FULLSCREEN) return GHOST_kWindowStateFullScreen; 00222 else if(flags & SDL_WINDOW_MAXIMIZED) return GHOST_kWindowStateMaximized; 00223 else if(flags & SDL_WINDOW_MINIMIZED) return GHOST_kWindowStateMinimized; 00224 return GHOST_kWindowStateNormal; 00225 } 00226 00227 00228 void 00229 GHOST_WindowSDL::setTitle(const STR_String& title) 00230 { 00231 SDL_SetWindowTitle(m_sdl_win, title.ReadPtr()); 00232 } 00233 00234 00235 void 00236 GHOST_WindowSDL::getTitle(STR_String& title) const 00237 { 00238 title= SDL_GetWindowTitle(m_sdl_win); 00239 } 00240 00241 00242 void 00243 GHOST_WindowSDL::getWindowBounds(GHOST_Rect& bounds) const 00244 { 00245 getClientBounds(bounds); 00246 } 00247 00248 00249 void 00250 GHOST_WindowSDL::getClientBounds(GHOST_Rect& bounds) const 00251 { 00252 int x, y, w, h; 00253 SDL_GetWindowSize(m_sdl_win, &w, &h); 00254 SDL_GetWindowPosition(m_sdl_win, &x, &y); 00255 00256 bounds.m_l= x; 00257 bounds.m_r= x + w; 00258 bounds.m_t= y; 00259 bounds.m_b= y + h; 00260 } 00261 00262 GHOST_TSuccess 00263 GHOST_WindowSDL::setClientWidth(GHOST_TUns32 width) 00264 { 00265 int height; 00266 SDL_GetWindowSize(m_sdl_win, NULL, &height); 00267 SDL_SetWindowSize(m_sdl_win, width, height); 00268 return GHOST_kSuccess; 00269 } 00270 00271 GHOST_TSuccess 00272 GHOST_WindowSDL::setClientHeight(GHOST_TUns32 height) 00273 { 00274 int width; 00275 SDL_GetWindowSize(m_sdl_win, &width, NULL); 00276 SDL_SetWindowSize(m_sdl_win, width, height); 00277 return GHOST_kSuccess; 00278 } 00279 00280 GHOST_TSuccess 00281 GHOST_WindowSDL::setClientSize(GHOST_TUns32 width, 00282 GHOST_TUns32 height) 00283 { 00284 SDL_SetWindowSize(m_sdl_win, width, height); 00285 return GHOST_kSuccess; 00286 } 00287 00288 void 00289 GHOST_WindowSDL::screenToClient( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const 00290 { 00291 /* XXXSDL_WEAK_ABS_COORDS */ 00292 int x_win, y_win; 00293 SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win); 00294 00295 outX = inX - x_win; 00296 outY = inY - y_win; 00297 } 00298 void 00299 GHOST_WindowSDL::clientToScreen( GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY ) const 00300 { 00301 /* XXXSDL_WEAK_ABS_COORDS */ 00302 int x_win, y_win; 00303 SDL_GetWindowPosition(m_sdl_win, &x_win, &y_win); 00304 00305 outX = inX + x_win; 00306 outY = inY + y_win; 00307 } 00308 00309 /* mouse cursor */ 00310 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,}; 00311 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,}; 00312 #define sdl_std_cursor_WIDTH_xterm 9 00313 #define sdl_std_cursor_HEIGHT_xterm 16 00314 #define sdl_std_cursor_HOT_X_xterm -3 00315 #define sdl_std_cursor_HOT_Y_xterm -7 00316 00317 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,}; 00318 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,}; 00319 #define sdl_std_cursor_WIDTH_watch 16 00320 #define sdl_std_cursor_HEIGHT_watch 16 00321 #define sdl_std_cursor_HOT_X_watch -15 00322 #define sdl_std_cursor_HOT_Y_watch -7 00323 00324 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,}; 00325 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,}; 00326 #define sdl_std_cursor_WIDTH_umbrella 16 00327 #define sdl_std_cursor_HEIGHT_umbrella 16 00328 #define sdl_std_cursor_HOT_X_umbrella -7 00329 #define sdl_std_cursor_HOT_Y_umbrella -12 00330 00331 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,}; 00332 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,}; 00333 #define sdl_std_cursor_WIDTH_top_side 15 00334 #define sdl_std_cursor_HEIGHT_top_side 16 00335 #define sdl_std_cursor_HOT_X_top_side -6 00336 #define sdl_std_cursor_HOT_Y_top_side -14 00337 00338 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,}; 00339 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,}; 00340 #define sdl_std_cursor_WIDTH_top_right_corner 16 00341 #define sdl_std_cursor_HEIGHT_top_right_corner 16 00342 #define sdl_std_cursor_HOT_X_top_right_corner -13 00343 #define sdl_std_cursor_HOT_Y_top_right_corner -14 00344 00345 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,}; 00346 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,}; 00347 #define sdl_std_cursor_WIDTH_top_left_corner 16 00348 #define sdl_std_cursor_HEIGHT_top_left_corner 16 00349 #define sdl_std_cursor_HOT_X_top_left_corner 0 00350 #define sdl_std_cursor_HOT_Y_top_left_corner -14 00351 00352 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,}; 00353 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,}; 00354 #define sdl_std_cursor_WIDTH_spraycan 12 00355 #define sdl_std_cursor_HEIGHT_spraycan 16 00356 #define sdl_std_cursor_HOT_X_spraycan -9 00357 #define sdl_std_cursor_HOT_Y_spraycan -14 00358 00359 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,}; 00360 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,}; 00361 #define sdl_std_cursor_WIDTH_sb_v_double_arrow 9 00362 #define sdl_std_cursor_HEIGHT_sb_v_double_arrow 15 00363 #define sdl_std_cursor_HOT_X_sb_v_double_arrow -3 00364 #define sdl_std_cursor_HOT_Y_sb_v_double_arrow -8 00365 00366 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,}; 00367 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}; 00368 #define sdl_std_cursor_WIDTH_sb_h_double_arrow 15 00369 #define sdl_std_cursor_HEIGHT_sb_h_double_arrow 9 00370 #define sdl_std_cursor_HOT_X_sb_h_double_arrow -7 00371 #define sdl_std_cursor_HOT_Y_sb_h_double_arrow -4 00372 00373 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,}; 00374 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,}; 00375 #define sdl_std_cursor_WIDTH_right_side 16 00376 #define sdl_std_cursor_HEIGHT_right_side 15 00377 #define sdl_std_cursor_HOT_X_right_side -13 00378 #define sdl_std_cursor_HOT_Y_right_side -7 00379 00380 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,}; 00381 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,}; 00382 #define sdl_std_cursor_WIDTH_right_ptr 10 00383 #define sdl_std_cursor_HEIGHT_right_ptr 16 00384 #define sdl_std_cursor_HOT_X_right_ptr -7 00385 #define sdl_std_cursor_HOT_Y_right_ptr -14 00386 00387 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,}; 00388 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,}; 00389 #define sdl_std_cursor_WIDTH_question_arrow 11 00390 #define sdl_std_cursor_HEIGHT_question_arrow 16 00391 #define sdl_std_cursor_HOT_X_question_arrow -4 00392 #define sdl_std_cursor_HOT_Y_question_arrow -8 00393 00394 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,}; 00395 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,}; 00396 #define sdl_std_cursor_WIDTH_pirate 16 00397 #define sdl_std_cursor_HEIGHT_pirate 16 00398 #define sdl_std_cursor_HOT_X_pirate -7 00399 #define sdl_std_cursor_HOT_Y_pirate -4 00400 00401 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,}; 00402 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,}; 00403 #define sdl_std_cursor_WIDTH_left_side 16 00404 #define sdl_std_cursor_HEIGHT_left_side 15 00405 #define sdl_std_cursor_HOT_X_left_side 0 00406 #define sdl_std_cursor_HOT_Y_left_side -7 00407 00408 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,}; 00409 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,}; 00410 #define sdl_std_cursor_WIDTH_left_ptr 10 00411 #define sdl_std_cursor_HEIGHT_left_ptr 16 00412 #define sdl_std_cursor_HOT_X_left_ptr -8 00413 #define sdl_std_cursor_HOT_Y_left_ptr -14 00414 00415 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,}; 00416 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,}; 00417 #define sdl_std_cursor_WIDTH_exchange 16 00418 #define sdl_std_cursor_HEIGHT_exchange 16 00419 #define sdl_std_cursor_HOT_X_exchange -6 00420 #define sdl_std_cursor_HOT_Y_exchange -8 00421 00422 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,}; 00423 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,}; 00424 #define sdl_std_cursor_WIDTH_crosshair 16 00425 #define sdl_std_cursor_HEIGHT_crosshair 16 00426 #define sdl_std_cursor_HOT_X_crosshair -7 00427 #define sdl_std_cursor_HOT_Y_crosshair -8 00428 00429 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,}; 00430 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,}; 00431 #define sdl_std_cursor_WIDTH_bottom_side 15 00432 #define sdl_std_cursor_HEIGHT_bottom_side 16 00433 #define sdl_std_cursor_HOT_X_bottom_side -6 00434 #define sdl_std_cursor_HOT_Y_bottom_side -1 00435 00436 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,}; 00437 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,}; 00438 #define sdl_std_cursor_WIDTH_bottom_right_corner 16 00439 #define sdl_std_cursor_HEIGHT_bottom_right_corner 16 00440 #define sdl_std_cursor_HOT_X_bottom_right_corner -13 00441 #define sdl_std_cursor_HOT_Y_bottom_right_corner -1 00442 00443 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,}; 00444 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,}; 00445 #define sdl_std_cursor_WIDTH_bottom_left_corner 16 00446 #define sdl_std_cursor_HEIGHT_bottom_left_corner 16 00447 #define sdl_std_cursor_HOT_X_bottom_left_corner 0 00448 #define sdl_std_cursor_HOT_Y_bottom_left_corner -1 00449 00450 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,}; 00451 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,}; 00452 #define sdl_std_cursor_WIDTH_arrow 16 00453 #define sdl_std_cursor_HEIGHT_arrow 16 00454 #define sdl_std_cursor_HOT_X_arrow -13 00455 #define sdl_std_cursor_HOT_Y_arrow -14 00456 /* end cursor data */ 00457 00458 00459 static SDL_Cursor *sdl_std_cursor_array[(int)GHOST_kStandardCursorNumCursors]= {0}; 00460 00461 /* utility function mostly a copy of SDL_CreateCursor but allows us to change 00462 * color and supports blenders flipped bits */ 00463 static SDL_Cursor * 00464 sdl_ghost_CreateCursor(const Uint8 *data, 00465 const Uint8 *mask, 00466 int w, 00467 int h, 00468 int hot_x, 00469 int hot_y) 00470 { 00471 SDL_Surface *surface; 00472 SDL_Cursor *cursor; 00473 int x, y; 00474 Uint32 *pixel; 00475 Uint8 datab= 0, maskb= 0; 00476 const Uint32 black= 0xFF000000; 00477 const Uint32 white= 0xFFFFFFFF; 00478 const Uint32 transparent= 0x00000000; 00479 00480 /* Make sure the width is a multiple of 8 */ 00481 w= ((w + 7) & ~7); 00482 00483 /* Create the surface from a bitmap */ 00484 surface= SDL_CreateRGBSurface(0, w, h, 32, 00485 0x00FF0000, 00486 0x0000FF00, 00487 0x000000FF, 00488 0xFF000000); 00489 if (!surface) { 00490 return NULL; 00491 } 00492 for (y= 0; y < h; ++y) { 00493 pixel= (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch); 00494 for (x= 0; x < w; ++x) { 00495 if ((x % 8) == 0) { 00496 datab= *data++; 00497 maskb= *mask++; 00498 00499 /* reverse bit order */ 00500 datab= (datab * 0x0202020202ULL & 0x010884422010ULL) % 1023; 00501 maskb= (maskb * 0x0202020202ULL & 0x010884422010ULL) % 1023; 00502 } 00503 if (maskb & 0x80) { 00504 *pixel++= (datab & 0x80) ? white : black; 00505 } 00506 else { 00507 *pixel++= (datab & 0x80) ? white : transparent; 00508 } 00509 datab <<= 1; 00510 maskb <<= 1; 00511 } 00512 } 00513 00514 cursor= SDL_CreateColorCursor(surface, hot_x, hot_y); 00515 00516 SDL_FreeSurface(surface); 00517 00518 return cursor; 00519 } 00520 00521 /* TODO, this is currently never freed but it wont leak either. */ 00522 static void sdl_cursor_init(void) 00523 { 00524 00525 #define DEF_CURSOR(name, ind) \ 00526 assert(\ 00527 (\ 00528 sdl_std_cursor_array[(int)ind]= \ 00529 sdl_ghost_CreateCursor(sdl_std_cursor_##name, \ 00530 sdl_std_cursor_mask_##name, \ 00531 sdl_std_cursor_WIDTH_##name, \ 00532 sdl_std_cursor_HEIGHT_##name, \ 00533 (sdl_std_cursor_WIDTH_##name + (sdl_std_cursor_HOT_X_##name)) - 1, \ 00534 (sdl_std_cursor_HEIGHT_##name + (sdl_std_cursor_HOT_Y_##name)) - 1) \ 00535 ) != NULL) \ 00536 00537 00538 DEF_CURSOR(left_ptr, GHOST_kStandardCursorDefault); 00539 DEF_CURSOR(right_ptr, GHOST_kStandardCursorRightArrow); 00540 DEF_CURSOR(left_ptr, GHOST_kStandardCursorLeftArrow); 00541 DEF_CURSOR(umbrella, GHOST_kStandardCursorInfo); // TODO, replace this one. 00542 DEF_CURSOR(pirate, GHOST_kStandardCursorDestroy); 00543 DEF_CURSOR(question_arrow, GHOST_kStandardCursorHelp); 00544 DEF_CURSOR(exchange, GHOST_kStandardCursorCycle); 00545 DEF_CURSOR(spraycan, GHOST_kStandardCursorSpray); 00546 DEF_CURSOR(watch, GHOST_kStandardCursorWait); 00547 DEF_CURSOR(xterm, GHOST_kStandardCursorText); 00548 DEF_CURSOR(crosshair, GHOST_kStandardCursorCrosshair); 00549 DEF_CURSOR(sb_v_double_arrow, GHOST_kStandardCursorUpDown); 00550 DEF_CURSOR(sb_h_double_arrow, GHOST_kStandardCursorLeftRight); 00551 DEF_CURSOR(top_side, GHOST_kStandardCursorTopSide); 00552 DEF_CURSOR(bottom_side, GHOST_kStandardCursorBottomSide); 00553 DEF_CURSOR(left_side, GHOST_kStandardCursorLeftSide); 00554 DEF_CURSOR(right_side, GHOST_kStandardCursorRightSide); 00555 DEF_CURSOR(top_left_corner, GHOST_kStandardCursorTopLeftCorner); 00556 DEF_CURSOR(top_right_corner, GHOST_kStandardCursorTopRightCorner); 00557 DEF_CURSOR(bottom_right_corner, GHOST_kStandardCursorBottomRightCorner); 00558 DEF_CURSOR(bottom_left_corner , GHOST_kStandardCursorBottomLeftCorner); 00559 DEF_CURSOR(arrow , GHOST_kStandardCursorCopy); 00560 //DEF_CURSOR(arrow, GHOST_kStandardCursorCustom); 00561 DEF_CURSOR(arrow, GHOST_kStandardCursorPencil); 00562 00563 #undef DEF_CURSOR 00564 00565 } 00566 00567 00568 00569 GHOST_TSuccess 00570 GHOST_WindowSDL::setWindowCursorGrab(GHOST_TGrabCursorMode mode) 00571 { 00572 return GHOST_kSuccess; 00573 } 00574 00575 00576 GHOST_TSuccess 00577 GHOST_WindowSDL::setWindowCursorShape(GHOST_TStandardCursor shape) 00578 { 00579 if(sdl_std_cursor_array[0] == NULL) { 00580 sdl_cursor_init(); 00581 } 00582 00583 SDL_SetCursor(sdl_std_cursor_array[(int)shape]); 00584 return GHOST_kSuccess; 00585 } 00586 00587 00588 GHOST_TSuccess 00589 GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], 00590 GHOST_TUns8 mask[16][2], 00591 int hotX, 00592 int hotY) 00593 { 00594 return setWindowCustomCursorShape((GHOST_TUns8 *)bitmap, 00595 (GHOST_TUns8 *)mask, 00596 16, 16, 00597 hotX, hotY, 00598 0, 1); 00599 } 00600 00601 00602 GHOST_TSuccess 00603 GHOST_WindowSDL::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, 00604 GHOST_TUns8 *mask, 00605 int sizex, int sizey, 00606 int hotX, int hotY, 00607 int fg_color, int bg_color) 00608 { 00609 if(m_sdl_custom_cursor) { 00610 SDL_FreeCursor(m_sdl_custom_cursor); 00611 } 00612 00613 m_sdl_custom_cursor= sdl_ghost_CreateCursor((const Uint8 *)bitmap, 00614 (const Uint8 *)mask, 00615 sizex, sizex, 00616 hotX, hotY); 00617 00618 SDL_SetCursor(m_sdl_custom_cursor); 00619 return GHOST_kSuccess; 00620 } 00621 00622 00623 GHOST_TSuccess 00624 GHOST_WindowSDL::setWindowCursorVisibility(bool visible) 00625 { 00626 SDL_ShowCursor(visible); 00627 return GHOST_kSuccess; 00628 }