Mercurial > sdl-ios-xcode
diff src/events/SDL_mouse.c @ 1671:89f7510fe17a SDL-1.3
Moved the cursor handling into the mouse code.
Added support for multiple mice, potentially dynamically added and removed.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Fri, 09 Jun 2006 06:42:42 +0000 |
parents | eef792d31de8 |
children | 7688a73b25b1 |
line wrap: on
line diff
--- a/src/events/SDL_mouse.c Wed Jun 07 16:10:28 2006 +0000 +++ b/src/events/SDL_mouse.c Fri Jun 09 06:42:42 2006 +0000 @@ -26,11 +26,12 @@ #include "SDL_events.h" #include "SDL_events_c.h" #include "SDL_mouse_c.h" +#include "default_cursor.h" static int SDL_num_mice; static int SDL_current_mouse; -static SDL_Mouse *SDL_mice; +static SDL_Mouse **SDL_mice; /* Public functions */ @@ -40,45 +41,97 @@ return (0); } -int -SDL_AddMouse(SDL_WindowID focus, int x, int y, Uint8 buttonstate) -{ - SDL_Mouse *new_mice; - int index; - SDL_Mouse *mouse; - - new_mice = - (SDL_Mouse *) SDL_realloc(SDL_mice, - (SDL_num_mice + 1) * sizeof(*new_mice)); - if (!new_mice) { - SDL_OutOfMemory(); - return -1; - } - - index = SDL_num_mice++; - mouse = &SDL_mice[index]; - mouse->focus = focus; - mouse->x = x; - mouse->y = y; - mouse->xdelta = 0; - mouse->ydelta = 0; - mouse->buttonstate = buttonstate; - - return index; -} - SDL_Mouse * SDL_GetMouse(int index) { if (index < 0 || index >= SDL_num_mice) { return NULL; } - return &SDL_mice[index]; + return SDL_mice[index]; +} + +int +SDL_AddMouse(const SDL_Mouse * mouse, int index) +{ + SDL_Mouse **mice; + SDL_Cursor *cursor; + int selected_mouse; + + /* Add the mouse to the list of mice */ + if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) { + mice = + (SDL_Mouse **) SDL_realloc(SDL_mice, + (SDL_num_mice + 1) * sizeof(*mice)); + if (!mice) { + SDL_OutOfMemory(); + return -1; + } + + SDL_mice = mice; + index = SDL_num_mice++; + } + SDL_mice[index] = (SDL_Mouse *) SDL_malloc(sizeof(*SDL_mice[index])); + if (!SDL_mice[index]) { + SDL_OutOfMemory(); + return -1; + } + *SDL_mice[index] = *mouse; + + /* Create the default cursor for the mouse */ + SDL_mice[index]->cursor_shown = SDL_TRUE; + selected_mouse = SDL_SelectMouse(index); + SDL_mice[index]->cur_cursor = NULL; + SDL_mice[index]->def_cursor = + SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, + DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); + SDL_SetCursor(SDL_mice[index]->def_cursor); + SDL_SelectMouse(selected_mouse); + + return index; +} + +void +SDL_DelMouse(int index) +{ + SDL_Mouse *mouse = SDL_GetMouse(index); + + if (!mouse) { + return; + } + + mouse->def_cursor = NULL; + while (mouse->cursors) { + SDL_FreeCursor(mouse->cursors); + } + + if (mouse->FreeMouse) { + mouse->FreeMouse(mouse); + } + SDL_free(mouse); + + SDL_mice[index] = NULL; +} + +void +SDL_ResetMouse(int index) +{ + SDL_Mouse *mouse = SDL_GetMouse(index); + + if (!mouse) { + return; + } + + /* FIXME */ } void SDL_MouseQuit(void) { + int i; + + for (i = 0; i < SDL_num_mice; ++i) { + SDL_DelMouse(i); + } SDL_num_mice = 0; SDL_current_mouse = 0; @@ -201,9 +254,16 @@ } /* Update internal mouse state */ + mouse->x = x; + mouse->y = y; mouse->xdelta += xrel; mouse->ydelta += yrel; + /* Move the mouse cursor, if needed */ + if (mouse->MoveCursor && mouse->cur_cursor) { + mouse->MoveCursor(mouse->cur_cursor); + } + /* Post the event, if desired */ posted = 0; if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) { @@ -225,8 +285,8 @@ } int -SDL_PrivateMouseButton(int index, SDL_WindowID windowID, Uint8 state, - Uint8 button) +SDL_SendMouseButton(int index, SDL_WindowID windowID, Uint8 state, + Uint8 button) { SDL_Mouse *mouse = SDL_GetMouse(index); int posted; @@ -282,4 +342,204 @@ return posted; } +void +SDL_WarpMouseInWindow(SDL_WindowID windowID, int x, int y) +{ + SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + + if (!mouse) { + return; + } + + if (mouse->WarpMouse) { + mouse->WarpMouse(mouse, windowID, x, y); + } else { + SDL_SendMouseMotion(SDL_current_mouse, windowID, 0, x, y); + } +} + +SDL_Cursor * +SDL_CreateCursor(const Uint8 * data, const Uint8 * mask, + int w, int h, int hot_x, int hot_y) +{ + SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + SDL_Surface *surface; + SDL_Cursor *cursor; + int x, y; + Uint32 *pixel; + Uint8 datab, maskb; + const Uint32 black = 0xFF000000; + const Uint32 white = 0xFFFFFFFF; + const Uint32 transparent = 0x00000000; + + if (!mouse) { + SDL_SetError("No mice are initialized"); + return NULL; + } + + if (!mouse->CreateCursor) { + SDL_SetError("Current mouse doesn't have cursor support"); + 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); + if (!surface) { + return NULL; + } + for (y = 0; y < h; ++y) { + pixel = + (Uint32 *) ((Uint8 *) surface->pixels + y * surface->pitch + + x * 4); + for (x = 0; x < w; ++x) { + if ((x % 8) == 0) { + datab = *data++; + maskb = *mask++; + } + if (maskb & 0x80) { + *pixel++ = (datab & 0x80) ? black : white; + } else { + *pixel++ = (datab & 0x80) ? black : transparent; + } + datab <<= 1; + maskb <<= 1; + } + } + + cursor = mouse->CreateCursor(surface, hot_x, hot_y); + if (cursor) { + cursor->mouse = mouse; + cursor->next = mouse->cursors; + mouse->cursors = cursor; + } + + SDL_FreeSurface(surface); + + 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. + */ +void +SDL_SetCursor(SDL_Cursor * cursor) +{ + SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + + if (!mouse) { + SDL_SetError("No mice are initialized"); + return; + } + + /* Set the new cursor */ + if (cursor) { + /* Make sure the cursor is still valid for this mouse */ + SDL_Cursor *found; + for (found = mouse->cursors; found; found = found->next) { + if (found == cursor) { + break; + } + } + if (!found) { + SDL_SetError("Cursor not associated with the current mouse"); + return; + } + mouse->cur_cursor = cursor; + } else { + cursor = mouse->cur_cursor; + } + + if (cursor && mouse->cursor_shown) { + if (mouse->ShowCursor) { + mouse->ShowCursor(cursor); + } + } else { + if (mouse->ShowCursor) { + mouse->ShowCursor(NULL); + } + } +} + +SDL_Cursor * +SDL_GetCursor(void) +{ + SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + + if (!mouse) { + return NULL; + } + return mouse->cur_cursor; +} + +void +SDL_FreeCursor(SDL_Cursor * cursor) +{ + SDL_Mouse *mouse; + SDL_Cursor *curr, *prev; + + if (!cursor) { + return; + } + mouse = cursor->mouse; + + if (cursor == mouse->def_cursor) { + return; + } + if (cursor == mouse->cur_cursor) { + SDL_SetCursor(mouse->def_cursor); + } + + for (prev = NULL, curr = mouse->cursors; curr; + prev = curr, curr = curr->next) { + if (curr == cursor) { + if (prev) { + prev->next = curr->next; + } else { + mouse->cursors = curr->next; + } + + if (mouse->FreeCursor) { + mouse->FreeCursor(curr); + } + return; + } + } +} + +int +SDL_ShowCursor(int toggle) +{ + SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + SDL_bool shown; + + if (!mouse) { + return 0; + } + + shown = mouse->cursor_shown; + if (toggle >= 0) { + if (toggle) { + mouse->cursor_shown = SDL_TRUE; + } else { + mouse->cursor_shown = SDL_FALSE; + } + if (mouse->cursor_shown != shown) { + SDL_SetCursor(NULL); + } + } + return shown; +} + /* vi: set ts=4 sw=4 expandtab: */