From 6526c4d0fc63f05402c78a36216a17eaf8ebba8f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 17 Jun 2023 08:59:52 -0700 Subject: [PATCH] Refactor VIDPID list loading code (cherry picked from commit d91e96e7f50b9c3cb0e1dacda39274b4af037a96) --- src/joystick/SDL_gamecontroller.c | 78 +++---------------------------- src/joystick/SDL_joystick.c | 66 ++++++++++++++++++++++++++ src/joystick/SDL_joystick_c.h | 12 +++++ 3 files changed, 84 insertions(+), 72 deletions(-) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index c4f8d6542..9bbb7cf76 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -156,61 +156,9 @@ struct _SDL_GameController return retval; \ } -typedef struct -{ - int num_entries; - int max_entries; - Uint32 *entries; -} SDL_vidpid_list; - static SDL_vidpid_list SDL_allowed_controllers; static SDL_vidpid_list SDL_ignored_controllers; -static void SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list) -{ - Uint32 entry; - char *spot; - char *file = NULL; - - list->num_entries = 0; - - if (hint && *hint == '@') { - spot = file = (char *)SDL_LoadFile(hint + 1, NULL); - } else { - spot = (char *)hint; - } - - if (!spot) { - return; - } - - while ((spot = SDL_strstr(spot, "0x")) != NULL) { - entry = (Uint16)SDL_strtol(spot, &spot, 0); - entry <<= 16; - spot = SDL_strstr(spot, "0x"); - if (!spot) { - break; - } - entry |= (Uint16)SDL_strtol(spot, &spot, 0); - - if (list->num_entries == list->max_entries) { - int max_entries = list->max_entries + 16; - Uint32 *entries = (Uint32 *)SDL_realloc(list->entries, max_entries * sizeof(*list->entries)); - if (!entries) { - /* Out of memory, go with what we have already */ - break; - } - list->entries = entries; - list->max_entries = max_entries; - } - list->entries[list->num_entries++] = entry; - } - - if (file) { - SDL_free(file); - } -} - static void SDLCALL SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint) { SDL_LoadVIDPIDListFromHint(hint, &SDL_ignored_controllers); @@ -2161,11 +2109,9 @@ static SDL_bool SDL_endswith(const char *string, const char *suffix) */ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid) { - int i; Uint16 vendor; Uint16 product; Uint16 version; - Uint32 vidpid; #if defined(__LINUX__) if (SDL_endswith(name, " Motion Sensors")) { @@ -2214,20 +2160,14 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid) } } - vidpid = MAKE_VIDPID(vendor, product); - if (SDL_allowed_controllers.num_entries > 0) { - for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) { - if (vidpid == SDL_allowed_controllers.entries[i]) { - return SDL_FALSE; - } + if (SDL_VIDPIDInList(vendor, product, &SDL_allowed_controllers)) { + return SDL_FALSE; } return SDL_TRUE; } else { - for (i = 0; i < SDL_ignored_controllers.num_entries; ++i) { - if (vidpid == SDL_ignored_controllers.entries[i]) { - return SDL_TRUE; - } + if (SDL_VIDPIDInList(vendor, product, &SDL_ignored_controllers)) { + return SDL_TRUE; } return SDL_FALSE; } @@ -3138,14 +3078,8 @@ void SDL_GameControllerQuitMappings(void) SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT, SDL_GameControllerIgnoreDevicesExceptChanged, NULL); - if (SDL_allowed_controllers.entries) { - SDL_free(SDL_allowed_controllers.entries); - SDL_zero(SDL_allowed_controllers); - } - if (SDL_ignored_controllers.entries) { - SDL_free(SDL_ignored_controllers.entries); - SDL_zero(SDL_ignored_controllers); - } + SDL_FreeVIDPIDList(&SDL_allowed_controllers); + SDL_FreeVIDPIDList(&SDL_ignored_controllers); } /* diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index ad7226491..6699513a5 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -3226,4 +3226,70 @@ int SDL_PrivateJoystickSensor(SDL_Joystick *joystick, SDL_SensorType type, Uint6 return posted; } +void SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list) +{ + Uint32 entry; + char *spot; + char *file = NULL; + + list->num_entries = 0; + + if (hint && *hint == '@') { + spot = file = (char *)SDL_LoadFile(hint + 1, NULL); + } else { + spot = (char *)hint; + } + + if (spot == NULL) { + return; + } + + while ((spot = SDL_strstr(spot, "0x")) != NULL) { + entry = (Uint16)SDL_strtol(spot, &spot, 0); + entry <<= 16; + spot = SDL_strstr(spot, "0x"); + if (spot == NULL) { + break; + } + entry |= (Uint16)SDL_strtol(spot, &spot, 0); + + if (list->num_entries == list->max_entries) { + int max_entries = list->max_entries + 16; + Uint32 *entries = (Uint32 *)SDL_realloc(list->entries, max_entries * sizeof(*list->entries)); + if (entries == NULL) { + /* Out of memory, go with what we have already */ + break; + } + list->entries = entries; + list->max_entries = max_entries; + } + list->entries[list->num_entries++] = entry; + } + + if (file) { + SDL_free(file); + } +} + +SDL_bool SDL_VIDPIDInList(Uint16 vendor_id, Uint16 product_id, const SDL_vidpid_list *list) +{ + int i; + Uint32 vidpid = MAKE_VIDPID(vendor_id, product_id); + + for (i = 0; i < list->num_entries; ++i) { + if (vidpid == list->entries[i]) { + return SDL_TRUE; + } + } + return SDL_FALSE; +} + +void SDL_FreeVIDPIDList(SDL_vidpid_list *list) +{ + if (list->entries) { + SDL_free(list->entries); + SDL_zerop(list); + } +} + /* vi: set ts=4 sw=4 expandtab: */ diff --git a/src/joystick/SDL_joystick_c.h b/src/joystick/SDL_joystick_c.h index 34249ec6c..46932b49d 100644 --- a/src/joystick/SDL_joystick_c.h +++ b/src/joystick/SDL_joystick_c.h @@ -231,6 +231,18 @@ typedef struct _SDL_GamepadMapping extern SDL_bool SDL_PrivateJoystickGetAutoGamepadMapping(int device_index, SDL_GamepadMapping *out); + +typedef struct +{ + int num_entries; + int max_entries; + Uint32 *entries; +} SDL_vidpid_list; + +extern void SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list); +extern SDL_bool SDL_VIDPIDInList(Uint16 vendor_id, Uint16 product_id, const SDL_vidpid_list *list); +extern void SDL_FreeVIDPIDList(SDL_vidpid_list *list); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus }