SDL  2.0
SDL_events.c File Reference
#include "../SDL_internal.h"
#include "SDL.h"
#include "SDL_events.h"
#include "SDL_thread.h"
#include "SDL_events_c.h"
#include "../timer/SDL_timer_c.h"
#include "../joystick/SDL_joystick_c.h"
#include "../video/SDL_sysvideo.h"
#include "SDL_syswm.h"
+ Include dependency graph for SDL_events.c:

Go to the source code of this file.

Data Structures

struct  SDL_EventWatcher
 
struct  SDL_DisabledEventBlock
 
struct  SDL_EventEntry
 
struct  SDL_SysWMEntry
 

Macros

#define SDL_MAX_QUEUED_EVENTS   65535
 

Functions

void SDL_StopEventLoop (void)
 
int SDL_StartEventLoop (void)
 
static int SDL_AddEvent (SDL_Event *event)
 
static void SDL_CutEvent (SDL_EventEntry *entry)
 
int SDL_PeepEvents (SDL_Event *events, int numevents, SDL_eventaction action, Uint32 minType, Uint32 maxType)
 
SDL_bool SDL_HasEvent (Uint32 type)
 
SDL_bool SDL_HasEvents (Uint32 minType, Uint32 maxType)
 
void SDL_FlushEvent (Uint32 type)
 
void SDL_FlushEvents (Uint32 minType, Uint32 maxType)
 
void SDL_PumpEvents (void)
 
int SDL_PollEvent (SDL_Event *event)
 Polls for currently pending events. More...
 
int SDL_WaitEvent (SDL_Event *event)
 Waits indefinitely for the next available event. More...
 
int SDL_WaitEventTimeout (SDL_Event *event, int timeout)
 Waits until the specified timeout (in milliseconds) for the next available event. More...
 
int SDL_PushEvent (SDL_Event *event)
 Add an event to the event queue. More...
 
void SDL_SetEventFilter (SDL_EventFilter filter, void *userdata)
 
SDL_bool SDL_GetEventFilter (SDL_EventFilter *filter, void **userdata)
 
void SDL_AddEventWatch (SDL_EventFilter filter, void *userdata)
 
void SDL_DelEventWatch (SDL_EventFilter filter, void *userdata)
 
void SDL_FilterEvents (SDL_EventFilter filter, void *userdata)
 
Uint8 SDL_EventState (Uint32 type, int state)
 
Uint32 SDL_RegisterEvents (int numevents)
 
int SDL_SendAppEvent (SDL_EventType eventType)
 
int SDL_SendSysWMEvent (SDL_SysWMmsg *message)
 
int SDL_SendKeymapChangedEvent (void)
 

Variables

static SDL_mutexSDL_event_watchers_lock
 
static SDL_EventWatcher SDL_EventOK
 
static SDL_EventWatcherSDL_event_watchers = NULL
 
static int SDL_event_watchers_count = 0
 
static SDL_bool SDL_event_watchers_dispatching = SDL_FALSE
 
static SDL_bool SDL_event_watchers_removed = SDL_FALSE
 
static SDL_DisabledEventBlockSDL_disabled_events [256]
 
static Uint32 SDL_userevents = SDL_USEREVENT
 
struct {
   SDL_mutex *   lock
 
   SDL_atomic_t   active
 
   SDL_atomic_t   count
 
   int   max_events_seen
 
   SDL_EventEntry *   head
 
   SDL_EventEntry *   tail
 
   SDL_EventEntry *   free
 
   SDL_SysWMEntry *   wmmsg_used
 
   SDL_SysWMEntry *   wmmsg_free
 
SDL_EventQ = { NULL, { 1 }, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }
 

Macro Definition Documentation

◆ SDL_MAX_QUEUED_EVENTS

#define SDL_MAX_QUEUED_EVENTS   65535

Definition at line 39 of file SDL_events.c.

Function Documentation

◆ SDL_AddEvent()

static int SDL_AddEvent ( SDL_Event event)
static

Definition at line 433 of file SDL_events.c.

434 {
435  SDL_EventEntry *entry;
436  const int initial_count = SDL_AtomicGet(&SDL_EventQ.count);
437  int final_count;
438 
439  if (initial_count >= SDL_MAX_QUEUED_EVENTS) {
440  SDL_SetError("Event queue is full (%d events)", initial_count);
441  return 0;
442  }
443 
444  if (SDL_EventQ.free == NULL) {
445  entry = (SDL_EventEntry *)SDL_malloc(sizeof(*entry));
446  if (!entry) {
447  return 0;
448  }
449  } else {
450  entry = SDL_EventQ.free;
451  SDL_EventQ.free = entry->next;
452  }
453 
454  #ifdef SDL_DEBUG_EVENTS
455  SDL_DebugPrintEvent(event);
456  #endif
457 
458  entry->event = *event;
459  if (event->type == SDL_SYSWMEVENT) {
460  entry->msg = *event->syswm.msg;
461  entry->event.syswm.msg = &entry->msg;
462  }
463 
464  if (SDL_EventQ.tail) {
465  SDL_EventQ.tail->next = entry;
466  entry->prev = SDL_EventQ.tail;
467  SDL_EventQ.tail = entry;
468  entry->next = NULL;
469  } else {
470  SDL_assert(!SDL_EventQ.head);
471  SDL_EventQ.head = entry;
472  SDL_EventQ.tail = entry;
473  entry->prev = NULL;
474  entry->next = NULL;
475  }
476 
477  final_count = SDL_AtomicAdd(&SDL_EventQ.count, 1) + 1;
478  if (final_count > SDL_EventQ.max_events_seen) {
479  SDL_EventQ.max_events_seen = final_count;
480  }
481 
482  return 1;
483 }

References SDL_EventEntry::event, SDL_SysWMEvent::msg, SDL_SysWMmsg::msg, SDL_EventEntry::msg, SDL_EventEntry::next, NULL, SDL_EventEntry::prev, SDL_assert, SDL_AtomicAdd, SDL_AtomicGet, SDL_EventQ, SDL_malloc, SDL_MAX_QUEUED_EVENTS, SDL_SetError, SDL_SYSWMEVENT, and SDL_Event::syswm.

Referenced by SDL_PeepEvents().

◆ SDL_AddEventWatch()

void SDL_AddEventWatch ( SDL_EventFilter  filter,
void userdata 
)

Add a function which is called when an event is added to the queue.

Definition at line 811 of file SDL_events.c.

812 {
814  SDL_EventWatcher *event_watchers;
815 
816  event_watchers = SDL_realloc(SDL_event_watchers, (SDL_event_watchers_count + 1) * sizeof(*event_watchers));
817  if (event_watchers) {
818  SDL_EventWatcher *watcher;
819 
820  SDL_event_watchers = event_watchers;
822  watcher->callback = filter;
823  watcher->userdata = userdata;
824  watcher->removed = SDL_FALSE;
826  }
827 
830  }
831  }
832 }

