SDL: Added SDL_AllocateEventString()

From 306c4164bc5e9c8976ad54c747885fbc645d9084 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 18 Jun 2024 13:50:18 -0700
Subject: [PATCH] Added SDL_AllocateEventString()

---
 include/SDL3/SDL_events.h   | 11 +++++------
 src/events/SDL_dropevents.c | 10 +++++-----
 src/events/SDL_events.c     |  8 ++++++++
 src/events/SDL_events_c.h   |  2 ++
 src/events/SDL_keyboard.c   | 12 ++----------
 5 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h
index 2cdcedae2ec57..d578cdd93fdf7 100644
--- a/include/SDL3/SDL_events.h
+++ b/include/SDL3/SDL_events.h
@@ -327,7 +327,7 @@ typedef struct SDL_TextEditingEvent
     Uint32 reserved;
     Uint64 timestamp;   /**< In nanoseconds, populated using SDL_GetTicksNS() */
     SDL_WindowID windowID; /**< The window with keyboard focus, if any */
-    char *text;         /**< The editing text */
+    const char *text;   /**< The editing text */
     Sint32 start;       /**< The start cursor of selected editing text */
     Sint32 length;      /**< The length of selected editing text */
 } SDL_TextEditingEvent;
@@ -352,7 +352,7 @@ typedef struct SDL_TextInputEvent
     Uint32 reserved;
     Uint64 timestamp;   /**< In nanoseconds, populated using SDL_GetTicksNS() */
     SDL_WindowID windowID; /**< The window with keyboard focus, if any */
-    char *text;         /**< The input text, UTF-8 encoded */
+    const char *text;   /**< The input text, UTF-8 encoded */
 } SDL_TextInputEvent;
 
 /**
@@ -733,8 +733,7 @@ typedef struct SDL_PenButtonEvent
  * An event used to drop text or request a file open by the system
  * (event.drop.*)
  *
- * The `data` is owned by SDL and should be copied if the application wants to
- * hold onto it beyond the scope of handling this event. Do not free it!
+ * The `source` and `data` are owned by SDL and should be copied if the application wants to hold onto them beyond the scope of handling this event.
  *
  * \since This struct is available since SDL 3.0.0.
  */
@@ -746,8 +745,8 @@ typedef struct SDL_DropEvent
     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 *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 */
+    const char *source; /**< The source app that sent this drop event, or NULL if that isn't available */
+    const char *data;   /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */
 } SDL_DropEvent;
 
 /**
diff --git a/src/events/SDL_dropevents.c b/src/events/SDL_dropevents.c
index 610652c256187..3af2356745a27 100644
--- a/src/events/SDL_dropevents.c
+++ b/src/events/SDL_dropevents.c
@@ -59,16 +59,16 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
         event.type = evtype;
         event.common.timestamp = 0;
         if (source) {
-            event.drop.source = SDL_strdup(source);
+            event.drop.source = SDL_AllocateEventString(source);
+            if (!event.drop.source) {
+                return 0;
+            }
         }
         if (data) {
-            size_t size = SDL_strlen(data) + 1;
-            event.drop.data = (char *)SDL_AllocateEventMemory(size);
+            event.drop.data = SDL_AllocateEventString(data);
             if (!event.drop.data) {
-                SDL_free(event.drop.source);
                 return 0;
             }
-            SDL_memcpy(event.drop.data, data, size);
         }
         event.drop.windowID = window ? window->id : 0;
 
diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c
index 7dd7ff7521ca0..63f140d1345bb 100644
--- a/src/events/SDL_events.c
+++ b/src/events/SDL_events.c
@@ -135,6 +135,14 @@ void *SDL_AllocateEventMemory(size_t size)
     return SDL_FreeLater(SDL_malloc(size));
 }
 
+const char *SDL_AllocateEventString(const char *string)
+{
+    if (string) {
+        return SDL_FreeLater(SDL_strdup(string));
+    }
+    return NULL;
+}
+
 static void SDL_FlushEventMemory(Uint32 eventID)
 {
     SDL_LockMutex(SDL_event_memory_lock);
diff --git a/src/events/SDL_events_c.h b/src/events/SDL_events_c.h
index 181583d71d07f..778af32cadbf0 100644
--- a/src/events/SDL_events_c.h
+++ b/src/events/SDL_events_c.h
@@ -40,6 +40,8 @@ extern int SDL_StartEventLoop(void);
 extern void SDL_StopEventLoop(void);
 extern void SDL_QuitInterrupt(void);
 
+extern const char *SDL_AllocateEventString(const char *string);
+
 extern int SDL_SendAppEvent(SDL_EventType eventType);
 extern int SDL_SendKeymapChangedEvent(void);
 extern int SDL_SendLocaleChangedEvent(void);
diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index 16571952a2f7f..e59844b144917 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -1205,14 +1205,10 @@ int SDL_SendKeyboardText(const char *text)
         event.type = SDL_EVENT_TEXT_INPUT;
         event.common.timestamp = 0;
         event.text.windowID = keyboard->focus ? keyboard->focus->id : 0;
-
-        size_t size = SDL_strlen(text) + 1;
-        event.text.text = (char *)SDL_AllocateEventMemory(size);
+        event.text.text = SDL_AllocateEventString(text);
         if (!event.text.text) {
             return 0;
         }
-        SDL_memcpy(event.text.text, text, size);
-
         posted = (SDL_PushEvent(&event) > 0);
     }
     return posted;
@@ -1241,14 +1237,10 @@ int SDL_SendEditingText(const char *text, int start, int length)
         event.edit.windowID = keyboard->focus ? keyboard->focus->id : 0;
         event.edit.start = start;
         event.edit.length = length;
-
-        size_t size = SDL_strlen(text) + 1;
-        event.edit.text = (char *)SDL_AllocateEventMemory(size);
+        event.edit.text = SDL_AllocateEventString(text);
         if (!event.edit.text) {
             return 0;
         }
-        SDL_memcpy(event.edit.text, text, size);
-
         posted = (SDL_PushEvent(&event) > 0);
     }
     return posted;