Add SDL_CreateSystemCursor for Windows and Linux.

This commit is contained in:
Michael Sartain 2012-11-19 15:11:10 -08:00
parent 7b16b8577c
commit 8f081103e5
6 changed files with 132 additions and 0 deletions

View file

@ -58,6 +58,24 @@ extern "C" {
typedef struct SDL_Cursor SDL_Cursor; /* Implementation dependent */ typedef struct SDL_Cursor SDL_Cursor; /* Implementation dependent */
/**
* \brief Cursor types for SDL_CreateSystemCursor.
*/
typedef enum
{
SDL_SYSTEM_CURSOR_ARROW, // Arrow
SDL_SYSTEM_CURSOR_IBEAM, // I-beam
SDL_SYSTEM_CURSOR_WAIT, // Wait
SDL_SYSTEM_CURSOR_CROSSHAIR, // Crosshair
SDL_SYSTEM_CURSOR_WAITARROW, // Small wait cursor (or Wait if not available)
SDL_SYSTEM_CURSOR_SIZENWSE, // Double arrow pointing northwest and southeast
SDL_SYSTEM_CURSOR_SIZENESW, // Double arrow pointing northeast and southwest
SDL_SYSTEM_CURSOR_SIZEWE, // Double arrow pointing west and east
SDL_SYSTEM_CURSOR_SIZENS, // Double arrow pointing north and south
SDL_SYSTEM_CURSOR_SIZEALL, // Four pointed arrow pointing north, south, east, and west
SDL_SYSTEM_CURSOR_NO, // Slashed circle or crossbones
SDL_SYSTEM_CURSOR_HAND, // Hand
} SDL_SystemCursor;
/* Function prototypes */ /* Function prototypes */
@ -154,6 +172,13 @@ extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface,
int hot_x, int hot_x,
int hot_y); int hot_y);
/**
* \brief Create a system cursor.
*
* \sa SDL_FreeCursor()
*/
extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateSystemCursor(SDL_SystemCursor id);
/** /**
* \brief Set the active cursor. * \brief Set the active cursor.
*/ */

View file

@ -528,6 +528,26 @@ SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
return cursor; return cursor;
} }
SDL_Cursor *
SDL_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_Mouse *mouse = SDL_GetMouse();
SDL_Cursor *cursor;
if (!mouse->CreateSystemCursor) {
SDL_SetError("CreateSystemCursor is not currently supported");
return NULL;
}
cursor = mouse->CreateSystemCursor(id);
if (cursor) {
cursor->next = mouse->cursors;
mouse->cursors = cursor;
}
return cursor;
}
/* SDL_SetCursor(NULL) can be used to force the cursor redraw, /* SDL_SetCursor(NULL) can be used to force the cursor redraw,
if this is desired for any reason. This is used when setting if this is desired for any reason. This is used when setting
the video mode and when the SDL window gains the mouse focus. the video mode and when the SDL window gains the mouse focus.

View file

@ -36,6 +36,9 @@ typedef struct
/* Create a cursor from a surface */ /* Create a cursor from a surface */
SDL_Cursor *(*CreateCursor) (SDL_Surface * surface, int hot_x, int hot_y); SDL_Cursor *(*CreateCursor) (SDL_Surface * surface, int hot_x, int hot_y);
/* Create a system cursor */
SDL_Cursor *(*CreateSystemCursor) (SDL_SystemCursor id);
/* Show the specified cursor, or hide if cursor is NULL */ /* Show the specified cursor, or hide if cursor is NULL */
int (*ShowCursor) (SDL_Cursor * cursor); int (*ShowCursor) (SDL_Cursor * cursor);

View file

