src/events/SDL_mouse.c
changeset 8066 658b461d81be
parent 8049 eac8f31e9bbd
child 8071 1ac2db4abe11
     1.1 --- a/src/events/SDL_mouse.c	Mon Dec 23 10:54:27 2013 -0800
     1.2 +++ b/src/events/SDL_mouse.c	Mon Dec 23 12:17:52 2013 -0800
     1.3 @@ -23,6 +23,7 @@
     1.4  /* General mouse handling code for SDL */
     1.5  
     1.6  #include "SDL_assert.h"
     1.7 +#include "SDL_timer.h"
     1.8  #include "SDL_events.h"
     1.9  #include "SDL_events_c.h"
    1.10  #include "default_cursor.h"
    1.11 @@ -32,6 +33,8 @@
    1.12  
    1.13  /* The mouse state */
    1.14  static SDL_Mouse SDL_mouse;
    1.15 +static Uint32 SDL_double_click_time = 500;
    1.16 +static int SDL_double_click_radius = 1;
    1.17  
    1.18  static int
    1.19  SDL_PrivateSendMouseMotion(SDL_Window * window, SDL_MouseID mouseID, int relative, int x, int y);
    1.20 @@ -64,6 +67,12 @@
    1.21      return &SDL_mouse;
    1.22  }
    1.23  
    1.24 +void
    1.25 +SDL_SetDoubleClickTime(Uint32 interval)
    1.26 +{
    1.27 +    SDL_double_click_time = interval;
    1.28 +}
    1.29 +
    1.30  SDL_Window *
    1.31  SDL_GetMouseFocus(void)
    1.32  {
    1.33 @@ -272,6 +281,23 @@
    1.34      return posted;
    1.35  }
    1.36  
    1.37 +static SDL_MouseClickState *GetMouseClickState(SDL_Mouse *mouse, Uint8 button)
    1.38 +{
    1.39 +    if (button >= mouse->num_clickstates) {
    1.40 +        int i, count = button + 1;
    1.41 +        mouse->clickstate = (SDL_MouseClickState *)SDL_realloc(mouse->clickstate, count * sizeof(*mouse->clickstate));
    1.42 +        if (!mouse->clickstate) {
    1.43 +            return NULL;
    1.44 +        }
    1.45 +
    1.46 +        for (i = mouse->num_clickstates; i < count; ++i) {
    1.47 +            SDL_zero(mouse->clickstate[i]);
    1.48 +        }
    1.49 +        mouse->num_clickstates = count;
    1.50 +    }
    1.51 +    return &mouse->clickstate[button];
    1.52 +}
    1.53 +
    1.54  int
    1.55  SDL_SendMouseButton(SDL_Window * window, SDL_MouseID mouseID, Uint8 state, Uint8 button)
    1.56  {
    1.57 @@ -279,6 +305,8 @@
    1.58      int posted;
    1.59      Uint32 type;
    1.60      Uint32 buttonstate = mouse->buttonstate;
    1.61 +    SDL_MouseClickState *clickstate = GetMouseClickState(mouse, button);
    1.62 +    Uint8 click_count;
    1.63  
    1.64      /* Figure out which event to perform */
    1.65      switch (state) {
    1.66 @@ -306,6 +334,27 @@
    1.67      }
    1.68      mouse->buttonstate = buttonstate;
    1.69  
    1.70 +    if (clickstate) {
    1.71 +        if (state == SDL_PRESSED) {
    1.72 +            Uint32 now = SDL_GetTicks();
    1.73 +
    1.74 +            if (SDL_TICKS_PASSED(now, clickstate->last_timestamp + SDL_double_click_time) ||
    1.75 +                SDL_abs(mouse->x - clickstate->last_x) > SDL_double_click_radius ||
    1.76 +                SDL_abs(mouse->y - clickstate->last_y) > SDL_double_click_radius) {
    1.77 +                clickstate->click_count = 0;
    1.78 +            }
    1.79 +            clickstate->last_timestamp = now;
    1.80 +            clickstate->last_x = mouse->x;
    1.81 +            clickstate->last_y = mouse->y;
    1.82 +            if (clickstate->click_count < 255) {
    1.83 +                ++clickstate->click_count;
    1.84 +            }
    1.85 +        }
    1.86 +        click_count = clickstate->click_count;
    1.87 +    } else {
    1.88 +        click_count = 1;
    1.89 +    }
    1.90 +
    1.91      /* Post the event, if desired */
    1.92      posted = 0;
    1.93      if (SDL_GetEventState(type) == SDL_ENABLE) {
    1.94 @@ -315,6 +364,7 @@
    1.95          event.button.which = mouseID;
    1.96          event.button.state = state;
    1.97          event.button.button = button;
    1.98 +        event.button.clicks = click_count;
    1.99          event.button.x = mouse->x;
   1.100          event.button.y = mouse->y;
   1.101          posted = (SDL_PushEvent(&event) > 0);
   1.102 @@ -376,6 +426,10 @@
   1.103          mouse->FreeCursor(mouse->def_cursor);
   1.104      }
   1.105  
   1.106 +    if (mouse->clickstate) {
   1.107 +        SDL_free(mouse->clickstate);
   1.108 +    }
   1.109 +
   1.110      SDL_zerop(mouse);
   1.111  }
   1.112