src/events/SDL_events.c
author Sam Lantinga
Mon, 20 May 2013 23:04:25 -0700
changeset 7201 c6b3d3c32507
parent 7191 75360622e65f
child 7304 9598cbf46957
permissions -rw-r--r--
Fixed bug 1113 - SDL_SetEventFilter()'s event deletion process is not safe against intervening event push.

This is not completely thread-safe since it's possible for an event to come in and be unfiltered between the flush call and the setting of the new filter, but it's much better than it was.
slouken@0
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6885
     3
  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
slouken@0
     4
slouken@5535
     5
  This software is provided 'as-is', without any express or implied
slouken@5535
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     7
  arising from the use of this software.
slouken@0
     8
slouken@5535
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
    10
  including commercial applications, and to alter it and redistribute it
slouken@5535
    11
  freely, subject to the following restrictions:
slouken@0
    12
slouken@5535
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@5535
    14
     claim that you wrote the original software. If you use this software
slouken@5535
    15
     in a product, an acknowledgment in the product documentation would be
slouken@5535
    16
     appreciated but is not required.
slouken@5535
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@5535
    18
     misrepresented as being the original software.
slouken@5535
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@0
    20
*/
slouken@1402
    21
#include "SDL_config.h"
slouken@0
    22
slouken@0
    23
/* General event handling code for SDL */
slouken@0
    24
slouken@0
    25
#include "SDL.h"
slouken@2984
    26
#include "SDL_events.h"
slouken@0
    27
#include "SDL_syswm.h"
slouken@2984
    28
#include "SDL_thread.h"
slouken@1361
    29
#include "SDL_events_c.h"
slouken@1361
    30
#include "../timer/SDL_timer_c.h"
slouken@1361
    31
#if !SDL_JOYSTICK_DISABLED
slouken@1361
    32
#include "../joystick/SDL_joystick_c.h"
slouken@1361
    33
#endif
slouken@5123
    34
#include "../video/SDL_sysvideo.h"
slouken@0
    35
slouken@0
    36
/* Public data -- the event filter */
slouken@0
    37
SDL_EventFilter SDL_EventOK = NULL;
slouken@1895
    38
void *SDL_EventOKParam;
slouken@4429
    39
slouken@5146
    40
typedef struct SDL_EventWatcher {
slouken@5146
    41
    SDL_EventFilter callback;
slouken@5146
    42
    void *userdata;
slouken@5146
    43
    struct SDL_EventWatcher *next;
slouken@5146
    44
} SDL_EventWatcher;
slouken@5146
    45
slouken@5146
    46
static SDL_EventWatcher *SDL_event_watchers = NULL;
slouken@5146
    47
slouken@4429
    48
typedef struct {
slouken@4429
    49
    Uint32 bits[8];
slouken@4429
    50
} SDL_DisabledEventBlock;
slouken@4429
    51
slouken@4429
    52
static SDL_DisabledEventBlock *SDL_disabled_events[256];
slouken@4429
    53
static Uint32 SDL_userevents = SDL_USEREVENT;
slouken@0
    54
slouken@0
    55
/* Private data -- event queue */
slouken@7191
    56
#define MAXEVENTS   128
slouken@1895
    57
static struct
slouken@1895
    58
{
slouken@1895
    59
    SDL_mutex *lock;
slouken@1895
    60
    int active;
slouken@1895
    61
    int head;
slouken@1895
    62
    int tail;
slouken@1895
    63
    SDL_Event event[MAXEVENTS];
slouken@1895
    64
    int wmmsg_next;
slouken@1895
    65
    struct SDL_SysWMmsg wmmsg[MAXEVENTS];
slouken@6588
    66
} SDL_EventQ = { NULL, 1 };
slouken@0
    67
slouken@0
    68
slouken@4429
    69
static __inline__ SDL_bool
slouken@4429
    70
SDL_ShouldPollJoystick()
slouken@4429
    71
{
paul@4698
    72
#if !SDL_JOYSTICK_DISABLED
slouken@6753
    73
    if ((!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] ||
slouken@6753
    74
         SDL_JoystickEventState(SDL_QUERY)) &&
slouken@6753
    75
        SDL_PrivateJoystickNeedsPolling()) {
slouken@4429
    76
        return SDL_TRUE;
slouken@4429
    77
    }
