From 537c62f4c1430e5014531461bae13d77cfa8f1a0 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 7 May 2024 09:13:50 -0700 Subject: [PATCH] Fixed memory leak cleaning up mouse and keyboard instances Fixes https://github.com/libsdl-org/SDL/issues/9487 --- src/core/linux/SDL_evdev.c | 4 ++-- src/events/SDL_keyboard.c | 18 +++++++++++------- src/events/SDL_keyboard_c.h | 2 +- src/events/SDL_mouse.c | 18 +++++++++++------- src/events/SDL_mouse_c.h | 2 +- src/video/uikit/SDL_uikitevents.m | 4 ++-- src/video/wayland/SDL_waylandevents.c | 4 ++-- src/video/windows/SDL_windowsevents.c | 4 ++-- src/video/x11/SDL_x11xinput2.c | 4 ++-- 9 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/core/linux/SDL_evdev.c b/src/core/linux/SDL_evdev.c index 0f464e301..1ed054ff4 100644 --- a/src/core/linux/SDL_evdev.c +++ b/src/core/linux/SDL_evdev.c @@ -619,7 +619,7 @@ static int SDL_EVDEV_init_keyboard(SDL_evdevlist_item *item, int udev_class) static void SDL_EVDEV_destroy_keyboard(SDL_evdevlist_item *item) { - SDL_RemoveKeyboard((SDL_KeyboardID)item->fd); + SDL_RemoveKeyboard((SDL_KeyboardID)item->fd, SDL_TRUE); } static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class) @@ -656,7 +656,7 @@ static int SDL_EVDEV_init_mouse(SDL_evdevlist_item *item, int udev_class) static void SDL_EVDEV_destroy_mouse(SDL_evdevlist_item *item) { - SDL_RemoveMouse((SDL_MouseID)item->fd); + SDL_RemoveMouse((SDL_MouseID)item->fd, SDL_TRUE); } static int SDL_EVDEV_init_touchscreen(SDL_evdevlist_item *item, int udev_class) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index d64e6716a..80e75ecce 100644 --- a/src/events/SDL_keyboard.c +++ b/src/events/SDL_keyboard.c @@ -734,7 +734,7 @@ void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, SDL_bool send_ } } -void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID) +void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event) { int keyboard_index = SDL_GetKeyboardIndex(keyboardID); if (keyboard_index < 0) { @@ -749,11 +749,13 @@ void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID) } --SDL_keyboard_count; - SDL_Event event; - SDL_zero(event); - event.type = SDL_EVENT_KEYBOARD_REMOVED; - event.kdevice.which = keyboardID; - SDL_PushEvent(&event); + if (send_event) { + SDL_Event event; + SDL_zero(event); + event.type = SDL_EVENT_KEYBOARD_REMOVED; + event.kdevice.which = keyboardID; + SDL_PushEvent(&event); + } } SDL_bool SDL_HasKeyboard(void) @@ -1254,7 +1256,9 @@ int SDL_SendEditingText(const char *text, int start, int length) void SDL_QuitKeyboard(void) { - SDL_keyboard_count = 0; + for (int i = SDL_keyboard_count; i--;) { + SDL_RemoveKeyboard(SDL_keyboards[i].instance_id, SDL_FALSE); + } SDL_free(SDL_keyboards); SDL_keyboards = NULL; } diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h index 323b139d1..14b8dea12 100644 --- a/src/events/SDL_keyboard_c.h +++ b/src/events/SDL_keyboard_c.h @@ -39,7 +39,7 @@ extern SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys); extern void SDL_AddKeyboard(SDL_KeyboardID keyboardID, const char *name, SDL_bool send_event); /* A keyboard has been removed from the system */ -extern void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID); +extern void SDL_RemoveKeyboard(SDL_KeyboardID keyboardID, SDL_bool send_event); /* Get the default keymap */ extern void SDL_GetDefaultKeymap(SDL_Keycode *keymap); diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index 885179c90..b4d5d4179 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -280,7 +280,7 @@ void SDL_AddMouse(SDL_MouseID mouseID, const char *name, SDL_bool send_event) } } -void SDL_RemoveMouse(SDL_MouseID mouseID) +void SDL_RemoveMouse(SDL_MouseID mouseID, SDL_bool send_event) { int mouse_index = SDL_GetMouseIndex(mouseID); if (mouse_index < 0) { @@ -308,11 +308,13 @@ void SDL_RemoveMouse(SDL_MouseID mouseID) } } - SDL_Event event; - SDL_zero(event); - event.type = SDL_EVENT_MOUSE_REMOVED; - event.mdevice.which = mouseID; - SDL_PushEvent(&event); + if (send_event) { + SDL_Event event; + SDL_zero(event); + event.type = SDL_EVENT_MOUSE_REMOVED; + event.mdevice.which = mouseID; + SDL_PushEvent(&event); + } } SDL_bool SDL_HasMouse(void) @@ -1118,7 +1120,9 @@ void SDL_QuitMouse(void) SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, SDL_MouseRelativeWarpMotionChanged, mouse); - SDL_mouse_count = 0; + for (int i = SDL_mouse_count; i--; ) { + SDL_RemoveMouse(SDL_mice[i].instance_id, SDL_FALSE); + } SDL_free(SDL_mice); SDL_mice = NULL; } diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h index 4dc0c1119..b824291a0 100644 --- a/src/events/SDL_mouse_c.h +++ b/src/events/SDL_mouse_c.h @@ -140,7 +140,7 @@ extern SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product); extern void SDL_AddMouse(SDL_MouseID mouseID, const char *name, SDL_bool send_event); /* A mouse has been removed from the system */ -extern void SDL_RemoveMouse(SDL_MouseID mouseID); +extern void SDL_RemoveMouse(SDL_MouseID mouseID, SDL_bool send_event); /* Get the mouse state structure */ extern SDL_Mouse *SDL_GetMouse(void); diff --git a/src/video/uikit/SDL_uikitevents.m b/src/video/uikit/SDL_uikitevents.m index 9afc03638..5ce8e6d03 100644 --- a/src/video/uikit/SDL_uikitevents.m +++ b/src/video/uikit/SDL_uikitevents.m @@ -193,7 +193,7 @@ static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(1 { SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)keyboard; - SDL_RemoveKeyboard(keyboardID); + SDL_RemoveKeyboard(keyboardID, SDL_TRUE); keyboard.keyboardInput.keyChangedHandler = nil; } @@ -385,7 +385,7 @@ static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios UpdatePointerLock(); - SDL_RemoveMouse(mouseID); + SDL_RemoveMouse(mouseID, SDL_TRUE); } void SDL_InitGCMouse(void) diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index 6e1be4c44..18f732632 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1732,7 +1732,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *seat, input->pointer = NULL; input->display->pointer = NULL; - SDL_RemoveMouse(input->pointer_id); + SDL_RemoveMouse(input->pointer_id, SDL_TRUE); input->pointer_id = 0; } @@ -1760,7 +1760,7 @@ static void seat_handle_capabilities(void *data, struct wl_seat *seat, wl_keyboard_destroy(input->keyboard); input->keyboard = NULL; - SDL_RemoveKeyboard(input->keyboard_id); + SDL_RemoveKeyboard(input->keyboard_id, SDL_TRUE); input->keyboard_id = 0; } diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index 1b594a85d..4f90bb146 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -926,13 +926,13 @@ void WIN_CheckKeyboardAndMouseHotplug(SDL_VideoDevice *_this, SDL_bool initial_c for (int i = old_keyboard_count; i--;) { if (!HasDeviceID(old_keyboards[i], new_keyboards, new_keyboard_count)) { - SDL_RemoveKeyboard(old_keyboards[i]); + SDL_RemoveKeyboard(old_keyboards[i], send_event); } } for (int i = old_mouse_count; i--;) { if (!HasDeviceID(old_mice[i], new_mice, new_mouse_count)) { - SDL_RemoveMouse(old_mice[i]); + SDL_RemoveMouse(old_mice[i], send_event); } } diff --git a/src/video/x11/SDL_x11xinput2.c b/src/video/x11/SDL_x11xinput2.c index b2b264cc3..0ea129022 100644 --- a/src/video/x11/SDL_x11xinput2.c +++ b/src/video/x11/SDL_x11xinput2.c @@ -823,13 +823,13 @@ void X11_Xinput2UpdateDevices(SDL_VideoDevice *_this, SDL_bool initial_check) for (int i = old_keyboard_count; i--;) { if (!HasDeviceID(old_keyboards[i], new_keyboards, new_keyboard_count)) { - SDL_RemoveKeyboard(old_keyboards[i]); + SDL_RemoveKeyboard(old_keyboards[i], send_event); } } for (int i = old_mouse_count; i--;) { if (!HasDeviceID(old_mice[i], new_mice, new_mouse_count)) { - SDL_RemoveMouse(old_mice[i]); + SDL_RemoveMouse(old_mice[i], send_event); } }