From ea7fbf7947ac87f134569efc1af2661ba3455ff1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 3 Aug 2022 19:39:37 -0700 Subject: [PATCH] Update in-flight SDL_CONTROLLERDEVICEADDED messages when a device is removed This fixes the application trying to open the wrong device index when a device is removed and another has just been added --- src/joystick/SDL_joystick.c | 39 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 931aa9e46..78ac09609 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -1331,13 +1331,13 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance) * to have the right value for which, because the number of controllers in * the system is now one less. */ -static void UpdateEventsForDeviceRemoval(int device_index) +static void UpdateEventsForDeviceRemoval(int device_index, Uint32 type) { int i, num_events; SDL_Event *events; SDL_bool isstack; - num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED); + num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type); if (num_events <= 0) { return; } @@ -1347,20 +1347,38 @@ static void UpdateEventsForDeviceRemoval(int device_index) return; } - num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED); + num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, type, type); for (i = 0; i < num_events; ++i) { - if (events[i].cdevice.which < device_index) { - /* No change for index values lower than the removed device */ + Sint32 which = -1; + switch (type) { + case SDL_JOYDEVICEADDED: + which = events[i].jdevice.which; + break; + case SDL_CONTROLLERDEVICEADDED: + which = events[i].cdevice.which; + break; + default: + break; } - else if (events[i].cdevice.which == device_index) { + if (which < device_index) { + /* No change for index values lower than the removed device */ + } else if (which == device_index) { /* Drop this event entirely */ SDL_memmove(&events[i], &events[i + 1], sizeof(*events) * (num_events - (i + 1))); --num_events; --i; - } - else { + } else { /* Fix up the device index if greater than the removed device */ - --events[i].cdevice.which; + switch (type) { + case SDL_JOYDEVICEADDED: + --events[i].jdevice.which; + break; + case SDL_CONTROLLERDEVICEADDED: + --events[i].cdevice.which; + break; + default: + break; + } } } SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0); @@ -1427,7 +1445,8 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance) SDL_PushEvent(&event); } - UpdateEventsForDeviceRemoval(device_index); + UpdateEventsForDeviceRemoval(device_index, SDL_JOYDEVICEADDED); + UpdateEventsForDeviceRemoval(device_index, SDL_CONTROLLERDEVICEADDED); #endif /* !SDL_EVENTS_DISABLED */ SDL_LockJoysticks();