paul@4698
    78
#endif
slouken@4429
    79
    return SDL_FALSE;
slouken@4429
    80
}
slouken@4429
    81
slouken@0
    82
/* Public functions */
slouken@0
    83
slouken@1895
    84
void
slouken@1895
    85
SDL_StopEventLoop(void)
slouken@0
    86
{
slouken@4429
    87
    int i;
slouken@4429
    88
slouken@6495
    89
    SDL_EventQ.active = 0;
slouken@6495
    90
slouken@5123
    91
    if (SDL_EventQ.lock) {
slouken@5123
    92
        SDL_DestroyMutex(SDL_EventQ.lock);
slouken@5123
    93
        SDL_EventQ.lock = NULL;
slouken@5123
    94
    }
slouken@1123
    95
slouken@1895
    96
    /* Clean out EventQ */
slouken@1895
    97
    SDL_EventQ.head = 0;
slouken@1895
    98
    SDL_EventQ.tail = 0;
slouken@1895
    99
    SDL_EventQ.wmmsg_next = 0;
slouken@4429
   100
slouken@4429
   101
    /* Clear disabled event state */
slouken@4429
   102
    for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
slouken@4429
   103
        if (SDL_disabled_events[i]) {
slouken@4429
   104
            SDL_free(SDL_disabled_events[i]);
slouken@4429
   105
            SDL_disabled_events[i] = NULL;
slouken@4429
   106
        }
slouken@4429
   107
    }
slouken@5146
   108
slouken@5146
   109
    while (SDL_event_watchers) {
slouken@5146
   110
        SDL_EventWatcher *tmp = SDL_event_watchers;
slouken@5146
   111
        SDL_event_watchers = tmp->next;
slouken@5146
   112
        SDL_free(tmp);
slouken@5146
   113
    }
slouken@7190
   114
    SDL_EventOK = NULL;
slouken@0
   115
}
slouken@0
   116
slouken@0
   117
/* This function (and associated calls) may be called more than once */
slouken@1895
   118
int
slouken@5123
   119
SDL_StartEventLoop(void)
slouken@0
   120
{
slouken@6588
   121
    /* We'll leave the event queue alone, since we might have gotten
slouken@6588
   122
       some important events at launch (like SDL_DROPFILE)
slouken@6588
   123
slouken@6588
   124
       FIXME: Does this introduce any other bugs with events at startup?
slouken@6588
   125
     */
slouken@0
   126
slouken@5123
   127
    /* Create the lock and set ourselves active */
slouken@5123
   128
#if !SDL_THREADS_DISABLED
slouken@6588
   129
    if (!SDL_EventQ.lock) {
slouken@6588
   130
        SDL_EventQ.lock = SDL_CreateMutex();
slouken@6588
   131
    }
slouken@5123
   132
    if (SDL_EventQ.lock == NULL) {
slouken@1895
   133
        return (-1);
slouken@1895
   134
    }
slouken@5123
   135
#endif /* !SDL_THREADS_DISABLED */
icculus@7077
   136
slouken@7190
   137
    /* Process most event types */
icculus@7077
   138
    SDL_EventState(SDL_TEXTINPUT, SDL_DISABLE);
icculus@7077
   139
    SDL_EventState(SDL_TEXTEDITING, SDL_DISABLE);
icculus@7077
   140
    SDL_EventState(SDL_SYSWMEVENT, SDL_DISABLE);
icculus@7077
   141
slouken@5123
   142
    SDL_EventQ.active = 1;
slouken@1895
   143
slouken@1895
   144
    return (0);
slouken@0
   145
}
slouken@0
   146
slouken@0
   147
slouken@0
   148
/* Add an event to the event queue -- called with the queue locked */
slouken@1895
   149
static int
slouken@1895
   150