References SDL_EventWatcher::callback, SDL_EventWatcher::removed, SDL_event_watchers, SDL_event_watchers_count, SDL_event_watchers_lock, SDL_FALSE, SDL_LockMutex, SDL_realloc, SDL_UnlockMutex, and SDL_EventWatcher::userdata.

◆ SDL_CutEvent()

static void SDL_CutEvent ( SDL_EventEntry entry)
static

Definition at line 487 of file SDL_events.c.

488 {
489  if (entry->prev) {
490  entry->prev->next = entry->next;
491  }
492  if (entry->next) {
493  entry->next->prev = entry->prev;
494  }
495 
496  if (entry == SDL_EventQ.head) {
497  SDL_assert(entry->prev == NULL);
498  SDL_EventQ.head = entry->next;
499  }
500  if (entry == SDL_EventQ.tail) {
501  SDL_assert(entry->next == NULL);
502  SDL_EventQ.tail = entry->prev;
503  }
504 
505  entry->next = SDL_EventQ.free;
506  SDL_EventQ.free = entry;
507  SDL_assert(SDL_AtomicGet(&SDL_EventQ.count) > 0);
508  SDL_AtomicAdd(&SDL_EventQ.count, -1);
509 }

References SDL_EventEntry::next, NULL, SDL_EventEntry::prev, SDL_assert, SDL_AtomicAdd, SDL_AtomicGet, and SDL_EventQ.

Referenced by SDL_FilterEvents(), SDL_FlushEvents(), and SDL_PeepEvents().

◆ SDL_DelEventWatch()

void SDL_DelEventWatch ( SDL_EventFilter  filter,
void userdata 
)

Remove an event watch function added with SDL_AddEventWatch()

Definition at line 835 of file SDL_events.c.

836 {
838  int i;
839 
840  for (i = 0; i < SDL_event_watchers_count; ++i) {
841  if (SDL_event_watchers[i].callback == filter && SDL_event_watchers[i].userdata == userdata) {
845  } else {
847  if (i < SDL_event_watchers_count) {
849  }
850  }
851  break;
852  }
853  }
854 
857  }
858  }
859 }

References callback(), i, SDL_EventWatcher::removed, SDL_event_watchers, SDL_event_watchers_count, SDL_event_watchers_dispatching, SDL_event_watchers_lock, SDL_event_watchers_removed, SDL_LockMutex, SDL_memmove, SDL_TRUE, and SDL_UnlockMutex.

◆ SDL_EventState()

Uint8 SDL_EventState ( Uint32  type,
int  state 
)

This function allows you to set the state of processing certain events.

  • If state is set to SDL_IGNORE, that event will be automatically dropped from the event queue and will not be filtered.
  • If state is set to SDL_ENABLE, that event will be processed normally.
  • If state is set to SDL_QUERY, SDL_EventState() will return the current processing state of the specified event.

Definition at line 879 of file SDL_events.c.

880 {
881  const SDL_bool isdnd = ((state == SDL_DISABLE) || (state == SDL_ENABLE)) &&
882  ((type == SDL_DROPFILE) || (type == SDL_DROPTEXT));
883  Uint8 current_state;
884  Uint8 hi = ((type >> 8) & 0xff);
885  Uint8 lo = (type & 0xff);
886 
887  if (SDL_disabled_events[hi] &&
888  (SDL_disabled_events[hi]->bits[lo/32] & (1 << (lo&31)))) {
889  current_state = SDL_DISABLE;
890  } else {
891  current_state = SDL_ENABLE;
892  }
893 
894  if (state != current_state)
895  {
896  switch (state) {
897  case SDL_DISABLE:
898  /* Disable this event type and discard pending events */
899  if (!SDL_disabled_events[hi]) {
901  if (!SDL_disabled_events[hi]) {
902  /* Out of memory, nothing we can do... */
903  break;
904  }
905  }
906  SDL_disabled_events[hi]->bits[lo/32] |= (1 << (lo&31));
908  break;
909  case SDL_ENABLE:
910  SDL_disabled_events[hi]->bits[lo/32] &= ~(1 << (lo&31));
911  break;
912  default:
913  /* Querying state... */
914  break;
915  }
916  }
917 
918  /* turn off drag'n'drop support if we've disabled the events.
919  This might change some UI details at the OS level. */
920  if (isdnd) {
922  }
923 
924  return current_state;
925 }

