summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Lantinga <slouken@libsdl.org>2006-06-24 17:31:46 +0000
committerSam Lantinga <slouken@libsdl.org>2006-06-24 17:31:46 +0000
commitbfa7ddfba02e698790be71993878c26ee0e669ae (patch)
tree9dd39ba537675bfe289cbd4abbae9534a120da44
parent65d23f427036cad57475a5b657ee808442e69337 (diff)
downloadsdl-bfa7ddfba02e698790be71993878c26ee0e669ae.tar.gz
Merged fix for bug #240 from SDL 1.2
-rw-r--r--src/video/quartz/SDL_QuartzWM.m215
-rw-r--r--test/Makefile.in5
-rw-r--r--test/testcursor.c223
3 files changed, 347 insertions, 96 deletions
diff --git a/src/video/quartz/SDL_QuartzWM.m b/src/video/quartz/SDL_QuartzWM.m
index e3ca95034..edda9428f 100644
--- a/src/video/quartz/SDL_QuartzWM.m
+++ b/src/video/quartz/SDL_QuartzWM.m
@@ -26,57 +26,82 @@
struct WMcursor
{
- Cursor curs;
+ NSCursor *nscursor;
};
void
-QZ_FreeWMCursor (_THIS, WMcursor * cursor)
+QZ_FreeWMCursor(_THIS, WMcursor * cursor)
{
- if (cursor != NULL)
- free (cursor);
+ if (cursor != NULL) {
+ [cursor->nscursor release];
+ free(cursor);
+ }
}
-/* Use the Carbon cursor routines for now */
WMcursor *
-QZ_CreateWMCursor (_THIS, Uint8 * data, Uint8 * mask,
- int w, int h, int hot_x, int hot_y)
+QZ_CreateWMCursor(_THIS, Uint8 * data, Uint8 * mask,
+ int w, int h, int hot_x, int hot_y)
{
WMcursor *cursor;
- int row, bytes;
-
- /* Allocate the cursor memory */
- cursor = (WMcursor *) SDL_malloc (sizeof (WMcursor));
- if (cursor == NULL) {
- SDL_OutOfMemory ();
- return (NULL);
- }
- SDL_memset (cursor, 0, sizeof (*cursor));
+ NSBitmapImageRep *imgrep;
+ NSImage *img;
+ unsigned char *planes[5];
+ int i;
+ NSAutoreleasePool *pool;
- if (w > 16)
- w = 16;
+ pool =[[NSAutoreleasePool alloc] init];
- if (h > 16)
- h = 16;
+ /* Allocate the cursor memory */
+ cursor = (WMcursor *) SDL_malloc(sizeof(WMcursor));
+ if (cursor == NULL)
+ goto outOfMemory;
- bytes = (w + 7) / 8;
+ /* create the image representation and get the pointers to its storage */
+ imgrep =[[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL pixelsWide: w pixelsHigh: h bitsPerSample: 1 samplesPerPixel: 2 hasAlpha: YES isPlanar: YES colorSpaceName: NSDeviceBlackColorSpace bytesPerRow: (w + 7) / 8 bitsPerPixel:0] autorelease];
+ if (imgrep == nil)
+ goto outOfMemory;
+ [imgrep getBitmapDataPlanes:planes];
- for (row = 0; row < h; ++row) {
- SDL_memcpy (&cursor->curs.data[row], data, bytes);
- data += bytes;
+ /* copy data and mask, extending the mask to all black pixels because the inversion effect doesn't work with Cocoa's alpha-blended cursors */
+ for (i = 0; i < (w + 7) / 8 * h; i++) {
+ planes[0][i] = data[i];
+ planes[1][i] = mask[i] | data[i];
}
- for (row = 0; row < h; ++row) {
- SDL_memcpy (&cursor->curs.mask[row], mask, bytes);
- mask += bytes;
+
+ /* create image and cursor */
+ img =[[[NSImage alloc] initWithSize:NSMakeSize(w, h)] autorelease];
+ if (img == nil)
+ goto outOfMemory;
+ [img addRepresentation:imgrep];
+ if (system_version < 0x1030) { /* on 10.2, cursors must be 16*16 */
+ if (w > 16 || h > 16) { /* too big: scale it down */
+ [img setScalesWhenResized:YES];
+ hot_x = hot_x * 16 / w;
+ hot_y = hot_y * 16 / h;
+ } else { /* too small (or just right): extend it (from the bottom left corner, so hot_y must be adjusted) */
+ hot_y += 16 - h;
+ }
+ [img setSize:NSMakeSize(16, 16)];
}
- cursor->curs.hotSpot.h = hot_x;
- cursor->curs.hotSpot.v = hot_y;
+ cursor->nscursor =[[NSCursor alloc] initWithImage: img hotSpot:NSMakePoint(hot_x,
+ hot_y)];
+ if (cursor->nscursor == nil)
+ goto outOfMemory;
+ [pool release];
return (cursor);
+
+ outOfMemory:
+ [pool release];
+ if (cursor != NULL)
+ SDL_free(cursor);
+ SDL_OutOfMemory();
+ return (NULL);
}
void
-QZ_ShowMouse (_THIS)
+QZ_ShowMouse(_THIS)
{
if (!cursor_visible) {
[NSCursor unhide];
@@ -85,42 +110,42 @@ QZ_ShowMouse (_THIS)
}
void
-QZ_HideMouse (_THIS)
+QZ_HideMouse(_THIS)
{
- if ((SDL_GetAppState () & SDL_APPMOUSEFOCUS) && cursor_visible) {
+ if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && cursor_visible) {
[NSCursor hide];
cursor_visible = NO;
}
}
BOOL
-QZ_IsMouseInWindow (_THIS)
+QZ_IsMouseInWindow(_THIS)
{
if (qz_window == nil)
return YES; /*fullscreen */
else {
NSPoint p =[qz_window mouseLocationOutsideOfEventStream];
p.y -= 1.0f; /* Apparently y goes from 1 to h, not from 0 to h-1 (i.e. the "location of the mouse" seems to be defined as "the location of the top left corner of the mouse pointer's hot pixel" */
- return NSPointInRect (p,[window_view frame]);
+ return NSPointInRect(p,[window_view frame]);
}
}
int
-QZ_ShowWMCursor (_THIS, WMcursor * cursor)
+QZ_ShowWMCursor(_THIS, WMcursor * cursor)
{
if (cursor == NULL) {
if (cursor_should_be_visible) {
- QZ_HideMouse (this);
+ QZ_HideMouse(this);
cursor_should_be_visible = NO;
- QZ_ChangeGrabState (this, QZ_HIDECURSOR);
+ QZ_ChangeGrabState(this, QZ_HIDECURSOR);
}
} else {
- SetCursor (&cursor->curs);
+ [cursor->nscursor set];
if (!cursor_should_be_visible) {
- QZ_ShowMouse (this);
+ QZ_ShowMouse(this);
cursor_should_be_visible = YES;
- QZ_ChangeGrabState (this, QZ_SHOWCURSOR);
+ QZ_ChangeGrabState(this, QZ_SHOWCURSOR);
}
}
@@ -137,7 +162,7 @@ QZ_ShowWMCursor (_THIS, WMcursor * cursor)
/* Convert Cocoa screen coordinate to Cocoa window coordinate */
void
-QZ_PrivateGlobalToLocal (_THIS, NSPoint * p)
+QZ_PrivateGlobalToLocal(_THIS, NSPoint * p)
{
*p =[qz_window convertScreenToBase:*p];
@@ -146,7 +171,7 @@ QZ_PrivateGlobalToLocal (_THIS, NSPoint * p)
/* Convert Cocoa window coordinate to Cocoa screen coordinate */
void
-QZ_PrivateLocalToGlobal (_THIS, NSPoint * p)
+QZ_PrivateLocalToGlobal(_THIS, NSPoint * p)
{
*p =[qz_window convertBaseToScreen:*p];
@@ -154,18 +179,18 @@ QZ_PrivateLocalToGlobal (_THIS, NSPoint * p)
/* Convert SDL coordinate to Cocoa coordinate */
void
-QZ_PrivateSDLToCocoa (_THIS, NSPoint * p)
+QZ_PrivateSDLToCocoa(_THIS, NSPoint * p)
{
- if (CGDisplayIsCaptured (display_id)) { /* capture signals fullscreen */
+ if (CGDisplayIsCaptured(display_id)) { /* capture signals fullscreen */
- p->y = CGDisplayPixelsHigh (display_id) - p->y;
+ p->y = CGDisplayPixelsHigh(display_id) - p->y;
} else {
*p =[window_view convertPoint: *p toView:nil];
/* We need a workaround in OpenGL mode */
- if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
+ if (SDL_VideoSurface->flags & SDL_OPENGL) {
p->y =[window_view frame].size.height - p->y;
}
}
@@ -173,19 +198,19 @@ QZ_PrivateSDLToCocoa (_THIS, NSPoint * p)
/* Convert Cocoa coordinate to SDL coordinate */
void
-QZ_PrivateCocoaToSDL (_THIS, NSPoint * p)
+QZ_PrivateCocoaToSDL(_THIS, NSPoint * p)
{
- if (CGDisplayIsCaptured (display_id)) { /* capture signals fullscreen */
+ if (CGDisplayIsCaptured(display_id)) { /* capture signals fullscreen */
- p->y = CGDisplayPixelsHigh (display_id) - p->y;
+ p->y = CGDisplayPixelsHigh(display_id) - p->y;
} else {
*p =[window_view convertPoint: *p fromView:nil];
/* We need a workaround in OpenGL mode */
if (SDL_VideoSurface != NULL
- && (SDL_VideoSurface->flags & SDL_INTERNALOPENGL)) {
+ && (SDL_VideoSurface->flags & SDL_OPENGL)) {
p->y =[window_view frame].size.height - p->y;
}
}
@@ -193,19 +218,19 @@ QZ_PrivateCocoaToSDL (_THIS, NSPoint * p)
/* Convert SDL coordinate to window server (CoreGraphics) coordinate */
CGPoint
-QZ_PrivateSDLToCG (_THIS, NSPoint * p)
+QZ_PrivateSDLToCG(_THIS, NSPoint * p)
{
CGPoint cgp;
- if (!CGDisplayIsCaptured (display_id)) { /* not captured => not fullscreen => local coord */
+ if (!CGDisplayIsCaptured(display_id)) { /* not captured => not fullscreen => local coord */
int height;
- QZ_PrivateSDLToCocoa (this, p);
- QZ_PrivateLocalToGlobal (this, p);
+ QZ_PrivateSDLToCocoa(this, p);
+ QZ_PrivateLocalToGlobal(this, p);
- height = CGDisplayPixelsHigh (display_id);
+ height = CGDisplayPixelsHigh(display_id);
p->y = height - p->y;
}
@@ -218,40 +243,40 @@ QZ_PrivateSDLToCG (_THIS, NSPoint * p)
#if 0 /* Dead code */
/* Convert window server (CoreGraphics) coordinate to SDL coordinate */
void
-QZ_PrivateCGToSDL (_THIS, NSPoint * p)
+QZ_PrivateCGToSDL(_THIS, NSPoint * p)
{
- if (!CGDisplayIsCaptured (display_id)) { /* not captured => not fullscreen => local coord */
+ if (!CGDisplayIsCaptured(display_id)) { /* not captured => not fullscreen => local coord */
int height;
/* Convert CG Global to Cocoa Global */
- height = CGDisplayPixelsHigh (display_id);
+ height = CGDisplayPixelsHigh(display_id);
p->y = height - p->y;
- QZ_PrivateGlobalToLocal (this, p);
- QZ_PrivateCocoaToSDL (this, p);
+ QZ_PrivateGlobalToLocal(this, p);
+ QZ_PrivateCocoaToSDL(this, p);
}
}
#endif /* Dead code */
void
-QZ_PrivateWarpCursor (_THIS, int x, int y)
+QZ_PrivateWarpCursor(_THIS, int x, int y)
{
NSPoint p;
CGPoint cgp;
- p = NSMakePoint (x, y);
- cgp = QZ_PrivateSDLToCG (this, &p);
+ p = NSMakePoint(x, y);
+ cgp = QZ_PrivateSDLToCG(this, &p);
/* this is the magic call that fixes cursor "freezing" after warp */
- CGSetLocalEventsSuppressionInterval (0.0);
- CGWarpMouseCursorPosition (cgp);
+ CGSetLocalEventsSuppressionInterval(0.0);
+ CGWarpMouseCursorPosition(cgp);
}
void
-QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y)
+QZ_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
{
/* Only allow warping when in foreground */
@@ -260,23 +285,23 @@ QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y)
/* Do the actual warp */
if (grab_state != QZ_INVISIBLE_GRAB)
- QZ_PrivateWarpCursor (this, x, y);
+ QZ_PrivateWarpCursor(this, x, y);
/* Generate the mouse moved event */
- SDL_PrivateMouseMotion (0, 0, x, y);
+ SDL_PrivateMouseMotion(0, 0, x, y);
}
void
-QZ_MoveWMCursor (_THIS, int x, int y)
+QZ_MoveWMCursor(_THIS, int x, int y)
{
}
void
-QZ_CheckMouseMode (_THIS)
+QZ_CheckMouseMode(_THIS)
{
}
void
-QZ_SetCaption (_THIS, const char *title, const char *icon)
+QZ_SetCaption(_THIS, const char *title, const char *icon)
{
if (qz_window != nil) {
@@ -295,7 +320,7 @@ QZ_SetCaption (_THIS, const char *title, const char *icon)
}
void
-QZ_SetIcon (_THIS, SDL_Surface * icon, Uint8 * mask)
+QZ_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask)
{
NSBitmapImageRep *imgrep;
NSImage *img;
@@ -312,7 +337,7 @@ QZ_SetIcon (_THIS, SDL_Surface * icon, Uint8 * mask)
if (imgrep == nil)
goto freePool;
pixels =[imgrep bitmapData];
- SDL_memset (pixels, 0, 4 * icon->w * icon->h); /* make the background, which will survive in colorkeyed areas, completely transparent */
+ SDL_memset(pixels, 0, 4 * icon->w * icon->h); /* make the background, which will survive in colorkeyed areas, completely transparent */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define BYTEORDER_DEPENDENT_RGBA_MASKS 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
@@ -320,20 +345,20 @@ QZ_SetIcon (_THIS, SDL_Surface * icon, Uint8 * mask)
#define BYTEORDER_DEPENDENT_RGBA_MASKS 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#endif
mergedSurface =
- SDL_CreateRGBSurfaceFrom (pixels, icon->w, icon->h, 32, 4 * icon->w,
- BYTEORDER_DEPENDENT_RGBA_MASKS);
+ SDL_CreateRGBSurfaceFrom(pixels, icon->w, icon->h, 32, 4 * icon->w,
+ BYTEORDER_DEPENDENT_RGBA_MASKS);
if (mergedSurface == NULL)
goto freePool;
/* blit, with temporarily cleared SRCALPHA flag because we want to copy, not alpha-blend */
iconSrcAlpha = ((icon->flags & SDL_SRCALPHA) != 0);
iconAlphaValue = icon->format->alpha;
- SDL_SetAlpha (icon, 0, 255);
- SDL_BlitSurface (icon, NULL, mergedSurface, NULL);
+ SDL_SetAlpha(icon, 0, 255);
+ SDL_BlitSurface(icon, NULL, mergedSurface, NULL);
if (iconSrcAlpha)
- SDL_SetAlpha (icon, SDL_SRCALPHA, iconAlphaValue);
+ SDL_SetAlpha(icon, SDL_SRCALPHA, iconAlphaValue);
- SDL_FreeSurface (mergedSurface);
+ SDL_FreeSurface(mergedSurface);
/* apply mask, source alpha, and premultiply color values by alpha */
maskPitch = (icon->w + 7) / 8;
@@ -361,8 +386,8 @@ QZ_SetIcon (_THIS, SDL_Surface * icon, Uint8 * mask)
}
}
- img =[[[NSImage alloc] initWithSize:NSMakeSize (icon->w,
- icon->h)] autorelease];
+ img =[[[NSImage alloc] initWithSize:NSMakeSize(icon->w,
+ icon->h)] autorelease];
if (img == nil)
goto freePool;
[img addRepresentation:imgrep];
@@ -373,14 +398,14 @@ QZ_SetIcon (_THIS, SDL_Surface * icon, Uint8 * mask)
}
int
-QZ_IconifyWindow (_THIS)
+QZ_IconifyWindow(_THIS)
{
if (![qz_window isMiniaturized]) {
[qz_window miniaturize:nil];
return 1;
} else {
- SDL_SetError ("window already iconified");
+ SDL_SetError("window already iconified");
return 0;
}
}
@@ -392,7 +417,7 @@ int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) {
}*/
void
-QZ_ChangeGrabState (_THIS, int action)
+QZ_ChangeGrabState(_THIS, int action)
{
/*
@@ -412,7 +437,7 @@ QZ_ChangeGrabState (_THIS, int action)
else if (action == QZ_HIDECURSOR)
grab_state = QZ_INVISIBLE_GRAB;
} else {
- assert (grab_state == QZ_INVISIBLE_GRAB);
+ assert(grab_state == QZ_INVISIBLE_GRAB);
if (action == QZ_DISABLE_GRAB)
grab_state = QZ_UNGRABBED;
@@ -423,28 +448,28 @@ QZ_ChangeGrabState (_THIS, int action)
/* now apply the new state */
if (grab_state == QZ_UNGRABBED) {
- CGAssociateMouseAndMouseCursorPosition (1);
+ CGAssociateMouseAndMouseCursorPosition(1);
} else if (grab_state == QZ_VISIBLE_GRAB) {
- CGAssociateMouseAndMouseCursorPosition (1);
+ CGAssociateMouseAndMouseCursorPosition(1);
} else {
- assert (grab_state == QZ_INVISIBLE_GRAB);
+ assert(grab_state == QZ_INVISIBLE_GRAB);
- QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2,
- SDL_VideoSurface->h / 2);
- CGAssociateMouseAndMouseCursorPosition (0);
+ QZ_PrivateWarpCursor(this, SDL_VideoSurface->w / 2,
+ SDL_VideoSurface->h / 2);
+ CGAssociateMouseAndMouseCursorPosition(0);
}
}
SDL_GrabMode
-QZ_GrabInput (_THIS, SDL_GrabMode grab_mode)
+QZ_GrabInput(_THIS, SDL_GrabMode grab_mode)
{
int doGrab = grab_mode & SDL_GRAB_ON;
/*int fullscreen = grab_mode & SDL_GRAB_FULLSCREEN; */
if (this->screen == NULL) {
- SDL_SetError ("QZ_GrabInput: screen is NULL");
+ SDL_SetError("QZ_GrabInput: screen is NULL");
return SDL_GRAB_OFF;
}
@@ -456,9 +481,9 @@ QZ_GrabInput (_THIS, SDL_GrabMode grab_mode)
if (grab_mode != SDL_GRAB_QUERY) {
if (doGrab)
- QZ_ChangeGrabState (this, QZ_ENABLE_GRAB);
+ QZ_ChangeGrabState(this, QZ_ENABLE_GRAB);
else
- QZ_ChangeGrabState (this, QZ_DISABLE_GRAB);
+ QZ_ChangeGrabState(this, QZ_DISABLE_GRAB);
current_grab_mode = doGrab ? SDL_GRAB_ON : SDL_GRAB_OFF;
}
diff --git a/test/Makefile.in b/test/Makefile.in
index bb1699434..a7ac4f1e0 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -7,7 +7,7 @@ EXE = @EXE@
CFLAGS = @CFLAGS@
LIBS = @LIBS@
-TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE)
+TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE)
all: $(TARGETS)
@@ -32,6 +32,9 @@ testblitspeed$(EXE): $(srcdir)/testblitspeed.c
testcdrom$(EXE): $(srcdir)/testcdrom.c
$(CC) -o $@ $? $(CFLAGS) $(LIBS)
+testcursor$(EXE): $(srcdir)/testcursor.c
+ $(CC) -o $@ $? $(CFLAGS) $(LIBS)
+
testdyngl$(EXE): $(srcdir)/testdyngl.c
$(CC) -o $@ $? $(CFLAGS) $(LIBS)
diff --git a/test/testcursor.c b/test/testcursor.c
new file mode 100644
index 000000000..2c2129665
--- /dev/null
+++ b/test/testcursor.c
@@ -0,0 +1,223 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "SDL.h"
+
+/* This is an example 16x16 cursor
+ top left : black
+ top right : inverted color or black
+ bottom left: white
+ bottom right: transparent
+ (swap left and right for different endianness)
+*/
+
+Uint16 cursor_data[16] = {
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+
+ 0xffff,
+ 0xffff,
+ 0xffff,
+ 0xffff,
+
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000,
+
+ 0x0000,
+ 0x0000,
+ 0x0000,
+ 0x0000
+};
+
+Uint16 cursor_mask[16] = {
+ 0xff00,
+ 0xff00,
+ 0xff00,
+ 0xff00,
+
+ 0xff00,
+ 0xff00,
+ 0xff00,
+ 0xff00,
+
+ 0xff00,
+ 0xff00,
+ 0xff00,
+ 0xff00,
+
+ 0xff00,
+ 0xff00,
+ 0xff00,
+ 0xff00
+};
+
+/* another test cursor: smaller than 16x16, and with an odd height */
+
+Uint8 small_cursor_data[11] =
+ { 0x00, 0x18, 0x08, 0x38, 0x44, 0x54, 0x44, 0x38, 0x20, 0x20, 0x00 };
+Uint8 small_cursor_mask[11] =
+ { 0x3C, 0x3C, 0x3C, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0x78, 0x70, 0x70 };
+
+/* XPM */
+static const char *arrow[] = {
+ /* width height num_colors chars_per_pixel */
+ " 32 32 3 1",
+ /* colors */
+ "X c #000000",
+ ". c #ffffff",
+ " c None",
+ /* pixels */
+ "X ",
+ "XX ",
+ "X.X ",
+ "X..X ",
+ "X...X ",
+ "X....X ",
+ "X.....X ",
+ "X......X ",
+ "X.......X ",
+ "X........X ",
+ "X.....XXXXX ",
+ "X..X..X ",
+ "X.X X..X ",
+ "XX X..X ",
+ "X X..X ",
+ " X..X ",
+ " X..X ",
+ " X..X ",
+ " XX ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "0,0"
+};
+
+static SDL_Cursor *
+create_arrow_cursor()
+{
+ int i, row, col;
+ Uint8 data[4 * 32];
+ Uint8 mask[4 * 32];
+ int hot_x, hot_y;
+
+ i = -1;
+ for (row = 0; row < 32; ++row) {
+ for (col = 0; col < 32; ++col) {
+ if (col % 8) {
+ data[i] <<= 1;
+ mask[i] <<= 1;
+ } else {
+ ++i;
+ data[i] = mask[i] = 0;
+ }
+ switch (arrow[4 + row][col]) {
+ case 'X':
+ data[i] |= 0x01;
+ mask[i] |= 0x01;
+ break;
+ case '.':
+ mask[i] |= 0x01;
+ break;
+ case ' ':
+ break;
+ }
+ }
+ }
+ sscanf(arrow[4 + row], "%d,%d", &hot_x, &hot_y);
+ return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ SDL_Surface *screen;
+ SDL_bool quit = SDL_FALSE, first_time = SDL_TRUE;
+ SDL_Cursor *cursor[3];
+ int current;
+
+ /* Load the SDL library */
+ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
+ fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
+ return (1);
+ }
+
+ screen = SDL_SetVideoMode(320, 200, 8, SDL_ANYFORMAT);
+ if (screen == NULL) {
+ fprintf(stderr, "Couldn't initialize video mode: %s\n",
+ SDL_GetError());
+ return (1);
+ }
+
+ SDL_FillRect(screen, NULL, 0x664422);
+
+ cursor[0] = SDL_CreateCursor((Uint8 *) cursor_data, (Uint8 *) cursor_mask,
+ 16, 16, 8, 8);
+ if (cursor[0] == NULL) {
+ fprintf(stderr, "Couldn't initialize test cursor: %s\n",
+ SDL_GetError());
+ SDL_Quit();
+ return (1);
+ }
+ cursor[1] = create_arrow_cursor();
+ if (cursor[1] == NULL) {
+ fprintf(stderr, "Couldn't initialize arrow cursor: %s\n",
+ SDL_GetError());
+ SDL_FreeCursor(cursor[0]);
+ SDL_Quit();
+ return (1);
+ }
+ cursor[2] = SDL_CreateCursor(small_cursor_data, small_cursor_mask,
+ 8, 11, 3, 5);
+ if (cursor[2] == NULL) {
+ fprintf(stderr, "Couldn't initialize test cursor: %s\n",
+ SDL_GetError());
+ SDL_Quit();
+ return (1);
+ }
+
+ current = 0;
+ SDL_SetCursor(cursor[current]);
+
+ while (!quit) {
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ switch (event.type) {
+ case SDL_MOUSEBUTTONDOWN:
+ current = (current + 1) % 3;
+ SDL_SetCursor(cursor[current]);
+ break;
+ case SDL_KEYDOWN:
+ if (event.key.keysym.sym == SDLK_ESCAPE) {
+ quit = SDL_TRUE;
+ }
+ break;
+ case SDL_QUIT:
+ quit = SDL_TRUE;
+ break;
+ }
+ }
+ SDL_Flip(screen);
+ SDL_Delay(1);
+ }
+
+ SDL_FreeCursor(cursor[0]);
+ SDL_FreeCursor(cursor[1]);
+
+ SDL_Quit();
+ return (0);
+}