@ -102,6 +102,45 @@ WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
return cursor; return cursor;
} }
static SDL_Cursor *
WIN_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_Cursor *cursor;
LPCTSTR name;
switch(id)
{
default:
SDL_assert(0);
return NULL;
case SDL_SYSTEM_CURSOR_ARROW: name = IDC_ARROW; break;
case SDL_SYSTEM_CURSOR_IBEAM: name = IDC_IBEAM; break;
case SDL_SYSTEM_CURSOR_WAIT: name = IDC_WAIT; break;
case SDL_SYSTEM_CURSOR_CROSSHAIR: name = IDC_CROSS; break;
case SDL_SYSTEM_CURSOR_WAITARROW: name = IDC_WAIT; break;
case SDL_SYSTEM_CURSOR_SIZENWSE: name = IDC_SIZENWSE; break;
case SDL_SYSTEM_CURSOR_SIZENESW: name = IDC_SIZENESW; break;
case SDL_SYSTEM_CURSOR_SIZEWE: name = IDC_SIZEWE; break;
case SDL_SYSTEM_CURSOR_SIZENS: name = IDC_SIZENS; break;
case SDL_SYSTEM_CURSOR_SIZEALL: name = IDC_SIZEALL; break;
case SDL_SYSTEM_CURSOR_NO: name = IDC_NO; break;
case SDL_SYSTEM_CURSOR_HAND: name = IDC_HAND; break;
}
cursor = SDL_calloc(1, sizeof(*cursor));
if (cursor) {
HICON hicon;
hicon = LoadCursor(NULL, name);
cursor->driverdata = hicon;
} else {
SDL_OutOfMemory();
}
return cursor;
}
static void static void
WIN_FreeCursor(SDL_Cursor * cursor) WIN_FreeCursor(SDL_Cursor * cursor)
{ {
@ -190,6 +229,7 @@ WIN_InitMouse(_THIS)
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = WIN_CreateCursor; mouse->CreateCursor = WIN_CreateCursor;
mouse->CreateSystemCursor = WIN_CreateSystemCursor;
mouse->ShowCursor = WIN_ShowCursor; mouse->ShowCursor = WIN_ShowCursor;
mouse->FreeCursor = WIN_FreeCursor; mouse->FreeCursor = WIN_FreeCursor;
mouse->WarpMouse = WIN_WarpMouse; mouse->WarpMouse = WIN_WarpMouse;

View file

@ -22,6 +22,7 @@
#if SDL_VIDEO_DRIVER_X11 #if SDL_VIDEO_DRIVER_X11
#include <X11/cursorfont.h>
#include "SDL_assert.h" #include "SDL_assert.h"
#include "SDL_x11video.h" #include "SDL_x11video.h"
#include "SDL_x11mouse.h" #include "SDL_x11mouse.h"
@ -218,6 +219,47 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
return cursor; return cursor;
} }
static SDL_Cursor *
X11_CreateSystemCursor(SDL_SystemCursor id)
{
SDL_Cursor *cursor;
unsigned int shape;
switch(id)
{
default:
SDL_assert(0);
return NULL;
// X Font Cursors reference:
// http://tronche.com/gui/x/xlib/appendix/b/
case SDL_SYSTEM_CURSOR_ARROW: shape = XC_arrow; break;
case SDL_SYSTEM_CURSOR_IBEAM: shape = XC_xterm; break;
case SDL_SYSTEM_CURSOR_WAIT: shape = XC_watch; break;
case SDL_SYSTEM_CURSOR_CROSSHAIR: shape = XC_tcross; break;
case SDL_SYSTEM_CURSOR_WAITARROW: shape = XC_watch; break;
case SDL_SYSTEM_CURSOR_SIZENWSE: shape = XC_fleur; break;
case SDL_SYSTEM_CURSOR_SIZENESW: shape = XC_fleur; break;
case SDL_SYSTEM_CURSOR_SIZEWE: shape = XC_sb_h_double_arrow; break;
case SDL_SYSTEM_CURSOR_SIZENS: shape = XC_sb_v_double_arrow; break;
case SDL_SYSTEM_CURSOR_SIZEALL: shape = XC_fleur; break;
case SDL_SYSTEM_CURSOR_NO: shape = XC_pirate; break;
case SDL_SYSTEM_CURSOR_HAND: shape = XC_hand2; break;
}
cursor = SDL_calloc(1, sizeof(*cursor));
if (cursor) {
Cursor x11_cursor;
x11_cursor = XCreateFontCursor(GetDisplay(), shape);
cursor->driverdata = (void*)x11_cursor;
} else {
SDL_OutOfMemory();
}
return cursor;
}
static void static void
X11_FreeCursor(SDL_Cursor * cursor) X11_FreeCursor(SDL_Cursor * cursor)
{ {
@ -288,6 +330,7 @@ X11_InitMouse(_THIS)
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = X11_CreateCursor; mouse->CreateCursor = X11_CreateCursor;
mouse->CreateSystemCursor = X11_CreateSystemCursor;
mouse->ShowCursor = X11_ShowCursor; mouse->ShowCursor = X11_ShowCursor;
mouse->FreeCursor = X11_FreeCursor; mouse->FreeCursor = X11_FreeCursor;
mouse->WarpMouse = X11_WarpMouse; mouse->WarpMouse = X11_WarpMouse;

View file

@ -36,6 +36,7 @@ SDL_X11_SYM(int,XConvertSelection,(Display* a,Atom b,Atom c,Atom d,Window e,Time
SDL_X11_SYM(Pixmap,XCreateBitmapFromData,(Display *dpy,Drawable d,_Xconst char *data,unsigned int width,unsigned int height),(dpy,d,data,width,height),return) SDL_X11_SYM(Pixmap,XCreateBitmapFromData,(Display *dpy,Drawable d,_Xconst char *data,unsigned int width,unsigned int height),(dpy,d,data,width,height),return)
SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return) SDL_X11_SYM(Colormap,XCreateColormap,(Display* a,Window b,Visual* c,int d),(a,b,c,d),return)
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) 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)
SDL_X11_SYM(Cursor,XCreateFontCursor,(Display* a,unsigned int b),(a,b),return)
SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return) SDL_X11_SYM(GC,XCreateGC,(Display* a,Drawable b,unsigned long c,XGCValues* d),(a,b,c,d),return)
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) 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)
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) 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)