References SDL_DisabledEventBlock::bits, SDL_calloc, SDL_DISABLE, SDL_disabled_events, SDL_DROPFILE, SDL_DROPTEXT, SDL_ENABLE, SDL_FlushEvent(), SDL_ToggleDragAndDropSupport(), and state.

Referenced by SDL_StartEventLoop().

◆ SDL_FilterEvents()

void SDL_FilterEvents ( SDL_EventFilter  filter,
void userdata 
)

Run the filter function on the current event queue, removing any events for which the filter returns 0.

Definition at line 862 of file SDL_events.c.

863 {
864  if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
865  SDL_EventEntry *entry, *next;
866  for (entry = SDL_EventQ.head; entry; entry = next) {
867  next = entry->next;
868  if (!filter(userdata, &entry->event)) {
869  SDL_CutEvent(entry);
870  }
871  }
872  if (SDL_EventQ.lock) {
874  }
875  }
876 }

References SDL_EventEntry::event, SDL_EventEntry::next, SDL_CutEvent(), SDL_EventQ, SDL_LockMutex, and SDL_UnlockMutex.

◆ SDL_FlushEvent()

void SDL_FlushEvent ( Uint32  type)

This function clears events from the event queue This function only affects currently queued events. If you want to make sure that all pending OS events are flushed, you can call SDL_PumpEvents() on the main thread immediately before the flush call.

Definition at line 603 of file SDL_events.c.

604 {
606 }

References SDL_FlushEvents().

Referenced by SDL_EventState().

◆ SDL_FlushEvents()

void SDL_FlushEvents ( Uint32  minType,
Uint32  maxType 
)

Definition at line 609 of file SDL_events.c.

610 {
611  /* !!! FIXME: we need to manually SDL_free() the strings in TEXTINPUT and
612  drag'n'drop events if we're flushing them without passing them to the
613  app, but I don't know if this is the right place to do that. */
614 
615  /* Don't look after we've quit */
616  if (!SDL_AtomicGet(&SDL_EventQ.active)) {
617  return;
618  }
619 
620  /* Make sure the events are current */
621 #if 0
622  /* Actually, we can't do this since we might be flushing while processing
623  a resize event, and calling this might trigger further resize events.
624  */
625  SDL_PumpEvents();
626 #endif
627 
628  /* Lock the event queue */
629  if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
630  SDL_EventEntry *entry, *next;
631  Uint32 type;
632  for (entry = SDL_EventQ.head; entry; entry = next) {
633  next = entry->next;
634  type = entry->event.type;
635  if (minType <= type && type <= maxType) {
636  SDL_CutEvent(entry);
637  }
638  }
639  if (SDL_EventQ.lock) {
641  }
642  }
643 }

References SDL_EventEntry::event, SDL_EventEntry::next, SDL_AtomicGet, SDL_CutEvent(), SDL_EventQ, SDL_LockMutex, SDL_PumpEvents(), SDL_UnlockMutex, and SDL_Event::type.

Referenced by SDL_FlushEvent(), and SDL_SetEventFilter().

◆ SDL_GetEventFilter()

SDL_bool SDL_GetEventFilter ( SDL_EventFilter filter,
void **  userdata 
)

Return the current event filter - can be used to "chain" filters. If there is no event filter set, this function returns SDL_FALSE.

Definition at line 787 of file SDL_events.c.

788 {
789  SDL_EventWatcher event_ok;
790 
792  event_ok = SDL_EventOK;
793 
796  }
797  } else {
798  SDL_zero(event_ok);
799  }
800 
801  if (filter) {
802  *filter = event_ok.callback;
803  }
804  if (userdata) {
805  *userdata = event_ok.userdata;
806  }
807  return event_ok.callback ? SDL_TRUE : SDL_FALSE;
808 }

References SDL_EventWatcher::callback, SDL_event_watchers_lock, SDL_EventOK, SDL_FALSE, SDL_LockMutex, SDL_TRUE, SDL_UnlockMutex, SDL_zero, and SDL_EventWatcher::userdata.

◆ SDL_HasEvent()

SDL_bool SDL_HasEvent ( Uint32  type)

Checks to see if certain event types are in the event queue.

Definition at line 591 of file SDL_events.c.

592 {
593  return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type) > 0);
594 }

References NULL, SDL_PEEKEVENT, and SDL_PeepEvents().

◆ SDL_HasEvents()

SDL_bool SDL_HasEvents ( Uint32  minType,
Uint32  maxType 
)

Definition at line 597 of file SDL_events.c.

598 {
599  return (SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, minType, maxType) > 0);
600 }

References NULL, SDL_PEEKEVENT, and SDL_PeepEvents().

◆ SDL_PeepEvents()

int SDL_PeepEvents ( SDL_Event events,
int  numevents,
SDL_eventaction  action,
Uint32  minType,
Uint32  maxType 
)

Checks the event queue for messages and optionally returns them.

If action is SDL_ADDEVENT, up to numevents events will be added to the back of the event queue.

If action is SDL_PEEKEVENT, up to numevents events at the front of the event queue, within the specified minimum and maximum type, will be returned and will not be removed from the queue.

If action is SDL_GETEVENT, up to numevents events at the front of the event queue, within the specified minimum and maximum type, will be returned and will be removed from the queue.

