Skip to content

Commit

Permalink
Added SDL_CleanupEvent()
Browse files Browse the repository at this point in the history
This is used to free any dynamically allocated memory in events.
  • Loading branch information
slouken committed Nov 4, 2023
1 parent a6b85c8 commit baa7bb5
Show file tree
Hide file tree
Showing 20 changed files with 146 additions and 232 deletions.
3 changes: 3 additions & 0 deletions docs/README-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
78 changes: 46 additions & 32 deletions include/SDL3/SDL_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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
Expand All @@ -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 */
Expand Down Expand Up @@ -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
*/
Expand All @@ -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);
Expand All @@ -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.
*
Expand Down
11 changes: 0 additions & 11 deletions include/SDL3/SDL_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
23 changes: 4 additions & 19 deletions src/core/linux/SDL_fcitx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
41 changes: 13 additions & 28 deletions src/core/linux/SDL_ibus.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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: *;
};
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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),)
10 changes: 9 additions & 1 deletion src/events/SDL_dropevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit baa7bb5

Please sign in to comment.