mirror of https://github.com/encounter/SDL.git
Fix joystick device add events containing invalid device indexes
This can happen if the application has not yet processed SDL_JOYDEVICEADD when the same joystick is removed. It may also happen if two joysticks are added and the second joystick is removed before the first joystick's SDL_JOYDEVICEADD has been processed by the application.
This commit is contained in:
parent
7854f43b6d
commit
9d40a0f317
|
@ -202,7 +202,7 @@ static int SDL_PrivateGameControllerButton(SDL_GameController *gamecontroller, S
|
||||||
* to have the right value for which, because the number of controllers in
|
* to have the right value for which, because the number of controllers in
|
||||||
* the system is now one less.
|
* the system is now one less.
|
||||||
*/
|
*/
|
||||||
static void UpdateEventsForDeviceRemoval()
|
static void UpdateEventsForDeviceRemoval(int device_index)
|
||||||
{
|
{
|
||||||
int i, num_events;
|
int i, num_events;
|
||||||
SDL_Event *events;
|
SDL_Event *events;
|
||||||
|
@ -220,7 +220,19 @@ static void UpdateEventsForDeviceRemoval()
|
||||||
|
|
||||||
num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
|
num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEADDED);
|
||||||
for (i = 0; i < num_events; ++i) {
|
for (i = 0; i < num_events; ++i) {
|
||||||
--events[i].cdevice.which;
|
if (events[i].cdevice.which < device_index) {
|
||||||
|
/* No change for index values lower than the removed device */
|
||||||
|
}
|
||||||
|
else if (events[i].cdevice.which == device_index) {
|
||||||
|
/* Drop this event entirely */
|
||||||
|
SDL_memmove(&events[i], &events[i + 1], sizeof(*events) * (num_events - (i + 1)));
|
||||||
|
--i;
|
||||||
|
--num_events;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Fix up the device index if greater than the removed device */
|
||||||
|
--events[i].cdevice.which;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
|
SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
|
||||||
|
|
||||||
|
@ -427,6 +439,7 @@ static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event * ev
|
||||||
case SDL_JOYDEVICEREMOVED:
|
case SDL_JOYDEVICEREMOVED:
|
||||||
{
|
{
|
||||||
SDL_GameController *controllerlist = SDL_gamecontrollers;
|
SDL_GameController *controllerlist = SDL_gamecontrollers;
|
||||||
|
int device_index = 0;
|
||||||
while (controllerlist) {
|
while (controllerlist) {
|
||||||
if (controllerlist->joystick->instance_id == event->jdevice.which) {
|
if (controllerlist->joystick->instance_id == event->jdevice.which) {
|
||||||
SDL_Event deviceevent;
|
SDL_Event deviceevent;
|
||||||
|
@ -437,10 +450,11 @@ static int SDLCALL SDL_GameControllerEventWatcher(void *userdata, SDL_Event * ev
|
||||||
deviceevent.cdevice.which = event->jdevice.which;
|
deviceevent.cdevice.which = event->jdevice.which;
|
||||||
SDL_PushEvent(&deviceevent);
|
SDL_PushEvent(&deviceevent);
|
||||||
|
|
||||||
UpdateEventsForDeviceRemoval();
|
UpdateEventsForDeviceRemoval(device_index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
controllerlist = controllerlist->next;
|
controllerlist = controllerlist->next;
|
||||||
|
++device_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1184,7 +1184,7 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
|
||||||
* to have the right value for which, because the number of controllers in
|
* to have the right value for which, because the number of controllers in
|
||||||
* the system is now one less.
|
* the system is now one less.
|
||||||
*/
|
*/
|
||||||
static void UpdateEventsForDeviceRemoval()
|
static void UpdateEventsForDeviceRemoval(int device_index)
|
||||||
{
|
{
|
||||||
int i, num_events;
|
int i, num_events;
|
||||||
SDL_Event *events;
|
SDL_Event *events;
|
||||||
|
@ -1202,7 +1202,19 @@ static void UpdateEventsForDeviceRemoval()
|
||||||
|
|
||||||
num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
|
num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED);
|
||||||
for (i = 0; i < num_events; ++i) {
|
for (i = 0; i < num_events; ++i) {
|
||||||
--events[i].jdevice.which;
|
if (events[i].cdevice.which < device_index) {
|
||||||
|
/* No change for index values lower than the removed device */
|
||||||
|
}
|
||||||
|
else if (events[i].cdevice.which == device_index) {
|
||||||
|
/* Drop this event entirely */
|
||||||
|
SDL_memmove(&events[i], &events[i + 1], sizeof(*events) * (num_events - (i + 1)));
|
||||||
|
--num_events;
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Fix up the device index if greater than the removed device */
|
||||||
|
--events[i].cdevice.which;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
|
SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
|
||||||
|
|
||||||
|
@ -1243,17 +1255,21 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
|
||||||
{
|
{
|
||||||
SDL_Joystick *joystick = NULL;
|
SDL_Joystick *joystick = NULL;
|
||||||
int player_index;
|
int player_index;
|
||||||
|
int device_index;
|
||||||
#if !SDL_EVENTS_DISABLED
|
#if !SDL_EVENTS_DISABLED
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Find this joystick... */
|
/* Find this joystick... */
|
||||||
|
device_index = 0;
|
||||||
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
|
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
|
||||||
if (joystick->instance_id == device_instance) {
|
if (joystick->instance_id == device_instance) {
|
||||||
SDL_PrivateJoystickForceRecentering(joystick);
|
SDL_PrivateJoystickForceRecentering(joystick);
|
||||||
joystick->attached = SDL_FALSE;
|
joystick->attached = SDL_FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++device_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !SDL_EVENTS_DISABLED
|
#if !SDL_EVENTS_DISABLED
|
||||||
|
@ -1265,7 +1281,7 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
|
||||||
SDL_PushEvent(&event);
|
SDL_PushEvent(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateEventsForDeviceRemoval();
|
UpdateEventsForDeviceRemoval(device_index);
|
||||||
#endif /* !SDL_EVENTS_DISABLED */
|
#endif /* !SDL_EVENTS_DISABLED */
|
||||||
|
|
||||||
SDL_LockJoysticks();
|
SDL_LockJoysticks();
|
||||||
|
|
Loading…
Reference in New Issue