mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 10:53:27 +08:00
Automatically clean up memory associated with events
This commit is contained in:
parent
1a83bf2399
commit
70c149c88f
@ -175,9 +175,8 @@ int SDL_AppEvent(const SDL_Event *event);
|
||||
```
|
||||
|
||||
This will be called whenever an SDL event arrives, on the thread that runs
|
||||
SDL_AppIterate. You should not call SDL_CleanupEvent() on the provided
|
||||
event, and your app should also not call SDL_PollEvent, SDL_PumpEvent, etc,
|
||||
as SDL will manage all this for you. Return values are the same as from
|
||||
SDL_AppIterate. Your app should also not call SDL_PollEvent, SDL_PumpEvent,
|
||||
etc, as SDL will manage all this for you. Return values are the same as from
|
||||
SDL_AppIterate(), so you can terminate in response to SDL_EVENT_QUIT, etc.
|
||||
|
||||
|
||||
|
@ -298,7 +298,7 @@ The timestamp_us member of the sensor events has been renamed sensor_timestamp a
|
||||
|
||||
You should set the event.common.timestamp field before passing an event to SDL_PushEvent(). If the timestamp is 0 it will be filled in with SDL_GetTicksNS().
|
||||
|
||||
You should call SDL_CleanupEvent() after handling SDL_EVENT_DROP_FILE, SDL_EVENT_DROP_TEXT, SDL_EVENT_SYSWM, SDL_EVENT_TEXT_EDITING, and SDL_EVENT_TEXT_INPUT. This cleans up the memory associated with those events, and you no longer have to free the data yourself.
|
||||
You should not call SDL_free() on the data in SDL_EVENT_DROP_FILE, SDL manages the memory for events internally, you no longer have to free the data yourself.
|
||||
|
||||
Mouse events use floating point values for mouse coordinates and relative motion values. You can get sub-pixel motion depending on the platform and display scaling.
|
||||
|
||||
@ -559,7 +559,7 @@ The following hints have been removed:
|
||||
* SDL_HINT_VIDEO_X11_FORCE_EGL - use SDL_HINT_VIDEO_FORCE_EGL instead
|
||||
* SDL_HINT_VIDEO_X11_XINERAMA - Xinerama no longer supported by the X11 backend
|
||||
* SDL_HINT_VIDEO_X11_XVIDMODE - Xvidmode no longer supported by the X11 backend
|
||||
* SDL_HINT_IME_SUPPORT_EXTENDED_TEXT - the normal text editing event has dynamically allocated text if needed, and should be freed with SDL_CleanupEvent() when processed
|
||||
* SDL_HINT_IME_SUPPORT_EXTENDED_TEXT - the normal text editing event has extended text
|
||||
|
||||
* Renamed hints SDL_HINT_VIDEODRIVER and SDL_HINT_AUDIODRIVER to SDL_HINT_VIDEO_DRIVER and SDL_HINT_AUDIO_DRIVER
|
||||
* Renamed environment variables SDL_VIDEODRIVER and SDL_AUDIODRIVER to SDL_VIDEO_DRIVER and SDL_AUDIO_DRIVER
|
||||
|
@ -236,7 +236,7 @@ typedef struct SDL_WindowEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_WINDOWEVENT_* */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID;/**< The associated window */
|
||||
SDL_WindowID windowID; /**< The associated window */
|
||||
Sint32 data1; /**< event dependent data */
|
||||
Sint32 data2; /**< event dependent data */
|
||||
} SDL_WindowEvent;
|
||||
@ -248,7 +248,7 @@ typedef struct SDL_KeyboardEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_KEY_DOWN or ::SDL_EVENT_KEY_UP */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID;/**< The window with keyboard focus, if any */
|
||||
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
|
||||
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
|
||||
Uint8 repeat; /**< Non-zero if this is a key repeat */
|
||||
Uint8 padding2;
|
||||
@ -259,33 +259,27 @@ typedef struct SDL_KeyboardEvent
|
||||
#define SDL_TEXTEDITINGEVENT_TEXT_SIZE 64
|
||||
/**
|
||||
* \brief Keyboard text editing event structure (event.edit.*)
|
||||
*
|
||||
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
|
||||
*/
|
||||
typedef struct SDL_TextEditingEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_TEXT_EDITING */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
|
||||
char *text; /**< The editing text */
|
||||
char short_text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< Memory space for short editing text, use 'text' instead */
|
||||
Sint32 start; /**< The start cursor of selected editing text */
|
||||
Sint32 length; /**< The length of selected editing text */
|
||||
Uint32 type; /**< ::SDL_EVENT_TEXT_EDITING */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
|
||||
char *text; /**< The editing text */
|
||||
Sint32 start; /**< The start cursor of selected editing text */
|
||||
Sint32 length; /**< The length of selected editing text */
|
||||
} SDL_TextEditingEvent;
|
||||
|
||||
#define SDL_TEXTINPUTEVENT_TEXT_SIZE 64
|
||||
/**
|
||||
* \brief Keyboard text input event structure (event.text.*)
|
||||
*
|
||||
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
|
||||
*/
|
||||
typedef struct SDL_TextInputEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_TEXT_INPUT */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
|
||||
char *text; /**< The input text */
|
||||
char short_text[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< Memory space for short input text, use 'text' instead */
|
||||
Uint32 type; /**< ::SDL_EVENT_TEXT_INPUT */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID; /**< The window with keyboard focus, if any */
|
||||
char *text; /**< The input text */
|
||||
} SDL_TextInputEvent;
|
||||
|
||||
/**
|
||||
@ -295,7 +289,7 @@ typedef struct SDL_MouseMotionEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_MOUSE_MOTION */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID;/**< The window with mouse focus, if any */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
|
||||
Uint32 state; /**< The current button state */
|
||||
float x; /**< X coordinate, relative to window */
|
||||
@ -311,7 +305,7 @@ typedef struct SDL_MouseButtonEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_MOUSE_BUTTON_DOWN or ::SDL_EVENT_MOUSE_BUTTON_UP */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID;/**< The window with mouse focus, if any */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
|
||||
Uint8 button; /**< The mouse button index */
|
||||
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
|
||||
@ -328,7 +322,7 @@ typedef struct SDL_MouseWheelEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_MOUSE_WHEEL */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID;/**< The window with mouse focus, if any */
|
||||
SDL_WindowID windowID; /**< The window with mouse focus, if any */
|
||||
SDL_MouseID which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
|
||||
float x; /**< The amount scrolled horizontally, positive to the right and negative to the left */
|
||||
float y; /**< The amount scrolled vertically, positive away from the user and negative toward the user */
|
||||
@ -507,15 +501,13 @@ typedef struct SDL_TouchFingerEvent
|
||||
float dx; /**< Normalized in the range -1...1 */
|
||||
float dy; /**< Normalized in the range -1...1 */
|
||||
float pressure; /**< Normalized in the range 0...1 */
|
||||
SDL_WindowID windowID;/**< The window underneath the finger, if any */
|
||||
SDL_WindowID windowID; /**< The window underneath the finger, if any */
|
||||
} SDL_TouchFingerEvent;
|
||||
|
||||
|
||||
#define SDL_DROPEVENT_DATA_SIZE 64
|
||||
/**
|
||||
* \brief An event used to drop text or request a file open by the system (event.drop.*)
|
||||
*
|
||||
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
|
||||
*/
|
||||
typedef struct SDL_DropEvent
|
||||
{
|
||||
@ -526,7 +518,6 @@ typedef struct SDL_DropEvent
|
||||
float y; /**< Y coordinate, relative to window (not on begin) */
|
||||
char *source; /**< The source app that sent this drop event, or NULL if that isn't available */
|
||||
char *data; /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */
|
||||
char short_data[SDL_DROPEVENT_DATA_SIZE]; /**< Memory space for short data, use 'data' instead */
|
||||
} SDL_DropEvent;
|
||||
|
||||
/**
|
||||
@ -545,7 +536,7 @@ typedef struct SDL_SensorEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_SENSOR_UPDATE */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_SensorID which; /**< The instance ID of the sensor */
|
||||
SDL_SensorID which; /**< The instance ID of the sensor */
|
||||
float data[6]; /**< Up to 6 values from the sensor - additional values can be queried using SDL_GetSensorData() */
|
||||
Uint64 sensor_timestamp; /**< The timestamp of the sensor reading in nanoseconds, not necessarily synchronized with the system clock */
|
||||
} SDL_SensorEvent;
|
||||
@ -575,7 +566,7 @@ typedef struct SDL_UserEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_USER through ::SDL_EVENT_LAST-1 */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_WindowID windowID;/**< The associated window if any */
|
||||
SDL_WindowID windowID; /**< The associated window if any */
|
||||
Sint32 code; /**< User defined event code */
|
||||
void *data1; /**< User defined data pointer */
|
||||
void *data2; /**< User defined data pointer */
|
||||
@ -589,8 +580,6 @@ typedef struct SDL_SysWMmsg SDL_SysWMmsg;
|
||||
* \brief A video driver dependent system event (event.syswm.*)
|
||||
* This event is disabled by default, you can enable it with SDL_SetEventEnabled()
|
||||
*
|
||||
* \note This event should be cleaned up with SDL_CleanupEvent() after processing.
|
||||
*
|
||||
* \note If you want to use this event, you should include SDL_syswm.h.
|
||||
*/
|
||||
typedef struct SDL_SysWMEvent
|
||||
@ -641,7 +630,7 @@ typedef union SDL_Event
|
||||
largest datatype within the union, which is 8 bytes on 64-bit
|
||||
architectures.
|
||||
|
||||
So... we'll add padding to force the size to be 56 bytes for both.
|
||||
So... we'll add padding to force the size to be the same for both.
|
||||
|
||||
On architectures where pointers are 16 bytes, this needs rounding up to
|
||||
the next multiple of 16, 64, and on architectures where pointers are
|
||||
@ -850,7 +839,6 @@ extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType);
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_CleanupEvent
|
||||
* \sa SDL_PushEvent
|
||||
* \sa SDL_WaitEvent
|
||||
* \sa SDL_WaitEventTimeout
|
||||
@ -873,7 +861,6 @@ extern DECLSPEC SDL_bool SDLCALL SDL_PollEvent(SDL_Event *event);
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_CleanupEvent
|
||||
* \sa SDL_PollEvent
|
||||
* \sa SDL_PushEvent
|
||||
* \sa SDL_WaitEventTimeout
|
||||
@ -902,33 +889,12 @@ extern DECLSPEC SDL_bool SDLCALL SDL_WaitEvent(SDL_Event *event);
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_CleanupEvent
|
||||
* \sa SDL_PollEvent
|
||||
* \sa SDL_PushEvent
|
||||
* \sa SDL_WaitEvent
|
||||
*/
|
||||
extern DECLSPEC SDL_bool SDLCALL SDL_WaitEventTimeout(SDL_Event *event, Sint32 timeoutMS);
|
||||
|
||||
/**
|
||||
* Clean up dynamically allocated memory for an event.
|
||||
*
|
||||
* Some events have dynamically allocated data that must be cleaned up when
|
||||
* the event is processed. If you handle any of these events, you should call
|
||||
* SDL_CleanupEvent() after processing them: SDL_EVENT_DROP_FILE
|
||||
* SDL_EVENT_DROP_TEXT SDL_EVENT_SYSWM SDL_EVENT_TEXT_EDITING
|
||||
*
|
||||
* It is safe, but not necessary, to call this function for other event types.
|
||||
*
|
||||
* \param event a pointer to the event that should be cleaned up
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_PollEvent
|
||||
* \sa SDL_WaitEvent
|
||||
* \sa SDL_WaitEventTimeout
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_CleanupEvent(SDL_Event *event);
|
||||
|
||||
/**
|
||||
* Add an event to the event queue.
|
||||
*
|
||||
@ -1145,6 +1111,20 @@ extern DECLSPEC SDL_bool SDLCALL SDL_EventEnabled(Uint32 type);
|
||||
*/
|
||||
extern DECLSPEC Uint32 SDLCALL SDL_RegisterEvents(int numevents);
|
||||
|
||||
/**
|
||||
* Allocate dynamic memory for an SDL event
|
||||
*
|
||||
* You can use this to allocate memory for user events that will be automatically freed after the event is processed.
|
||||
*
|
||||
* \param size the amount of memory to allocate
|
||||
* \returns a pointer to the memory allocated or NULL on failure; call SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_FlushEventMemory
|
||||
*/
|
||||
extern DECLSPEC void * SDLCALL SDL_AllocateEventMemory(size_t size);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -921,9 +921,9 @@ SDL3_0.0.0 {
|
||||
SDL_GetWindowProperties;
|
||||
SDL_ClearProperty;
|
||||
SDL_EnterAppMainCallbacks;
|
||||
SDL_CleanupEvent;
|
||||
SDL_RWprintf;
|
||||
SDL_RWvprintf;
|
||||
SDL_AllocateEventMemory;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
@ -946,6 +946,6 @@
|
||||
#define SDL_GetWindowProperties SDL_GetWindowProperties_REAL
|
||||
#define SDL_ClearProperty SDL_ClearProperty_REAL
|
||||
#define SDL_EnterAppMainCallbacks SDL_EnterAppMainCallbacks_REAL
|
||||
#define SDL_CleanupEvent SDL_CleanupEvent_REAL
|
||||
#define SDL_RWprintf SDL_RWprintf_REAL
|
||||
#define SDL_RWvprintf SDL_RWvprintf_REAL
|
||||
#define SDL_AllocateEventMemory SDL_AllocateEventMemory_REAL
|
||||
|
@ -979,5 +979,5 @@ SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetSurfaceProperties,(SDL_Surface *a),(a),r
|
||||
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetWindowProperties,(SDL_Window *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_ClearProperty,(SDL_PropertiesID a, const char *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_EnterAppMainCallbacks,(int a, char *b[], SDL_AppInit_func c, SDL_AppIterate_func d, SDL_AppEvent_func e, SDL_AppQuit_func f),(a,b,c,d,e,f),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_CleanupEvent,(SDL_Event *a),(a),)
|
||||
SDL_DYNAPI_PROC(size_t,SDL_RWvprintf,(SDL_RWops *a, const char *b, va_list c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(void*,SDL_AllocateEventMemory,(size_t a),(a),return)
|
||||
|
@ -62,13 +62,12 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
|
||||
event.drop.source = SDL_strdup(source);
|
||||
}
|
||||
if (data) {
|
||||
size_t len = SDL_strlen(data);
|
||||
if (len < sizeof(event.drop.short_data)) {
|
||||
SDL_memcpy(event.drop.short_data, data, len + 1);
|
||||
event.drop.data = event.drop.short_data;
|
||||
} else {
|
||||
event.drop.data = SDL_strdup(data);
|
||||
size_t size = SDL_strlen(data) + 1;
|
||||
event.drop.data = (char *)SDL_AllocateEventMemory(size);
|
||||
if (!event.drop.data) {
|
||||
return 0;
|
||||
}
|
||||
SDL_memcpy(event.drop.data, data, size);
|
||||
}
|
||||
event.drop.windowID = window ? window->id : 0;
|
||||
|
||||
|
@ -62,6 +62,7 @@ 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_AtomicInt SDL_sentinel_pending;
|
||||
static Uint32 SDL_last_event_id = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -90,6 +91,77 @@ static struct
|
||||
SDL_EventEntry *free;
|
||||
} SDL_EventQ = { NULL, SDL_FALSE, { 0 }, 0, NULL, NULL, NULL };
|
||||
|
||||
typedef struct SDL_EventMemory
|
||||
{
|
||||
Uint32 eventID;
|
||||
void *memory;
|
||||
struct SDL_EventMemory *next;
|
||||
} SDL_EventMemory;
|
||||
|
||||
static SDL_Mutex *SDL_event_memory_lock;
|
||||
static SDL_EventMemory *SDL_event_memory_head;
|
||||
static SDL_EventMemory *SDL_event_memory_tail;
|
||||
|
||||
void *SDL_AllocateEventMemory(size_t size)
|
||||
{
|
||||
void *memory = SDL_malloc(size);
|
||||
if (!memory) {
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_LockMutex(SDL_event_memory_lock);
|
||||
{
|
||||
SDL_EventMemory *entry = (SDL_EventMemory *)SDL_malloc(sizeof(*entry));
|
||||
if (entry) {
|
||||
entry->eventID = SDL_last_event_id;
|
||||
entry->memory = memory;
|
||||
entry->next = NULL;
|
||||
|
||||
if (SDL_event_memory_tail) {
|
||||
SDL_event_memory_tail->next = entry;
|
||||
} else {
|
||||
SDL_event_memory_head = entry;
|
||||
}
|
||||
SDL_event_memory_tail = entry;
|
||||
} else {
|
||||
SDL_free(memory);
|
||||
memory = NULL;
|
||||
SDL_OutOfMemory();
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(SDL_event_memory_lock);
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
static void SDL_FlushEventMemory(Uint32 eventID)
|
||||
{
|
||||
SDL_LockMutex(SDL_event_memory_lock);
|
||||
{
|
||||
if (SDL_event_memory_head) {
|
||||
while (SDL_event_memory_head) {
|
||||
SDL_EventMemory *entry = SDL_event_memory_head;
|
||||
|
||||
if (eventID && (Sint32)(eventID - entry->eventID) < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* If you crash here, your application has memory corruption
|
||||
* or freed memory in an event, which is no longer necessary.
|
||||
*/
|
||||
SDL_event_memory_head = entry->next;
|
||||
SDL_free(entry->memory);
|
||||
SDL_free(entry);
|
||||
}
|
||||
if (!SDL_event_memory_head) {
|
||||
SDL_event_memory_tail = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(SDL_event_memory_lock);
|
||||
}
|
||||
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
|
||||
static SDL_bool SDL_update_joysticks = SDL_TRUE;
|
||||
@ -468,22 +540,6 @@ static void SDL_LogEvent(const SDL_Event *event)
|
||||
#undef uint
|
||||
}
|
||||
|
||||
static void SDL_CopyEvent(SDL_Event *dst, SDL_Event *src)
|
||||
{
|
||||
SDL_copyp(dst, src);
|
||||
|
||||
/* Pointers to internal static data must be updated when copying. */
|
||||
if (src->type == SDL_EVENT_TEXT_EDITING && src->edit.text == src->edit.short_text) {
|
||||
dst->edit.text = dst->edit.short_text;
|
||||
} else if (src->type == SDL_EVENT_TEXT_INPUT && src->text.text == src->text.short_text) {
|
||||
dst->text.text = dst->text.short_text;
|
||||
} else if ((src->type == SDL_EVENT_DROP_FILE || src->type == SDL_EVENT_DROP_TEXT) && src->drop.data == src->drop.short_data) {
|
||||
dst->drop.data = dst->drop.short_data;
|
||||
}
|
||||
}
|
||||
|
||||
/* Public functions */
|
||||
|
||||
void SDL_StopEventLoop(void)
|
||||
{
|
||||
const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS");
|
||||
@ -518,12 +574,18 @@ void SDL_StopEventLoop(void)
|
||||
SDL_EventQ.free = NULL;
|
||||
SDL_AtomicSet(&SDL_sentinel_pending, 0);
|
||||
|
||||
SDL_FlushEventMemory(0);
|
||||
|
||||
/* Clear disabled event state */
|
||||
for (i = 0; i < SDL_arraysize(SDL_disabled_events); ++i) {
|
||||
SDL_free(SDL_disabled_events[i]);
|
||||
SDL_disabled_events[i] = NULL;
|
||||
}
|
||||
|
||||
if (SDL_event_memory_lock) {
|
||||
SDL_DestroyMutex(SDL_event_memory_lock);
|
||||
SDL_event_memory_lock = NULL;
|
||||
}
|
||||
if (SDL_event_watchers_lock) {
|
||||
SDL_DestroyMutex(SDL_event_watchers_lock);
|
||||
SDL_event_watchers_lock = NULL;
|
||||
@ -569,6 +631,14 @@ int SDL_StartEventLoop(void)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_event_memory_lock == NULL) {
|
||||
SDL_event_memory_lock = SDL_CreateMutex();
|
||||
if (SDL_event_memory_lock == NULL) {
|
||||
SDL_UnlockMutex(SDL_EventQ.lock);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* !SDL_THREADS_DISABLED */
|
||||
|
||||
/* Process most event types */
|
||||
@ -611,7 +681,7 @@ static int SDL_AddEvent(SDL_Event *event)
|
||||
SDL_LogEvent(event);
|
||||
}
|
||||
|
||||
SDL_CopyEvent(&entry->event, event);
|
||||
SDL_copyp(&entry->event, event);
|
||||
if (event->type == SDL_EVENT_POLL_SENTINEL) {
|
||||
SDL_AtomicAdd(&SDL_sentinel_pending, 1);
|
||||
}
|
||||
@ -634,6 +704,8 @@ static int SDL_AddEvent(SDL_Event *event)
|
||||
SDL_EventQ.max_events_seen = final_count;
|
||||
}
|
||||
|
||||
++SDL_last_event_id;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -720,7 +792,7 @@ static int SDL_PeepEventsInternal(SDL_Event *events, int numevents, SDL_eventact
|
||||
type = entry->event.type;
|
||||
if (minType <= type && type <= maxType) {
|
||||
if (events) {
|
||||
SDL_CopyEvent(&events[used], &entry->event);
|
||||
SDL_copyp(&events[used], &entry->event);
|
||||
|
||||
if (action == SDL_GETEVENT) {
|
||||
SDL_CutEvent(entry);
|
||||
@ -799,7 +871,6 @@ void SDL_FlushEvents(Uint32 minType, Uint32 maxType)
|
||||
next = entry->next;
|
||||
type = entry->event.type;
|
||||
if (minType <= type && type <= maxType) {
|
||||
SDL_CleanupEvent(&entry->event);
|
||||
SDL_CutEvent(entry);
|
||||
}
|
||||
}
|
||||
@ -812,6 +883,12 @@ static void SDL_PumpEventsInternal(SDL_bool push_sentinel)
|
||||
{
|
||||
SDL_VideoDevice *_this = SDL_GetVideoDevice();
|
||||
|
||||
/* Free old event memory */
|
||||
/*SDL_FlushEventMemory(SDL_last_event_id - SDL_MAX_QUEUED_EVENTS);*/
|
||||
if (SDL_AtomicGet(&SDL_EventQ.count) == 0) {
|
||||
SDL_FlushEventMemory(SDL_last_event_id);
|
||||
}
|
||||
|
||||
/* Release any keys held down from last frame */
|
||||
SDL_ReleaseAutoReleaseKeys();
|
||||
|
||||
@ -1082,43 +1159,6 @@ SDL_bool SDL_WaitEventTimeoutNS(SDL_Event *event, Sint64 timeoutNS)
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_CleanupEvent(SDL_Event *event)
|
||||
{
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_DROP_FILE:
|
||||
case SDL_EVENT_DROP_TEXT:
|
||||
if (event->drop.source) {
|
||||
SDL_free(event->drop.source);
|
||||
event->drop.data = NULL;
|
||||
}
|
||||
if (event->drop.data && event->drop.data != event->drop.short_data) {
|
||||
SDL_free(event->drop.data);
|
||||
event->drop.data = NULL;
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_SYSWM:
|
||||
if (event->syswm.msg) {
|
||||
SDL_free(event->syswm.msg);
|
||||
event->syswm.msg = NULL;
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_TEXT_EDITING:
|
||||
if (event->edit.text && event->edit.text != event->edit.short_text) {
|
||||
SDL_free(event->edit.text);
|
||||
event->edit.text = NULL;
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
if (event->text.text && event->text.text != event->text.short_text) {
|
||||
SDL_free(event->text.text);
|
||||
event->text.text = NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int SDL_PushEvent(SDL_Event *event)
|
||||
{
|
||||
if (!event->common.timestamp) {
|
||||
@ -1375,7 +1415,7 @@ int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
|
||||
SDL_memset(&event, 0, sizeof(event));
|
||||
event.type = SDL_EVENT_SYSWM;
|
||||
event.common.timestamp = 0;
|
||||
event.syswm.msg = (SDL_SysWMmsg *)SDL_malloc(sizeof(*message));
|
||||
event.syswm.msg = (SDL_SysWMmsg *)SDL_AllocateEventMemory(sizeof(*message));
|
||||
if (!event.syswm.msg) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1075,13 +1075,12 @@ int SDL_SendKeyboardText(const char *text)
|
||||
event.common.timestamp = 0;
|
||||
event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
|
||||
|
||||
size_t len = SDL_strlen(text);
|
||||
if (len < sizeof(event.text.short_text)) {
|
||||
SDL_memcpy(event.text.short_text, text, len + 1);
|
||||
event.text.text = event.text.short_text;
|
||||
} else {
|
||||
event.text.text = SDL_strdup(text);
|
||||
size_t size = SDL_strlen(text) + 1;
|
||||
event.text.text = (char *)SDL_AllocateEventMemory(size);
|
||||
if (!event.text.text) {
|
||||
return 0;
|
||||
}
|
||||
SDL_memcpy(event.text.text, text, size);
|
||||
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
@ -1104,13 +1103,12 @@ int SDL_SendEditingText(const char *text, int start, int length)
|
||||
event.edit.start = start;
|
||||
event.edit.length = length;
|
||||
|
||||
size_t len = SDL_strlen(text);
|
||||
if (len < sizeof(event.edit.short_text)) {
|
||||
SDL_memcpy(event.edit.short_text, text, len + 1);
|
||||
event.edit.text = event.edit.short_text;
|
||||
} else {
|
||||
event.edit.text = SDL_strdup(text);
|
||||
size_t size = SDL_strlen(text) + 1;
|
||||
event.edit.text = (char *)SDL_AllocateEventMemory(size);
|
||||
if (!event.edit.text) {
|
||||
return 0;
|
||||
}
|
||||
SDL_memcpy(event.edit.text, text, size);
|
||||
|
||||
posted = (SDL_PushEvent(&event) > 0);
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ static void SDL_DispatchMainCallbackEvent(SDL_Event *event)
|
||||
if (SDL_AtomicGet(&apprc) == 0) { // if already quitting, don't send the event to the app.
|
||||
SDL_AtomicCAS(&apprc, 0, SDL_main_event_callback(event));
|
||||
}
|
||||
SDL_CleanupEvent(event);
|
||||
}
|
||||
|
||||
static void SDL_DispatchMainCallbackEvents()
|
||||
|
@ -2424,8 +2424,6 @@ int SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event
|
||||
void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
|
||||
{
|
||||
*done = SDLTest_CommonEventMainCallbacks(state, event) ? 1 : 0;
|
||||
|
||||
SDL_CleanupEvent(event);
|
||||
}
|
||||
|
||||
void SDLTest_CommonQuit(SDLTest_CommonState *state)
|
||||
|
@ -181,12 +181,10 @@ static void loop(void)
|
||||
break;
|
||||
case SDL_EVENT_TEXT_EDITING:
|
||||
PrintText("EDIT", event.edit.text);
|
||||
SDL_CleanupEvent(&event);
|
||||
break;
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
PrintText("INPUT", event.text.text);
|
||||
SDLTest_TextWindowAddText(textwin, "%s", event.text.text);
|
||||
SDL_CleanupEvent(&event);
|
||||
break;
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
if (SDL_TextInputActive()) {
|
||||
|
@ -183,11 +183,9 @@ static void loop(void)
|
||||
break;
|
||||
case SDL_EVENT_TEXT_EDITING:
|
||||
PrintText("EDIT", event.text.text);
|
||||
SDL_CleanupEvent(&event);
|
||||
break;
|
||||
case SDL_EVENT_TEXT_INPUT:
|
||||
PrintText("INPUT", event.text.text);
|
||||
SDL_CleanupEvent(&event);
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
/* Left button quits the app, other buttons toggles text input */
|
||||
|
@ -1728,7 +1728,6 @@ static void loop(void *arg)
|
||||
AddControllerNameText(event.text.text);
|
||||
}
|
||||
}
|
||||
SDL_CleanupEvent(&event);
|
||||
break;
|
||||
case SDL_EVENT_QUIT:
|
||||
done = SDL_TRUE;
|
||||
|
@ -69,8 +69,6 @@ int main(int argc, char *argv[])
|
||||
} else if ((event.type == SDL_EVENT_DROP_FILE) || (event.type == SDL_EVENT_DROP_TEXT)) {
|
||||
const char *typestr = (event.type == SDL_EVENT_DROP_FILE) ? "File" : "Text";
|
||||
SDL_Log("%s dropped on window %u: %s at (%f, %f)", typestr, (unsigned int)event.drop.windowID, event.drop.data, event.drop.x, event.drop.y);
|
||||
/* Normally you'd have to do this, but this is freed in SDLTest_CommonEvent() */
|
||||
/*SDL_CleanupEvent(&event);*/
|
||||
} else if (event.type == SDL_EVENT_DROP_POSITION) {
|
||||
is_hover = SDL_TRUE;
|
||||
x = event.drop.x;
|
||||
|
@ -770,7 +770,6 @@ int main(int argc, char *argv[])
|
||||
/* is committed */
|
||||
markedText[0] = 0;
|
||||
Redraw();
|
||||
SDL_CleanupEvent(&event);
|
||||
break;
|
||||
|
||||
case SDL_EVENT_TEXT_EDITING:
|
||||
@ -780,7 +779,6 @@ int main(int argc, char *argv[])
|
||||
SDL_strlcpy(markedText, event.edit.text, SDL_TEXTEDITINGEVENT_TEXT_SIZE);
|
||||
cursor = event.edit.start;
|
||||
Redraw();
|
||||
SDL_CleanupEvent(&event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user