Returns
The number of events actually stored, or -1 if there was an error.

This function is thread-safe.

Definition at line 513 of file SDL_events.c.

515 {
516  int i, used;
517 
518  /* Don't look after we've quit */
519  if (!SDL_AtomicGet(&SDL_EventQ.active)) {
520  /* We get a few spurious events at shutdown, so don't warn then */
521  if (action != SDL_ADDEVENT) {
522  SDL_SetError("The event system has been shut down");
523  }
524  return (-1);
525  }
526  /* Lock the event queue */
527  used = 0;
528  if (!SDL_EventQ.lock || SDL_LockMutex(SDL_EventQ.lock) == 0) {
529  if (action == SDL_ADDEVENT) {
530  for (i = 0; i < numevents; ++i) {
531  used += SDL_AddEvent(&events[i]);
532  }
533  } else {
534  SDL_EventEntry *entry, *next;
535  SDL_SysWMEntry *wmmsg, *wmmsg_next;
536  Uint32 type;
537 
538  if (action == SDL_GETEVENT) {
539  /* Clean out any used wmmsg data
540  FIXME: Do we want to retain the data for some period of time?
541  */
542  for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
543  wmmsg_next = wmmsg->next;
544  wmmsg->next = SDL_EventQ.wmmsg_free;
545  SDL_EventQ.wmmsg_free = wmmsg;
546  }
547  SDL_EventQ.wmmsg_used = NULL;
548  }
549 
550  for (entry = SDL_EventQ.head; entry && (!events || used < numevents); entry = next) {
551  next = entry->next;
552  type = entry->event.type;
553  if (minType <= type && type <= maxType) {
554  if (events) {
555  events[used] = entry->event;
556  if (entry->event.type == SDL_SYSWMEVENT) {
557  /* We need to copy the wmmsg somewhere safe.
558  For now we'll guarantee it's valid at least until
559  the next call to SDL_PeepEvents()
560  */
561  if (SDL_EventQ.wmmsg_free) {
562  wmmsg = SDL_EventQ.wmmsg_free;
563  SDL_EventQ.wmmsg_free = wmmsg->next;
564  } else {
565  wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
566  }
567  wmmsg->msg = *entry->event.syswm.msg;
568  wmmsg->next = SDL_EventQ.wmmsg_used;
569  SDL_EventQ.wmmsg_used = wmmsg;
570  events[used].syswm.msg = &wmmsg->msg;
571  }
572 
573  if (action == SDL_GETEVENT) {
574  SDL_CutEvent(entry);
575  }
576  }
577  ++used;
578  }
579  }
580  }
581  if (SDL_EventQ.lock) {
583  }
584  } else {
585  return SDL_SetError("Couldn't lock event queue");
586  }
587  return (used);
588 }

References SDL_EventEntry::event, events, i, SDL_SysWMEvent::msg, SDL_SysWMEntry::msg, SDL_EventEntry::next, SDL_SysWMEntry::next, NULL, SDL_ADDEVENT, SDL_AddEvent(), SDL_AtomicGet, SDL_CutEvent(), SDL_EventQ, SDL_GETEVENT, SDL_LockMutex, SDL_malloc, SDL_SetError, SDL_SYSWMEVENT, SDL_UnlockMutex, SDL_Event::syswm, and SDL_Event::type.

Referenced by SDL_HasEvent(), SDL_HasEvents(), SDL_PushEvent(), and SDL_WaitEventTimeout().

◆ SDL_PollEvent()

int SDL_PollEvent ( SDL_Event event)

Polls for currently pending events.

Returns
1 if there are any pending events, or 0 if there are none available.
Parameters
eventIf not NULL, the next event is removed from the queue and stored in that area.

Definition at line 675 of file SDL_events.c.

676 {
677  return SDL_WaitEventTimeout(event, 0);
678 }

References SDL_WaitEventTimeout().

◆ SDL_PumpEvents()

void SDL_PumpEvents ( void  )

Pumps the event loop, gathering events from the input devices.

This function updates the event queue and internal input device state.

This should only be run in the thread that sets the video mode.

Definition at line 647 of file SDL_events.c.

648 {
650 
651  /* Get events from the video subsystem */
652  if (_this) {
654  }
655 #if !SDL_JOYSTICK_DISABLED
656  /* Check for joystick state change */
659  }
660 #endif
661 
662 #if !SDL_SENSOR_DISABLED
663  /* Check for sensor state change */
666  }
667 #endif
668 
669  SDL_SendPendingQuit(); /* in case we had a signal handler fire, etc. */
670 }

References _this, SDL_VideoDevice::PumpEvents, SDL_disabled_events, SDL_GetVideoDevice(), SDL_JOYAXISMOTION, SDL_JoystickEventState, SDL_JoystickUpdate, SDL_QUERY, SDL_SendPendingQuit(), SDL_SENSORUPDATE, and SDL_SensorUpdate.

Referenced by SDL_FlushEvents(), and SDL_WaitEventTimeout().

◆ SDL_PushEvent()

int SDL_PushEvent ( SDL_Event event)

Add an event to the event queue.

Returns
1 on success, 0 if the event was filtered, or -1 if the event queue was full or there was some other error.

Definition at line 718 of file SDL_events.c.

