Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Add SDL_CreateSystemCursor for Windows and Linux.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Sartain committed Nov 19, 2012
1 parent d36de55 commit 62d8685
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 0 deletions.
25 changes: 25 additions & 0 deletions include/SDL_mouse.h
Expand Up @@ -58,6 +58,24 @@ extern "C" {

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 */

Expand Down Expand Up @@ -154,6 +172,13 @@ extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface,
int hot_x,
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.
*/
Expand Down
20 changes: 20 additions & 0 deletions src/events/SDL_mouse.c
Expand Up @@ -528,6 +528,26 @@ SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
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,
if this is desired for any reason. This is used when setting
the video mode and when the SDL window gains the mouse focus.
Expand Down
3 changes: 3 additions & 0 deletions src/events/SDL_mouse_c.h
Expand Up @@ -36,6 +36,9 @@ typedef struct
/* Create a cursor from a surface */
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 */
int (*ShowCursor) (SDL_Cursor * cursor);

Expand Down
40 changes: 40 additions & 0 deletions src/video/windows/SDL_windowsmouse.c
Expand Up @@ -102,6 +102,45 @@ WIN_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
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
WIN_FreeCursor(SDL_Cursor * cursor)
{
Expand Down Expand Up @@ -190,6 +229,7 @@ WIN_InitMouse(_THIS)
SDL_Mouse *mouse = SDL_GetMouse();

mouse->CreateCursor = WIN_CreateCursor;
mouse->CreateSystemCursor = WIN_CreateSystemCursor;
mouse->ShowCursor = WIN_ShowCursor;
mouse->FreeCursor = WIN_FreeCursor;
mouse->WarpMouse = WIN_WarpMouse;
Expand Down
43 changes: 43 additions & 0 deletions src/video/x11/SDL_x11mouse.c
Expand Up @@ -22,6 +22,7 @@

#if SDL_VIDEO_DRIVER_X11

#include <X11/cursorfont.h>
#include "SDL_assert.h"
#include "SDL_x11video.h"
#include "SDL_x11mouse.h"
Expand Down Expand Up @@ -218,6 +219,47 @@ X11_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
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
X11_FreeCursor(SDL_Cursor * cursor)
{
Expand Down Expand Up @@ -288,6 +330,7 @@ X11_InitMouse(_THIS)
SDL_Mouse *mouse = SDL_GetMouse();

mouse->CreateCursor = X11_CreateCursor;
mouse->CreateSystemCursor = X11_CreateSystemCursor;
mouse->ShowCursor = X11_ShowCursor;
mouse->FreeCursor = X11_FreeCursor;
mouse->WarpMouse = X11_WarpMouse;
Expand Down
1 change: 1 addition & 0 deletions src/video/x11/SDL_x11sym.h
Expand Up @@ -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(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,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(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)
Expand Down

0 comments on commit 62d8685

Please sign in to comment.