Added a function to create color cursors: SDL_CreateColorCursor()
authorSam Lantinga <slouken@libsdl.org>
Fri, 11 Mar 2011 14:14:38 -0800
changeset 5473 5665ccbd6792
parent 5472 674d45edfaeb
child 5474 c2a1f62433e1
Added a function to create color cursors: SDL_CreateColorCursor()
include/SDL_mouse.h
src/events/SDL_mouse.c
test/testcursor.c
--- a/include/SDL_mouse.h	Fri Mar 11 13:59:52 2011 -0800
+++ b/include/SDL_mouse.h	Fri Mar 11 14:14:38 2011 -0800
@@ -147,6 +147,15 @@
                                                      int hot_y);
 
 /**
+ *  \brief Create a color cursor.
+ *  
+ *  \sa SDL_FreeCursor()
+ */
+extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateColorCursor(SDL_Surface *surface,
+                                                          int hot_x,
+                                                          int hot_y);
+
+/**
  *  \brief Set the active cursor.
  */
 extern DECLSPEC void SDLCALL SDL_SetCursor(SDL_Cursor * cursor);
--- a/src/events/SDL_mouse.c	Fri Mar 11 13:59:52 2011 -0800
+++ b/src/events/SDL_mouse.c	Fri Mar 11 14:14:38 2011 -0800
@@ -360,24 +360,15 @@
     const Uint32 white = 0xFFFFFFFF;
     const Uint32 transparent = 0x00000000;
 
-    if (!mouse->CreateCursor) {
-        SDL_SetError("Cursors are not currently supported");
-        return NULL;
-    }
-
-    /* Sanity check the hot spot */
-    if ((hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h)) {
-        SDL_SetError("Cursor hot spot doesn't lie within cursor");
-        return NULL;
-    }
-
     /* Make sure the width is a multiple of 8 */
     w = ((w + 7) & ~7);
 
     /* Create the surface from a bitmap */
-    surface =
-        SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF,
-                             0xFF000000);
+    surface = SDL_CreateRGBSurface(0, w, h, 32,
+                                   0x00FF0000,
+                                   0x0000FF00,
+                                   0x000000FF,
+                                   0xFF000000);
     if (!surface) {
         return NULL;
     }
@@ -398,13 +389,54 @@
         }
     }
 
+    cursor = SDL_CreateColorCursor(surface, hot_x, hot_y);
+
+    SDL_FreeSurface(surface);
+
+    return cursor;
+}
+
+SDL_Cursor *
+SDL_CreateColorCursor(SDL_Surface *surface, int hot_x, int hot_y)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+    SDL_Surface *temp = NULL;
+    SDL_Cursor *cursor;
+
+    if (!surface) {
+        SDL_SetError("Passed NULL cursor surface");
+        return NULL;
+    }
+
+    if (!mouse->CreateCursor) {
+        SDL_SetError("Cursors are not currently supported");
+        return NULL;
+    }
+
+    /* Sanity check the hot spot */
+    if ((hot_x < 0) || (hot_y < 0) ||
+        (hot_x >= surface->w) || (hot_y >= surface->h)) {
+        SDL_SetError("Cursor hot spot doesn't lie within cursor");
+        return NULL;
+    }
+
+    if (surface->format->format != SDL_PIXELFORMAT_ARGB8888) {
+        temp = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888, 0);
+        if (!temp) {
+            return NULL;
+        }
+        surface = temp;
+    }
+
     cursor = mouse->CreateCursor(surface, hot_x, hot_y);
     if (cursor) {
         cursor->next = mouse->cursors;
         mouse->cursors = cursor;
     }
 
-    SDL_FreeSurface(surface);
+    if (temp) {
+        SDL_FreeSurface(temp);
+    }
 
     return cursor;
 }
--- a/test/testcursor.c	Fri Mar 11 13:59:52 2011 -0800
+++ b/test/testcursor.c	Fri Mar 11 14:14:38 2011 -0800
@@ -141,13 +141,34 @@
     return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
 }
 
+SDL_Surface *
+LoadSprite(char *file)
+{
+    SDL_Surface *sprite;
+
+    /* Load the sprite image */
+    sprite = SDL_LoadBMP(file);
+    if (sprite == NULL) {
+        fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
+        return NULL;
+    }
+
+    /* Set transparent pixel as the pixel at (0,0) */
+    if (sprite->format->palette) {
+        SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY | SDL_RLEACCEL),
+                        *(Uint8 *) sprite->pixels);
+    }
+
+    /* We're ready to roll. :) */
+    return sprite;
+}
 
 int
 main(int argc, char *argv[])
 {
     SDL_Surface *screen;
     SDL_bool quit = SDL_FALSE, first_time = SDL_TRUE;
-    SDL_Cursor *cursor[4];
+    SDL_Cursor *cursor[5];
     int current;
 
     /* Load the SDL library */
@@ -189,9 +210,10 @@
         SDL_Quit();
         return (1);
     }
-    cursor[3] = SDL_GetCursor();
+    cursor[3] = SDL_CreateColorCursor(LoadSprite("icon.bmp"), 0, 0);
+    cursor[4] = SDL_GetCursor();
 
-    current = 0;
+    current = SDL_arraysize(cursor)-1;
     SDL_SetCursor(cursor[current]);
 
     while (!quit) {
@@ -216,9 +238,9 @@
         SDL_Delay(1);
     }
 
-    SDL_FreeCursor(cursor[0]);
-    SDL_FreeCursor(cursor[1]);
-    SDL_FreeCursor(cursor[2]);
+    for (current = 0; current < SDL_arraysize(cursor); ++current) {
+        SDL_FreeCursor(cursor[current]);
+    }
 
     SDL_Quit();
     return (0);