From 7e445da56990ce741e356ff7ed354abea129f288 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sat, 4 Nov 2023 00:55:55 -0700
Subject: [PATCH] Added SDL_CleanupEvent()
This is used to free any dynamically allocated memory in events.
---
docs/README-migration.md | 3 +
include/SDL3/SDL_events.h | 78 +++++++++++++---------
include/SDL3/SDL_hints.h | 11 ----
src/core/linux/SDL_fcitx.c | 23 ++-----
src/core/linux/SDL_ibus.c | 41 ++++--------
src/dynapi/SDL_dynapi.sym | 1 +
src/dynapi/SDL_dynapi_overrides.h | 1 +
src/dynapi/SDL_dynapi_procs.h | 1 +
src/events/SDL_dropevents.c | 10 ++-
src/events/SDL_events.c | 95 ++++++++++-----------------
src/events/SDL_keyboard.c | 25 ++++---
src/main/SDL_main_callbacks.c | 17 +----
src/test/SDL_test_common.c | 11 +---
src/video/wayland/SDL_waylandevents.c | 32 +++------
test/checkkeys.c | 8 +--
test/checkkeysthreads.c | 1 +
test/testaudio.c | 6 +-
test/testdropfile.c | 10 +--
test/testime.c | 1 +
test/testwm.c | 3 -
20 files changed, 146 insertions(+), 232 deletions(-)
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 494d69fce426..e9ea32828238 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -298,6 +298,8 @@ 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, and SDL_EVENT_TEXT_EDITING. This cleans up the memory associated with those events, and 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.
The SDL_DISPLAYEVENT_* events have been moved to top level events, and SDL_DISPLAYEVENT has been removed. In general, handling this change just means checking for the individual events instead of first checking for SDL_DISPLAYEVENT and then checking for display events. You can compare the event >= SDL_EVENT_DISPLAY_FIRST and <= SDL_EVENT_DISPLAY_LAST if you need to see whether it's a display event.
@@ -555,6 +557,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
* 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
diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h
index 48746d545281..312452444cd9 100644
--- a/include/SDL3/SDL_events.h
+++ b/include/SDL3/SDL_events.h
@@ -136,7 +136,6 @@ typedef enum
SDL_EVENT_TEXT_INPUT, /**< Keyboard text input */
SDL_EVENT_KEYMAP_CHANGED, /**< Keymap changed due to a system event such as an
input language or keyboard layout change. */
- SDL_EVENT_TEXT_EDITING_EXT, /**< Extended keyboard text editing (composition) */
/* Mouse events */
SDL_EVENT_MOUSE_MOTION = 0x400, /**< Mouse moved */
@@ -257,44 +256,35 @@ typedef struct SDL_KeyboardEvent
SDL_Keysym keysym; /**< The key that was pressed or released */
} SDL_KeyboardEvent;
-#define SDL_TEXTEDITINGEVENT_TEXT_SIZE (32)
+#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[SDL_TEXTEDITINGEVENT_TEXT_SIZE]; /**< The editing text */
+ 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 */
Sint32 start; /**< The start cursor of selected editing text */
Sint32 length; /**< The length of selected editing text */
} SDL_TextEditingEvent;
-/**
- * \brief Extended keyboard text editing event structure (event.editExt.*) when text would be
- * truncated if stored in the text buffer SDL_TextEditingEvent
- */
-typedef struct SDL_TextEditingExtEvent
-{
- Uint32 type; /**< ::SDL_EVENT_TEXT_EDITING_EXT */
- Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
- SDL_WindowID windowID; /**< The window with keyboard focus, if any */
- char* text; /**< The editing text, which should be freed with SDL_free(), and will not be NULL */
- Sint32 start; /**< The start cursor of selected editing text */
- Sint32 length; /**< The length of selected editing text */
-} SDL_TextEditingExtEvent;
-
-#define SDL_TEXTINPUTEVENT_TEXT_SIZE (32)
+#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() */
+ 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[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */
+ char text[SDL_TEXTINPUTEVENT_TEXT_SIZE]; /**< The input text */
} SDL_TextInputEvent;
/**
@@ -520,19 +510,21 @@ typedef struct SDL_TouchFingerEvent
} SDL_TouchFingerEvent;
+#define SDL_DROPEVENT_DATA_SIZE 64
/**
- * \brief An event used to request a file open by the system (event.drop.*)
- * This event is enabled by default, you can disable it with SDL_SetEventEnabled().
- * \note If this event is enabled, you must free the filename in the event.
+ * \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
{
Uint32 type; /**< ::SDL_EVENT_DROP_BEGIN or ::SDL_EVENT_DROP_FILE or ::SDL_EVENT_DROP_TEXT or ::SDL_EVENT_DROP_COMPLETE or ::SDL_EVENT_DROP_POSITION */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
- char *file; /**< The file name, which should be freed with SDL_free(), is NULL on begin/complete */
SDL_WindowID windowID; /**< The window that was dropped on, if any */
float x; /**< X coordinate, relative to window (not on begin) */
float y; /**< Y coordinate, relative to window (not on begin) */
+ 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 */
} SDL_DropEvent;
/**
@@ -595,6 +587,8 @@ 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
@@ -615,7 +609,6 @@ typedef union SDL_Event
SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing event data */
- SDL_TextEditingExtEvent editExt; /**< Extended text editing event data */
SDL_TextInputEvent text; /**< Text input event data */
SDL_MouseMotionEvent motion; /**< Mouse motion event data */
SDL_MouseButtonEvent button; /**< Mouse button event data */
@@ -855,10 +848,8 @@ extern DECLSPEC void SDLCALL SDL_FlushEvents(Uint32 minType, Uint32 maxType);
*
* \since This function is available since SDL 3.0.0.
*
- * \sa SDL_GetEventFilter
- * \sa SDL_PeepEvents
+ * \sa SDL_CleanupEvent
* \sa SDL_PushEvent
- * \sa SDL_SetEventFilter
* \sa SDL_WaitEvent
* \sa SDL_WaitEventTimeout
*/
@@ -880,8 +871,9 @@ 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_PumpEvents
+ * \sa SDL_PushEvent
* \sa SDL_WaitEventTimeout
*/
extern DECLSPEC SDL_bool SDLCALL SDL_WaitEvent(SDL_Event *event);
@@ -908,12 +900,34 @@ 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_PumpEvents
+ * \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.
*
diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h
index 2af3c88fff89..fd746553ce2c 100644
--- a/include/SDL3/SDL_hints.h
+++ b/include/SDL3/SDL_hints.h
@@ -632,17 +632,6 @@ extern "C" {
*/
#define SDL_HINT_IME_SHOW_UI "SDL_IME_SHOW_UI"
-/**
- * \brief A variable to control if extended IME text support is enabled.
- * If enabled then SDL_TextEditingExtEvent will be issued if the text would be truncated otherwise.
- * Additionally SDL_TextInputEvent will be dispatched multiple times so that it is not truncated.
- *
- * The variable can be set to the following values:
- * "0" - Legacy behavior. Text can be truncated, no heap allocations. (default)
- * "1" - Modern behavior.
- */
-#define SDL_HINT_IME_SUPPORT_EXTENDED_TEXT "SDL_IME_SUPPORT_EXTENDED_TEXT"
-
/**
* \brief A variable controlling whether the home indicator bar on iPhone X
* should be hidden.
diff --git a/src/core/linux/SDL_fcitx.c b/src/core/linux/SDL_fcitx.c
index d7cfe6be28a6..bbf3f453764a 100644
--- a/src/core/linux/SDL_fcitx.c
+++ b/src/core/linux/SDL_fcitx.c
@@ -212,26 +212,11 @@ static DBusHandlerResult DBus_MessageFilter(DBusConnection *conn, DBusMessage *m
Sint32 start_pos, end_pos;
size_t text_bytes = Fcitx_GetPreeditString(dbus, msg, &text, &start_pos, &end_pos);
if (text_bytes) {
- if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) {
- if (start_pos == -1) {
- Sint32 byte_pos = Fcitx_GetPreeditCursorByte(dbus, msg);
- start_pos = byte_pos >= 0 ? SDL_utf8strnlen(text, byte_pos) : -1;
- }
- SDL_SendEditingText(text, start_pos, end_pos >= 0 ? end_pos - start_pos : -1);
- } else {
- char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
- size_t i = 0;
- size_t cursor = 0;
- while (i < text_bytes) {
- const size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
- const size_t chars = SDL_utf8strlen(buf);
-
- SDL_SendEditingText(buf, cursor, chars);
-
- i += sz;
- cursor += chars;
- }
+ if (start_pos == -1) {
+ Sint32 byte_pos = Fcitx_GetPreeditCursorByte(dbus, msg);
+ start_pos = byte_pos >= 0 ? SDL_utf8strnlen(text, byte_pos) : -1;
}
+ SDL_SendEditingText(text, start_pos, end_pos >= 0 ? end_pos - start_pos : -1);
SDL_free(text);
} else {
SDL_SendEditingText("", 0, 0);
diff --git a/src/core/linux/SDL_ibus.c b/src/core/linux/SDL_ibus.c
index 592dc9d49e76..4c1b838635fa 100644
--- a/src/core/linux/SDL_ibus.c
+++ b/src/core/linux/SDL_ibus.c
@@ -252,38 +252,23 @@ static DBusHandlerResult IBus_MessageHandler(DBusConnection *conn, DBusMessage *
text = IBus_GetVariantText(conn, &iter, dbus);
if (text) {
- if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) {
- Uint32 pos, start_pos, end_pos;
- SDL_bool has_pos = SDL_FALSE;
- SDL_bool has_dec_pos = SDL_FALSE;
+ Uint32 pos, start_pos, end_pos;
+ SDL_bool has_pos = SDL_FALSE;
+ SDL_bool has_dec_pos = SDL_FALSE;
+ dbus->message_iter_init(msg, &iter);
+ has_dec_pos = IBus_GetDecorationPosition(conn, &iter, dbus, &start_pos, &end_pos);
+ if (!has_dec_pos) {
dbus->message_iter_init(msg, &iter);
- has_dec_pos = IBus_GetDecorationPosition(conn, &iter, dbus, &start_pos, &end_pos);
- if (!has_dec_pos) {
- dbus->message_iter_init(msg, &iter);
- has_pos = IBus_GetVariantCursorPos(conn, &iter, dbus, &pos);
- }
+ has_pos = IBus_GetVariantCursorPos(conn, &iter, dbus, &pos);
+ }
- if (has_dec_pos) {
- SDL_SendEditingText(text, start_pos, end_pos - start_pos);
- } else if (has_pos) {
- SDL_SendEditingText(text, pos, -1);
- } else {
- SDL_SendEditingText(text, -1, -1);
- }
+ if (has_dec_pos) {
+ SDL_SendEditingText(text, start_pos, end_pos - start_pos);
+ } else if (has_pos) {
+ SDL_SendEditingText(text, pos, -1);
} else {
- char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
- size_t text_bytes = SDL_strlen(text), i = 0;
- size_t cursor = 0;
-
- do {
- const size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
- const size_t chars = SDL_utf8strlen(buf);
-
- SDL_SendEditingText(buf, cursor, chars);
- i += sz;
- cursor += chars;
- } while (i < text_bytes);
+ SDL_SendEditingText(text, -1, -1);
}
}
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 6ee8a813a979..75e19c3c1bf1 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -921,6 +921,7 @@ SDL3_0.0.0 {
SDL_GetWindowProperties;
SDL_ClearProperty;
SDL_EnterAppMainCallbacks;
+ SDL_CleanupEvent;
# extra symbols go here (don't modify this line)
local: *;
};
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 09c6dbbd4571..4cfa59166466 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -946,3 +946,4 @@
#define SDL_GetWindowProperties SDL_GetWindowProperties_REAL
#define SDL_ClearProperty SDL_ClearProperty_REAL
#define SDL_EnterAppMainCallbacks SDL_EnterAppMainCallbacks_REAL
+#define SDL_CleanupEvent SDL_CleanupEvent_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index d584067fb231..d73e3e312af6 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -978,3 +978,4 @@ 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),)
diff --git a/src/events/SDL_dropevents.c b/src/events/SDL_dropevents.c
index 5aa4a99236e4..211b8d3b37f3 100644
--- a/src/events/SDL_dropevents.c
+++ b/src/events/SDL_dropevents.c
@@ -58,7 +58,15 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
SDL_zero(event);
event.type = evtype;
event.common.timestamp = 0;
- event.drop.file = data ? SDL_strdup(data) : NULL;
+ 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);
+ }
+ }
event.drop.windowID = window ? window->id : 0;
if (evtype == SDL_EVENT_DROP_POSITION) {
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 031e660accbc..1ce42ad5756d 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -75,17 +75,10 @@ static Uint32 SDL_userevents = SDL_EVENT_USER;
typedef struct SDL_EventEntry
{
SDL_Event event;
- SDL_SysWMmsg msg;
struct SDL_EventEntry *prev;
struct SDL_EventEntry *next;
} SDL_EventEntry;
-typedef struct SDL_SysWMEntry
-{
- SDL_SysWMmsg msg;
- struct SDL_SysWMEntry *next;
-} SDL_SysWMEntry;
-
static struct
{
SDL_Mutex *lock;
@@ -95,9 +88,7 @@ static struct
SDL_EventEntry *head;
SDL_EventEntry *tail;
SDL_EventEntry *free;
- SDL_SysWMEntry *wmmsg_used;
- SDL_SysWMEntry *wmmsg_free;
-} SDL_EventQ = { NULL, SDL_FALSE, { 0 }, 0, NULL, NULL, NULL, NULL, NULL };
+} SDL_EventQ = { NULL, SDL_FALSE, { 0 }, 0, NULL, NULL, NULL };
#ifndef SDL_JOYSTICK_DISABLED
@@ -419,7 +410,7 @@ static void SDL_LogEvent(const SDL_Event *event)
break;
#undef PRINT_FINGER_EVENT
-#define PRINT_DROP_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (file='%s' timestamp=%u windowid=%u x=%f y=%f)", event->drop.file, (uint)event->drop.timestamp, (uint)event->drop.windowID, event->drop.x, event->drop.y)
+#define PRINT_DROP_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (data='%s' timestamp=%u windowid=%u x=%f y=%f)", event->drop.data, (uint)event->drop.timestamp, (uint)event->drop.windowID, event->drop.x, event->drop.y)
SDL_EVENT_CASE(SDL_EVENT_DROP_FILE)
PRINT_DROP_EVENT(event);
break;
@@ -484,7 +475,6 @@ void SDL_StopEventLoop(void)
const char *report = SDL_GetHint("SDL_EVENT_QUEUE_STATISTICS");
int i;
SDL_EventEntry *entry;
- SDL_SysWMEntry *wmmsg;
SDL_LockMutex(SDL_EventQ.lock);
@@ -506,24 +496,12 @@ void SDL_StopEventLoop(void)
SDL_free(entry);
entry = next;
}
- for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg;) {
- SDL_SysWMEntry *next = wmmsg->next;
- SDL_free(wmmsg);
- wmmsg = next;
- }
- for (wmmsg = SDL_EventQ.wmmsg_free; wmmsg;) {
- SDL_SysWMEntry *next = wmmsg->next;
- SDL_free(wmmsg);
- wmmsg = next;
- }
SDL_AtomicSet(&SDL_EventQ.count, 0);
SDL_EventQ.max_events_seen = 0;
SDL_EventQ.head = NULL;
SDL_EventQ.tail = NULL;
SDL_EventQ.free = NULL;
- SDL_EventQ.wmmsg_used = NULL;
- SDL_EventQ.wmmsg_free = NULL;
SDL_AtomicSet(&SDL_sentinel_pending, 0);
/* Clear disabled event state */
@@ -622,9 +600,6 @@ static int SDL_AddEvent(SDL_Event *event)
entry->event = *event;
if (event->type == SDL_EVENT_POLL_SENTINEL) {
SDL_AtomicAdd(&SDL_sentinel_pending, 1);
- } else if (event->type == SDL_EVENT_SYSWM) {
- entry->msg = *event->syswm.msg;
- entry->event.syswm.msg = &entry->msg;
}
if (SDL_EventQ.tail) {
@@ -724,43 +699,14 @@ static int SDL_PeepEventsInternal(SDL_Event *events, int numevents, SDL_eventact
}
} else {
SDL_EventEntry *entry, *next;
- SDL_SysWMEntry *wmmsg, *wmmsg_next;
Uint32 type;
- if (action == SDL_GETEVENT) {
- /* Clean out any used wmmsg data
- FIXME: Do we want to retain the data for some period of time?
- */
- for (wmmsg = SDL_EventQ.wmmsg_used; wmmsg; wmmsg = wmmsg_next) {
- wmmsg_next = wmmsg->next;
- wmmsg->next = SDL_EventQ.wmmsg_free;
- SDL_EventQ.wmmsg_free = wmmsg;
- }
- SDL_EventQ.wmmsg_used = NULL;
- }
-
for (entry = SDL_EventQ.head; entry && (events == NULL || used < numevents); entry = next) {
next = entry->next;
type = entry->event.type;
if (minType <= type && type <= maxType) {
if (events) {
events[used] = entry->event;
- if (entry->event.type == SDL_EVENT_SYSWM) {
- /* We need to copy the wmmsg somewhere safe.
- For now we'll guarantee it's valid at least until
- the next call to SDL_PeepEvents()
- */
- if (SDL_EventQ.wmmsg_free) {
- wmmsg = SDL_EventQ.wmmsg_free;
- SDL_EventQ.wmmsg_free = wmmsg->next;
- } else {
- wmmsg = (SDL_SysWMEntry *)SDL_malloc(sizeof(*wmmsg));
- }
- wmmsg->msg = *entry->event.syswm.msg;
- wmmsg->next = SDL_EventQ.wmmsg_used;
- SDL_EventQ.wmmsg_used = wmmsg;
- events[used].syswm.msg = &wmmsg->msg;
- }
if (action == SDL_GETEVENT) {
SDL_CutEvent(entry);
@@ -818,9 +764,6 @@ void SDL_FlushEvents(Uint32 minType, Uint32 maxType)
{
SDL_EventEntry *entry, *next;
Uint32 type;
- /* !!! FIXME: we need to manually SDL_free() the strings in TEXTINPUT and
- drag'n'drop events if we're flushing them without passing them to the
- app, but I don't know if this is the right place to do that. */
/* Make sure the events are current */
#if 0
@@ -842,6 +785,7 @@ 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);
}
}
@@ -1124,6 +1068,33 @@ 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.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;
+ default:
+ break;
+ }
+}
+
int SDL_PushEvent(SDL_Event *event)
{
if (!event->common.timestamp) {
@@ -1380,7 +1351,11 @@ int SDL_SendSysWMEvent(SDL_SysWMmsg *message)
SDL_memset(&event, 0, sizeof(event));
event.type = SDL_EVENT_SYSWM;
event.common.timestamp = 0;
- event.syswm.msg = message;
+ event.syswm.msg = (SDL_SysWMmsg *)SDL_malloc(sizeof(*message));
+ if (!event.syswm.msg) {
+ return 0;
+ }
+ SDL_copyp(event.syswm.msg, message);
posted = (SDL_PushEvent(&event) > 0);
}
/* Update internal event state */
diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index 59968b55fc6a..49f38b9f490d 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -1098,21 +1098,18 @@ int SDL_SendEditingText(const char *text, int start, int length)
if (SDL_EventEnabled(SDL_EVENT_TEXT_EDITING)) {
SDL_Event event;
- if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE) &&
- SDL_strlen(text) >= SDL_arraysize(event.text.text)) {
- event.type = SDL_EVENT_TEXT_EDITING_EXT;
- event.common.timestamp = 0;
- event.editExt.windowID = keyboard->focus ? keyboard->focus->id : 0;
- event.editExt.text = text ? SDL_strdup(text) : NULL;
- event.editExt.start = start;
- event.editExt.length = length;
+ event.type = SDL_EVENT_TEXT_EDITING;
+ event.common.timestamp = 0;
+ event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
+ 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.type = SDL_EVENT_TEXT_EDITING;
- event.common.timestamp = 0;
- event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
- event.edit.start = start;
- event.edit.length = length;
- SDL_utf8strlcpy(event.edit.text, text, SDL_arraysize(event.edit.text));
+ event.edit.text = SDL_strdup(text);
}
posted = (SDL_PushEvent(&event) > 0);
diff --git a/src/main/SDL_main_callbacks.c b/src/main/SDL_main_callbacks.c
index a20f9f6ac862..2ac9abaf8f5a 100644
--- a/src/main/SDL_main_callbacks.c
+++ b/src/main/SDL_main_callbacks.c
@@ -83,22 +83,7 @@ int SDL_IterateMainCallbacks(void)
{
// Just pump events and empty the queue, EventWatcher sends the events to the app.
SDL_PumpEvents();
-
- for (;;) {
- SDL_Event events[32];
- int count = SDL_PeepEvents(events, SDL_arraysize(events), SDL_GETEVENT, SDL_EVENT_FIRST, SDL_EVENT_LAST);
- if (count <= 0) {
- break;
- }
- for (int i = 0; i < count; ++i) {
- switch (events[i].type) {
- case SDL_EVENT_DROP_FILE:
- case SDL_EVENT_DROP_TEXT:
- SDL_free(events[i].drop.file);
- break;
- }
- }
- }
+ SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST);
int rc = SDL_main_iteration_callback();
if (!SDL_AtomicCAS(&apprc, 0, rc)) {
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index b10bc2425505..4e179829ce3a 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -1823,10 +1823,10 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
SDL_Log("SDL EVENT: Drag and drop beginning");
break;
case SDL_EVENT_DROP_FILE:
- SDL_Log("SDL EVENT: Drag and drop file: '%s'", event->drop.file);
+ SDL_Log("SDL EVENT: Drag and drop file: '%s'", event->drop.data);
break;
case SDL_EVENT_DROP_TEXT:
- SDL_Log("SDL EVENT: Drag and drop text: '%s'", event->drop.file);
+ SDL_Log("SDL EVENT: Drag and drop text: '%s'", event->drop.data);
break;
case SDL_EVENT_DROP_COMPLETE:
SDL_Log("SDL EVENT: Drag and drop ending");
@@ -2425,12 +2425,7 @@ void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done
{
*done = SDLTest_CommonEventMainCallbacks(state, event) ? 1 : 0;
- switch (event->type) {
- case SDL_EVENT_DROP_FILE:
- case SDL_EVENT_DROP_TEXT:
- SDL_free(event->drop.file); // SDL frees these if you use SDL_AppEvent, not us, so explicitly handle it here.
- break;
- }
+ SDL_CleanupEvent(event);
}
void SDLTest_CommonQuit(SDLTest_CommonState *state)
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index b4700e8db48f..c68b49c3c250 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -2191,33 +2191,19 @@ static void text_input_preedit_string(void *data,
char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
text_input->has_preedit = SDL_TRUE;
if (text) {
- if (SDL_GetHintBoolean(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, SDL_FALSE)) {
- int cursor_begin_utf8 = cursor_begin >= 0 ? (int)SDL_utf8strnlen(text, cursor_begin) : -1;
- int cursor_end_utf8 = cursor_end >= 0 ? (int)SDL_utf8strnlen(text, cursor_end) : -1;
- int cursor_size_utf8;
- if (cursor_end_utf8 >= 0) {
- if (cursor_begin_utf8 >= 0) {
- cursor_size_utf8 = cursor_end_utf8 - cursor_begin_utf8;
- } else {
- cursor_size_utf8 = cursor_end_utf8;
- }
+ int cursor_begin_utf8 = cursor_begin >= 0 ? (int)SDL_utf8strnlen(text, cursor_begin) : -1;
+ int cursor_end_utf8 = cursor_end >= 0 ? (int)SDL_utf8strnlen(text, cursor_end) : -1;
+ int cursor_size_utf8;
+ if (cursor_end_utf8 >= 0) {
+ if (cursor_begin_utf8 >= 0) {
+ cursor_size_utf8 = cursor_end_utf8 - cursor_begin_utf8;
} else {
- cursor_size_utf8 = -1;
+ cursor_size_utf8 = cursor_end_utf8;
}
- SDL_SendEditingText(text, cursor_begin_utf8, cursor_size_utf8);
} else {
- int text_bytes = (int)SDL_strlen(text), i = 0;
- int cursor = 0;
- do {
- const int sz = (int)SDL_utf8strlcpy(b
(Patch may be truncated, please check the link at the top of this post.)