SDL  2.0
SDL_events.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../SDL_internal.h"
22 
23 /* General event handling code for SDL */
24 
25 #include "SDL.h"
26 #include "SDL_events.h"
27 #include "SDL_syswm.h"
28 #include "SDL_thread.h"
29 #include "SDL_events_c.h"
30 #include "../timer/SDL_timer_c.h"
31 #if !SDL_JOYSTICK_DISABLED
32 #include "../joystick/SDL_joystick_c.h"
33 #endif
34 #include "../video/SDL_sysvideo.h"
35 
36 /* An arbitrary limit so we don't have unbounded growth */
37 #define SDL_MAX_QUEUED_EVENTS 65535
38 
39 /* Public data -- the event filter */
42 
43 typedef struct SDL_EventWatcher {
45  void *userdata;
48 
50 
51 typedef struct {
54 
57 
58 /* Private data -- event queue */
59 typedef struct _SDL_EventEntry
60 {
63  struct _SDL_EventEntry *prev;
64  struct _SDL_EventEntry *next;
66 
67 typedef struct _SDL_SysWMEntry
68 {
70  struct _SDL_SysWMEntry *next;
72 
73 static struct
74 {
76  volatile SDL_bool active;
77  volatile int count;
78  volatile int max_events_seen;
84 } SDL_EventQ = { NULL, SDL_TRUE, 0, 0, NULL, NULL, NULL, NULL, NULL };
85 
86 
87 /* Public functions */
88 
89 void
91 {
92  const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS");
93  int i;
94  SDL_EventEntry *entry;
95  SDL_SysWMEntry *wmmsg;
96 
97  if (SDL_EventQ.lock) {
99  }
100 
101  SDL_EventQ.active = SDL_FALSE;
102 
103  if (report && SDL_atoi(report)) {
104  SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
105  SDL_EventQ.max_events_seen);
106  }
107 
108  /* Clean out EventQ */
109  for (entry = SDL_EventQ.head; entry; ) {
110  SDL_EventEntry *next = entry->next;
111  SDL_free(entry);
112  entry = next;
113  }
114  for (entry = SDL_EventQ.free; entry; ) {
115  SDL_EventEntry *next = entry->next;
116  SDL_free(entry);
117  entry = next;
118  }
119  for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; ) {
120  SDL_SysWMEntry *next = wmmsg->next;
121  SDL_free(wmmsg);
122  wmmsg = next;
123  }
124  for (wmmsg = SDL_EventQ.wmmsg_free; wmmsg; ) {
125  SDL_SysWMEntry *next = wmmsg->next;
126  SDL_free(wmmsg);
127  wmmsg = next;
128  }
129 
130  SDL_EventQ.count = 0;
131  SDL_EventQ.max_events_seen = 0;
132  SDL_EventQ.head = NULL;
133  SDL_EventQ.tail = NULL;
134  SDL_EventQ.free = NULL;
135  SDL_EventQ.wmmsg_used = NULL;
136  SDL_EventQ.wmmsg_free = NULL;
137 
138  /* Clear disabled event state */
139  for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
140  SDL_free(SDL_disabled_events[i]);
141  SDL_disabled_events[i] = NULL;
142  }
143 
144  while (SDL_event_watchers) {
146  SDL_event_watchers = tmp->next;
147  SDL_free(tmp);
148  }
149  SDL_EventOK = NULL;
150 
151  if (SDL_EventQ.lock) {
154  SDL_EventQ.lock = NULL;
155  }
156 }
157 
158 /* This function (and associated calls) may be called more than once */
159 int
161 {
162  /* We'll leave the event queue alone, since we might have gotten
163  some important events at launch (like SDL_DROPFILE)
164 
165  FIXME: Does this introduce any other bugs with events at startup?
166  */
167 
168  /* Create the lock and set ourselves active */
169 #if !SDL_THREADS_DISABLED
170  if (!SDL_EventQ.lock) {
171  SDL_EventQ.lock = SDL_CreateMutex();
172  }
173  if (SDL_EventQ.lock == NULL) {
174  return (-1);
175  }
176 #endif /* !SDL_THREADS_DISABLED */
177 
178  /* Process most event types */
182 
183  SDL_EventQ.active = SDL_TRUE;
184 
185  return (0);
186 }
187 
188 
189 /* Add an event to the event queue -- called with the queue locked */
190 static int
192 {
193  SDL_EventEntry *entry;
194 
195  if (SDL_EventQ.count >= SDL_MAX_QUEUED_EVENTS) {
196  SDL_SetError("Event queue is full (%d events)", SDL_EventQ.count);
197  return 0;
198  }
199 
200  if (SDL_EventQ.free == NULL) {
201  entry = (SDL_EventEntry *)SDL_malloc(sizeof(*entry));
202  if (!entry) {
203  return 0;
204  }
205  } else {
206  entry = SDL_EventQ.free;
207  SDL_EventQ.free = entry->next;
208  }
209 
210  entry->event = *event;
211  if (event->type == SDL_SYSWMEVENT) {
212  entry->msg = *event->syswm.msg;
213  entry->event.syswm.msg = &entry->msg;
214  }
215 
216  if (SDL_EventQ.tail) {
217  SDL_EventQ.tail->next = entry;
218  entry->prev = SDL_EventQ.tail;
219  SDL_EventQ.tail = entry;
220  entry->next = NULL;
221  } else {
222  SDL_assert(!SDL_EventQ.head);
223  SDL_EventQ.head = entry;
224  SDL_EventQ.tail = entry;
225  entry->prev = NULL;
226  entry->next = NULL;
227  }
228  ++SDL_EventQ.count;
229 
230  if (SDL_EventQ.count > SDL_EventQ.max_events_seen) {
231  SDL_EventQ.max_events_seen = SDL_EventQ.count;
232  }
233 
234  return 1;
235 }
236 
237 /* Remove an event from the queue -- called with the queue locked */
238 static void
240 {
241  if (entry->prev) {
242  entry->prev->next = entry->next;
243  }
244  if (entry->next) {
245  entry->next->prev = entry->prev;
246  }
247 
248  if (entry == SDL_EventQ.head) {
249  SDL_assert(entry->prev == NULL);
250  SDL_EventQ.head = entry->next;
251  }
252  if (entry == SDL_EventQ.tail) {
253  SDL_assert(entry->next == NULL);
254  SDL_EventQ.tail = entry->prev;
255  }
256 
257  entry->next = SDL_EventQ.free;
258  SDL_EventQ.free = entry;
259  SDL_assert(SDL_EventQ.count > 0);
260  --SDL_EventQ.count;
261 }
262 
263 /* Lock the event queue, take a peep at it, and unlock it */
264 int
266  Uint32 minType, Uint32 maxType)
267 {
268  int i, used;
269 
270  /* Don't look after we've quit */
271  if (!SDL_EventQ.active) {
272  /* We get a few spurious events at shutdown, so don't warn then */
273  if (action != SDL_ADDEVENT) {
274  SDL_SetError("The event system has been shut down");
275  }
276  return (-1);
277  }
278  /* Lock the event queue */
279  used = 0;
280  if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
281  if (action == SDL_ADDEVENT) {
282  for (i = 0; i < numevents; ++i) {
283  used += SDL_AddEvent(&events[i]);
284  }
285  } else {
286  SDL_EventEntry *entry, *next;
287  SDL_SysWMEntry *wmmsg, *wmmsg_next;
288  SDL_Event tmpevent;
289  Uint32 type;
290 
291  /* If 'events' is NULL, just see if they exist */
292  if (events == NULL) {
293  action = SDL_PEEKEVENT;
294  numevents = 1;
295  events = &tmpevent;
296  }
297 
298  /* Clean out any used wmmsg data
299  FIXME: Do we want to retain the data for some period of time?
300  */
301  for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
302  wmmsg_next = wmmsg->next;
303  wmmsg->next = SDL_EventQ.wmmsg_free;
304  SDL_EventQ.wmmsg_free = wmmsg;
305  }
306  SDL_EventQ.wmmsg_used = NULL;
307 
308  for (entry = SDL_EventQ.head; entry && used < numevents; entry = next) {
309  next = entry->next;
310  type = entry->event.type;
311  if (minType <= type && type <= maxType) {
312  events[used] = entry->event;
313  if (entry->event.type == SDL_SYSWMEVENT) {
314  /* We need to copy the wmmsg somewhere safe.
315  For now we'll guarantee it's valid at least until
316  the next call to SDL_PeepEvents()
317  */
318  if (SDL_EventQ.wmmsg_free) {
319  wmmsg = SDL_EventQ.wmmsg_free;
320  SDL_EventQ.wmmsg_free = wmmsg->next;
321  } else {
322  wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
323  }
324  wmmsg->msg = *entry->event.syswm.msg;
325  wmmsg->next = SDL_EventQ.wmmsg_used;
326  SDL_EventQ.wmmsg_used = wmmsg;
327  events[used].syswm.msg = &wmmsg->msg;
328  }
329  ++used;
330 
331  if (action == SDL_GETEVENT) {
332  SDL_CutEvent(entry);
333  }
334  }
335  }
336  }
338  } else {
339  return SDL_SetError("Couldn't lock event queue");
340  }
341  return (used);
342 }
343 
344 SDL_bool
346 {
347  return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0);
348 }
349 
350 SDL_bool
351 SDL_HasEvents(Uint32 minType, Uint32 maxType)
352 {
353  return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0);
354 }
355 
356 void
358 {
359  SDL_FlushEvents(type, type);
360 }
361 
362 void
363 SDL_FlushEvents(Uint32 minType, Uint32 maxType)
364 {
365  /* Don't look after we've quit */
366  if (!SDL_EventQ.active) {
367  return;
368  }
369 
370  /* Make sure the events are current */
371 #if 0
372  /* Actually, we can't do this since we might be flushing while processing
373  a resize event, and calling this might trigger further resize events.
374  */
375  SDL_PumpEvents();
376 #endif
377 
378  /* Lock the event queue */
379  if (SDL_LockMutex(SDL_EventQ.lock) == 0) {
380  SDL_EventEntry *entry, *next;
381  Uint32 type;
382  for (entry = SDL_EventQ.head; entry; entry = next) {
383  next = entry->next;
384  type = entry->event.type;
385  if (minType <= type && type <= maxType) {
386  SDL_CutEvent(entry);
387  }
388  }
390  }
391 }
392 
393 /* Run the system dependent event loops */
394 void
396 {
398 
399  /* Get events from the video subsystem */
400  if (_this) {
401  _this->PumpEvents(_this);
402  }
403 #if !SDL_JOYSTICK_DISABLED
404  /* Check for joystick state change */
405  if ((!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] || SDL_JoystickEventState(SDL_QUERY))) {
407  }
408 #endif
409 
410  SDL_SendPendingQuit(); /* in case we had a signal handler fire, etc. */
411 }
412 
413 /* Public functions */
414 
415 int
417 {
418  return SDL_WaitEventTimeout(event, 0);
419 }
420 
421 int
423 {
424  return SDL_WaitEventTimeout(event, -1);
425 }
426 
427 int
429 {
430  Uint32 expiration = 0;
431 
432  if (timeout > 0)
433  expiration = SDL_GetTicks() + timeout;
434 
435  for (;;) {
436  SDL_PumpEvents();
438  case -1:
439  return 0;
440  case 1:
441  return 1;
442  case 0:
443  if (timeout == 0) {
444  /* Polling and no events, just return */
445  return 0;
446  }
447  if (timeout > 0 && SDL_TICKS_PASSED(SDL_GetTicks(), expiration)) {
448  /* Timeout expired and no events */
449  return 0;
450  }
451  SDL_Delay(10);
452  break;
453  }
454  }
455 }
456 
457 int
459 {
460  SDL_EventWatcher *curr;
461 
462  event->common.timestamp = SDL_GetTicks();
463 
464  if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) {
465  return 0;
466  }
467 
468  for (curr = SDL_event_watchers; curr; curr = curr->next) {
469  curr->callback(curr->userdata, event);
470  }
471 
472  if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
473  return -1;
474  }
475 
477 
478  return 1;
479 }
480 
481 void
483 {
484  /* Set filter and discard pending events */
485  SDL_EventOK = NULL;
489 }
490 
491 SDL_bool
493 {
494  if (filter) {
495  *filter = SDL_EventOK;
496  }
497  if (userdata) {
498  *userdata = SDL_EventOKParam;
499  }
500  return SDL_EventOK ? SDL_TRUE : SDL_FALSE;
501 }
502 
503 /* FIXME: This is not thread-safe yet */
504 void
506 {
507  SDL_EventWatcher *watcher, *tail;
508 
509  watcher = (SDL_EventWatcher *)SDL_malloc(sizeof(*watcher));
510  if (!watcher) {
511  /* Uh oh... */
512  return;
513  }
514 
515  /* create the watcher */
516  watcher->callback = filter;
517  watcher->userdata = userdata;
518  watcher->next = NULL;
519 
520  /* add the watcher to the end of the list */
521  if (SDL_event_watchers) {
522  for (tail = SDL_event_watchers; tail->next; tail = tail->next) {
523  continue;
524  }
525  tail->next = watcher;
526  } else {
527  SDL_event_watchers = watcher;
528  }
529 }
530 
531 /* FIXME: This is not thread-safe yet */
532 void
534 {
535  SDL_EventWatcher *prev = NULL;
536  SDL_EventWatcher *curr;
537 
538  for (curr = SDL_event_watchers; curr; prev = curr, curr = curr->next) {
539  if (curr->callback == filter && curr->userdata == userdata) {
540  if (prev) {
541  prev->next = curr->next;
542  } else {
543  SDL_event_watchers = curr->next;
544  }
545  SDL_free(curr);
546  break;
547  }
548  }
549 }
550 
551 void
553 {
554  if (SDL_EventQ.lock && SDL_LockMutex(SDL_EventQ.lock) == 0) {
555  SDL_EventEntry *entry, *next;
556  for (entry = SDL_EventQ.head; entry; entry = next) {
557  next = entry->next;
558  if (!filter(userdata, &entry->event)) {
559  SDL_CutEvent(entry);
560  }
561  }
563  }
564 }
565 
566 Uint8
568 {
569  Uint8 current_state;
570  Uint8 hi = ((type >> 8) & 0xff);
571  Uint8 lo = (type & 0xff);
572 
573  if (SDL_disabled_events[hi] &&
574  (SDL_disabled_events[hi]->bits[lo/32] & (1 << (lo&31)))) {
575  current_state = SDL_DISABLE;
576  } else {
577  current_state = SDL_ENABLE;
578  }
579 
580  if (state != current_state)
581  {
582  switch (state) {
583  case SDL_DISABLE:
584  /* Disable this event type and discard pending events */
585  if (!SDL_disabled_events[hi]) {
586  SDL_disabled_events[hi] = (SDL_DisabledEventBlock*) SDL_calloc(1, sizeof(SDL_DisabledEventBlock));
587  if (!SDL_disabled_events[hi]) {
588  /* Out of memory, nothing we can do... */
589  break;
590  }
591  }
592  SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
593  SDL_FlushEvent(type);
594  break;
595  case SDL_ENABLE:
596  SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
597  break;
598  default:
599  /* Querying state... */
600  break;
601  }
602  }
603 
604  return current_state;
605 }
606 
607 Uint32
608 SDL_RegisterEvents(int numevents)
609 {
610  Uint32 event_base;
611 
612  if ((numevents > 0) && (SDL_userevents+numevents <= SDL_LASTEVENT)) {
613  event_base = SDL_userevents;
614  SDL_userevents += numevents;
615  } else {
616  event_base = (Uint32)-1;
617  }
618  return event_base;
619 }
620 
621 int
623 {
624  int posted;
625 
626  posted = 0;
627  if (SDL_GetEventState(eventType) == SDL_ENABLE) {
629  event.type = eventType;
630  posted = (SDL_PushEvent(&event) > 0);
631  }
632  return (posted);
633 }
634 
635 int
637 {
638  int posted;
639 
640  posted = 0;
643  SDL_memset(&event, 0, sizeof(event));
644  event.type = SDL_SYSWMEVENT;
645  event.syswm.msg = message;
646  posted = (SDL_PushEvent(&event) > 0);
647  }
648  /* Update internal event state */
649  return (posted);
650 }
651 
652 int
654 {
656 }
657 
658 /* vi: set ts=4 sw=4 expandtab: */
SDL_SysWMEntry * wmmsg_used
Definition: SDL_events.c:82
SDL_eventaction
Definition: SDL_events.h:572
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 minType, Uint32 maxType)
Definition: SDL_events.c:265
int SDL_WaitEventTimeout(SDL_Event *event, int timeout)
Waits until the specified timeout (in milliseconds) for the next available event. ...
Definition: SDL_events.c:428
#define SDL_LockMutex
volatile SDL_bool active
Definition: SDL_events.c:76
SDL_bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata)
Definition: SDL_events.c:492
struct _SDL_EventEntry * next
Definition: SDL_events.c:64
static SDL_EventWatcher * SDL_event_watchers
Definition: SDL_events.c:49
void SDL_PumpEvents(void)
Definition: SDL_events.c:395
SDL_SysWMmsg msg
Definition: SDL_events.c:69
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
GLuint GLsizei const GLchar * message
SDL_EventFilter callback
Definition: SDL_events.c:44
SDL_bool SDL_HasEvent(Uint32 type)
Definition: SDL_events.c:345
static int SDL_AddEvent(SDL_Event *event)
Definition: SDL_events.c:191
volatile int max_events_seen
Definition: SDL_events.c:78
SDL_SysWMmsg * msg
Definition: SDL_events.h:515
#define SDL_CreateMutex
struct xkb_state * state
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:36
SDL_EventEntry * free
Definition: SDL_events.c:81
int SDL_StartEventLoop(void)
Definition: SDL_events.c:160
#define SDL_MAX_QUEUED_EVENTS
Definition: SDL_events.c:37
int(* SDL_EventFilter)(void *userdata, SDL_Event *event)
Definition: SDL_events.h:658
#define SDL_GetHint
SDL_Event event
Definition: SDL_events.c:61
#define SDL_ENABLE
Definition: SDL_events.h:718
Definition: SDL_events.c:67
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
union SDL_SysWMmsg::@16 msg
SDL_bool SDL_HasEvents(Uint32 minType, Uint32 maxType)
Definition: SDL_events.c:351
int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
Definition: SDL_events.c:636
static SDL_VideoDevice * _this
Definition: SDL_video.c:114
SDL_bool
Definition: SDL_stdinc.h:126
struct _SDL_SysWMEntry * next
Definition: SDL_events.c:70
void SDL_GestureProcessEvent(SDL_Event *event)
Definition: SDL_gesture.c:510
#define SDL_Log
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1564
void SDL_FlushEvents(Uint32 minType, Uint32 maxType)
Definition: SDL_events.c:363
void * SDL_calloc(size_t nmemb, size_t size)
#define SDL_GetEventState(type)
Definition: SDL_events.h:731
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
struct _cl_event * event
struct SDL_EventWatcher * next
Definition: SDL_events.c:46
void SDL_free(void *mem)
SDL_EventFilter SDL_EventOK
Definition: SDL_events.c:40
SDL_EventType
The types of events that can be delivered.
Definition: SDL_events.h:55
void SDL_FlushEvent(Uint32 type)
Definition: SDL_events.c:357
int SDL_PushEvent(SDL_Event *event)
Add an event to the event queue.
Definition: SDL_events.c:458
void SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:552
Definition: SDL_events.c:59
static void SDL_CutEvent(SDL_EventEntry *entry)
Definition: SDL_events.c:239
#define SDL_atoi
Uint8 SDL_EventState(Uint32 type, int state)
Definition: SDL_events.c:567
#define SDL_Delay
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:42
#define SDL_assert(condition)
Definition: SDL_assert.h:167
void * SDL_EventOKParam
Definition: SDL_events.c:41
#define SDL_DISABLE
Definition: SDL_events.h:717
#define NULL
Definition: begin_code.h:143
SDL_EventEntry * tail
Definition: SDL_events.c:80
#define SDL_JoystickUpdate
#define SDL_SetError
SDL_SysWMEvent syswm
Definition: SDL_events.h:543
#define SDL_DestroyMutex
int SDL_SendKeymapChangedEvent(void)
Definition: SDL_events.c:653
void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:533
struct _SDL_EventEntry * prev
Definition: SDL_events.c:63
SDL_mutex * lock
Definition: SDL_events.c:75
static Uint32 SDL_userevents
Definition: SDL_events.c:56
GLbitfield GLuint64 timeout
static SDL_DisabledEventBlock * SDL_disabled_events[256]
Definition: SDL_events.c:55
SDL_SysWMEntry * wmmsg_free
Definition: SDL_events.c:83
volatile int count
Definition: SDL_events.c:77
#define SDL_JoystickEventState
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:573
#define SDL_UnlockMutex
void SDL_SendPendingQuit(void)
Definition: SDL_quit.c:146
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:93
General event structure.
Definition: SDL_events.h:521
#define SDL_malloc
int SDL_PollEvent(SDL_Event *event)
Polls for currently pending events.
Definition: SDL_events.c:416
int SDL_SendAppEvent(SDL_EventType eventType)
Definition: SDL_events.c:622
void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:505
#define SDL_QUERY
Definition: SDL_events.h:715
int SDL_WaitEvent(SDL_Event *event)
Waits indefinitely for the next available event.
Definition: SDL_events.c:422
SDL_EventEntry * head
Definition: SDL_events.c:79
static struct @21 SDL_EventQ
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
void SDL_SetEventFilter(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:482
#define SDL_memset
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Uint32 type
Definition: SDL_events.h:523
void SDL_StopEventLoop(void)
Definition: SDL_events.c:90
void(* PumpEvents)(_THIS)
Definition: SDL_sysvideo.h:249
Uint32 SDL_RegisterEvents(int numevents)
Definition: SDL_events.c:608
SDL_SysWMmsg msg
Definition: SDL_events.c:62