Mercurial > sdl-ios-xcode
diff src/events/SDL_mouse.c @ 2710:44e49d3fa6cf
Final merge of Google Summer of Code 2008 work...
Many-mouse and tablet support
by Szymon Wilczek, mentored by Ryan C. Gordon
Everything concerning the project is noted on the wiki:
http://wilku.ravenlord.ws/doku.php?id=start
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 25 Aug 2008 06:33:00 +0000 |
parents | 003c1b5b07da |
children | c4e697245676 |
line wrap: on
line diff
--- a/src/events/SDL_mouse.c Mon Aug 25 05:30:28 2008 +0000 +++ b/src/events/SDL_mouse.c Mon Aug 25 06:33:00 2008 +0000 @@ -28,9 +28,13 @@ #include "default_cursor.h" -static int SDL_num_mice; -static int SDL_current_mouse; -static SDL_Mouse **SDL_mice; +static int SDL_num_mice = 0; +static int SDL_current_mouse = -1; +static SDL_Mouse **SDL_mice = NULL; +static int *SDL_IdIndex = NULL; +static int SDL_highestId = -1; +static int last_x, last_y; /* the last reported x and y coordinates by the system cursor */ +int x_max, y_max; /* current window width and height */ /* Public functions */ @@ -50,10 +54,44 @@ } int -SDL_AddMouse(const SDL_Mouse * mouse, int index) +SDL_SetMouseIndexId(int id, int index) +{ + if (id < 0) { + SDL_SetError("Invalid Mouse ID"); + return -1; + } + if (id > SDL_highestId) { + int *indexes; + indexes = (int *) SDL_realloc(SDL_IdIndex, (id + 1) * sizeof(int)); + if (!indexes) { + SDL_OutOfMemory(); + return -1; + } + SDL_IdIndex = indexes; + SDL_IdIndex[id] = index; + SDL_highestId = id; + } else { + SDL_IdIndex[id] = index; + } + return 1; +} + +SDL_Mouse * +SDL_GetMouseByID(int id) +{ + if (id < 0 || id > SDL_highestId) { + return NULL; + } + return SDL_GetMouse(SDL_IdIndex[id]); +} + +int +SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name, int pressure_max, + int pressure_min, int ends) { SDL_Mouse **mice; int selected_mouse; + int length; /* Add the mouse to the list of mice */ if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) { @@ -75,7 +113,13 @@ } *SDL_mice[index] = *mouse; - /* Create the default cursor for the mouse */ + /* we're setting the mouse properties */ + length = 0; + length = SDL_strlen(name); + SDL_mice[index]->name = SDL_malloc((length + 1) * sizeof(char)); + SDL_strlcpy(SDL_mice[index]->name, name, length); + SDL_mice[index]->pressure_max = pressure_max; + SDL_mice[index]->pressure_min = pressure_min; SDL_mice[index]->cursor_shown = SDL_TRUE; selected_mouse = SDL_SelectMouse(index); SDL_mice[index]->cur_cursor = NULL; @@ -83,6 +127,14 @@ SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH, DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY); SDL_SetCursor(SDL_mice[index]->def_cursor); + /* we're assuming that all mice are in the computer sensing zone */ + SDL_mice[index]->proximity = SDL_TRUE; + /* we're assuming that all mice are working in the absolute position mode + thanx to that, the users that don't want to use many mice don't have to + worry about anything */ + SDL_mice[index]->relative_mode = SDL_FALSE; + SDL_mice[index]->current_end = 0; + SDL_mice[index]->total_ends = ends; SDL_SelectMouse(selected_mouse); return index; @@ -98,6 +150,7 @@ } mouse->def_cursor = NULL; + SDL_free(mouse->name); while (mouse->cursors) { SDL_FreeCursor(mouse->cursors); } @@ -155,9 +208,9 @@ } SDL_WindowID -SDL_GetMouseFocusWindow() +SDL_GetMouseFocusWindow(int index) { - SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + SDL_Mouse *mouse = SDL_GetMouse(index); if (!mouse) { return 0; @@ -177,9 +230,9 @@ } int -SDL_SetRelativeMouseMode(SDL_bool enabled) +SDL_SetRelativeMouseMode(int index, SDL_bool enabled) { - SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + SDL_Mouse *mouse = SDL_GetMouse(index); if (!mouse) { return -1; @@ -205,9 +258,9 @@ } SDL_bool -SDL_GetRelativeMouseMode() +SDL_GetRelativeMouseMode(int index) { - SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + SDL_Mouse *mouse = SDL_GetMouse(index); if (!mouse) { return SDL_FALSE; @@ -216,9 +269,9 @@ } Uint8 -SDL_GetMouseState(int *x, int *y) +SDL_GetMouseState(int index, int *x, int *y) { - SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + SDL_Mouse *mouse = SDL_GetMouse(index); if (!mouse) { if (x) { @@ -240,9 +293,9 @@ } Uint8 -SDL_GetRelativeMouseState(int *x, int *y) +SDL_GetRelativeMouseState(int index, int *x, int *y) { - SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse); + SDL_Mouse *mouse = SDL_GetMouse(index); if (!mouse) { if (x) { @@ -266,16 +319,18 @@ } void -SDL_SetMouseFocus(int index, SDL_WindowID windowID) +SDL_SetMouseFocus(int id, SDL_WindowID windowID) { - SDL_Mouse *mouse = SDL_GetMouse(index); - int i; + SDL_Mouse *mouse = SDL_GetMouseByID(id); + int i, index; SDL_bool focus; if (!mouse || (mouse->focus == windowID)) { return; } + index = SDL_IdIndex[id]; + /* See if the current window has lost focus */ if (mouse->focus) { focus = SDL_FALSE; @@ -315,28 +370,62 @@ } int -SDL_SendMouseMotion(int index, int relative, int x, int y) +SDL_SendProximity(int id, int x, int y, int type) { - SDL_Mouse *mouse = SDL_GetMouse(index); + SDL_Mouse *mouse = SDL_GetMouseByID(id); + int posted = 0; + last_x = x; + last_y = y; + if (SDL_ProcessEvents[type] == SDL_ENABLE) { + SDL_Event event; + event.proximity.which = (Uint8) index; + event.proximity.x = x; + event.proximity.y = y; + event.proximity.cursor = mouse->current_end; + event.proximity.type = type; + posted = (SDL_PushEvent(&event) > 0); + if (type == SDL_PROXIMITYIN) { + mouse->proximity = SDL_TRUE; + } else { + mouse->proximity = SDL_FALSE; + } + } + return posted; +} + +int +SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure) +{ + SDL_Mouse *mouse = SDL_GetMouseByID(id); int posted; int xrel; int yrel; + /* while using the relative mode and many windows, we have to be sure, + that the pointers find themselves inside the windows */ + if (x > x_max) { + x = x_max; + } + if (y > y_max) { + y = y_max; + } + if (!mouse || mouse->flush_motion) { return 0; } - if (relative) { - /* Push the cursor around */ - xrel = x; - yrel = y; - x = (mouse->x + xrel); - y = (mouse->y + yrel); - } else { - xrel = x - mouse->x; - yrel = y - mouse->y; + /* if the mouse is out of proximity we don't to want to have any motion from it */ + if (mouse->proximity == SDL_FALSE) { + last_x = x; + last_y = y; + return 0; } + /* the relative motion is calculated regarding the system cursor last position */ + + xrel = x - last_x; + yrel = y - last_y; + /* Drop events that don't change state */ if (!xrel && !yrel) { #if 0 @@ -345,13 +434,29 @@ return 0; } - /* Update internal mouse state */ - if (!mouse->relative_mode) { + /* Update internal mouse coordinates */ + if (mouse->relative_mode == SDL_FALSE) { mouse->x = x; mouse->y = y; + } else { + if (mouse->x + xrel > x_max) { + mouse->x = x_max; + } else if (mouse->x + xrel < 0) { + mouse->x = 0; + } else { + mouse->x += xrel; + } + if (mouse->y + yrel > y_max) { + mouse->y = y_max; + } else if (mouse->y + yrel < 0) { + mouse->y = 0; + } else { + mouse->y += yrel; + } } mouse->xdelta += xrel; mouse->ydelta += yrel; + mouse->pressure = pressure; /* Move the mouse cursor, if needed */ if (mouse->cursor_shown && !mouse->relative_mode && @@ -361,25 +466,32 @@ /* Post the event, if desired */ posted = 0; - if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) { + if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE && + mouse->proximity == SDL_TRUE) { SDL_Event event; event.motion.type = SDL_MOUSEMOTION; event.motion.which = (Uint8) index; event.motion.state = mouse->buttonstate; event.motion.x = mouse->x; event.motion.y = mouse->y; + event.motion.pressure = mouse->pressure; event.motion.xrel = xrel; event.motion.yrel = yrel; event.motion.windowID = mouse->focus; + event.motion.pressure_max = mouse->pressure_max; + event.motion.pressure_min = mouse->pressure_min; + event.motion.cursor = mouse->current_end; posted = (SDL_PushEvent(&event) > 0); } + last_x = x; + last_y = y; return posted; } int -SDL_SendMouseButton(int index, Uint8 state, Uint8 button) +SDL_SendMouseButton(int id, Uint8 state, Uint8 button) { - SDL_Mouse *mouse = SDL_GetMouse(index); + SDL_Mouse *mouse = SDL_GetMouseByID(id); int posted; Uint8 type; @@ -398,10 +510,6 @@ mouse->buttonstate |= SDL_BUTTON(button); break; case SDL_RELEASED: - if (!(mouse->buttonstate & SDL_BUTTON(button))) { - /* Ignore this event, no state change */ - return 0; - } type = SDL_MOUSEBUTTONUP; mouse->buttonstate &= ~SDL_BUTTON(button); break; @@ -463,7 +571,7 @@ mouse->WarpMouse(mouse, windowID, x, y); } else { SDL_SetMouseFocus(SDL_current_mouse, windowID); - SDL_SendMouseMotion(SDL_current_mouse, 0, x, y); + SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0); } } @@ -649,4 +757,53 @@ return shown; } +char * +SDL_GetMouseName(int index) +{ + SDL_Mouse *mouse = SDL_GetMouse(index); + if (!mouse) { + return NULL; + } + return mouse->name; +} + +void +SDL_UpdateCoordinates(int x, int y) +{ + x_max = x; + y_max = y; +} + +void +SDL_ChangeEnd(int id, int end) +{ + SDL_Mouse *mouse = SDL_GetMouseByID(id); + + if (mouse) { + mouse->current_end = end; + } +} + +int +SDL_GetCursorsNumber(int index) +{ + SDL_Mouse *mouse = SDL_GetMouse(index); + + if (!mouse) { + return -1; + } + return mouse->total_ends; +} + +int +SDL_GetCurrentCursor(int index) +{ + SDL_Mouse *mouse = SDL_GetMouse(index); + + if (!mouse) { + return -1; + } + return mouse->current_end; +} + /* vi: set ts=4 sw=4 expandtab: */