SDL_AddEvent(SDL_Event * event)
slouken@0
   151
{
slouken@1895
   152
    int tail, added;
slouken@0
   153
slouken@1895
   154
    tail = (SDL_EventQ.tail + 1) % MAXEVENTS;
slouken@1895
   155
    if (tail == SDL_EventQ.head) {
slouken@1895
   156
        /* Overflow, drop event */
slouken@1895
   157
        added = 0;
slouken@1895
   158
    } else {
slouken@1895
   159
        SDL_EventQ.event[SDL_EventQ.tail] = *event;
slouken@1895
   160
        if (event->type == SDL_SYSWMEVENT) {
slouken@1895
   161
            /* Note that it's possible to lose an event */
slouken@1895
   162
            int next = SDL_EventQ.wmmsg_next;
slouken@1895
   163
            SDL_EventQ.wmmsg[next] = *event->syswm.msg;
slouken@1895
   164
            SDL_EventQ.event[SDL_EventQ.tail].syswm.msg =
slouken@1895
   165
                &SDL_EventQ.wmmsg[next];
slouken@1895
   166
            SDL_EventQ.wmmsg_next = (next + 1) % MAXEVENTS;
slouken@1895
   167
        }
slouken@1895
   168
        SDL_EventQ.tail = tail;
slouken@1895
   169
        added = 1;
slouken@1895
   170
    }
slouken@1895
   171
    return (added);
slouken@0
   172
}
slouken@0
   173
slouken@0
   174
/* Cut an event, and return the next valid spot, or the tail */
slouken@0
   175
/*                           -- called with the queue locked */
slouken@1895
   176
static int
slouken@1895
   177
SDL_CutEvent(int spot)
slouken@0
   178
{
slouken@1895
   179
    if (spot == SDL_EventQ.head) {
slouken@1895
   180
        SDL_EventQ.head = (SDL_EventQ.head + 1) % MAXEVENTS;
slouken@1895
   181
        return (SDL_EventQ.head);
slouken@1895
   182
    } else if ((spot + 1) % MAXEVENTS == SDL_EventQ.tail) {
slouken@1895
   183
        SDL_EventQ.tail = spot;
slouken@1895
   184
        return (SDL_EventQ.tail);
slouken@1895
   185
    } else
slouken@1895
   186
        /* We cut the middle -- shift everything over */
slouken@1895
   187
    {
slouken@1895
   188
        int here, next;
slouken@0
   189
slouken@1895
   190
        /* This can probably be optimized with SDL_memcpy() -- careful! */
slouken@1895
   191
        if (--SDL_EventQ.tail < 0) {
slouken@1895
   192
            SDL_EventQ.tail = MAXEVENTS - 1;
slouken@1895
   193
        }
slouken@1895
   194
        for (here = spot; here != SDL_EventQ.tail; here = next) {
slouken@1895
   195
            next = (here + 1) % MAXEVENTS;
slouken@1895
   196
            SDL_EventQ.event[here] = SDL_EventQ.event[next];
slouken@1895
   197
        }
slouken@1895
   198
        return (spot);
slouken@1895
   199
    }
slouken@1895
   200
    /* NOTREACHED */
slouken@0
   201
}
slouken@0
   202
slouken@0
   203
/* Lock the event queue, take a peep at it, and unlock it */
slouken@1895
   204
int
slouken@1895
   205
SDL_PeepEvents(SDL_Event * events, int numevents, SDL_eventaction action,
slouken@4429
   206
               Uint32 minType, Uint32 maxType)