719 {
720  event->common.timestamp = SDL_GetTicks();
721 
727  }
728  return 0;
729  }
730 
731  if (SDL_event_watchers_count > 0) {
732  /* Make sure we only dispatch the current watcher list */
733  int i, event_watchers_count = SDL_event_watchers_count;
734 
736  for (i = 0; i < event_watchers_count; ++i) {
737  if (!SDL_event_watchers[i].removed) {
739  }
740  }
742 
744  for (i = SDL_event_watchers_count; i--; ) {
745  if (SDL_event_watchers[i].removed) {
747  if (i < SDL_event_watchers_count) {
749  }
750  }
751  }
753  }
754  }
755 
758  }
759  }
760  }
761 
762  if (SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0, 0) <= 0) {
763  return -1;
764  }
765 
767 
768  return 1;
769 }

References SDL_EventWatcher::callback, i, SDL_ADDEVENT, SDL_event_watchers, SDL_event_watchers_count, SDL_event_watchers_dispatching, SDL_event_watchers_lock, SDL_event_watchers_removed, SDL_EventOK, SDL_FALSE, SDL_GestureProcessEvent(), SDL_GetTicks(), SDL_LockMutex, SDL_memmove, SDL_PeepEvents(), SDL_TRUE, SDL_UnlockMutex, and SDL_EventWatcher::userdata.

Referenced by SDL_SendAppEvent(), and SDL_SendSysWMEvent().

◆ SDL_RegisterEvents()

Uint32 SDL_RegisterEvents ( int  numevents)

This function allocates a set of user-defined events, and returns the beginning event number for that set of events.

If there aren't enough user-defined events left, this function returns (Uint32)-1

Definition at line 928 of file SDL_events.c.

929 {
930  Uint32 event_base;
931 
932  if ((numevents > 0) && (SDL_userevents+numevents <= SDL_LASTEVENT)) {
933  event_base = SDL_userevents;
934  SDL_userevents += numevents;
935  } else {
936  event_base = (Uint32)-1;
937  }
938  return event_base;
939 }

References SDL_LASTEVENT, and SDL_userevents.

◆ SDL_SendAppEvent()

int SDL_SendAppEvent ( SDL_EventType  eventType)

Definition at line 942 of file SDL_events.c.

943 {
944  int posted;
945 
946  posted = 0;
947  if (SDL_GetEventState(eventType) == SDL_ENABLE) {
949  event.type = eventType;
950  posted = (SDL_PushEvent(&event) > 0);
951  }
952  return (posted);
953 }

References SDL_ENABLE, SDL_GetEventState, and SDL_PushEvent().

Referenced by SDL_OnApplicationDidBecomeActive(), SDL_OnApplicationDidEnterBackground(), SDL_OnApplicationDidReceiveMemoryWarning(), SDL_OnApplicationWillEnterForeground(), SDL_OnApplicationWillResignActive(), SDL_OnApplicationWillTerminate(), SDL_SendKeymapChangedEvent(), and SDL_SendQuit().

◆ SDL_SendKeymapChangedEvent()

int SDL_SendKeymapChangedEvent ( void  )

Definition at line 973 of file SDL_events.c.

974 {
976 }

References SDL_KEYMAPCHANGED, and SDL_SendAppEvent().

◆ SDL_SendSysWMEvent()

int SDL_SendSysWMEvent ( SDL_SysWMmsg message)

Definition at line 956 of file SDL_events.c.

957 {
958  int posted;
959 
960  posted = 0;
963  SDL_memset(&event, 0, sizeof(event));
964  event.type = SDL_SYSWMEVENT;
965  event.syswm.msg = message;
966  posted = (SDL_PushEvent(&event) > 0);
967  }
968  /* Update internal event state */
969  return (posted);
970 }

References SDL_ENABLE, SDL_GetEventState, SDL_memset, SDL_PushEvent(), and SDL_SYSWMEVENT.

◆ SDL_SetEventFilter()

void SDL_SetEventFilter ( SDL_EventFilter  filter,
void userdata 
)

Sets up a filter to process all events before they change internal state and are posted to the internal event queue.

The filter is prototyped as:

int SDL_EventFilter(void *userdata, SDL_Event * event);

If the filter returns 1, then the event will be added to the internal queue. If it returns 0, then the event will be dropped from the queue, but the internal state will still be updated. This allows selective filtering of dynamically arriving events.

Warning
Be very careful of what you do in the event filter function, as it may run in a different thread!

There is one caveat when dealing with the SDL_QuitEvent event type. The event filter is only called when the window manager desires to close the application window. If the event filter returns 1, then the window will be closed, otherwise the window will remain open if possible.

If the quit event is generated by an interrupt signal, it will bypass the internal queue and be delivered to the application at the next event poll.

Definition at line 772 of file SDL_events.c.

773 {
775  /* Set filter and discard pending events */
777  SDL_EventOK.userdata = userdata;
779 
782  }
783  }
784 }

References SDL_EventWatcher::callback, SDL_event_watchers_lock, SDL_EventOK, SDL_FIRSTEVENT, SDL_FlushEvents(), SDL_LASTEVENT, SDL_LockMutex, SDL_UnlockMutex, and SDL_EventWatcher::userdata.

◆ SDL_StartEventLoop()

int SDL_StartEventLoop ( void  )

Definition at line 391 of file SDL_events.c.

392 {
393  /* We'll leave the event queue alone, since we might have gotten
394  some important events at launch (like SDL_DROPFILE)
395 
396  FIXME: Does this introduce any other bugs with events at startup?
397  */
398 
399  /* Create the lock and set ourselves active */
400 #if !SDL_THREADS_DISABLED
401  if (!SDL_EventQ.lock) {
402  SDL_EventQ.lock = SDL_CreateMutex();
403  if (SDL_EventQ.lock == NULL) {
404  return -1;
405  }
406  }
407 
410  if (SDL_event_watchers_lock == NULL) {
411  return -1;
412  }
413  }
414 #endif /* !SDL_THREADS_DISABLED */
415 
416  /* Process most event types */
420 #if 0 /* Leave these events enabled so apps can respond to items being dragged onto them at startup */
423 #endif
424 
425  SDL_AtomicSet(&SDL_EventQ.active, 1);
426 
427  return 0;
428 }

