src/events/SDL_mouse.c
changeset 2710 44e49d3fa6cf
parent 2152 003c1b5b07da
child 2712 c4e697245676
     1.1 --- a/src/events/SDL_mouse.c	Mon Aug 25 05:30:28 2008 +0000
     1.2 +++ b/src/events/SDL_mouse.c	Mon Aug 25 06:33:00 2008 +0000
     1.3 @@ -28,9 +28,13 @@
     1.4  #include "default_cursor.h"
     1.5  
     1.6  
     1.7 -static int SDL_num_mice;
     1.8 -static int SDL_current_mouse;
     1.9 -static SDL_Mouse **SDL_mice;
    1.10 +static int SDL_num_mice = 0;
    1.11 +static int SDL_current_mouse = -1;
    1.12 +static SDL_Mouse **SDL_mice = NULL;
    1.13 +static int *SDL_IdIndex = NULL;
    1.14 +static int SDL_highestId = -1;
    1.15 +static int last_x, last_y;      /* the last reported x and y coordinates by the system cursor */
    1.16 +int x_max, y_max;               /* current window width and height */
    1.17  
    1.18  
    1.19  /* Public functions */
    1.20 @@ -50,10 +54,44 @@
    1.21  }
    1.22  
    1.23  int
    1.24 -SDL_AddMouse(const SDL_Mouse * mouse, int index)
    1.25 +SDL_SetMouseIndexId(int id, int index)
    1.26 +{
    1.27 +    if (id < 0) {
    1.28 +        SDL_SetError("Invalid Mouse ID");
    1.29 +        return -1;
    1.30 +    }
    1.31 +    if (id > SDL_highestId) {
    1.32 +        int *indexes;
    1.33 +        indexes = (int *) SDL_realloc(SDL_IdIndex, (id + 1) * sizeof(int));
    1.34 +        if (!indexes) {
    1.35 +            SDL_OutOfMemory();
    1.36 +            return -1;
    1.37 +        }
    1.38 +        SDL_IdIndex = indexes;
    1.39 +        SDL_IdIndex[id] = index;
    1.40 +        SDL_highestId = id;
    1.41 +    } else {
    1.42 +        SDL_IdIndex[id] = index;
    1.43 +    }
    1.44 +    return 1;
    1.45 +}
    1.46 +
    1.47 +SDL_Mouse *
    1.48 +SDL_GetMouseByID(int id)
    1.49 +{
    1.50 +    if (id < 0 || id > SDL_highestId) {
    1.51 +        return NULL;
    1.52 +    }
    1.53 +    return SDL_GetMouse(SDL_IdIndex[id]);
    1.54 +}
    1.55 +
    1.56 +int
    1.57 +SDL_AddMouse(const SDL_Mouse * mouse, int index, char *name, int pressure_max,
    1.58 +             int pressure_min, int ends)
    1.59  {
    1.60      SDL_Mouse **mice;
    1.61      int selected_mouse;
    1.62 +    int length;
    1.63  
    1.64      /* Add the mouse to the list of mice */
    1.65      if (index < 0 || index >= SDL_num_mice || SDL_mice[index]) {
    1.66 @@ -75,7 +113,13 @@
    1.67      }
    1.68      *SDL_mice[index] = *mouse;
    1.69  
    1.70 -    /* Create the default cursor for the mouse */
    1.71 +    /* we're setting the mouse properties */
    1.72 +    length = 0;
    1.73 +    length = SDL_strlen(name);
    1.74 +    SDL_mice[index]->name = SDL_malloc((length + 1) * sizeof(char));
    1.75 +    SDL_strlcpy(SDL_mice[index]->name, name, length);
    1.76 +    SDL_mice[index]->pressure_max = pressure_max;
    1.77 +    SDL_mice[index]->pressure_min = pressure_min;
    1.78      SDL_mice[index]->cursor_shown = SDL_TRUE;
    1.79      selected_mouse = SDL_SelectMouse(index);
    1.80      SDL_mice[index]->cur_cursor = NULL;
    1.81 @@ -83,6 +127,14 @@
    1.82          SDL_CreateCursor(default_cdata, default_cmask, DEFAULT_CWIDTH,
    1.83                           DEFAULT_CHEIGHT, DEFAULT_CHOTX, DEFAULT_CHOTY);
    1.84      SDL_SetCursor(SDL_mice[index]->def_cursor);
    1.85 +    /* we're assuming that all mice are in the computer sensing zone */
    1.86 +    SDL_mice[index]->proximity = SDL_TRUE;
    1.87 +    /* we're assuming that all mice are working in the absolute position mode
    1.88 +       thanx to that, the users that don't want to use many mice don't have to
    1.89 +       worry about anything */
    1.90 +    SDL_mice[index]->relative_mode = SDL_FALSE;
    1.91 +    SDL_mice[index]->current_end = 0;
    1.92 +    SDL_mice[index]->total_ends = ends;
    1.93      SDL_SelectMouse(selected_mouse);
    1.94  
    1.95      return index;
    1.96 @@ -98,6 +150,7 @@
    1.97      }
    1.98  
    1.99      mouse->def_cursor = NULL;
   1.100 +    SDL_free(mouse->name);
   1.101      while (mouse->cursors) {
   1.102          SDL_FreeCursor(mouse->cursors);
   1.103      }
   1.104 @@ -155,9 +208,9 @@
   1.105  }
   1.106  
   1.107  SDL_WindowID
   1.108 -SDL_GetMouseFocusWindow()
   1.109 +SDL_GetMouseFocusWindow(int index)
   1.110  {
   1.111 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   1.112 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.113  
   1.114      if (!mouse) {
   1.115          return 0;
   1.116 @@ -177,9 +230,9 @@
   1.117  }
   1.118  
   1.119  int
   1.120 -SDL_SetRelativeMouseMode(SDL_bool enabled)
   1.121 +SDL_SetRelativeMouseMode(int index, SDL_bool enabled)
   1.122  {
   1.123 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   1.124 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.125  
   1.126      if (!mouse) {
   1.127          return -1;
   1.128 @@ -205,9 +258,9 @@
   1.129  }
   1.130  
   1.131  SDL_bool
   1.132 -SDL_GetRelativeMouseMode()
   1.133 +SDL_GetRelativeMouseMode(int index)
   1.134  {
   1.135 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   1.136 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.137  
   1.138      if (!mouse) {
   1.139          return SDL_FALSE;
   1.140 @@ -216,9 +269,9 @@
   1.141  }
   1.142  
   1.143  Uint8
   1.144 -SDL_GetMouseState(int *x, int *y)
   1.145 +SDL_GetMouseState(int index, int *x, int *y)
   1.146  {
   1.147 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   1.148 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.149  
   1.150      if (!mouse) {
   1.151          if (x) {
   1.152 @@ -240,9 +293,9 @@
   1.153  }
   1.154  
   1.155  Uint8
   1.156 -SDL_GetRelativeMouseState(int *x, int *y)
   1.157 +SDL_GetRelativeMouseState(int index, int *x, int *y)
   1.158  {
   1.159 -    SDL_Mouse *mouse = SDL_GetMouse(SDL_current_mouse);
   1.160 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.161  
   1.162      if (!mouse) {
   1.163          if (x) {
   1.164 @@ -266,16 +319,18 @@
   1.165  }
   1.166  
   1.167  void
   1.168 -SDL_SetMouseFocus(int index, SDL_WindowID windowID)
   1.169 +SDL_SetMouseFocus(int id, SDL_WindowID windowID)
   1.170  {
   1.171 -    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.172 -    int i;
   1.173 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   1.174 +    int i, index;
   1.175      SDL_bool focus;
   1.176  
   1.177      if (!mouse || (mouse->focus == windowID)) {
   1.178          return;
   1.179      }
   1.180  
   1.181 +    index = SDL_IdIndex[id];
   1.182 +
   1.183      /* See if the current window has lost focus */
   1.184      if (mouse->focus) {
   1.185          focus = SDL_FALSE;
   1.186 @@ -315,28 +370,62 @@
   1.187  }
   1.188  
   1.189  int
   1.190 -SDL_SendMouseMotion(int index, int relative, int x, int y)
   1.191 +SDL_SendProximity(int id, int x, int y, int type)
   1.192  {
   1.193 -    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.194 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   1.195 +    int posted = 0;
   1.196 +    last_x = x;
   1.197 +    last_y = y;
   1.198 +    if (SDL_ProcessEvents[type] == SDL_ENABLE) {
   1.199 +        SDL_Event event;
   1.200 +        event.proximity.which = (Uint8) index;
   1.201 +        event.proximity.x = x;
   1.202 +        event.proximity.y = y;
   1.203 +        event.proximity.cursor = mouse->current_end;
   1.204 +        event.proximity.type = type;
   1.205 +        posted = (SDL_PushEvent(&event) > 0);
   1.206 +        if (type == SDL_PROXIMITYIN) {
   1.207 +            mouse->proximity = SDL_TRUE;
   1.208 +        } else {
   1.209 +            mouse->proximity = SDL_FALSE;
   1.210 +        }
   1.211 +    }
   1.212 +    return posted;
   1.213 +}
   1.214 +
   1.215 +int
   1.216 +SDL_SendMouseMotion(int id, int relative, int x, int y, int pressure)
   1.217 +{
   1.218 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   1.219      int posted;
   1.220      int xrel;
   1.221      int yrel;
   1.222  
   1.223 +    /* while using the relative mode and many windows, we have to be sure,
   1.224 +       that the pointers find themselves inside the windows */
   1.225 +    if (x > x_max) {
   1.226 +        x = x_max;
   1.227 +    }
   1.228 +    if (y > y_max) {
   1.229 +        y = y_max;
   1.230 +    }
   1.231 +
   1.232      if (!mouse || mouse->flush_motion) {
   1.233          return 0;
   1.234      }
   1.235  
   1.236 -    if (relative) {
   1.237 -        /* Push the cursor around */
   1.238 -        xrel = x;
   1.239 -        yrel = y;
   1.240 -        x = (mouse->x + xrel);
   1.241 -        y = (mouse->y + yrel);
   1.242 -    } else {
   1.243 -        xrel = x - mouse->x;
   1.244 -        yrel = y - mouse->y;
   1.245 +    /* if the mouse is out of proximity we don't to want to have any motion from it */
   1.246 +    if (mouse->proximity == SDL_FALSE) {
   1.247 +        last_x = x;
   1.248 +        last_y = y;
   1.249 +        return 0;
   1.250      }
   1.251  
   1.252 +    /* the relative motion is calculated regarding the system cursor last position */
   1.253 +
   1.254 +    xrel = x - last_x;
   1.255 +    yrel = y - last_y;
   1.256 +
   1.257      /* Drop events that don't change state */
   1.258      if (!xrel && !yrel) {
   1.259  #if 0
   1.260 @@ -345,13 +434,29 @@
   1.261          return 0;
   1.262      }
   1.263  
   1.264 -    /* Update internal mouse state */
   1.265 -    if (!mouse->relative_mode) {
   1.266 +    /* Update internal mouse coordinates */
   1.267 +    if (mouse->relative_mode == SDL_FALSE) {
   1.268          mouse->x = x;
   1.269          mouse->y = y;
   1.270 +    } else {
   1.271 +        if (mouse->x + xrel > x_max) {
   1.272 +            mouse->x = x_max;
   1.273 +        } else if (mouse->x + xrel < 0) {
   1.274 +            mouse->x = 0;
   1.275 +        } else {
   1.276 +            mouse->x += xrel;
   1.277 +        }
   1.278 +        if (mouse->y + yrel > y_max) {
   1.279 +            mouse->y = y_max;
   1.280 +        } else if (mouse->y + yrel < 0) {
   1.281 +            mouse->y = 0;
   1.282 +        } else {
   1.283 +            mouse->y += yrel;
   1.284 +        }
   1.285      }
   1.286      mouse->xdelta += xrel;
   1.287      mouse->ydelta += yrel;
   1.288 +    mouse->pressure = pressure;
   1.289  
   1.290      /* Move the mouse cursor, if needed */
   1.291      if (mouse->cursor_shown && !mouse->relative_mode &&
   1.292 @@ -361,25 +466,32 @@
   1.293  
   1.294      /* Post the event, if desired */
   1.295      posted = 0;
   1.296 -    if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE) {
   1.297 +    if (SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE &&
   1.298 +        mouse->proximity == SDL_TRUE) {
   1.299          SDL_Event event;
   1.300          event.motion.type = SDL_MOUSEMOTION;
   1.301          event.motion.which = (Uint8) index;
   1.302          event.motion.state = mouse->buttonstate;
   1.303          event.motion.x = mouse->x;
   1.304          event.motion.y = mouse->y;
   1.305 +        event.motion.pressure = mouse->pressure;
   1.306          event.motion.xrel = xrel;
   1.307          event.motion.yrel = yrel;
   1.308          event.motion.windowID = mouse->focus;
   1.309 +        event.motion.pressure_max = mouse->pressure_max;
   1.310 +        event.motion.pressure_min = mouse->pressure_min;
   1.311 +        event.motion.cursor = mouse->current_end;
   1.312          posted = (SDL_PushEvent(&event) > 0);
   1.313      }
   1.314 +    last_x = x;
   1.315 +    last_y = y;
   1.316      return posted;
   1.317  }
   1.318  
   1.319  int
   1.320 -SDL_SendMouseButton(int index, Uint8 state, Uint8 button)
   1.321 +SDL_SendMouseButton(int id, Uint8 state, Uint8 button)
   1.322  {
   1.323 -    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.324 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   1.325      int posted;
   1.326      Uint8 type;
   1.327  
   1.328 @@ -398,10 +510,6 @@
   1.329          mouse->buttonstate |= SDL_BUTTON(button);
   1.330          break;
   1.331      case SDL_RELEASED:
   1.332 -        if (!(mouse->buttonstate & SDL_BUTTON(button))) {
   1.333 -            /* Ignore this event, no state change */
   1.334 -            return 0;
   1.335 -        }
   1.336          type = SDL_MOUSEBUTTONUP;
   1.337          mouse->buttonstate &= ~SDL_BUTTON(button);
   1.338          break;
   1.339 @@ -463,7 +571,7 @@
   1.340          mouse->WarpMouse(mouse, windowID, x, y);
   1.341      } else {
   1.342          SDL_SetMouseFocus(SDL_current_mouse, windowID);
   1.343 -        SDL_SendMouseMotion(SDL_current_mouse, 0, x, y);
   1.344 +        SDL_SendMouseMotion(SDL_current_mouse, 0, x, y, 0);
   1.345      }
   1.346  }
   1.347  
   1.348 @@ -649,4 +757,53 @@
   1.349      return shown;
   1.350  }
   1.351  
   1.352 +char *
   1.353 +SDL_GetMouseName(int index)
   1.354 +{
   1.355 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.356 +    if (!mouse) {
   1.357 +        return NULL;
   1.358 +    }
   1.359 +    return mouse->name;
   1.360 +}
   1.361 +
   1.362 +void
   1.363 +SDL_UpdateCoordinates(int x, int y)
   1.364 +{
   1.365 +    x_max = x;
   1.366 +    y_max = y;
   1.367 +}
   1.368 +
   1.369 +void
   1.370 +SDL_ChangeEnd(int id, int end)
   1.371 +{
   1.372 +    SDL_Mouse *mouse = SDL_GetMouseByID(id);
   1.373 +
   1.374 +    if (mouse) {
   1.375 +        mouse->current_end = end;
   1.376 +    }
   1.377 +}
   1.378 +
   1.379 +int
   1.380 +SDL_GetCursorsNumber(int index)
   1.381 +{
   1.382 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.383 +
   1.384 +    if (!mouse) {
   1.385 +        return -1;
   1.386 +    }
   1.387 +    return mouse->total_ends;
   1.388 +}
   1.389 +
   1.390 +int
   1.391 +SDL_GetCurrentCursor(int index)
   1.392 +{
   1.393 +    SDL_Mouse *mouse = SDL_GetMouse(index);
   1.394 +
   1.395 +    if (!mouse) {
   1.396 +        return -1;
   1.397 +    }
   1.398 +    return mouse->current_end;
   1.399 +}
   1.400 +
   1.401  /* vi: set ts=4 sw=4 expandtab: */