slouken@0
   207
{
slouken@1895
   208
    int i, used;
slouken@0
   209
slouken@1895
   210
    /* Don't look after we've quit */
slouken@1895
   211
    if (!SDL_EventQ.active) {
slouken@1895
   212
        return (-1);
slouken@1895
   213
    }
slouken@1895
   214
    /* Lock the event queue */
slouken@1895
   215
    used = 0;
slouken@6977
   216
    if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
slouken@1895
   217
        if (action == SDL_ADDEVENT) {
slouken@1895
   218
            for (i = 0; i < numevents; ++i) {
slouken@1895
   219
                used += SDL_AddEvent(&events[i]);
slouken@1895
   220
            }
slouken@1895
   221
        } else {
slouken@1895
   222
            SDL_Event tmpevent;
slouken@1895
   223
            int spot;
slouken@0
   224
slouken@1895
   225
            /* If 'events' is NULL, just see if they exist */
slouken@1895
   226
            if (events == NULL) {
slouken@1895
   227
                action = SDL_PEEKEVENT;
slouken@1895
   228
                numevents = 1;
slouken@1895
   229
                events = &tmpevent;
slouken@1895
   230
            }
slouken@1895
   231
            spot = SDL_EventQ.head;
slouken@1895
   232
            while ((used < numevents) && (spot != SDL_EventQ.tail)) {
slouken@4429
   233
                Uint32 type = SDL_EventQ.event[spot].type;
slouken@4429
   234
                if (minType <= type && type <= maxType) {
slouken@1895
   235
                    events[used++] = SDL_EventQ.event[spot];
slouken@1895
   236
                    if (action == SDL_GETEVENT) {
slouken@1895
   237
                        spot = SDL_CutEvent(spot);
slouken@1895
   238
                    } else {
slouken@1895
   239
                        spot = (spot + 1) % MAXEVENTS;
slouken@1895
   240
                    }
slouken@1895
   241
                } else {
slouken@1895
   242
                    spot = (spot + 1) % MAXEVENTS;
slouken@1895
   243
                }
slouken@1895
   244
            }
slouken@1895
   245
        }
slouken@6977
   246
        SDL_UnlockMutex(SDL_EventQ.lock);
slouken@1895
   247
    } else {
icculus@7037
   248
        return SDL_SetError("Couldn't lock event queue");
slouken@1895
   249
    }
slouken@1895
   250
    return (used);
slouken@1895
   251
}
slouken@1895
   252
slouken@1895
   253
SDL_bool
slouken@4429
   254
SDL_HasEvent(Uint32 type)
slouken@4429
   255
{
slouken@4429
   256
    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0);
slouken@4429
   257
}
slouken@4429
   258
slouken@4429
   259
SDL_bool
slouken@4429
   260
SDL_HasEvents(Uint32 minType, Uint32 maxType)
slouken@4429
   261
{
slouken@4429
   262
    return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0);
slouken@4429
   263
}
slouken@4429
   264
slouken@4429
   265
void
slouken@4429
   266
SDL_FlushEvent(Uint32 type)
slouken@1895
   267
{
slouken@4429
   268
    SDL_FlushEvents(type, type);
slouken@4429
   269
}
slouken@4429
   270
slouken@4429
   271
void
slouken@4429
   272
SDL_FlushEvents(Uint32 minType, Uint32 maxType)
slouken@4429
   273
{
slouken@4429
   274
    /* Don't look after we've quit */
slouken@4429
   275
    if (!SDL_EventQ.active) {
slouken@4429
   276
        return;
slouken@4429
   277
    }
slouken@4429
   278
slouken@4460
   279
    /* Make sure the events are current */
slouken@5293
   280
#if 0
slouken@5293
   281
    /* Actually, we can't do this since we might be flushing while processing
slouken@5293
   282
       a resize event, and calling this might trigger further resize events.
slouken@5293
   283
    */
slouken@4460
   284
    SDL_PumpEvents();
slouken@5293
   285
#endif
slouken@4460
   286
slouken@4429
   287
    /* Lock the event queue */
slouken@6977
   288
    if (SDL_LockMutex(SDL_EventQ.lock) == 0) {
slouken@4429
   289
        int spot = SDL_EventQ.head;
slouken@4429
   290
        while (spot != SDL_EventQ.tail) {
slouken@4429
   291
            Uint32 type = SDL_EventQ.event[spot].type;
slouken@4429
   292
            if (minType <= type && type <= maxType) {
slouken@4429
   293
                spot = SDL_CutEvent(spot);
slouken@4429
   294
            } else {
slouken@4429
   295
                spot = (spot + 1) % MAXEVENTS;
slouken@4429
   296
            }
slouken@4429
   297
        }
slouken@6977
   298
        SDL_UnlockMutex(SDL_EventQ.lock);
slouken@4429
   299
    }
slouken@0
   300
}
slouken@0
   301