References NULL, SDL_AtomicSet, SDL_CreateMutex, SDL_DISABLE, SDL_DROPFILE, SDL_DROPTEXT, SDL_event_watchers_lock, SDL_EventQ, SDL_EventState(), SDL_SYSWMEVENT, SDL_TEXTEDITING, and SDL_TEXTINPUT.

Referenced by SDL_InitSubSystem().

◆ SDL_StopEventLoop()

void SDL_StopEventLoop ( void  )

Definition at line 317 of file SDL_events.c.

318 {
319  const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS");
320  int i;
321  SDL_EventEntry *entry;
322  SDL_SysWMEntry *wmmsg;
323 
324  if (SDL_EventQ.lock) {
326  }
327 
328  SDL_AtomicSet(&SDL_EventQ.active, 0);
329 
330  if (report && SDL_atoi(report)) {
331  SDL_Log("SDL EVENT QUEUE: Maximum events in-flight: %d\n",
332  SDL_EventQ.max_events_seen);
333  }
334 
335  /* Clean out EventQ */
336  for (entry = SDL_EventQ.head; entry; ) {
337  SDL_EventEntry *next = entry->next;
338  SDL_free(entry);
339  entry = next;
340  }
341  for (entry = SDL_EventQ.free; entry; ) {
342  SDL_EventEntry *next = entry->next;
343  SDL_free(entry);
344  entry = next;
345  }
346  for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; ) {
347  SDL_SysWMEntry *next = wmmsg->next;
348  SDL_free(wmmsg);
349  wmmsg = next;
350  }
351  for (wmmsg = SDL_EventQ.wmmsg_free; wmmsg; ) {
352  SDL_SysWMEntry *next = wmmsg->next;
353  SDL_free(wmmsg);
354  wmmsg = next;
355  }
356 
357  SDL_AtomicSet(&SDL_EventQ.count, 0);
358  SDL_EventQ.max_events_seen = 0;
359  SDL_EventQ.head = NULL;
360  SDL_EventQ.tail = NULL;
361  SDL_EventQ.free = NULL;
362  SDL_EventQ.wmmsg_used = NULL;
363  SDL_EventQ.wmmsg_free = NULL;
364 
365  /* Clear disabled event state */
366  for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
369  }
370 
374  }
375  if (SDL_event_watchers) {
379  }
381 
382  if (SDL_EventQ.lock) {
385  SDL_EventQ.lock = NULL;
386  }
387 }

References i, SDL_EventEntry::next, SDL_SysWMEntry::next, NULL, SDL_arraysize, SDL_atoi, SDL_AtomicSet, SDL_DestroyMutex, SDL_disabled_events, SDL_event_watchers, SDL_event_watchers_count, SDL_event_watchers_lock, SDL_EventOK, SDL_EventQ, SDL_free, SDL_GetHint, SDL_LockMutex, SDL_Log, SDL_UnlockMutex, and SDL_zero.

Referenced by SDL_QuitSubSystem().

◆ SDL_WaitEvent()

int SDL_WaitEvent ( SDL_Event event)

Waits indefinitely for the next available event.

Returns
1, or 0 if there was an error while waiting for events.
Parameters
eventIf not NULL, the next event is removed from the queue and stored in that area.

Definition at line 681 of file SDL_events.c.

682 {
683  return SDL_WaitEventTimeout(event, -1);
684 }

References SDL_WaitEventTimeout().

◆ SDL_WaitEventTimeout()

int SDL_WaitEventTimeout ( SDL_Event event,
int  timeout 
)

Waits until the specified timeout (in milliseconds) for the next available event.

Returns
1, or 0 if there was an error while waiting for events.
Parameters
eventIf not NULL, the next event is removed from the queue and stored in that area.
timeoutThe timeout (in milliseconds) to wait for next event.

Definition at line 687 of file SDL_events.c.

688 {
689  Uint32 expiration = 0;
690 
691  if (timeout > 0)
692  expiration = SDL_GetTicks() + timeout;
693 
694  for (;;) {
695  SDL_PumpEvents();
697  case -1:
698  return 0;
699  case 0:
700  if (timeout == 0) {
701  /* Polling and no events, just return */
702  return 0;
703  }
704  if (timeout > 0 && SDL_TICKS_PASSED(SDL_GetTicks(), expiration)) {
705  /* Timeout expired and no events */
706  return 0;
707  }
708  SDL_Delay(10);
709  break;
710  default:
711  /* Has events */
712  return 1;
713  }
714  }
715 }

References SDL_Delay, SDL_FIRSTEVENT, SDL_GETEVENT, SDL_GetTicks(), SDL_LASTEVENT, SDL_PeepEvents(), SDL_PumpEvents(), and SDL_TICKS_PASSED.

Referenced by SDL_PollEvent(), and SDL_WaitEvent().

Variable Documentation

◆ active

SDL_atomic_t active

Definition at line 79 of file SDL_events.c.

Referenced by SDL_BWin::WindowActivated().

◆ count

Definition at line 80 of file SDL_events.c.

◆ free

◆ head

Definition at line 82 of file SDL_events.c.

