src/events/SDL_events.c
changeset 4429 faa9fc8e7f67
parent 3697 f7b03b6838cb
child 4460 363604b42e84
     1.1 --- a/src/events/SDL_events.c	Wed Mar 10 15:07:20 2010 +0000
     1.2 +++ b/src/events/SDL_events.c	Thu Mar 25 01:08:26 2010 -0700
     1.3 @@ -37,8 +37,13 @@
     1.4  /* Public data -- the event filter */
     1.5  SDL_EventFilter SDL_EventOK = NULL;
     1.6  void *SDL_EventOKParam;
     1.7 -Uint8 SDL_ProcessEvents[SDL_NUMEVENTS];
     1.8 -static Uint32 SDL_eventstate = 0;
     1.9 +
    1.10 +typedef struct {
    1.11 +    Uint32 bits[8];
    1.12 +} SDL_DisabledEventBlock;
    1.13 +
    1.14 +static SDL_DisabledEventBlock *SDL_disabled_events[256];
    1.15 +static Uint32 SDL_userevents = SDL_USEREVENT;
    1.16  
    1.17  /* Private data -- event queue */
    1.18  #define MAXEVENTS	128
    1.19 @@ -84,6 +89,17 @@
    1.20      }
    1.21  }
    1.22  
    1.23 +static __inline__ SDL_bool
    1.24 +SDL_ShouldPollJoystick()
    1.25 +{
    1.26 +    if (SDL_numjoysticks &&
    1.27 +        (!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] ||
    1.28 +         SDL_JoystickEventState(SDL_QUERY))) {
    1.29 +        return SDL_TRUE;
    1.30 +    }
    1.31 +    return SDL_FALSE;
    1.32 +}
    1.33 +
    1.34  static int SDLCALL
    1.35  SDL_GobbleEvents(void *unused)
    1.36  {
    1.37 @@ -98,7 +114,7 @@
    1.38          }
    1.39  #if !SDL_JOYSTICK_DISABLED
    1.40          /* Check for joystick state change */
    1.41 -        if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) {
    1.42 +        if (SDL_ShouldPollJoystick()) {
    1.43              SDL_JoystickUpdate();
    1.44          }
    1.45  #endif
    1.46 @@ -195,6 +211,8 @@
    1.47  void
    1.48  SDL_StopEventLoop(void)
    1.49  {
    1.50 +    int i;
    1.51 +
    1.52      /* Halt the event thread, if running */
    1.53      SDL_StopEventThread();
    1.54  
    1.55 @@ -207,6 +225,14 @@
    1.56      SDL_EventQ.head = 0;
    1.57      SDL_EventQ.tail = 0;
    1.58      SDL_EventQ.wmmsg_next = 0;
    1.59 +
    1.60 +    /* Clear disabled event state */
    1.61 +    for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
    1.62 +        if (SDL_disabled_events[i]) {
    1.63 +            SDL_free(SDL_disabled_events[i]);
    1.64 +            SDL_disabled_events[i] = NULL;
    1.65 +        }
    1.66 +    }
    1.67  }
    1.68  
    1.69  /* This function (and associated calls) may be called more than once */
    1.70 @@ -222,11 +248,7 @@
    1.71  
    1.72      /* No filter to start with, process most event types */
    1.73      SDL_EventOK = NULL;
    1.74 -    SDL_memset(SDL_ProcessEvents, SDL_ENABLE, sizeof(SDL_ProcessEvents));
    1.75 -    SDL_eventstate = ~0;
    1.76 -    /* It's not save to call SDL_EventState() yet */
    1.77 -    SDL_eventstate &= ~(0x00000001 << SDL_SYSWMEVENT);
    1.78 -    SDL_ProcessEvents[SDL_SYSWMEVENT] = SDL_IGNORE;
    1.79 +    SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
    1.80  
    1.81      /* Initialize event handlers */
    1.82      retcode = 0;
    1.83 @@ -305,7 +327,7 @@
    1.84  /* Lock the event queue, take a peep at it, and unlock it */
    1.85  int
    1.86  SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
    1.87 -               Uint32 mask)
    1.88 +               Uint32 minType, Uint32 maxType)
    1.89  {
    1.90      int i, used;
    1.91  
    1.92 @@ -332,7 +354,8 @@
    1.93              }
    1.94              spot = SDL_EventQ.head;
    1.95              while ((used < numevents) && (spot != SDL_EventQ.tail)) {
    1.96 -                if (mask & SDL_EVENTMASK(SDL_EventQ.event[spot].type)) {
    1.97 +                Uint32 type = SDL_EventQ.event[spot].type;
    1.98 +                if (minType <= type && type <= maxType) {
    1.99                      events[used++] = SDL_EventQ.event[spot];
   1.100                      if (action == SDL_GETEVENT) {
   1.101                          spot = SDL_CutEvent(spot);
   1.102 @@ -353,9 +376,44 @@
   1.103  }
   1.104  
   1.105  SDL_bool
   1.106 -SDL_HasEvent(Uint32 mask)
   1.107 +SDL_HasEvent(Uint32 type)
   1.108 +{
   1.109 +    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0);
   1.110 +}
   1.111 +
   1.112 +SDL_bool
   1.113 +SDL_HasEvents(Uint32 minType, Uint32 maxType)
   1.114 +{
   1.115 +    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0);
   1.116 +}
   1.117 +
   1.118 +void
   1.119 +SDL_FlushEvent(Uint32 type)
   1.120  {
   1.121 -    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, mask) > 0);
   1.122 +    SDL_FlushEvents(type, type);
   1.123 +}
   1.124 +
   1.125 +void
   1.126 +SDL_FlushEvents(Uint32 minType, Uint32 maxType)
   1.127 +{
   1.128 +    /* Don't look after we've quit */
   1.129 +    if (!SDL_EventQ.active) {
   1.130 +        return;
   1.131 +    }
   1.132 +
   1.133 +    /* Lock the event queue */
   1.134 +    if (SDL_mutexP(SDL_EventQ.lock) == 0) {
   1.135 +        int spot = SDL_EventQ.head;
   1.136 +        while (spot != SDL_EventQ.tail) {
   1.137 +            Uint32 type = SDL_EventQ.event[spot].type;
   1.138 +            if (minType <= type && type <= maxType) {
   1.139 +                spot = SDL_CutEvent(spot);
   1.140 +            } else {
   1.141 +                spot = (spot + 1) % MAXEVENTS;
   1.142 +            }
   1.143 +        }
   1.144 +        SDL_mutexV(SDL_EventQ.lock);
   1.145 +    }
   1.146  }
   1.147  
   1.148  /* Run the system dependent event loops */
   1.149 @@ -371,7 +429,7 @@
   1.150          }
   1.151  #if !SDL_JOYSTICK_DISABLED
   1.152          /* Check for joystick state change */
   1.153 -        if (SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK)) {
   1.154 +        if (SDL_ShouldPollJoystick()) {
   1.155              SDL_JoystickUpdate();
   1.156          }
   1.157  #endif
   1.158 @@ -402,7 +460,7 @@
   1.159  
   1.160      for (;;) {
   1.161          SDL_PumpEvents();
   1.162 -        switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) {
   1.163 +        switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
   1.164          case -1:
   1.165              return 0;
   1.166          case 1:
   1.167 @@ -428,7 +486,7 @@
   1.168      if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) {
   1.169          return 0;
   1.170      }
   1.171 -    if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0) <= 0) {
   1.172 +    if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
   1.173          return -1;
   1.174      }
   1.175      return 1;
   1.176 @@ -476,48 +534,58 @@
   1.177  }
   1.178  
   1.179  Uint8
   1.180 -SDL_EventState(Uint8 type, int state)
   1.181 +SDL_EventState(Uint32 type, int state)
   1.182  {
   1.183 -    SDL_Event bitbucket;
   1.184      Uint8 current_state;
   1.185 +    Uint8 hi = ((type >> 8) & 0xff);
   1.186 +    Uint8 lo = (type & 0xff);
   1.187  
   1.188 -    /* If SDL_ALLEVENTS was specified... */
   1.189 -    if (type == 0xFF) {
   1.190 -        current_state = SDL_IGNORE;
   1.191 -        for (type = 0; type < SDL_NUMEVENTS; ++type) {
   1.192 -            if (SDL_ProcessEvents[type] != SDL_IGNORE) {
   1.193 -                current_state = SDL_ENABLE;
   1.194 -            }
   1.195 -            SDL_ProcessEvents[type] = state;
   1.196 -            if (state == SDL_ENABLE) {
   1.197 -                SDL_eventstate |= (0x00000001 << (type));
   1.198 -            } else {
   1.199 -                SDL_eventstate &= ~(0x00000001 << (type));
   1.200 -            }
   1.201 -        }
   1.202 -        while (SDL_PollEvent(&bitbucket) > 0);
   1.203 -        return (current_state);
   1.204 +    if (SDL_disabled_events[hi] &&
   1.205 +        (SDL_disabled_events[hi]->bits[lo/32] & (1 << (lo&31)))) {
   1.206 +        current_state = SDL_DISABLE;
   1.207 +    } else {
   1.208 +        current_state = SDL_ENABLE;
   1.209      }
   1.210  
   1.211 -    /* Just set the state for one event type */
   1.212 -    current_state = SDL_ProcessEvents[type];
   1.213 -    switch (state) {
   1.214 -    case SDL_IGNORE:
   1.215 -    case SDL_ENABLE:
   1.216 -        /* Set state and discard pending events */
   1.217 -        SDL_ProcessEvents[type] = state;
   1.218 -        if (state == SDL_ENABLE) {
   1.219 -            SDL_eventstate |= (0x00000001 << (type));
   1.220 -        } else {
   1.221 -            SDL_eventstate &= ~(0x00000001 << (type));
   1.222 +    if (state != current_state)
   1.223 +    {
   1.224 +        switch (state) {
   1.225 +        case SDL_DISABLE:
   1.226 +            /* Disable this event type and discard pending events */
   1.227 +            if (!SDL_disabled_events[hi]) {
   1.228 +                SDL_disabled_events[hi] = (SDL_DisabledEventBlock*) SDL_calloc(1, sizeof(SDL_DisabledEventBlock));
   1.229 +                if (!SDL_disabled_events[hi]) {
   1.230 +                    /* Out of memory, nothing we can do... */
   1.231 +                    break;
   1.232 +                }
   1.233 +            }
   1.234 +            SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
   1.235 +            SDL_FlushEvent(type);
   1.236 +            break;
   1.237 +        case SDL_ENABLE:
   1.238 +            SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
   1.239 +            break;
   1.240 +        default:
   1.241 +            /* Querying state... */
   1.242 +            break;
   1.243          }
   1.244 -        while (SDL_PollEvent(&bitbucket) > 0);
   1.245 -        break;
   1.246 -    default:
   1.247 -        /* Querying state? */
   1.248 -        break;
   1.249      }
   1.250 -    return (current_state);
   1.251 +
   1.252 +    return current_state;
   1.253 +}
   1.254 +
   1.255 +Uint32
   1.256 +SDL_RegisterEvents(int numevents)
   1.257 +{
   1.258 +    Uint32 event_base;
   1.259 +
   1.260 +    if (SDL_userevents+numevents <= SDL_LASTEVENT) {
   1.261 +        event_base = SDL_userevents;
   1.262 +        SDL_userevents += numevents;
   1.263 +    } else {
   1.264 +        event_base = (Uint32)-1;
   1.265 +    }
   1.266 +    return event_base;
   1.267  }
   1.268  
   1.269  /* This is a generic event handler.
   1.270 @@ -528,7 +596,7 @@
   1.271      int posted;
   1.272  
   1.273      posted = 0;
   1.274 -    if (SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE) {
   1.275 +    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
   1.276          SDL_Event event;
   1.277          SDL_memset(&event, 0, sizeof(event));
   1.278          event.type = SDL_SYSWMEVENT;