slouken@0
   302
/* Run the system dependent event loops */
slouken@1895
   303
void
slouken@1895
   304
SDL_PumpEvents(void)
slouken@0
   305
{
slouken@5123
   306
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
slouken@0
   307
slouken@5123
   308
    /* Get events from the video subsystem */
slouken@5123
   309
    if (_this) {
slouken@5123
   310
        _this->PumpEvents(_this);
slouken@5123
   311
    }
slouken@1361
   312
#if !SDL_JOYSTICK_DISABLED
slouken@5123
   313
    /* Check for joystick state change */
slouken@5123
   314
    if (SDL_ShouldPollJoystick()) {
slouken@5123
   315
        SDL_JoystickUpdate();
slouken@5123
   316
    }
slouken@0
   317
#endif
slouken@0
   318
}
slouken@0
   319
slouken@0
   320
/* Public functions */
slouken@0
   321
slouken@1895
   322
int
slouken@1895
   323
SDL_PollEvent(SDL_Event * event)
slouken@0
   324
{
slouken@3072
   325
    return SDL_WaitEventTimeout(event, 0);
slouken@1895
   326
}
slouken@0
   327
slouken@1895
   328
int
slouken@1895
   329
SDL_WaitEvent(SDL_Event * event)
slouken@1895
   330
{
slouken@3072
   331
    return SDL_WaitEventTimeout(event, -1);
slouken@3072
   332
}
slouken@3072
   333
slouken@3072
   334
int
slouken@3072
   335
SDL_WaitEventTimeout(SDL_Event * event, int timeout)
slouken@3072
   336
{
slouken@3072
   337
    Uint32 expiration = 0;
slouken@3072
   338
slouken@3072
   339
    if (timeout > 0)
slouken@3072
   340
        expiration = SDL_GetTicks() + timeout;
slouken@3072
   341
slouken@3072
   342
    for (;;) {
slouken@1895
   343
        SDL_PumpEvents();
slouken@4429
   344
        switch (SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) {
slouken@1895
   345
        case -1:
slouken@1895
   346
            return 0;
slouken@1895
   347
        case 1:
slouken@1895
   348
            return 1;
slouken@1895
   349
        case 0:
slouken@3072
   350
            if (timeout == 0) {
slouken@3072
   351
                /* Polling and no events, just return */
slouken@3072
   352
                return 0;
slouken@3072
   353
            }
slouken@3072
   354
            if (timeout > 0 && ((int) (SDL_GetTicks() - expiration) >= 0)) {
slouken@3072
   355
                /* Timeout expired and no events */
slouken@3072
   356
                return 0;
slouken@3072
   357
            }
slouken@1895
   358
            SDL_Delay(10);
slouken@3072
   359
            break;
slouken@1895
   360
        }
slouken@1895
   361
    }
slouken@0
   362
}
slouken@0
   363
slouken@1895
   364
int
slouken@1895
   365
SDL_PushEvent(SDL_Event * event)
slouken@0
   366
{
slouken@5146
   367
    SDL_EventWatcher *curr;
slouken@7190
   368
dludwig@7082
   369
    event->common.timestamp = SDL_GetTicks();
slouken@7190
   370
slouken@1895
   371
    if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) {
slouken@1895
   372
        return 0;
slouken@1895
   373
    }
slouken@5146
   374
slouken@5146
   375
    for (curr = SDL_event_watchers; curr; curr = curr->next) {
slouken@5146
   376
        curr->callback(curr->userdata, event);
slouken@5146
   377
    }
slouken@5146
   378
slouken@4429
   379
    if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
slouken@1895
   380
        return -1;
slouken@1895
   381
    }
jim@4657
   382
jim@4657
   383
    SDL_GestureProcessEvent(event);
jim@4657
   384
slouken@1895
   385
    return 1;
slouken@0
   386
}
slouken@0
   387
slouken@1895
   388
void
slouken@1895
   389