Referenced by mmap_alloc().

◆ lock

◆ max_events_seen

int max_events_seen

Definition at line 81 of file SDL_events.c.

◆ SDL_disabled_events

SDL_DisabledEventBlock* SDL_disabled_events[256]
static

Definition at line 58 of file SDL_events.c.

Referenced by SDL_EventState(), SDL_PumpEvents(), and SDL_StopEventLoop().

◆ SDL_event_watchers

SDL_EventWatcher* SDL_event_watchers = NULL
static

◆ SDL_event_watchers_count

int SDL_event_watchers_count = 0
static

◆ SDL_event_watchers_dispatching

SDL_bool SDL_event_watchers_dispatching = SDL_FALSE
static

Definition at line 51 of file SDL_events.c.

Referenced by SDL_DelEventWatch(), and SDL_PushEvent().

◆ SDL_event_watchers_lock

◆ SDL_event_watchers_removed

SDL_bool SDL_event_watchers_removed = SDL_FALSE
static

Definition at line 52 of file SDL_events.c.

Referenced by SDL_DelEventWatch(), and SDL_PushEvent().

◆ SDL_EventOK

SDL_EventWatcher SDL_EventOK
static

◆ SDL_EventQ

◆ SDL_userevents

Uint32 SDL_userevents = SDL_USEREVENT
static

Definition at line 59 of file SDL_events.c.

Referenced by SDL_RegisterEvents().

◆ tail

Definition at line 83 of file SDL_events.c.

◆ wmmsg_free

SDL_SysWMEntry* wmmsg_free

Definition at line 86 of file SDL_events.c.

◆ wmmsg_used

SDL_SysWMEntry* wmmsg_used

Definition at line 85 of file SDL_events.c.

