Add SDL_CreateSystemCursor for Windows and Linux.
authorMichael Sartain <mikesart@valvesoftware.com>
Mon, 19 Nov 2012 15:11:10 -0800
changeset 667520f3cdea0fd2
parent 6674 45a21e50ba5e
child 6676 4ff261ffaa42
Add SDL_CreateSystemCursor for Windows and Linux.
include/SDL_mouse.h
src/events/SDL_mouse.c
src/events/SDL_mouse_c.h
src/video/windows/SDL_windowsmouse.c
src/video/x11/SDL_x11mouse.c
src/video/x11/SDL_x11sym.h
     1.1 --- a/include/SDL_mouse.h	Fri Nov 16 09:23:18 2012 -0300
     1.2 +++ b/include/SDL_mouse.h	Mon Nov 19 15:11:10 2012 -0800
     1.3 @@ -58,6 +58,24 @@
     1.4  
     1.5  typedef struct SDL_Cursor SDL_Cursor;   /* Implementation dependent */
     1.6  
     1.7 +/**
     1.8 + * \brief Cursor types for SDL_CreateSystemCursor.
     1.9 + */
    1.10 +typedef enum
    1.11 +{
    1.12 +    SDL_SYSTEM_CURSOR_ARROW,     // Arrow
    1.13 +    SDL_SYSTEM_CURSOR_IBEAM,     // I-beam
    1.14 +    SDL_SYSTEM_CURSOR_WAIT,      // Wait
    1.15 +    SDL_SYSTEM_CURSOR_CROSSHAIR, // Crosshair
    1.16 +    SDL_SYSTEM_CURSOR_WAITARROW, // Small wait cursor (or Wait if not available)
    1.17 +    SDL_SYSTEM_CURSOR_SIZENWSE,  // Double arrow pointing northwest and southeast
    1.18 +    SDL_SYSTEM_CURSOR_SIZENESW,  // Double arrow pointing northeast and southwest
    1.19 +    SDL_SYSTEM_CURSOR_SIZEWE,    // Double arrow pointing west and east
    1.20 +    SDL_SYSTEM_CURSOR_SIZENS,    // Double arrow pointing north and south
    1.21 +    SDL_SYSTEM_CURSOR_SIZEALL,   // Four pointed arrow pointing north, south, east, and west
    1.22 +    SDL_SYSTEM_CURSOR_NO,        // Slashed circle or crossbones
    1.23 +    SDL_SYSTEM_CURSOR_HAND,      // Hand
    1.24 +} SDL_SystemCursor;
    1.25  
    1.26  /* Function prototypes */
    1.27  
    1.28 @@ -155,6 +173,13 @@
    1.29                                                            int hot_y);
    1.30  
    1.31  /**
    1.32 + *  \brief Create a system cursor.
    1.33 + *
    1.34 + *  \sa SDL_FreeCursor()
    1.35 + */
    1.36 +extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id);
    1.37 +
    1.38 +/**
    1.39   *  \brief Set the active cursor.
    1.40   */
    1.41  extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor);
     2.1 --- a/src/events/SDL_mouse.c	Fri Nov 16 09:23:18 2012 -0300
     2.2 +++ b/src/events/SDL_mouse.c	Mon Nov 19 15:11:10 2012 -0800
     2.3 @@ -528,6 +528,26 @@
     2.4      return cursor;
     2.5  }
     2.6  
     2.7 +SDL_Cursor *
     2.8 +SDL_CreateSystemCursor(SDL_SystemCursor id)
     2.9 +{
    2.10 +    SDL_Mouse *mouse = SDL_GetMouse();
    2.11 +    SDL_Cursor *cursor;
    2.12 +
    2.13 +    if (!mouse->CreateSystemCursor) {
    2.14 +        SDL_SetError("CreateSystemCursor is not currently supported");
    2.15 +        return NULL;
    2.16 +    }
    2.17 +
    2.18 +	cursor = mouse->CreateSystemCursor(id);
    2.19 +    if (cursor) {
    2.20 +        cursor->next = mouse->cursors;
    2.21 +        mouse->cursors = cursor;
    2.22 +    }
    2.23 +
    2.24 +	return cursor;
    2.25 +}
    2.26 +
    2.27  /* SDL_SetCursor(NULL) can be used to force the cursor redraw,
    2.28     if this is desired for any reason.  This is used when setting
    2.29     the video mode and when the SDL window gains the mouse focus.
     3.1 --- a/src/events/SDL_mouse_c.h	Fri Nov 16 09:23:18 2012 -0300
     3.2 +++ b/src/events/SDL_mouse_c.h	Mon Nov 19 15:11:10 2012 -0800
     3.3 @@ -36,6 +36,9 @@
     3.4      /* Create a cursor from a surface */
     3.5      SDL_Cursor *(*CreateCursor) (SDL_Surface * surface, int hot_x, int hot_y);
     3.6  
     3.7 +    /* Create a system cursor */
     3.8 +	SDL_Cursor *(*CreateSystemCursor) (SDL_SystemCursor id);
     3.9 +
    3.10      /* Show the specified cursor, or hide if cursor is NULL */
    3.11      int (*ShowCursor) (SDL_Cursor * cursor);
    3.12  
     4.1 --- a/src/video/windows/SDL_windowsmouse.c	Fri Nov 16 09:23:18 2012 -0300
     4.2 +++ b/src/video/windows/SDL_windowsmouse.c	Mon Nov 19 15:11:10 2012 -0800
     4.3 @@ -102,6 +102,45 @@
     4.4      return cursor;
     4.5  }
     4.6  
     4.7 +static SDL_Cursor *
     4.8 +WIN_CreateSystemCursor(SDL_SystemCursor id)
     4.9 +{
    4.10 +    SDL_Cursor *cursor;
    4.11 +    LPCTSTR name;
    4.12 +
    4.13 +    switch(id)
    4.14 +    {
    4.15 +    default:
    4.16 +        SDL_assert(0);
    4.17 +        return NULL;
    4.18 +    case SDL_SYSTEM_CURSOR_ARROW:     name = IDC_ARROW; break;
    4.19 +    case SDL_SYSTEM_CURSOR_IBEAM:     name = IDC_IBEAM; break;
    4.20 +    case SDL_SYSTEM_CURSOR_WAIT:      name = IDC_WAIT; break;
    4.21 +    case SDL_SYSTEM_CURSOR_CROSSHAIR: name = IDC_CROSS; break;
    4.22 +    case SDL_SYSTEM_CURSOR_WAITARROW: name = IDC_WAIT; break;
    4.23 +    case SDL_SYSTEM_CURSOR_SIZENWSE:  name = IDC_SIZENWSE; break;
    4.24 +    case SDL_SYSTEM_CURSOR_SIZENESW:  name = IDC_SIZENESW; break;
    4.25 +    case SDL_SYSTEM_CURSOR_SIZEWE:    name = IDC_SIZEWE; break;
    4.26 +    case SDL_SYSTEM_CURSOR_SIZENS:    name = IDC_SIZENS; break;
    4.27 +    case SDL_SYSTEM_CURSOR_SIZEALL:   name = IDC_SIZEALL; break;
    4.28 +    case SDL_SYSTEM_CURSOR_NO:        name = IDC_NO; break;
    4.29 +    case SDL_SYSTEM_CURSOR_HAND:      name = IDC_HAND; break;
    4.30 +    }
    4.31 +
    4.32 +    cursor = SDL_calloc(1, sizeof(*cursor));
    4.33 +    if (cursor) {
    4.34 +        HICON hicon;
    4.35 +
    4.36 +        hicon = LoadCursor(NULL, name);
    4.37 +
    4.38 +        cursor->driverdata = hicon;
    4.39 +    } else {
    4.40 +        SDL_OutOfMemory();
    4.41 +    }
    4.42 +
    4.43 +    return cursor;
    4.44 +}
    4.45 +
    4.46  static void
    4.47  WIN_FreeCursor(SDL_Cursor * cursor)
    4.48  {
    4.49 @@ -190,6 +229,7 @@
    4.50      SDL_Mouse *mouse = SDL_GetMouse();
    4.51  
    4.52      mouse->CreateCursor = WIN_CreateCursor;
    4.53 +	mouse->CreateSystemCursor = WIN_CreateSystemCursor;
    4.54      mouse->ShowCursor = WIN_ShowCursor;
    4.55      mouse->FreeCursor = WIN_FreeCursor;
    4.56      mouse->WarpMouse = WIN_WarpMouse;
     5.1 --- a/src/video/x11/SDL_x11mouse.c	Fri Nov 16 09:23:18 2012 -0300
     5.2 +++ b/src/video/x11/SDL_x11mouse.c	Mon Nov 19 15:11:10 2012 -0800
     5.3 @@ -22,6 +22,7 @@
     5.4  
     5.5  #if SDL_VIDEO_DRIVER_X11
     5.6  
     5.7 +#include <X11/cursorfont.h>
     5.8  #include "SDL_assert.h"
     5.9  #include "SDL_x11video.h"
    5.10  #include "SDL_x11mouse.h"
    5.11 @@ -218,6 +219,47 @@
    5.12      return cursor;
    5.13  }
    5.14  
    5.15 +static SDL_Cursor *
    5.16 +X11_CreateSystemCursor(SDL_SystemCursor id)
    5.17 +{
    5.18 +    SDL_Cursor *cursor;
    5.19 +    unsigned int shape;
    5.20 +
    5.21 +    switch(id)
    5.22 +    {
    5.23 +    default:
    5.24 +        SDL_assert(0);
    5.25 +        return NULL;
    5.26 +	// X Font Cursors reference:
    5.27 +	//   http://tronche.com/gui/x/xlib/appendix/b/
    5.28 +    case SDL_SYSTEM_CURSOR_ARROW:     shape = XC_arrow; break;
    5.29 +    case SDL_SYSTEM_CURSOR_IBEAM:     shape = XC_xterm; break;
    5.30 +    case SDL_SYSTEM_CURSOR_WAIT:      shape = XC_watch; break;
    5.31 +    case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break;
    5.32 +    case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break;
    5.33 +    case SDL_SYSTEM_CURSOR_SIZENWSE:  shape = XC_fleur; break;
    5.34 +    case SDL_SYSTEM_CURSOR_SIZENESW:  shape = XC_fleur; break;
    5.35 +    case SDL_SYSTEM_CURSOR_SIZEWE:    shape = XC_sb_h_double_arrow; break;
    5.36 +    case SDL_SYSTEM_CURSOR_SIZENS:    shape = XC_sb_v_double_arrow; break;
    5.37 +    case SDL_SYSTEM_CURSOR_SIZEALL:   shape = XC_fleur; break;
    5.38 +    case SDL_SYSTEM_CURSOR_NO:        shape = XC_pirate; break;
    5.39 +    case SDL_SYSTEM_CURSOR_HAND:      shape = XC_hand2; break;
    5.40 +    }
    5.41 +
    5.42 +    cursor = SDL_calloc(1, sizeof(*cursor));
    5.43 +    if (cursor) {
    5.44 +        Cursor x11_cursor;
    5.45 +
    5.46 +        x11_cursor = XCreateFontCursor(GetDisplay(), shape);
    5.47 +
    5.48 +        cursor->driverdata = (void*)x11_cursor;
    5.49 +    } else {
    5.50 +        SDL_OutOfMemory();
    5.51 +    }
    5.52 +
    5.53 +    return cursor;
    5.54 +}
    5.55 +
    5.56  static void
    5.57  X11_FreeCursor(SDL_Cursor * cursor)
    5.58  {
    5.59 @@ -288,6 +330,7 @@
    5.60      SDL_Mouse *mouse = SDL_GetMouse();
    5.61  
    5.62      mouse->CreateCursor = X11_CreateCursor;
    5.63 +	mouse->CreateSystemCursor = X11_CreateSystemCursor;
    5.64      mouse->ShowCursor = X11_ShowCursor;
    5.65      mouse->FreeCursor = X11_FreeCursor;
    5.66      mouse->WarpMouse = X11_WarpMouse;
     6.1 --- a/src/video/x11/SDL_x11sym.h	Fri Nov 16 09:23:18 2012 -0300
     6.2 +++ b/src/video/x11/SDL_x11sym.h	Mon Nov 19 15:11:10 2012 -0800
     6.3 @@ -36,6 +36,7 @@
     6.4  SDL_X11_SYM(Pixmap,XCreateBitmapFromData,(Display *dpy,Drawable d,_Xconst char *data,unsigned int width,unsigned int height),(dpy,d,data,width,height),return)
     6.5  SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return)
     6.6  SDL_X11_SYM(Cursor,XCreatePixmapCursor,(Display* a,Pixmap b,Pixmap c,XColor* d,XColor* e,unsigned int f,unsigned int g),(a,b,c,d,e,f,g),return)
     6.7 +SDL_X11_SYM(Cursor,XCreateFontCursor,(Display* a,unsigned int b),(a,b),return)
     6.8  SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return)
     6.9  SDL_X11_SYM(XImage*,XCreateImage,(Display* a,Visual* b,unsigned int c,int d,int e,char* f,unsigned int g,unsigned int h,int i,int j),(a,b,c,d,e,f,g,h,i,j),return)
    6.10  SDL_X11_SYM(Window,XCreateWindow,(Display* a,Window b,int c,int d,unsigned int e,unsigned int f,unsigned int g,int h,unsigned int i,Visual* j,unsigned long k,XSetWindowAttributes* l),(a,b,c,d,e,f,g,h,i,j,k,l),return)