SDL_SetEventFilter(SDL_EventFilter filter, void *userdata)
slouken@0
   390
{
slouken@1895
   391
    /* Set filter and discard pending events */
slouken@7201
   392
    SDL_EventOK = NULL;
slouken@7201
   393
    SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
slouken@1895
   394
    SDL_EventOKParam = userdata;
slouken@7201
   395
    SDL_EventOK = filter;
slouken@0
   396
}
slouken@0
   397
slouken@1895
   398
SDL_bool
slouken@1895
   399
SDL_GetEventFilter(SDL_EventFilter * filter, void **userdata)
slouken@0
   400
{
slouken@1895
   401
    if (filter) {
slouken@1895
   402
        *filter = SDL_EventOK;
slouken@1895
   403
    }
slouken@1895
   404
    if (userdata) {
slouken@1895
   405
        *userdata = SDL_EventOKParam;
slouken@1895
   406
    }
slouken@1895
   407
    return SDL_EventOK ? SDL_TRUE : SDL_FALSE;
slouken@0
   408
}
slouken@0
   409
slouken@5146
   410
/* FIXME: This is not thread-safe yet */
slouken@5146
   411
void
slouken@5146
   412
SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
slouken@5146
   413
{
slouken@5146
   414
    SDL_EventWatcher *watcher;
slouken@5146
   415
slouken@5146
   416
    watcher = (SDL_EventWatcher *)SDL_malloc(sizeof(*watcher));
slouken@5146
   417
    if (!watcher) {
slouken@5146
   418
        /* Uh oh... */
slouken@5146
   419
        return;
slouken@5146
   420
    }
slouken@5146
   421
    watcher->callback = filter;
slouken@5146
   422
    watcher->userdata = userdata;
slouken@5146
   423
    watcher->next = SDL_event_watchers;
slouken@5146
   424
    SDL_event_watchers = watcher;
slouken@5146
   425
}
slouken@5146
   426
slouken@5146
   427
/* FIXME: This is not thread-safe yet */
slouken@5146
   428
void
slouken@5146
   429
SDL_DelEventWatch(SDL_EventFilter filter, void *userdata)
slouken@5146
   430
{
slouken@5146
   431
    SDL_EventWatcher *prev = NULL;
slouken@5146
   432
    SDL_EventWatcher *curr;
slouken@5146
   433
slouken@5146
   434
    for (curr = SDL_event_watchers; curr; prev = curr, curr = curr->next) {
slouken@5146
   435
        if (curr->callback == filter && curr->userdata == userdata) {
slouken@5146
   436
            if (prev) {
slouken@5146
   437
                prev->next = curr->next;
slouken@5146
   438
            } else {
slouken@5146
   439
                SDL_event_watchers = curr->next;
slouken@5146
   440
            }
slouken@5146
   441
            SDL_free(curr);
slouken@5146
   442
            break;
slouken@5146
   443
        }
slouken@5146
   444
    }
slouken@5146
   445
}
slouken@5146
   446
slouken@1895
   447
void
slouken@1895
   448
SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
slouken@0
   449
{
slouken@6977
   450
    if (SDL_LockMutex(SDL_EventQ.lock) == 0) {
slouken@1895
   451
        int spot;
slouken@1895
   452
slouken@1895
   453
        spot = SDL_EventQ.head;
slouken@1895
   454
        while (spot != SDL_EventQ.tail) {
slouken@1895
   455
            if (filter(userdata, &SDL_EventQ.event[spot])) {
slouken@1895
   456
                spot = (spot + 1) % MAXEVENTS;
slouken@1895
   457
            } else {
slouken@1895
   458
                spot = SDL_CutEvent(spot);
slouken@1895
   459
            }
slouken@1895
   460
        }
slouken@1895
   461
    }
slouken@6977
   462
    SDL_UnlockMutex(SDL_EventQ.lock);
slouken@1895
   463
}
slouken@1895
   464
slouken@1895
   465
Uint8
slouken@4429
   466