SDL_zero
#define SDL_zero(x)
Definition: SDL_stdinc.h:416
SDL_SysWMEntry
Definition: SDL_events.c:71
SDL_Event::type
Uint32 type
Definition: SDL_events.h:559
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_EventWatcher::callback
SDL_EventFilter callback
Definition: SDL_events.c:42
SDL_EventWatcher::removed
SDL_bool removed
Definition: SDL_events.c:44
SDL_SendPendingQuit
void SDL_SendPendingQuit(void)
Definition: SDL_quit.c:144
SDL_AddEvent
static int SDL_AddEvent(SDL_Event *event)
Definition: SDL_events.c:433
SDL_LockMutex
#define SDL_LockMutex
Definition: SDL_dynapi_overrides.h:260
SDL_EventWatcher::userdata
void * userdata
Definition: SDL_events.c:43
SDL_event_watchers_count
static int SDL_event_watchers_count
Definition: SDL_events.c:50
SDL_ADDEVENT
@ SDL_ADDEVENT
Definition: SDL_events.h:612
NULL
#define NULL
Definition: begin_code.h:164
message
GLuint GLsizei const GLchar * message
Definition: SDL_opengl_glext.h:2483
timeout
GLbitfield GLuint64 timeout
Definition: SDL_opengl_glext.h:1483
SDL_CutEvent
static void SDL_CutEvent(SDL_EventEntry *entry)
Definition: SDL_events.c:487
SDL_SensorUpdate
#define SDL_SensorUpdate
Definition: SDL_dynapi_overrides.h:696
SDL_EventFilter
int(* SDL_EventFilter)(void *userdata, SDL_Event *event)
Definition: SDL_events.h:696
SDL_ToggleDragAndDropSupport
void SDL_ToggleDragAndDropSupport(void)
Definition: SDL_video.c:1374
SDL_realloc
#define SDL_realloc
Definition: SDL_dynapi_overrides.h:376
SDL_TEXTEDITING
@ SDL_TEXTEDITING
Definition: SDL_events.h:98
SDL_CreateMutex
#define SDL_CreateMutex
Definition: SDL_dynapi_overrides.h:259
SDL_SysWMmsg::msg
union SDL_SysWMmsg::@16 msg
callback
static Uint32 callback(Uint32 interval, void *param)
Definition: testtimer.c:34
SDL_EventQ
static struct @21 SDL_EventQ
SDL_GestureProcessEvent
void SDL_GestureProcessEvent(SDL_Event *event)
Definition: SDL_gesture.c:538
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_ENABLE
#define SDL_ENABLE
Definition: SDL_events.h:756
SDL_GetHint
#define SDL_GetHint
Definition: SDL_dynapi_overrides.h:191
SDL_DisabledEventBlock::bits
Uint32 bits[8]
Definition: SDL_events.c:55
SDL_EventEntry
Definition: SDL_events.c:63
SDL_EventWatcher
Definition: SDL_events.c:41
SDL_FIRSTEVENT
@ SDL_FIRSTEVENT
Definition: SDL_events.h:57
SDL_SysWMEvent::msg
SDL_SysWMmsg * msg
Definition: SDL_events.h:551
filter
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: SDL_opengl_glext.h:1184
SDL_event_watchers_lock
static SDL_mutex * SDL_event_watchers_lock
Definition: SDL_events.c:47
SDL_EventEntry::msg
SDL_SysWMmsg msg
Definition: SDL_events.c:65
SDL_QUERY
#define SDL_QUERY
Definition: SDL_events.h:753
SDL_PushEvent
int SDL_PushEvent(SDL_Event *event)
Add an event to the event queue.
Definition: SDL_events.c:718
SDL_event_watchers_removed
static SDL_bool SDL_event_watchers_removed
Definition: SDL_events.c:52
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_SysWMEntry::next
struct _SDL_SysWMEntry * next
Definition: SDL_events.c:73
_this
static SDL_VideoDevice * _this
Definition: SDL_video.c:121
SDL_GetEventState
#define SDL_GetEventState(type)
Definition: SDL_events.h:769
SDL_Log
#define SDL_Log
Definition: SDL_dynapi_overrides.h:31
SDL_TEXTINPUT
@ SDL_TEXTINPUT
Definition: SDL_events.h:99
SDL_event_watchers_dispatching
static SDL_bool SDL_event_watchers_dispatching
Definition: SDL_events.c:51
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_SENSORUPDATE
@ SDL_SENSORUPDATE
Definition: SDL_events.h:151
SDL_DROPTEXT
@ SDL_DROPTEXT
Definition: SDL_events.h:142
SDL_GetTicks
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
SDL_memmove
#define SDL_memmove
Definition: SDL_dynapi_overrides.h:388
SDL_JOYAXISMOTION
@ SDL_JOYAXISMOTION
Definition: SDL_events.h:111
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_Delay
#define SDL_Delay
Definition: SDL_dynapi_overrides.h:486
SDL_EventEntry::event
SDL_Event event
Definition: SDL_events.c:64
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_DISABLE
#define SDL_DISABLE
Definition: SDL_events.h:755
SDL_VideoDevice
Definition: SDL_sysvideo.h:149
SDL_JoystickUpdate
#define SDL_JoystickUpdate
Definition: SDL_dynapi_overrides.h:209
SDL_KEYMAPCHANGED
@ SDL_KEYMAPCHANGED
Definition: SDL_events.h:100
SDL_arraysize
#define SDL_arraysize(array)
Definition: SDL_stdinc.h:115
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_atoi
#define SDL_atoi
Definition: SDL_dynapi_overrides.h:410
SDL_FlushEvent
void SDL_FlushEvent(Uint32 type)
Definition: SDL_events.c:603
SDL_userevents
static Uint32 SDL_userevents
Definition: SDL_events.c:59
SDL_EventEntry::prev
struct _SDL_EventEntry * prev
Definition: SDL_events.c:66
events
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:35
SDL_EventState
Uint8 SDL_EventState(Uint32 type, int state)
Definition: SDL_events.c:879
SDL_AtomicAdd
#define SDL_AtomicAdd
Definition: SDL_dynapi_overrides.h:69
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_EventOK
static SDL_EventWatcher SDL_EventOK
Definition: SDL_events.c:48
SDL_disabled_events
static SDL_DisabledEventBlock * SDL_disabled_events[256]
Definition: SDL_events.c:58
SDL_event_watchers
static SDL_EventWatcher * SDL_event_watchers
Definition: SDL_events.c:49
SDL_JoystickEventState
#define SDL_JoystickEventState
Definition: SDL_dynapi_overrides.h:210
SDL_DestroyMutex
#define SDL_DestroyMutex
Definition: SDL_dynapi_overrides.h:263
SDL_SysWMEntry::msg
SDL_SysWMmsg msg
Definition: SDL_events.c:72
SDL_GETEVENT
@ SDL_GETEVENT
Definition: SDL_events.h:614
SDL_SYSWMEVENT
@ SDL_SYSWMEVENT
Definition: SDL_events.h:93
SDL_WaitEventTimeout
int SDL_WaitEventTimeout(SDL_Event *event, int timeout)
Waits until the specified timeout (in milliseconds) for the next available event.
Definition: SDL_events.c:687
SDL_PumpEvents
void SDL_PumpEvents(void)
Definition: SDL_events.c:647
SDL_TICKS_PASSED
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
SDL_EventEntry::next
struct _SDL_EventEntry * next
Definition: SDL_events.c:67
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:162
bits
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition: SDL_opengl_glext.h:6176
SDL_Event::syswm
SDL_SysWMEvent syswm
Definition: SDL_events.h:581
SDL_Event
General event structure.
Definition: SDL_events.h:558
SDL_GetVideoDevice
SDL_VideoDevice * SDL_GetVideoDevice(void)
Definition: SDL_video.c:586
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_AtomicSet
#define SDL_AtomicSet
Definition: SDL_dynapi_overrides.h:67
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_AtomicGet
#define SDL_AtomicGet
Definition: SDL_dynapi_overrides.h:68
SDL_DisabledEventBlock
Definition: SDL_events.c:54
SDL_LASTEVENT
@ SDL_LASTEVENT
Definition: SDL_events.h:165
SDL_UnlockMutex
#define SDL_UnlockMutex
Definition: SDL_dynapi_overrides.h:262
SDL_VideoDevice::PumpEvents
void(* PumpEvents)(_THIS)
Definition: SDL_sysvideo.h:281
SDL_SendAppEvent
int SDL_SendAppEvent(SDL_EventType eventType)
Definition: SDL_events.c:942
SDL_PeepEvents
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 minType, Uint32 maxType)
Definition: SDL_events.c:513
SDL_FlushEvents
void SDL_FlushEvents(Uint32 minType, Uint32 maxType)
Definition: SDL_events.c:609
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1571
state
struct xkb_state * state
Definition: SDL_waylandsym.h:113
i
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
SDL_DROPFILE
@ SDL_DROPFILE
Definition: SDL_events.h:141
SDL_MAX_QUEUED_EVENTS
#define SDL_MAX_QUEUED_EVENTS
Definition: SDL_events.c:39
SDL_PEEKEVENT
@ SDL_PEEKEVENT
Definition: SDL_events.h:613