diff src/events/SDL_mouse.c @ 4465:3e69e077cb95

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.
author Sam Lantinga <slouken@libsdl.org>
date Sun, 09 May 2010 20:47:22 -0700
parents faa9fc8e7f67
children 9322f7db8603
line wrap: on
line diff
--- a/src/events/SDL_mouse.c	Sun May 09 19:55:28 2010 -0700
+++ b/src/events/SDL_mouse.c	Sun May 09 20:47:22 2010 -0700
@@ -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 @@
     return (0);
 }
 
-SDL_Mouse *
-SDL_GetMouse(int index)
+void
+SDL_ResetMouse(void)
 {
-    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;
+    /* FIXME */
 }
 
-int
-SDL_AddMouse(const SDL_Mouse * mouse, char *name, int pressure_max,
-             int pressure_min, int ends)
+SDL_Window *
+SDL_GetMouseFocus(void)
 {
-    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;
+    SDL_Mouse *mouse = &SDL_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_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 */
+    return mouse->focus;
 }
 
 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_SetMouseFocus(SDL_Window * window)
 {
-    SDL_Mouse *mouse = SDL_GetMouse(index);
-
-    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);
+    SDL_Mouse *mouse = &SDL_mouse;
 
-    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)
-{
-    int index = SDL_GetMouseIndexId(id);
-    SDL_Mouse *mouse = SDL_GetMouse(index);
-    int i;
-    SDL_bool focus;
-
-    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 @@
 
     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 @@
 }
 
 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 @@
     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 @@
 }
 
 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 @@
     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 @@
 
     cursor = mouse->CreateCursor(surface, hot_x, hot_y);
     if (cursor) {
-        cursor->mouse = mouse;
         cursor->next = mouse->cursors;
         mouse->cursors = cursor;
     }
@@ -655,12 +409,7 @@
 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_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 @@
 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 @@
 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 @@
     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: */