From e8972716424c8a1d16a26b5965c1831155350828 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 11 Mar 2011 14:14:38 -0800 Subject: [PATCH] Added a function to create color cursors: SDL_CreateColorCursor() --- include/SDL_mouse.h | 9 ++++++ src/events/SDL_mouse.c | 62 ++++++++++++++++++++++++++++++++---------- test/testcursor.c | 34 +++++++++++++++++++---- 3 files changed, 84 insertions(+), 21 deletions(-) diff --git a/include/SDL_mouse.h b/include/SDL_mouse.h index e551a27e8..9edfbd53d 100644 --- a/include/SDL_mouse.h +++ b/include/SDL_mouse.h @@ -146,6 +146,15 @@ extern DECLSPEC SDL_Cursor *SDLCALL SDL_CreateCursor(const Uint8 * data, int w, int h, int hot_x, 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. */ diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index cf10f47d7..d2a8fa7d1 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -360,24 +360,15 @@ SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, 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 @@ SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, } } + 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; } diff --git a/test/testcursor.c b/test/testcursor.c index 08acd575e..564a61762 100644 --- a/test/testcursor.c +++ b/test/testcursor.c @@ -141,13 +141,34 @@ create_arrow_cursor() 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 @@ main(int argc, char *argv[]) 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 @@ main(int argc, char *argv[]) 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);