SDL_EventState(Uint32 type, int state)
slouken@1895
   467
{
slouken@1895
   468
    Uint8 current_state;
slouken@4429
   469
    Uint8 hi = ((type >> 8) & 0xff);
slouken@4429
   470
    Uint8 lo = (type & 0xff);
slouken@0
   471
slouken@4429
   472
    if (SDL_disabled_events[hi] &&
slouken@4429
   473
        (SDL_disabled_events[hi]->bits[lo/32] & (1 << (lo&31)))) {
slouken@4429
   474
        current_state = SDL_DISABLE;
slouken@4429
   475
    } else {
slouken@4429
   476
        current_state = SDL_ENABLE;
slouken@1895
   477
    }
slouken@0
   478
slouken@4429
   479
    if (state != current_state)
slouken@4429
   480
    {
slouken@4429
   481
        switch (state) {
slouken@4429
   482
        case SDL_DISABLE:
slouken@4429
   483
            /* Disable this event type and discard pending events */
slouken@4429
   484
            if (!SDL_disabled_events[hi]) {
slouken@4429
   485
                SDL_disabled_events[hi] = (SDL_DisabledEventBlock*) SDL_calloc(1, sizeof(SDL_DisabledEventBlock));
slouken@4429
   486
                if (!SDL_disabled_events[hi]) {
slouken@4429
   487
                    /* Out of memory, nothing we can do... */
slouken@4429
   488
                    break;
slouken@4429
   489
                }
slouken@4429
   490
            }
slouken@4429
   491
            SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
slouken@4429
   492
            SDL_FlushEvent(type);
slouken@4429
   493
            break;
slouken@4429
   494
        case SDL_ENABLE:
slouken@4429
   495
            SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
slouken@4429
   496
            break;
slouken@4429
   497
        default:
slouken@4429
   498
            /* Querying state... */
slouken@4429
   499
            break;
slouken@1895
   500
        }
slouken@1895
   501
    }
slouken@4429
   502
slouken@4429
   503
    return current_state;
slouken@4429
   504
}
slouken@4429
   505
slouken@4429
   506
Uint32
slouken@4429
   507
SDL_RegisterEvents(int numevents)
slouken@4429
   508
{
slouken@4429
   509
    Uint32 event_base;
slouken@4429
   510
slouken@4429
   511
    if (SDL_userevents+numevents <= SDL_LASTEVENT) {
slouken@4429
   512
        event_base = SDL_userevents;
slouken@4429
   513
        SDL_userevents += numevents;
slouken@4429
   514
    } else {
slouken@4429
   515
        event_base = (Uint32)-1;
slouken@4429
   516
    }
slouken@4429
   517
    return event_base;
slouken@0
   518
}
slouken@0
   519
slouken@7190
   520
int
slouken@7190
   521
SDL_SendAppEvent(SDL_EventType eventType)
slouken@7190
   522
{
slouken@7190
   523
    int posted;
slouken@7190
   524
slouken@7190
   525
    posted = 0;
slouken@7190
   526
    if (SDL_GetEventState(eventType) == SDL_ENABLE) {
slouken@7190
   527
        SDL_Event event;
slouken@7190
   528
        event.type = eventType;
slouken@7190
   529
        posted = (SDL_PushEvent(&event) > 0);
slouken@7190
   530
    }
slouken@7190
   531
    return (posted);
slouken@7190
   532
}
slouken@7190
   533
slouken@1895
   534
int
slouken@1895
   535
SDL_SendSysWMEvent(SDL_SysWMmsg * message)
slouken@0
   536
{
slouken@1895
   537
    int posted;
slouken@0
   538
slouken@1895
   539
    posted = 0;
slouken@4429
   540
    if (SDL_GetEventState(SDL_SYSWMEVENT) == SDL_ENABLE) {
slouken@1895
   541
        SDL_Event event;
slouken@1895
   542
        SDL_memset(&event, 0, sizeof(event));
slouken@1895
   543
        event.type = SDL_SYSWMEVENT;
slouken@1895
   544
        event.syswm.msg = message;
slouken@1895
   545
        posted = (SDL_PushEvent(&event) > 0);
slouken@1895
   546
    }
slouken@1895
   547
    /* Update internal event state */
slouken@1895
   548
    return (posted);
slouken@0
   549
}
slouken@1895
   550
slouken@1895
   551
/* vi: set ts=4 sw=4 expandtab: */