Blender V2.61 - r43446

GHOST_WindowSDL.cpp

Go to the documentation of this file.
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 }