Removed multi-mouse / multi-keyboard support in anticipation of a real multi-mouse and multi-touch API.

Plus, this lets me start implementing cursor support.
This commit is contained in:
Sam Lantinga 2010-05-09 20:47:22 -07:00
parent d12afdaedb
commit 338f95eb06
36 changed files with 514 additions and 2986 deletions

View file

@ -29,9 +29,44 @@
#include "../video/SDL_sysvideo.h"
static int SDL_num_mice = 0;
static int SDL_current_mouse = -1;
static SDL_Mouse **SDL_mice = NULL;
/* Global mouse information */
typedef struct SDL_Mouse SDL_Mouse;
struct SDL_Mouse
{
/* Create a cursor from a surface */
SDL_Cursor *(*CreateCursor) (SDL_Surface * surface, int hot_x, int hot_y);
/* Show the specified cursor, or hide if cursor is NULL */
int (*ShowCursor) (SDL_Cursor * cursor);
/* This is called when a mouse motion event occurs */
void (*MoveCursor) (SDL_Cursor * cursor);
/* Free a window manager cursor */
void (*FreeCursor) (SDL_Cursor * cursor);
/* Warp the mouse to (x,y) */
void (*WarpMouse) (SDL_Mouse * mouse, SDL_Window * window, int x, int y);
/* Data common to all mice */
SDL_Window *focus;
int x;
int y;
int xdelta;
int ydelta;
int last_x, last_y; /* the last reported x and y coordinates */
Uint8 buttonstate;
SDL_bool relative_mode;
SDL_Cursor *cursors;
SDL_Cursor *def_cursor;
SDL_Cursor *cur_cursor;
SDL_bool cursor_shown;
};
static SDL_Mouse SDL_mouse;
/* Public functions */
@ -41,370 +76,50 @@ SDL_MouseInit(void)
return (0);
}
SDL_Mouse *
SDL_GetMouse(int index)
{
if (index < 0 || index >= SDL_num_mice) {
return NULL;
}
return SDL_mice[index];
}
static int
SDL_GetMouseIndexId(int id)
{
int index;
SDL_Mouse *mouse;
for (index = 0; index < SDL_num_mice; ++index) {
mouse = SDL_GetMouse(index);
if (mouse->id == id) {
return index;
}
}
return -1;
}
int
SDL_AddMouse(const SDL_Mouse * mouse, char *name, int pressure_max,
int pressure_min, int ends)
{
SDL_Mouse **mice;
int selected_mouse;
int index;
size_t length;
if (SDL_GetMouseIndexId(mouse->id) != -1) {
SDL_SetError("Mouse ID already in use");
}
/* Add the mouse to the list of mice */
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;
/* we're setting the mouse properties */
length = 0;
length = SDL_strlen(name);
SDL_mice[index]->focus = 0;
SDL_mice[index]->name = SDL_malloc((length + 2) * sizeof(char));
SDL_strlcpy(SDL_mice[index]->name, name, length + 1);
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;
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);
/* 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;
}
void
SDL_DelMouse(int index)
SDL_ResetMouse(void)
{
SDL_Mouse *mouse = SDL_GetMouse(index);
if (!mouse) {
return;
}
mouse->def_cursor = NULL;
SDL_free(mouse->name);
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 = -1;
if (SDL_mice) {
SDL_free(SDL_mice);
SDL_mice = NULL;
}
}
int
SDL_GetNumMice(void)
{
return SDL_num_mice;
}
int
SDL_SelectMouse(int index)
{
if (index >= 0 && index < SDL_num_mice) {
SDL_current_mouse = index;
}
return SDL_current_mouse;
}
SDL_Window *
SDL_GetMouseFocusWindow(int index)
SDL_GetMouseFocus(void)
{
SDL_Mouse *mouse = SDL_GetMouse(index);
SDL_Mouse *mouse = &SDL_mouse;
if (!mouse) {
return 0;
}
return mouse->focus;
}
static int SDLCALL
FlushMouseMotion(void *param, SDL_Event * event)
{
if (event->type == SDL_MOUSEMOTION
&& event->motion.which == (Uint8) SDL_current_mouse) {
return 0;
} else {
return 1;
}
}
int
SDL_SetRelativeMouseMode(int index, SDL_bool enabled)
{
SDL_Mouse *mouse = SDL_GetMouse(index);
if (!mouse) {
return -1;
}
/* Flush pending mouse motion */
mouse->flush_motion = SDL_TRUE;
SDL_PumpEvents();
mouse->flush_motion = SDL_FALSE;
SDL_FilterEvents(FlushMouseMotion, mouse);
/* Set the relative mode */
mouse->relative_mode = enabled;
/* Update cursor visibility */
SDL_SetCursor(NULL);
if (!enabled) {
/* Restore the expected mouse position */
SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
}
return 0;
}
SDL_bool
SDL_GetRelativeMouseMode(int index)
{
SDL_Mouse *mouse = SDL_GetMouse(index);
if (!mouse) {
return SDL_FALSE;
}
return mouse->relative_mode;
}
Uint8
SDL_GetMouseState(int *x, int *y)
{
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
if (!mouse) {
if (x) {
*x = 0;
}
if (y) {
*y = 0;
}
return 0;
}
if (x) {
*x = mouse->x;
}
if (y) {
*y = mouse->y;
}
return mouse->buttonstate;
}
Uint8
SDL_GetRelativeMouseState(int index, int *x, int *y)
{
SDL_Mouse *mouse = SDL_GetMouse(index);
if (!mouse) {
if (x) {
*x = 0;
}
if (y) {
*y = 0;
}
return 0;
}
if (x) {
*x = mouse->xdelta;
}
if (y) {
*y = mouse->ydelta;
}
mouse->xdelta = 0;
mouse->ydelta = 0;
return mouse->buttonstate;
}
void
SDL_SetMouseFocus(int id, SDL_Window * window)
SDL_SetMouseFocus(SDL_Window * window)
{
int index = SDL_GetMouseIndexId(id);
SDL_Mouse *mouse = SDL_GetMouse(index);
int i;
SDL_bool focus;
SDL_Mouse *mouse = &SDL_mouse;
if (!mouse || (mouse->focus == window)) {
if (mouse->focus == window) {
return;
}
/* See if the current window has lost focus */
if (mouse->focus) {
focus = SDL_FALSE;
for (i = 0; i < SDL_num_mice; ++i) {
SDL_Mouse *check;
if (i != index) {
check = SDL_GetMouse(i);
if (check && check->focus == mouse->focus) {
focus = SDL_TRUE;
break;
}
}
}
if (!focus) {
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
}
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_LEAVE, 0, 0);
}
mouse->focus = window;
if (mouse->focus) {
focus = SDL_FALSE;
for (i = 0; i < SDL_num_mice; ++i) {
SDL_Mouse *check;
if (i != index) {
check = SDL_GetMouse(i);
if (check && check->focus == mouse->focus) {
focus = SDL_TRUE;
break;
}
}
}
if (!focus) {
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
}
SDL_SendWindowEvent(mouse->focus, SDL_WINDOWEVENT_ENTER, 0, 0);
}
}
int
SDL_SendProximity(int id, int x, int y, int type)
SDL_SendMouseMotion(int relative, int x, int y)
{
int index = SDL_GetMouseIndexId(id);
SDL_Mouse *mouse = SDL_GetMouse(index);
int posted = 0;
if (!mouse) {
return 0;
}
mouse->last_x = x;
mouse->last_y = y;
if (SDL_GetEventState(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;
/* FIXME: is this right? */
event.proximity.windowID = mouse->focus ? mouse->focus->id : 0;
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)
{
int index = SDL_GetMouseIndexId(id);
SDL_Mouse *mouse = SDL_GetMouse(index);
SDL_Mouse *mouse = &SDL_mouse;
int posted;
int xrel;
int yrel;
int x_max = 0, y_max = 0;
if (!mouse || mouse->flush_motion) {
return 0;
}
/* if the mouse is out of proximity we don't to want to have any motion from it */
if (mouse->proximity == SDL_FALSE) {
mouse->last_x = x;
mouse->last_y = y;
return 0;
}
/* the relative motion is calculated regarding the system cursor last position */
if (relative) {
xrel = x;
@ -451,35 +166,26 @@ SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure)
mouse->xdelta += xrel;
mouse->ydelta += yrel;
mouse->pressure = pressure;
#if 0 /* FIXME */
/* Move the mouse cursor, if needed */
if (mouse->cursor_shown && !mouse->relative_mode &&
mouse->MoveCursor && mouse->cur_cursor) {
mouse->MoveCursor(mouse->cur_cursor);
}
#endif
/* Post the event, if desired */
posted = 0;
if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE &&
mouse->proximity == SDL_TRUE) {
if (SDL_GetEventState(SDL_MOUSEMOTION) == SDL_ENABLE) {
SDL_Event event;
event.motion.type = SDL_MOUSEMOTION;
event.motion.which = (Uint8) index;
event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
event.motion.state = mouse->buttonstate;
event.motion.x = mouse->x;
event.motion.y = mouse->y;
event.motion.z = mouse->z;
event.motion.pressure = mouse->pressure;
event.motion.pressure_max = mouse->pressure_max;
event.motion.pressure_min = mouse->pressure_min;
event.motion.rotation = 0;
event.motion.tilt_x = 0;
event.motion.tilt_y = 0;
event.motion.cursor = mouse->current_end;
event.motion.xrel = xrel;
event.motion.yrel = yrel;
event.motion.windowID = mouse->focus ? mouse->focus->id : 0;
posted = (SDL_PushEvent(&event) > 0);
}
mouse->last_x = mouse->x;
@ -488,17 +194,12 @@ SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure)
}
int
SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
SDL_SendMouseButton(Uint8 state, Uint8 button)
{
int index = SDL_GetMouseIndexId(id);
SDL_Mouse *mouse = SDL_GetMouse(index);
SDL_Mouse *mouse = &SDL_mouse;
int posted;
Uint32 type;
if (!mouse) {
return 0;
}
/* Figure out which event to perform */
switch (state) {
case SDL_PRESSED:
@ -527,7 +228,6 @@ SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
if (SDL_GetEventState(type) == SDL_ENABLE) {
SDL_Event event;
event.type = type;
event.button.which = (Uint8) index;
event.button.state = state;
event.button.button = button;
event.button.x = mouse->x;
@ -539,12 +239,12 @@ SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
}
int
SDL_SendMouseWheel(int index, int x, int y)
SDL_SendMouseWheel(int x, int y)
{
SDL_Mouse *mouse = SDL_GetMouse(index);
SDL_Mouse *mouse = &SDL_mouse;
int posted;
if (!mouse || (!x && !y)) {
if (!x && !y) {
return 0;
}
@ -553,53 +253,108 @@ SDL_SendMouseWheel(int index, int x, int y)
if (SDL_GetEventState(SDL_MOUSEWHEEL) == SDL_ENABLE) {
SDL_Event event;
event.type = SDL_MOUSEWHEEL;
event.wheel.which = (Uint8) index;
event.wheel.windowID = mouse->focus ? mouse->focus->id : 0;
event.wheel.x = x;
event.wheel.y = y;
event.wheel.windowID = mouse->focus ? mouse->focus->id : 0;
posted = (SDL_PushEvent(&event) > 0);
}
return posted;
}
void
SDL_MouseQuit(void)
{
}
Uint8
SDL_GetMouseState(int *x, int *y)
{
SDL_Mouse *mouse = &SDL_mouse;
if (x) {
*x = mouse->x;
}
if (y) {
*y = mouse->y;
}
return mouse->buttonstate;
}
Uint8
SDL_GetRelativeMouseState(int *x, int *y)
{
SDL_Mouse *mouse = &SDL_mouse;
if (x) {
*x = mouse->xdelta;
}
if (y) {
*y = mouse->ydelta;
}
mouse->xdelta = 0;
mouse->ydelta = 0;
return mouse->buttonstate;
}
void
SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
{
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
if (!mouse) {
return;
}
SDL_Mouse *mouse = &SDL_mouse;
if (mouse->WarpMouse) {
mouse->WarpMouse(mouse, window, x, y);
} else {
SDL_SetMouseFocus(SDL_current_mouse, window);
SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0);
SDL_SetMouseFocus(window);
SDL_SendMouseMotion(0, x, y);
}
}
int
SDL_SetRelativeMouseMode(SDL_bool enabled)
{
SDL_Mouse *mouse = &SDL_mouse;
/* Flush pending mouse motion */
SDL_FlushEvent(SDL_MOUSEMOTION);
/* Set the relative mode */
mouse->relative_mode = enabled;
if (!enabled) {
/* Restore the expected mouse position */
SDL_WarpMouseInWindow(mouse->focus, mouse->x, mouse->y);
}
/* Update cursor visibility */
SDL_SetCursor(NULL);
return 0;
}
SDL_bool
SDL_GetRelativeMouseMode()
{
SDL_Mouse *mouse = &SDL_mouse;
return mouse->relative_mode;
}
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_Mouse *mouse = &SDL_mouse;
SDL_Surface *surface;
SDL_Cursor *cursor;
int x, y;
Uint32 *pixel;
Uint8 datab, maskb;
Uint8 datab = 0, maskb = 0;
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");
SDL_SetError("Cursors are not currently supported");
return NULL;
}
@ -638,7 +393,6 @@ SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
cursor = mouse->CreateCursor(surface, hot_x, hot_y);
if (cursor) {
cursor->mouse = mouse;
cursor->next = mouse->cursors;
mouse->cursors = cursor;
}
@ -655,12 +409,7 @@ SDL_CreateCursor(const Uint8 * data, const Uint8 * mask,
void
SDL_SetCursor(SDL_Cursor * cursor)
{
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
if (!mouse) {
SDL_SetError("No mice are initialized");
return;
}
SDL_Mouse *mouse = &SDL_mouse;
/* Set the new cursor */
if (cursor) {
@ -694,7 +443,7 @@ SDL_SetCursor(SDL_Cursor * cursor)
SDL_Cursor *
SDL_GetCursor(void)
{
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
SDL_Mouse *mouse = &SDL_mouse;
if (!mouse) {
return NULL;
@ -705,13 +454,12 @@ SDL_GetCursor(void)
void
SDL_FreeCursor(SDL_Cursor * cursor)
{
SDL_Mouse *mouse;
SDL_Mouse *mouse = &SDL_mouse;
SDL_Cursor *curr, *prev;
if (!cursor) {
return;
}
mouse = cursor->mouse;
if (cursor == mouse->def_cursor) {
return;
@ -740,7 +488,7 @@ SDL_FreeCursor(SDL_Cursor * cursor)
int
SDL_ShowCursor(int toggle)
{
SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
SDL_Mouse *mouse = &SDL_mouse;
SDL_bool shown;
if (!mouse) {
@ -761,47 +509,4 @@ SDL_ShowCursor(int toggle)
return shown;
}
char *
SDL_GetMouseName(int index)
{
SDL_Mouse *mouse = SDL_GetMouse(index);
if (!mouse) {
return NULL;
}
return mouse->name;
}
void
SDL_ChangeEnd(int id, int end)
{
int index = SDL_GetMouseIndexId(id);
SDL_Mouse *mouse = SDL_GetMouse(index);
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: */