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 {
84 } SDL_EventQ = { NULL, { 1 }, { 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_AtomicSet(&SDL_EventQ.active, 0);
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_AtomicSet(&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_AtomicSet(&SDL_EventQ.active, 1);
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  const int initial_count = SDL_AtomicGet(&SDL_EventQ.count);
195  int final_count;
196 
197  if (initial_count >= SDL_MAX_QUEUED_EVENTS) {
198  SDL_SetError("Event queue is full (%d events)", initial_count);
199  return 0;
200  }
201 
202  if (SDL_EventQ.free == NULL) {
203  entry = (SDL_EventEntry *)SDL_malloc(sizeof(*entry));
204  if (!entry) {
205  return 0;
206  }
207  } else {
208  entry = SDL_EventQ.free;
209  SDL_EventQ.free = entry->next;
210  }
211 
212  entry->event = *event;
213  if (event->type == SDL_SYSWMEVENT) {
214  entry->msg = *event->syswm.msg;
215  entry->event.syswm.msg = &entry->msg;
216  }
217 
218  if (SDL_EventQ.tail) {
219  SDL_EventQ.tail->next = entry;
220  entry->prev = SDL_EventQ.tail;
221  SDL_EventQ.tail = entry;
222  entry->next = NULL;
223  } else {
224  SDL_assert(!SDL_EventQ.head);
225  SDL_EventQ.head = entry;
226  SDL_EventQ.tail = entry;
227  entry->prev = NULL;
228  entry->next = NULL;
229  }
230 
231  final_count = SDL_AtomicAdd(&SDL_EventQ.count, 1) + 1;
232  if (final_count > SDL_EventQ.max_events_seen) {
233  SDL_EventQ.max_events_seen = final_count;
234  }
235 
236  return 1;
237 }
238 
239 /* Remove an event from the queue -- called with the queue locked */
240 static void
242 {
243  if (entry->prev) {
244  entry->prev->next = entry->next;
245  }
246  if (entry->next) {
247  entry->next->prev = entry->prev;
248  }
249 
250  if (entry == SDL_EventQ.head) {
251  SDL_assert(entry->prev == NULL);
252  SDL_EventQ.head = entry->next;
253  }
254  if (entry == SDL_EventQ.tail) {
255  SDL_assert(entry->next == NULL);
256  SDL_EventQ.tail = entry->prev;
257  }
258 
259  entry->next = SDL_EventQ.free;
260  SDL_EventQ.free = entry;
261  SDL_assert(SDL_AtomicGet(&SDL_EventQ.count) > 0);
262  SDL_AtomicAdd(&SDL_EventQ.count, -1);
263 }
264 
265 /* Lock the event queue, take a peep at it, and unlock it */
266 int
268  Uint32 minType, Uint32 maxType)
269 {
270  int i, used;
271 
272  /* Don't look after we've quit */
273  if (!SDL_AtomicGet(&SDL_EventQ.active)) {
274  /* We get a few spurious events at shutdown, so don't warn then */
275  if (action != SDL_ADDEVENT) {
276  SDL_SetError("The event system has been shut down");
277  }
278  return (-1);
279  }
280  /* Lock the event queue */
281  used = 0;
282  if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
283  if (action == SDL_ADDEVENT) {
284  for (i = 0; i < numevents; ++i) {
285  used += SDL_AddEvent(&events[i]);
286  }
287  } else {
288  SDL_EventEntry *entry, *next;
289  SDL_SysWMEntry *wmmsg, *wmmsg_next;
290  Uint32 type;
291 
292  if (action == SDL_GETEVENT) {
293  /* Clean out any used wmmsg data
294  FIXME: Do we want to retain the data for some period of time?
295  */
296  for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
297  wmmsg_next = wmmsg->next;
298  wmmsg->next = SDL_EventQ.wmmsg_free;
299  SDL_EventQ.wmmsg_free = wmmsg;
300  }
301  SDL_EventQ.wmmsg_used = NULL;
302  }
303 
304  for (entry = SDL_EventQ.head; entry && (!events || used < numevents); entry = next) {
305  next = entry->next;
306  type = entry->event.type;
307  if (minType <= type && type <= maxType) {
308  if (events) {
309  events[used] = entry->event;
310  if (entry->event.type == SDL_SYSWMEVENT) {
311  /* We need to copy the wmmsg somewhere safe.
312  For now we'll guarantee it's valid at least until
313  the next call to SDL_PeepEvents()
314  */
315  if (SDL_EventQ.wmmsg_free) {
316  wmmsg = SDL_EventQ.wmmsg_free;
317  SDL_EventQ.wmmsg_free = wmmsg->next;
318  } else {
319  wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
320  }
321  wmmsg->msg = *entry->event.syswm.msg;
322  wmmsg->next = SDL_EventQ.wmmsg_used;
323  SDL_EventQ.wmmsg_used = wmmsg;
324  events[used].syswm.msg = &wmmsg->msg;
325  }
326 
327  if (action == SDL_GETEVENT) {
328  SDL_CutEvent(entry);
329  }
330  }
331  ++used;
332  }
333  }
334  }
335  if (SDL_EventQ.lock) {
337  }
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_AtomicGet(&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_EventQ.lock && 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 0:
441  if (timeout == 0) {
442  /* Polling and no events, just return */
443  return 0;
444  }
445  if (timeout > 0 && SDL_TICKS_PASSED(SDL_GetTicks(), expiration)) {
446  /* Timeout expired and no events */
447  return 0;
448  }
449  SDL_Delay(10);
450  break;
451  default:
452  /* Has events */
453  return 1;
454  }
455  }
456 }
457 
458 int
460 {
461  SDL_EventWatcher *curr;
462 
463  event->common.timestamp = SDL_GetTicks();
464 
465  if (SDL_EventOK && !SDL_EventOK(SDL_EventOKParam, event)) {
466  return 0;
467  }
468 
469  for (curr = SDL_event_watchers; curr; curr = curr->next) {
470  curr->callback(curr->userdata, event);
471  }
472 
473  if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
474  return -1;
475  }
476 
478 
479  return 1;
480 }
481 
482 void
484 {
485  /* Set filter and discard pending events */
486  SDL_EventOK = NULL;
490 }
491 
492 SDL_bool
494 {
495  if (filter) {
496  *filter = SDL_EventOK;
497  }
498  if (userdata) {
499  *userdata = SDL_EventOKParam;
500  }
501  return SDL_EventOK ? SDL_TRUE : SDL_FALSE;
502 }
503 
504 /* FIXME: This is not thread-safe yet */
505 void
507 {
508  SDL_EventWatcher *watcher, *tail;
509 
510  watcher = (SDL_EventWatcher *)SDL_malloc(sizeof(*watcher));
511  if (!watcher) {
512  /* Uh oh... */
513  return;
514  }
515 
516  /* create the watcher */
517  watcher->callback = filter;
518  watcher->userdata = userdata;
519  watcher->next = NULL;
520 
521  /* add the watcher to the end of the list */
522  if (SDL_event_watchers) {
523  for (tail = SDL_event_watchers; tail->next; tail = tail->next) {
524  continue;
525  }
526  tail->next = watcher;
527  } else {
528  SDL_event_watchers = watcher;
529  }
530 }
531 
532 /* FIXME: This is not thread-safe yet */
533 void
535 {
536  SDL_EventWatcher *prev = NULL;
537  SDL_EventWatcher *curr;
538 
539  for (curr = SDL_event_watchers; curr; prev = curr, curr = curr->next) {
540  if (curr->callback == filter && curr->userdata == userdata) {
541  if (prev) {
542  prev->next = curr->next;
543  } else {
544  SDL_event_watchers = curr->next;
545  }
546  SDL_free(curr);
547  break;
548  }
549  }
550 }
551 
552 void
554 {
555  if (SDL_EventQ.lock && SDL_LockMutex(SDL_EventQ.lock) == 0) {
556  SDL_EventEntry *entry, *next;
557  for (entry = SDL_EventQ.head; entry; entry = next) {
558  next = entry->next;
559  if (!filter(userdata, &entry->event)) {
560  SDL_CutEvent(entry);
561  }
562  }
564  }
565 }
566 
567 Uint8
569 {
570  Uint8 current_state;
571  Uint8 hi = ((type >> 8) & 0xff);
572  Uint8 lo = (type & 0xff);
573 
574  if (SDL_disabled_events[hi] &&
575  (SDL_disabled_events[hi]->bits[lo/32] & (1 << (lo&31)))) {
576  current_state = SDL_DISABLE;
577  } else {
578  current_state = SDL_ENABLE;
579  }
580 
581  if (state != current_state)
582  {
583  switch (state) {
584  case SDL_DISABLE:
585  /* Disable this event type and discard pending events */
586  if (!SDL_disabled_events[hi]) {
587  SDL_disabled_events[hi] = (SDL_DisabledEventBlock*) SDL_calloc(1, sizeof(SDL_DisabledEventBlock));
588  if (!SDL_disabled_events[hi]) {
589  /* Out of memory, nothing we can do... */
590  break;
591  }
592  }
593  SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
594  SDL_FlushEvent(type);
595  break;
596  case SDL_ENABLE:
597  SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
598  break;
599  default:
600  /* Querying state... */
601  break;
602  }
603  }
604 
605  return current_state;
606 }
607 
608 Uint32
609 SDL_RegisterEvents(int numevents)
610 {
611  Uint32 event_base;
612 
613  if ((numevents > 0) && (SDL_userevents+numevents <= SDL_LASTEVENT)) {
614  event_base = SDL_userevents;
615  SDL_userevents += numevents;
616  } else {
617  event_base = (Uint32)-1;
618  }
619  return event_base;
620 }
621 
622 int
624 {
625  int posted;
626 
627  posted = 0;
628  if (SDL_GetEventState(eventType) == SDL_ENABLE) {
630  event.type = eventType;
631  posted = (SDL_PushEvent(&event) > 0);
632  }
633  return (posted);
634 }
635 
636 int
638 {
639  int posted;
640 
641  posted = 0;
644  SDL_memset(&event, 0, sizeof(event));
645  event.type = SDL_SYSWMEVENT;
646  event.syswm.msg = message;
647  posted = (SDL_PushEvent(&event) > 0);
648  }
649  /* Update internal event state */
650  return (posted);
651 }
652 
653 int
655 {
657 }
658 
659 /* vi: set ts=4 sw=4 expandtab: */
SDL_SysWMEntry * wmmsg_used
Definition: SDL_events.c:82
SDL_eventaction
Definition: SDL_events.h:576
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 minType, Uint32 maxType)
Definition: SDL_events.c:267
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
SDL_bool SDL_GetEventFilter(SDL_EventFilter *filter, void **userdata)
Definition: SDL_events.c:493
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
GLuint GLsizei const GLchar * message
SDL_atomic_t active
Definition: SDL_events.c:76
SDL_EventFilter callback
Definition: SDL_events.c:44
SDL_bool SDL_HasEvent(Uint32 type)
Definition: SDL_events.c:345
A type representing an atomic integer value. It is a struct so people don&#39;t accidentally use numeric ...
Definition: SDL_atomic.h:189
static int SDL_AddEvent(SDL_Event *event)
Definition: SDL_events.c:191
SDL_SysWMmsg * msg
Definition: SDL_events.h:519
#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:662
#define SDL_GetHint
SDL_Event event
Definition: SDL_events.c:61
#define SDL_ENABLE
Definition: SDL_events.h:722
int max_events_seen
Definition: SDL_events.c:78
Definition: SDL_events.c:67
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:159
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:637
static SDL_VideoDevice * _this
Definition: SDL_video.c:118
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:735
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:143
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:459
void SDL_FilterEvents(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:553
Definition: SDL_events.c:59
static void SDL_CutEvent(SDL_EventEntry *entry)
Definition: SDL_events.c:241
#define SDL_atoi
Uint8 SDL_EventState(Uint32 type, int state)
Definition: SDL_events.c:568
#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:50
#define SDL_assert(condition)
Definition: SDL_assert.h:167
void * SDL_EventOKParam
Definition: SDL_events.c:41
#define SDL_DISABLE
Definition: SDL_events.h:721
#define NULL
Definition: begin_code.h:143
#define SDL_AtomicAdd
SDL_bool
Definition: SDL_stdinc.h:130
SDL_EventEntry * tail
Definition: SDL_events.c:80
#define SDL_JoystickUpdate
#define SDL_SetError
SDL_SysWMEvent syswm
Definition: SDL_events.h:547
#define SDL_DestroyMutex
int SDL_SendKeymapChangedEvent(void)
Definition: SDL_events.c:654
void SDL_DelEventWatch(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:534
struct _SDL_EventEntry * prev
Definition: SDL_events.c:63
SDL_mutex * lock
Definition: SDL_events.c:75
SDL_atomic_t count
Definition: SDL_events.c:77
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
#define SDL_AtomicSet
#define SDL_AtomicGet
#define SDL_JoystickEventState
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:571
#define SDL_UnlockMutex
void SDL_SendPendingQuit(void)
Definition: SDL_quit.c:144
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:90
General event structure.
Definition: SDL_events.h:525
#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:623
void SDL_AddEventWatch(SDL_EventFilter filter, void *userdata)
Definition: SDL_events.c:506
#define SDL_QUERY
Definition: SDL_events.h:719
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:483
#define SDL_memset
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Uint32 type
Definition: SDL_events.h:527
void SDL_StopEventLoop(void)
Definition: SDL_events.c:90
void(* PumpEvents)(_THIS)
Definition: SDL_sysvideo.h:262
Uint32 SDL_RegisterEvents(int numevents)
Definition: SDL_events.c:609
SDL_SysWMmsg msg
Definition: SDL_events.c:62