Added SDL hints to filter the set of game controllers reported by SDL
authorSam Lantinga <slouken@libsdl.org>
Wed, 09 Aug 2017 11:59:29 -0700
changeset 11201813a8510bd0c
parent 11200 8bcc1cc9ac4c
child 11202 e393438c4a95
Added SDL hints to filter the set of game controllers reported by SDL
include/SDL_hints.h
src/joystick/SDL_gamecontroller.c
src/joystick/SDL_joystick.c
src/joystick/SDL_joystick_c.h
src/joystick/darwin/SDL_sysjoystick.c
src/joystick/linux/SDL_sysjoystick.c
src/joystick/windows/SDL_dinputjoystick.c
src/joystick/windows/SDL_xinputjoystick.c
     1.1 --- a/include/SDL_hints.h	Wed Aug 09 11:58:38 2017 -0700
     1.2 +++ b/include/SDL_hints.h	Wed Aug 09 11:59:29 2017 -0700
     1.3 @@ -359,7 +359,6 @@
     1.4   */
     1.5  #define SDL_HINT_ACCELEROMETER_AS_JOYSTICK "SDL_ACCELEROMETER_AS_JOYSTICK"
     1.6  
     1.7 -
     1.8  /**
     1.9   *  \brief  A variable that lets you disable the detection and use of Xinput gamepad devices
    1.10   *
    1.11 @@ -369,7 +368,6 @@
    1.12   */
    1.13  #define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED"
    1.14  
    1.15 -
    1.16  /**
    1.17   *  \brief  A variable that causes SDL to use the old axis and button mapping for XInput devices.
    1.18   *
    1.19 @@ -379,9 +377,8 @@
    1.20   */
    1.21  #define SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING"
    1.22  
    1.23 -
    1.24  /**
    1.25 - *  \brief  A variable that lets you manually hint extra gamecontroller db entries
    1.26 + *  \brief  A variable that lets you manually hint extra gamecontroller db entries.
    1.27   *
    1.28   *  The variable should be newline delimited rows of gamecontroller config data, see SDL_gamecontroller.h
    1.29   *
    1.30 @@ -390,6 +387,31 @@
    1.31   */
    1.32  #define SDL_HINT_GAMECONTROLLERCONFIG "SDL_GAMECONTROLLERCONFIG"
    1.33  
    1.34 +/**
    1.35 + *  \brief  A variable containing a list of devices to skip when scanning for game controllers.
    1.36 + *
    1.37 + *  The format of the string is a comma separated list of USB VID/PID pairs
    1.38 + *  in hexadecimal form, e.g.
    1.39 + *
    1.40 + *      0xAAAA/0xBBBB,0xCCCC/0xDDDD
    1.41 + *
    1.42 + *  The variable can also take the form of @file, in which case the named
    1.43 + *  file will be loaded and interpreted as the value of the variable.
    1.44 + */
    1.45 +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES "SDL_GAMECONTROLLER_IGNORE_DEVICES"
    1.46 +
    1.47 +/**
    1.48 + *  \brief  If set, all devices will be skipped when scanning for game controllers except for the ones listed in this variable.
    1.49 + *
    1.50 + *  The format of the string is a comma separated list of USB VID/PID pairs
    1.51 + *  in hexadecimal form, e.g.
    1.52 + *
    1.53 + *      0xAAAA/0xBBBB,0xCCCC/0xDDDD
    1.54 + *
    1.55 + *  The variable can also take the form of @file, in which case the named
    1.56 + *  file will be loaded and interpreted as the value of the variable.
    1.57 + */
    1.58 +#define SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT "SDL_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT"
    1.59  
    1.60  /**
    1.61   *  \brief  A variable that lets you enable joystick (and gamecontroller) events even when your app is in the background.
    1.62 @@ -404,7 +426,6 @@
    1.63   */
    1.64  #define SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS"
    1.65  
    1.66 -
    1.67  /**
    1.68   *  \brief If set to "0" then never set the top most bit on a SDL Window, even if the video mode expects it.
    1.69   *      This is a debugging aid for developers and not expected to be used by end users. The default is "1"
    1.70 @@ -415,7 +436,6 @@
    1.71   */
    1.72  #define SDL_HINT_ALLOW_TOPMOST "SDL_ALLOW_TOPMOST"
    1.73  
    1.74 -
    1.75  /**
    1.76   *  \brief A variable that controls the timer resolution, in milliseconds.
    1.77   *
     2.1 --- a/src/joystick/SDL_gamecontroller.c	Wed Aug 09 11:58:38 2017 -0700
     2.2 +++ b/src/joystick/SDL_gamecontroller.c	Wed Aug 09 11:59:29 2017 -0700
     2.3 @@ -112,6 +112,74 @@
     2.4  };
     2.5  
     2.6  
     2.7 +typedef struct
     2.8 +{
     2.9 +    int num_entries;
    2.10 +    int max_entries;
    2.11 +    Uint32 *entries;
    2.12 +} SDL_vidpid_list;
    2.13 +
    2.14 +static SDL_vidpid_list SDL_allowed_controllers;
    2.15 +static SDL_vidpid_list SDL_ignored_controllers;
    2.16 +
    2.17 +static void
    2.18 +SDL_LoadVIDPIDListFromHint(const char *hint, SDL_vidpid_list *list)
    2.19 +{
    2.20 +    Uint32 entry;
    2.21 +    char *spot;
    2.22 +    char *file = NULL;
    2.23 +
    2.24 +    list->num_entries = 0;
    2.25 +
    2.26 +    if (hint && *hint == '@') {
    2.27 +        spot = file = (char *)SDL_LoadFile(hint+1, NULL);
    2.28 +    } else {
    2.29 +        spot = (char *)hint;
    2.30 +    }
    2.31 +
    2.32 +    if (!spot) {
    2.33 +        return;
    2.34 +    }
    2.35 +
    2.36 +    while ((spot = SDL_strstr(spot, "0x")) != NULL) {
    2.37 +        entry = SDL_strtol(spot, &spot, 0);
    2.38 +        entry <<= 16;
    2.39 +        spot = SDL_strstr(spot, "0x");
    2.40 +        if (!spot) {
    2.41 +            break;
    2.42 +        }
    2.43 +        entry |= SDL_strtol(spot, &spot, 0);
    2.44 +
    2.45 +        if (list->num_entries == list->max_entries) {
    2.46 +            int max_entries = list->max_entries + 16;
    2.47 +            Uint32 *entries = (Uint32 *)SDL_realloc(list->entries, max_entries*sizeof(*list->entries));
    2.48 +            if (entries == NULL) {
    2.49 +                /* Out of memory, go with what we have already */
    2.50 +                break;
    2.51 +            }
    2.52 +            list->entries = entries;
    2.53 +            list->max_entries = max_entries;
    2.54 +        }
    2.55 +        list->entries[list->num_entries++] = entry;
    2.56 +    }
    2.57 +
    2.58 +    if (file) {
    2.59 +        SDL_free(file);
    2.60 +    }
    2.61 +}
    2.62 +
    2.63 +static void
    2.64 +SDL_GameControllerIgnoreDevicesChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
    2.65 +{
    2.66 +    SDL_LoadVIDPIDListFromHint(hint, &SDL_ignored_controllers);
    2.67 +}
    2.68 +
    2.69 +static void
    2.70 +SDL_GameControllerIgnoreDevicesExceptChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
    2.71 +{
    2.72 +    SDL_LoadVIDPIDListFromHint(hint, &SDL_allowed_controllers);
    2.73 +}
    2.74 +
    2.75  static int SDL_PrivateGameControllerAxis(SDL_GameController * gamecontroller, SDL_GameControllerAxis axis, Sint16 value);
    2.76  static int SDL_PrivateGameControllerButton(SDL_GameController * gamecontroller, SDL_GameControllerButton button, Uint8 state);
    2.77  
    2.78 @@ -799,47 +867,48 @@
    2.79  /*
    2.80   * Helper function to determine pre-calculated offset to certain joystick mappings
    2.81   */
    2.82 +static ControllerMapping_t *SDL_PrivateGetControllerMappingForNameAndGUID(const char *name, SDL_JoystickGUID guid)
    2.83 +{
    2.84 +    ControllerMapping_t *mapping;
    2.85 +
    2.86 +    mapping = SDL_PrivateGetControllerMappingForGUID(&guid);
    2.87 +#if defined(SDL_JOYSTICK_EMSCRIPTEN)
    2.88 +    if (!mapping && s_pEmscriptenMapping) {
    2.89 +        mapping = s_pEmscriptenMapping;
    2.90 +    }
    2.91 +#else
    2.92 +    (void) s_pEmscriptenMapping;  /* pacify ARMCC */
    2.93 +#endif
    2.94 +#ifdef __LINUX__
    2.95 +    if (!mapping && name) {
    2.96 +        if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
    2.97 +            /* The Linux driver xpad.c maps the wireless dpad to buttons */
    2.98 +            SDL_bool existing;
    2.99 +            mapping = SDL_PrivateAddMappingForGUID(jGUID,
   2.100 +"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   2.101 +                          &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
   2.102 +        }
   2.103 +    }
   2.104 +#endif /* __LINUX__ */
   2.105 +
   2.106 +    if (!mapping && name) {
   2.107 +        if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box")) {
   2.108 +            mapping = s_pXInputMapping;
   2.109 +        }
   2.110 +    }
   2.111 +    return mapping;
   2.112 +}
   2.113 +
   2.114  static ControllerMapping_t *SDL_PrivateGetControllerMapping(int device_index)
   2.115  {
   2.116 -    SDL_JoystickGUID jGUID = SDL_JoystickGetDeviceGUID(device_index);
   2.117 -    ControllerMapping_t *mapping;
   2.118 -
   2.119 -    (void) s_pEmscriptenMapping;  /* pacify ARMCC */
   2.120 -
   2.121 -    mapping = SDL_PrivateGetControllerMappingForGUID(&jGUID);
   2.122 +    const char *name = SDL_JoystickNameForIndex(device_index);
   2.123 +    SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(device_index);
   2.124 +    ControllerMapping_t *mapping = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid);
   2.125  #if SDL_JOYSTICK_XINPUT
   2.126      if (!mapping && SDL_SYS_IsXInputGamepad_DeviceIndex(device_index)) {
   2.127          mapping = s_pXInputMapping;
   2.128      }
   2.129  #endif
   2.130 -#if defined(SDL_JOYSTICK_EMSCRIPTEN)
   2.131 -    if (!mapping && s_pEmscriptenMapping) {
   2.132 -        mapping = s_pEmscriptenMapping;
   2.133 -    }
   2.134 -#endif
   2.135 -#ifdef __LINUX__
   2.136 -    if (!mapping) {
   2.137 -        const char *name = SDL_JoystickNameForIndex(device_index);
   2.138 -        if (name) {
   2.139 -            if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
   2.140 -                /* The Linux driver xpad.c maps the wireless dpad to buttons */
   2.141 -                SDL_bool existing;
   2.142 -                mapping = SDL_PrivateAddMappingForGUID(jGUID,
   2.143 -"none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
   2.144 -                              &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
   2.145 -            }
   2.146 -        }
   2.147 -    }
   2.148 -#endif /* __LINUX__ */
   2.149 -
   2.150 -    if (!mapping) {
   2.151 -        const char *name = SDL_JoystickNameForIndex(device_index);
   2.152 -        if (name) {
   2.153 -            if (SDL_strstr(name, "Xbox") || SDL_strstr(name, "X-Box")) {
   2.154 -                mapping = s_pXInputMapping;
   2.155 -            }
   2.156 -        }
   2.157 -    }
   2.158      return mapping;
   2.159  }
   2.160  
   2.161 @@ -1092,7 +1161,7 @@
   2.162   * Initialize the game controller system, mostly load our DB of controller config mappings
   2.163   */
   2.164  int
   2.165 -SDL_GameControllerInit(void)
   2.166 +SDL_GameControllerInitMappings(void)
   2.167  {
   2.168      int i = 0;
   2.169      const char *pMappingString = NULL;
   2.170 @@ -1107,6 +1176,19 @@
   2.171      /* load in any user supplied config */
   2.172      SDL_GameControllerLoadHints();
   2.173  
   2.174 +    SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES,
   2.175 +                        SDL_GameControllerIgnoreDevicesChanged, NULL);
   2.176 +    SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT,
   2.177 +                        SDL_GameControllerIgnoreDevicesExceptChanged, NULL);
   2.178 +
   2.179 +    return (0);
   2.180 +}
   2.181 +
   2.182 +int
   2.183 +SDL_GameControllerInit(void)
   2.184 +{
   2.185 +    int i;
   2.186 +
   2.187      /* watch for joy events and fire controller ones if needed */
   2.188      SDL_AddEventWatch(SDL_GameControllerEventWatcher, NULL);
   2.189  
   2.190 @@ -1139,6 +1221,19 @@
   2.191  
   2.192  
   2.193  /*
   2.194 + * Return 1 if the joystick with this name and GUID is a supported controller
   2.195 + */
   2.196 +SDL_bool
   2.197 +SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid)
   2.198 +{
   2.199 +    ControllerMapping_t *pSupportedController = SDL_PrivateGetControllerMappingForNameAndGUID(name, guid);
   2.200 +    if (pSupportedController) {
   2.201 +        return SDL_TRUE;
   2.202 +    }
   2.203 +    return SDL_FALSE;
   2.204 +}
   2.205 +
   2.206 +/*
   2.207   * Return 1 if the joystick at this device index is a supported controller
   2.208   */
   2.209  SDL_bool
   2.210 @@ -1152,6 +1247,41 @@
   2.211  }
   2.212  
   2.213  /*
   2.214 + * Return 1 if the game controller should be ignored by SDL
   2.215 + */
   2.216 +SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
   2.217 +{
   2.218 +    int i;
   2.219 +    Uint16 vendor;
   2.220 +    Uint16 product;
   2.221 +    Uint32 vidpid;
   2.222 +
   2.223 +    if (SDL_allowed_controllers.num_entries == 0 &&
   2.224 +        SDL_ignored_controllers.num_entries == 0) {
   2.225 +        return SDL_FALSE;
   2.226 +    }
   2.227 +
   2.228 +    SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
   2.229 +    vidpid = MAKE_VIDPID(vendor, product);
   2.230 +
   2.231 +    if (SDL_allowed_controllers.num_entries > 0) {
   2.232 +        for (i = 0; i < SDL_allowed_controllers.num_entries; ++i) {
   2.233 +            if (vidpid == SDL_allowed_controllers.entries[i]) {
   2.234 +                return SDL_FALSE;
   2.235 +            }
   2.236 +        }
   2.237 +        return SDL_TRUE;
   2.238 +    } else {
   2.239 +        for (i = 0; i < SDL_ignored_controllers.num_entries; ++i) {
   2.240 +            if (vidpid == SDL_ignored_controllers.entries[i]) {
   2.241 +                return SDL_TRUE;
   2.242 +            }
   2.243 +        }
   2.244 +        return SDL_FALSE;
   2.245 +    }
   2.246 +}
   2.247 +
   2.248 +/*
   2.249   * Open a controller for use - the index passed as an argument refers to
   2.250   * the N'th controller on the system.  This index is the value which will
   2.251   * identify this controller in future controller events.
   2.252 @@ -1536,14 +1666,18 @@
   2.253  void
   2.254  SDL_GameControllerQuit(void)
   2.255  {
   2.256 -    ControllerMapping_t *pControllerMap;
   2.257 -
   2.258      SDL_LockJoystickList();
   2.259      while (SDL_gamecontrollers) {
   2.260          SDL_gamecontrollers->ref_count = 1;
   2.261          SDL_GameControllerClose(SDL_gamecontrollers);
   2.262      }
   2.263      SDL_UnlockJoystickList();
   2.264 +}
   2.265 +
   2.266 +void
   2.267 +SDL_GameControllerQuitMappings(void)
   2.268 +{
   2.269 +    ControllerMapping_t *pControllerMap;
   2.270  
   2.271      while (s_pSupportedControllers) {
   2.272          pControllerMap = s_pSupportedControllers;
   2.273 @@ -1555,6 +1689,19 @@
   2.274  
   2.275      SDL_DelEventWatch(SDL_GameControllerEventWatcher, NULL);
   2.276  
   2.277 +    SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES,
   2.278 +                        SDL_GameControllerIgnoreDevicesChanged, NULL);
   2.279 +    SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_IGNORE_DEVICES_EXCEPT,
   2.280 +                        SDL_GameControllerIgnoreDevicesExceptChanged, NULL);
   2.281 +
   2.282 +    if (SDL_allowed_controllers.entries) {
   2.283 +        SDL_free(SDL_allowed_controllers.entries);
   2.284 +        SDL_zero(SDL_allowed_controllers);
   2.285 +    }
   2.286 +    if (SDL_ignored_controllers.entries) {
   2.287 +        SDL_free(SDL_ignored_controllers.entries);
   2.288 +        SDL_zero(SDL_ignored_controllers);
   2.289 +    }
   2.290  }
   2.291  
   2.292  /*
     3.1 --- a/src/joystick/SDL_joystick.c	Wed Aug 09 11:58:38 2017 -0700
     3.2 +++ b/src/joystick/SDL_joystick.c	Wed Aug 09 11:59:29 2017 -0700
     3.3 @@ -70,6 +70,8 @@
     3.4  {
     3.5      int status;
     3.6  
     3.7 +    SDL_GameControllerInitMappings();
     3.8 +
     3.9      /* Create the joystick list lock */
    3.10      if (!SDL_joystick_lock) {
    3.11          SDL_joystick_lock = SDL_CreateMutex();
    3.12 @@ -561,10 +563,15 @@
    3.13      SDL_QuitSubSystem(SDL_INIT_EVENTS);
    3.14  #endif
    3.15  
    3.16 +    SDL_DelHintCallback(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS,
    3.17 +                        SDL_JoystickAllowBackgroundEventsChanged, NULL);
    3.18 +
    3.19      if (SDL_joystick_lock) {
    3.20          SDL_DestroyMutex(SDL_joystick_lock);
    3.21          SDL_joystick_lock = NULL;
    3.22      }
    3.23 +
    3.24 +    SDL_GameControllerQuitMappings();
    3.25  }
    3.26  
    3.27  
    3.28 @@ -930,7 +937,7 @@
    3.29  #endif /* SDL_EVENTS_DISABLED */
    3.30  }
    3.31  
    3.32 -static void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
    3.33 +void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version)
    3.34  {
    3.35      Uint16 *guid16 = (Uint16 *)guid.data;
    3.36  
    3.37 @@ -1273,5 +1280,4 @@
    3.38      return joystick->epowerlevel;
    3.39  }
    3.40  
    3.41 -
    3.42  /* vi: set ts=4 sw=4 expandtab: */
     4.1 --- a/src/joystick/SDL_joystick_c.h	Wed Aug 09 11:58:38 2017 -0700
     4.2 +++ b/src/joystick/SDL_joystick_c.h	Wed Aug 09 11:59:29 2017 -0700
     4.3 @@ -28,6 +28,8 @@
     4.4  extern void SDL_JoystickQuit(void);
     4.5  
     4.6  /* Initialization and shutdown functions */
     4.7 +extern int SDL_GameControllerInitMappings(void);
     4.8 +extern void SDL_GameControllerQuitMappings(void);
     4.9  extern int SDL_GameControllerInit(void);
    4.10  extern void SDL_GameControllerQuit(void);
    4.11  
    4.12 @@ -35,6 +37,15 @@
    4.13  extern void SDL_LockJoystickList(void);
    4.14  extern void SDL_UnlockJoystickList(void);
    4.15  
    4.16 +/* Function to extract information from an SDL joystick GUID */
    4.17 +extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version);
    4.18 +
    4.19 +/* Function to return whether a joystick name and GUID is a game controller  */
    4.20 +extern SDL_bool SDL_IsGameControllerNameAndGUID(const char *name, SDL_JoystickGUID guid);
    4.21 +
    4.22 +/* Function to return whether a game controller should be ignored */
    4.23 +extern SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid);
    4.24 +
    4.25  /* Internal event queueing functions */
    4.26  extern void SDL_PrivateJoystickAdded(int device_index);
    4.27  extern void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance);
     5.1 --- a/src/joystick/darwin/SDL_sysjoystick.c	Wed Aug 09 11:58:38 2017 -0700
     5.2 +++ b/src/joystick/darwin/SDL_sysjoystick.c	Wed Aug 09 11:59:29 2017 -0700
     5.3 @@ -445,6 +445,12 @@
     5.4          return;   /* not a device we care about, probably. */
     5.5      }
     5.6  
     5.7 +    if (SDL_IsGameControllerNameAndGUID(device->product, device->guid) &&
     5.8 +        SDL_ShouldIgnoreGameController(device->product, device->guid)) {
     5.9 +        SDL_free(device);
    5.10 +        return;
    5.11 +    }
    5.12 +
    5.13      /* Get notified when this device is disconnected. */
    5.14      IOHIDDeviceRegisterRemovalCallback(ioHIDDeviceObject, JoystickDeviceWasRemovedCallback, device);
    5.15      IOHIDDeviceScheduleWithRunLoop(ioHIDDeviceObject, CFRunLoopGetCurrent(), SDL_JOYSTICK_RUNLOOP_MODE);
     6.1 --- a/src/joystick/linux/SDL_sysjoystick.c	Wed Aug 09 11:58:38 2017 -0700
     6.2 +++ b/src/joystick/linux/SDL_sysjoystick.c	Wed Aug 09 11:59:29 2017 -0700
     6.3 @@ -233,6 +233,10 @@
     6.4          SDL_strlcpy((char*)guid16, namebuf, sizeof(guid->data) - 4);
     6.5      }
     6.6  
     6.7 +    if (SDL_IsGameControllerNameAndGUID(namebuf, *guid) &&
     6.8 +        SDL_ShouldIgnoreGameController(namebuf, *guid)) {
     6.9 +        return 0;
    6.10 +    }
    6.11      return 1;
    6.12  }
    6.13  
     7.1 --- a/src/joystick/windows/SDL_dinputjoystick.c	Wed Aug 09 11:58:38 2017 -0700
     7.2 +++ b/src/joystick/windows/SDL_dinputjoystick.c	Wed Aug 09 11:59:29 2017 -0700
     7.3 @@ -428,6 +428,12 @@
     7.4          SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
     7.5      }
     7.6  
     7.7 +    if (SDL_IsGameControllerNameAndGUID(pNewJoystick->joystickname, pNewJoystick->guid) &&
     7.8 +        SDL_ShouldIgnoreGameController(pNewJoystick->joystickname, pNewJoystick->guid)) {
     7.9 +        SDL_free(pNewJoystick);
    7.10 +        return DIENUM_CONTINUE;
    7.11 +    }
    7.12 +
    7.13      SDL_SYS_AddJoystickDevice(pNewJoystick);
    7.14  
    7.15      return DIENUM_CONTINUE; /* get next device, please */
     8.1 --- a/src/joystick/windows/SDL_xinputjoystick.c	Wed Aug 09 11:58:38 2017 -0700
     8.2 +++ b/src/joystick/windows/SDL_xinputjoystick.c	Wed Aug 09 11:59:29 2017 -0700
     8.3 @@ -251,6 +251,12 @@
     8.4      }
     8.5      pNewJoystick->SubType = SubType;
     8.6      pNewJoystick->XInputUserId = userid;
     8.7 +
     8.8 +    if (SDL_ShouldIgnoreGameController(pNewJoystick->joystickname, pNewJoystick->guid)) {
     8.9 +        SDL_free(pNewJoystick);
    8.10 +        return;
    8.11 +    }
    8.12 +
    8.13      SDL_SYS_AddJoystickDevice(pNewJoystick);
    8.14  }
    8.15