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