mirror of https://github.com/encounter/SDL.git
Unified code to standardize joystick names
This commit is contained in:
parent
db3b3a1d84
commit
c44473ba73
|
@ -278,23 +278,6 @@ SDL_GetDriverAndJoystickIndex(int device_index, SDL_JoystickDriver **driver, int
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform any needed fixups for joystick names
|
|
||||||
*/
|
|
||||||
static const char *
|
|
||||||
SDL_FixupJoystickName(const char *name)
|
|
||||||
{
|
|
||||||
if (name) {
|
|
||||||
const char *skip_prefix = "NVIDIA Corporation ";
|
|
||||||
|
|
||||||
if (SDL_strncmp(name, skip_prefix, SDL_strlen(skip_prefix)) == 0) {
|
|
||||||
name += SDL_strlen(skip_prefix);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the implementation dependent name of a joystick
|
* Get the implementation dependent name of a joystick
|
||||||
*/
|
*/
|
||||||
|
@ -306,7 +289,7 @@ SDL_JoystickNameForIndex(int device_index)
|
||||||
|
|
||||||
SDL_LockJoysticks();
|
SDL_LockJoysticks();
|
||||||
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
|
if (SDL_GetDriverAndJoystickIndex(device_index, &driver, &device_index)) {
|
||||||
name = SDL_FixupJoystickName(driver->GetDeviceName(device_index));
|
name = driver->GetDeviceName(device_index);
|
||||||
}
|
}
|
||||||
SDL_UnlockJoysticks();
|
SDL_UnlockJoysticks();
|
||||||
|
|
||||||
|
@ -721,7 +704,7 @@ SDL_JoystickName(SDL_Joystick * joystick)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SDL_FixupJoystickName(joystick->name);
|
return joystick->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1369,23 +1352,112 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
static int
|
||||||
SDL_GetCustomJoystickManufacturer(const char *manufacturer)
|
PrefixMatch(const char *a, const char *b)
|
||||||
{
|
{
|
||||||
if (manufacturer) {
|
int matchlen = 0;
|
||||||
if (SDL_strcmp(manufacturer, "Performance Designed Products") == 0) {
|
while (*a && *b) {
|
||||||
return "PDP";
|
if (*a++ == *b++) {
|
||||||
} else if (SDL_strcmp(manufacturer, "HORI CO.,LTD") == 0) {
|
++matchlen;
|
||||||
return "HORI";
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return manufacturer;
|
return matchlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
char *
|
||||||
SDL_GetCustomJoystickName(Uint16 vendor, Uint16 product)
|
SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name)
|
||||||
{
|
{
|
||||||
return GuessControllerName(vendor, product);
|
static struct {
|
||||||
|
const char *prefix;
|
||||||
|
const char *replacement;
|
||||||
|
} replacements[] = {
|
||||||
|
{ "NVIDIA Corporation ", "" },
|
||||||
|
{ "Performance Designed Products", "PDP" },
|
||||||
|
{ "HORI CO.,LTD", "HORI" },
|
||||||
|
};
|
||||||
|
const char *custom_name;
|
||||||
|
char *name;
|
||||||
|
size_t i, len;
|
||||||
|
|
||||||
|
custom_name = GuessControllerName(vendor, product);
|
||||||
|
if (custom_name) {
|
||||||
|
return SDL_strdup(custom_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vendor_name) {
|
||||||
|
vendor_name = "";
|
||||||
|
}
|
||||||
|
if (!product_name) {
|
||||||
|
product_name = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*vendor_name == ' ') {
|
||||||
|
++vendor_name;
|
||||||
|
}
|
||||||
|
while (*product_name == ' ') {
|
||||||
|
++product_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*vendor_name && *product_name) {
|
||||||
|
len = (SDL_strlen(vendor_name) + 1 + SDL_strlen(product_name) + 1);
|
||||||
|
name = (char *)SDL_malloc(len);
|
||||||
|
if (!name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
SDL_snprintf(name, len, "%s %s", vendor_name, product_name);
|
||||||
|
} else if (*product_name) {
|
||||||
|
name = SDL_strdup(product_name);
|
||||||
|
} else if (vendor || product) {
|
||||||
|
len = (6 + 1 + 6 + 1);
|
||||||
|
name = (char *)SDL_malloc(len);
|
||||||
|
if (!name) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
SDL_snprintf(name, len, "0x%.4x/0x%.4x", vendor, product);
|
||||||
|
} else {
|
||||||
|
name = SDL_strdup("Controller");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Trim trailing whitespace */
|
||||||
|
for (len = SDL_strlen(name); (len > 0 && name[len - 1] == ' '); --len) {
|
||||||
|
/* continue */
|
||||||
|
}
|
||||||
|
name[len] = '\0';
|
||||||
|
|
||||||
|
/* Compress duplicate spaces */
|
||||||
|
for (i = 0; i < (len - 1); ) {
|
||||||
|
if (name[i] == ' ' && name[i+1] == ' ') {
|
||||||
|
SDL_memmove(&name[i], &name[i+1], (len - i));
|
||||||
|
--len;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove duplicate manufacturer in the name */
|
||||||
|
for (i = 0; i < (len - 1); ++i) {
|
||||||
|
int matchlen = PrefixMatch(name, &name[i]);
|
||||||
|
if (matchlen > 0 && name[matchlen - 1] == ' ') {
|
||||||
|
SDL_memmove(name, name+matchlen, len-matchlen+1);
|
||||||
|
len -= matchlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform any manufacturer replacements */
|
||||||
|
for (i = 0; i < SDL_arraysize(replacements); ++i) {
|
||||||
|
size_t prefixlen = SDL_strlen(replacements[i].prefix);
|
||||||
|
if (SDL_strncasecmp(name, replacements[i].prefix, prefixlen) == 0) {
|
||||||
|
size_t replacementlen = SDL_strlen(replacements[i].replacement);
|
||||||
|
SDL_memcpy(name, replacements[i].replacement, replacementlen);
|
||||||
|
SDL_memmove(name+replacementlen, name+prefixlen, (len-prefixlen+1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GameControllerType
|
SDL_GameControllerType
|
||||||
|
|
|
@ -52,11 +52,10 @@ extern int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id);
|
||||||
/* Function to extract information from an SDL joystick GUID */
|
/* Function to extract information from an SDL joystick GUID */
|
||||||
extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version);
|
extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version);
|
||||||
|
|
||||||
/* Function to get a custom name for a controller manufacturer, if it's available */
|
/* Function to standardize the name for a controller
|
||||||
extern const char *SDL_GetCustomJoystickManufacturer(const char *manufacturer);
|
This should be freed with SDL_free() when no longer needed
|
||||||
|
*/
|
||||||
/* Function to get a custom name for a controller, if it's available */
|
extern char *SDL_CreateJoystickName(Uint16 vendor, Uint16 product, const char *vendor_name, const char *product_name);
|
||||||
extern const char *SDL_GetCustomJoystickName(Uint16 vendor, Uint16 product);
|
|
||||||
|
|
||||||
/* Function to return the type of a controller */
|
/* Function to return the type of a controller */
|
||||||
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name);
|
extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name);
|
||||||
|
|
|
@ -410,7 +410,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
|
||||||
SDL_zerop(item);
|
SDL_zerop(item);
|
||||||
item->guid = guid;
|
item->guid = guid;
|
||||||
item->device_id = device_id;
|
item->device_id = device_id;
|
||||||
item->name = SDL_strdup(name);
|
item->name = SDL_CreateJoystickName(vendor_id, product_id, NULL, name);
|
||||||
if (item->name == NULL) {
|
if (item->name == NULL) {
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -443,7 +443,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo
|
||||||
SDL_PrivateJoystickAdded(item->device_instance);
|
SDL_PrivateJoystickAdded(item->device_instance);
|
||||||
|
|
||||||
#ifdef DEBUG_JOYSTICK
|
#ifdef DEBUG_JOYSTICK
|
||||||
SDL_Log("Added joystick %s with device_id %d", name, device_id);
|
SDL_Log("Added joystick %s with device_id %d", item->name, device_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return numjoysticks;
|
return numjoysticks;
|
||||||
|
|
|
@ -404,7 +404,7 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
|
||||||
Sint32 vendor = 0;
|
Sint32 vendor = 0;
|
||||||
Sint32 product = 0;
|
Sint32 product = 0;
|
||||||
Sint32 version = 0;
|
Sint32 version = 0;
|
||||||
const char *name;
|
char *name;
|
||||||
const char *manufacturer_remapped;
|
const char *manufacturer_remapped;
|
||||||
char manufacturer_string[256];
|
char manufacturer_string[256];
|
||||||
char product_string[256];
|
char product_string[256];
|
||||||
|
@ -460,36 +460,18 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get device name */
|
/* get device name */
|
||||||
name = SDL_GetCustomJoystickName(vendor, product);
|
refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey));
|
||||||
|
if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) {
|
||||||
|
manufacturer_string[0] = '\0';
|
||||||
|
}
|
||||||
|
refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey));
|
||||||
|
if ((!refCF) || (!CFStringGetCString(refCF, product_string, sizeof(product_string), kCFStringEncodingUTF8))) {
|
||||||
|
product_string[0] = '\0';
|
||||||
|
}
|
||||||
|
name = SDL_CreateJoystickName(vendor, product, manufacturer_string, product_string);
|
||||||
if (name) {
|
if (name) {
|
||||||
SDL_strlcpy(pDevice->product, name, sizeof(pDevice->product));
|
SDL_strlcpy(pDevice->product, name, sizeof(pDevice->product));
|
||||||
} else {
|
SDL_free(name);
|
||||||
refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDManufacturerKey));
|
|
||||||
if ((!refCF) || (!CFStringGetCString(refCF, manufacturer_string, sizeof(manufacturer_string), kCFStringEncodingUTF8))) {
|
|
||||||
manufacturer_string[0] = '\0';
|
|
||||||
}
|
|
||||||
refCF = IOHIDDeviceGetProperty(hidDevice, CFSTR(kIOHIDProductKey));
|
|
||||||
if ((!refCF) || (!CFStringGetCString(refCF, product_string, sizeof(product_string), kCFStringEncodingUTF8))) {
|
|
||||||
SDL_strlcpy(product_string, "Unidentified joystick", sizeof(product_string));
|
|
||||||
}
|
|
||||||
for (i = (int)SDL_strlen(manufacturer_string) - 1; i > 0; --i) {
|
|
||||||
if (SDL_isspace(manufacturer_string[i])) {
|
|
||||||
manufacturer_string[i] = '\0';
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
manufacturer_remapped = SDL_GetCustomJoystickManufacturer(manufacturer_string);
|
|
||||||
if (manufacturer_remapped != manufacturer_string) {
|
|
||||||
SDL_strlcpy(manufacturer_string, manufacturer_remapped, sizeof(manufacturer_string));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_strncasecmp(manufacturer_string, product_string, SDL_strlen(manufacturer_string)) == 0) {
|
|
||||||
SDL_strlcpy(pDevice->product, product_string, sizeof(pDevice->product));
|
|
||||||
} else {
|
|
||||||
SDL_snprintf(pDevice->product, sizeof(pDevice->product), "%s %s", manufacturer_string, product_string);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDL_JOYSTICK_HIDAPI
|
#ifdef SDL_JOYSTICK_HIDAPI
|
||||||
|
|
|
@ -60,7 +60,7 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa
|
||||||
SDL_zerop(item);
|
SDL_zerop(item);
|
||||||
item->index = gamepadEvent->index;
|
item->index = gamepadEvent->index;
|
||||||
|
|
||||||
item->name = SDL_strdup(gamepadEvent->id);
|
item->name = SDL_CreateJoystickName(0, 0, NULL, gamepadEvent->id);
|
||||||
if ( item->name == NULL ) {
|
if ( item->name == NULL ) {
|
||||||
SDL_free(item);
|
SDL_free(item);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -75,7 +75,7 @@ extern "C"
|
||||||
BString stick_name;
|
BString stick_name;
|
||||||
joystick.GetControllerName(&stick_name);
|
joystick.GetControllerName(&stick_name);
|
||||||
SDL_joyport[numjoysticks] = SDL_strdup(name);
|
SDL_joyport[numjoysticks] = SDL_strdup(name);
|
||||||
SDL_joyname[numjoysticks] = SDL_strdup(stick_name.String());
|
SDL_joyname[numjoysticks] = SDL_CreateJoystickName(0, 0, NULL, stick_name.String());
|
||||||
numjoysticks++;
|
numjoysticks++;
|
||||||
joystick.Close();
|
joystick.Close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,14 +698,7 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
||||||
device->dev_lock = SDL_CreateMutex();
|
device->dev_lock = SDL_CreateMutex();
|
||||||
|
|
||||||
/* Need the device name before getting the driver to know whether to ignore this device */
|
/* Need the device name before getting the driver to know whether to ignore this device */
|
||||||
if (!device->name) {
|
{
|
||||||
const char *name = SDL_GetCustomJoystickName(device->vendor_id, device->product_id);
|
|
||||||
if (name) {
|
|
||||||
device->name = SDL_strdup(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!device->name && info->manufacturer_string && info->product_string) {
|
|
||||||
const char *manufacturer_remapped;
|
|
||||||
char *manufacturer_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t));
|
char *manufacturer_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->manufacturer_string, (SDL_wcslen(info->manufacturer_string)+1)*sizeof(wchar_t));
|
||||||
char *product_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t));
|
char *product_string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)info->product_string, (SDL_wcslen(info->product_string)+1)*sizeof(wchar_t));
|
||||||
if (!manufacturer_string && !product_string) {
|
if (!manufacturer_string && !product_string) {
|
||||||
|
@ -718,39 +711,20 @@ HIDAPI_AddDevice(struct hid_device_info *info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
manufacturer_remapped = SDL_GetCustomJoystickManufacturer(manufacturer_string);
|
device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string);
|
||||||
if (manufacturer_remapped != manufacturer_string) {
|
|
||||||
SDL_free(manufacturer_string);
|
|
||||||
manufacturer_string = SDL_strdup(manufacturer_remapped);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (manufacturer_string && product_string) {
|
|
||||||
size_t name_size = (SDL_strlen(manufacturer_string) + 1 + SDL_strlen(product_string) + 1);
|
|
||||||
device->name = (char *)SDL_malloc(name_size);
|
|
||||||
if (device->name) {
|
|
||||||
if (SDL_strncasecmp(manufacturer_string, product_string, SDL_strlen(manufacturer_string)) == 0) {
|
|
||||||
SDL_strlcpy(device->name, product_string, name_size);
|
|
||||||
} else {
|
|
||||||
SDL_snprintf(device->name, name_size, "%s %s", manufacturer_string, product_string);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (manufacturer_string) {
|
if (manufacturer_string) {
|
||||||
SDL_free(manufacturer_string);
|
SDL_free(manufacturer_string);
|
||||||
}
|
}
|
||||||
if (product_string) {
|
if (product_string) {
|
||||||
SDL_free(product_string);
|
SDL_free(product_string);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!device->name) {
|
|
||||||
size_t name_size = (6 + 1 + 6 + 1);
|
|
||||||
device->name = (char *)SDL_malloc(name_size);
|
|
||||||
if (!device->name) {
|
if (!device->name) {
|
||||||
SDL_free(device->path);
|
SDL_free(device->path);
|
||||||
SDL_free(device);
|
SDL_free(device);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SDL_snprintf(device->name, name_size, "0x%.4x/0x%.4x", info->vendor_id, info->product_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add it to the list */
|
/* Add it to the list */
|
||||||
|
|
|
@ -125,7 +125,7 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
|
||||||
name = "MFi Gamepad";
|
name = "MFi Gamepad";
|
||||||
}
|
}
|
||||||
|
|
||||||
device->name = SDL_strdup(name);
|
device->name = SDL_CreateJoystickName(0, 0, NULL, name);
|
||||||
|
|
||||||
if (controller.extendedGamepad) {
|
if (controller.extendedGamepad) {
|
||||||
GCExtendedGamepad *gamepad = controller.extendedGamepad;
|
GCExtendedGamepad *gamepad = controller.extendedGamepad;
|
||||||
|
|
|
@ -88,20 +88,6 @@ static time_t last_input_dir_mtime;
|
||||||
(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
|
(((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
|
||||||
#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
|
#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
|
||||||
|
|
||||||
static int
|
|
||||||
PrefixMatch(const char *a, const char *b)
|
|
||||||
{
|
|
||||||
int matchlen = 0;
|
|
||||||
while (*a && *b) {
|
|
||||||
if (*a++ == *b++) {
|
|
||||||
++matchlen;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return matchlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
|
FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
|
||||||
{
|
{
|
||||||
|
@ -120,12 +106,12 @@ FixupDeviceInfoForMapping(int fd, struct input_id *inpid)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *guid)
|
IsJoystick(int fd, char **name_return, SDL_JoystickGUID *guid)
|
||||||
{
|
{
|
||||||
struct input_id inpid;
|
struct input_id inpid;
|
||||||
Uint16 *guid16 = (Uint16 *)guid->data;
|
Uint16 *guid16 = (Uint16 *)guid->data;
|
||||||
const char *name;
|
char *name;
|
||||||
const char *spot;
|
char product_string[128];
|
||||||
|
|
||||||
#if !SDL_USE_LIBUDEV
|
#if !SDL_USE_LIBUDEV
|
||||||
/* When udev is enabled we only get joystick devices here, so there's no need to test them */
|
/* When udev is enabled we only get joystick devices here, so there's no need to test them */
|
||||||
|
@ -149,27 +135,19 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = SDL_GetCustomJoystickName(inpid.vendor, inpid.product);
|
if (ioctl(fd, EVIOCGNAME(sizeof(product_string)), product_string) < 0) {
|
||||||
if (name) {
|
return 0;
|
||||||
SDL_strlcpy(namebuf, name, namebuflen);
|
}
|
||||||
} else {
|
|
||||||
if (ioctl(fd, EVIOCGNAME(namebuflen), namebuf) < 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove duplicate manufacturer in the name */
|
name = SDL_CreateJoystickName(inpid.vendor, inpid.product, NULL, product_string);
|
||||||
for (spot = namebuf + 1; *spot; ++spot) {
|
if (!name) {
|
||||||
int matchlen = PrefixMatch(namebuf, spot);
|
return 0;
|
||||||
if (matchlen > 0 && spot[matchlen - 1] == ' ') {
|
|
||||||
SDL_memmove(namebuf, spot, SDL_strlen(spot)+1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SDL_JOYSTICK_HIDAPI
|
#ifdef SDL_JOYSTICK_HIDAPI
|
||||||
if (HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version, namebuf)) {
|
if (HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version, name)) {
|
||||||
/* The HIDAPI driver is taking care of this device */
|
/* The HIDAPI driver is taking care of this device */
|
||||||
|
SDL_free(name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -177,7 +155,7 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui
|
||||||
FixupDeviceInfoForMapping(fd, &inpid);
|
FixupDeviceInfoForMapping(fd, &inpid);
|
||||||
|
|
||||||
#ifdef DEBUG_JOYSTICK
|
#ifdef DEBUG_JOYSTICK
|
||||||
printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", namebuf, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
|
printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", name, inpid.bustype, inpid.vendor, inpid.product, inpid.version);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SDL_memset(guid->data, 0, sizeof(guid->data));
|
SDL_memset(guid->data, 0, sizeof(guid->data));
|
||||||
|
@ -195,12 +173,14 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui
|
||||||
*guid16++ = SDL_SwapLE16(inpid.version);
|
*guid16++ = SDL_SwapLE16(inpid.version);
|
||||||
*guid16++ = 0;
|
*guid16++ = 0;
|
||||||
} else {
|
} else {
|
||||||
SDL_strlcpy((char*)guid16, namebuf, sizeof(guid->data) - 4);
|
SDL_strlcpy((char*)guid16, name, sizeof(guid->data) - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_ShouldIgnoreJoystick(namebuf, *guid)) {
|
if (SDL_ShouldIgnoreJoystick(name, *guid)) {
|
||||||
|
SDL_free(name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*name_return = name;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +216,7 @@ MaybeAddDevice(const char *path)
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int isstick = 0;
|
int isstick = 0;
|
||||||
char namebuf[128];
|
char *name = NULL;
|
||||||
SDL_JoystickGUID guid;
|
SDL_JoystickGUID guid;
|
||||||
SDL_joylist_item *item;
|
SDL_joylist_item *item;
|
||||||
|
|
||||||
|
@ -264,7 +244,7 @@ MaybeAddDevice(const char *path)
|
||||||
printf("Checking %s\n", path);
|
printf("Checking %s\n", path);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
isstick = IsJoystick(fd, namebuf, sizeof (namebuf), &guid);
|
isstick = IsJoystick(fd, &name, &guid);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (!isstick) {
|
if (!isstick) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -278,7 +258,7 @@ MaybeAddDevice(const char *path)
|
||||||
SDL_zerop(item);
|
SDL_zerop(item);
|
||||||
item->devnum = sb.st_rdev;
|
item->devnum = sb.st_rdev;
|
||||||
item->path = SDL_strdup(path);
|
item->path = SDL_strdup(path);
|
||||||
item->name = SDL_strdup(namebuf);
|
item->name = name;
|
||||||
item->guid = guid;
|
item->guid = guid;
|
||||||
|
|
||||||
if ((item->path == NULL) || (item->name == NULL)) {
|
if ((item->path == NULL) || (item->name == NULL)) {
|
||||||
|
|
|
@ -244,7 +244,7 @@ static const IID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,{ 0x89, 0x1f,
|
||||||
static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } };
|
static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } };
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
|
WIN_IsXInputDevice(LPTSTR *name, const GUID* pGuidProductFromDirectInput)
|
||||||
{
|
{
|
||||||
IWbemLocator* pIWbemLocator = NULL;
|
IWbemLocator* pIWbemLocator = NULL;
|
||||||
IEnumWbemClassObject* pEnumDevices = NULL;
|
IEnumWbemClassObject* pEnumDevices = NULL;
|
||||||
|
@ -259,6 +259,17 @@ WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
|
||||||
VARIANT var;
|
VARIANT var;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (!SDL_XINPUT_Enabled()) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_wcsstr(name, " XINPUT ") != NULL) {
|
||||||
|
/* This is a duplicate interface for a controller that will show up with XInput,
|
||||||
|
e.g. Xbox One Elite Series 2 in Bluetooth mode.
|
||||||
|
*/
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_zeroa(pDevices);
|
SDL_zeroa(pDevices);
|
||||||
|
|
||||||
// Create WMI
|
// Create WMI
|
||||||
|
@ -363,7 +374,7 @@ LCleanup:
|
||||||
#endif /* 0 */
|
#endif /* 0 */
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
|
SDL_IsXInputDevice(LPTSTR *name, const GUID* pGuidProductFromDirectInput)
|
||||||
{
|
{
|
||||||
UINT i;
|
UINT i;
|
||||||
|
|
||||||
|
@ -371,6 +382,13 @@ SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SDL_wcsstr(name, " XINPUT ") != NULL) {
|
||||||
|
/* This is a duplicate interface for a controller that will show up with XInput,
|
||||||
|
e.g. Xbox One Elite Series 2 in Bluetooth mode.
|
||||||
|
*/
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) {
|
if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) {
|
||||||
Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1);
|
Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1);
|
||||||
Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1);
|
Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1);
|
||||||
|
@ -521,7 +539,7 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||||
Uint16 product = 0;
|
Uint16 product = 0;
|
||||||
Uint16 version = 0;
|
Uint16 version = 0;
|
||||||
WCHAR hidPath[MAX_PATH];
|
WCHAR hidPath[MAX_PATH];
|
||||||
const char *name;
|
char *name;
|
||||||
|
|
||||||
if (devtype == DI8DEVTYPE_SUPPLEMENTAL) {
|
if (devtype == DI8DEVTYPE_SUPPLEMENTAL) {
|
||||||
/* Add any supplemental devices that should be ignored here */
|
/* Add any supplemental devices that should be ignored here */
|
||||||
|
@ -539,7 +557,7 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SDL_IsXInputDevice(&pdidInstance->guidProduct)) {
|
if (SDL_IsXInputDevice(pdidInstance->tszProductName, &pdidInstance->guidProduct)) {
|
||||||
return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */
|
return DIENUM_CONTINUE; /* ignore XInput devices here, keep going. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,12 +627,22 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||||
SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE));
|
SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE));
|
||||||
SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
|
SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
|
||||||
|
|
||||||
guid16 = (Uint16 *)pNewJoystick->guid.data;
|
|
||||||
if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
|
if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
|
||||||
vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1);
|
vendor = (Uint16)LOWORD(pdidInstance->guidProduct.Data1);
|
||||||
product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1);
|
product = (Uint16)HIWORD(pdidInstance->guidProduct.Data1);
|
||||||
version = 0;
|
}
|
||||||
|
|
||||||
|
name = WIN_StringToUTF8(pdidInstance->tszProductName);
|
||||||
|
pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, name);
|
||||||
|
SDL_free(name);
|
||||||
|
|
||||||
|
if (!pNewJoystick->joystickname) {
|
||||||
|
SDL_free(pNewJoystick);
|
||||||
|
return DIENUM_CONTINUE; /* better luck next time? */
|
||||||
|
}
|
||||||
|
|
||||||
|
guid16 = (Uint16 *)pNewJoystick->guid.data;
|
||||||
|
if (SDL_memcmp(&pdidInstance->guidProduct.Data4[2], "PIDVID", 6) == 0) {
|
||||||
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
|
*guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
|
||||||
*guid16++ = 0;
|
*guid16++ = 0;
|
||||||
*guid16++ = SDL_SwapLE16(vendor);
|
*guid16++ = SDL_SwapLE16(vendor);
|
||||||
|
@ -629,26 +657,6 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
|
||||||
SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
|
SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
name = SDL_GetCustomJoystickName(vendor, product);
|
|
||||||
if (name) {
|
|
||||||
pNewJoystick->joystickname = SDL_strdup(name);
|
|
||||||
} else {
|
|
||||||
pNewJoystick->joystickname = WIN_StringToUTF8(pdidInstance->tszProductName);
|
|
||||||
}
|
|
||||||
if (!pNewJoystick->joystickname) {
|
|
||||||
SDL_free(pNewJoystick);
|
|
||||||
return DIENUM_CONTINUE; /* better luck next time? */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_strstr(pNewJoystick->joystickname, " XINPUT ") != NULL) {
|
|
||||||
/* This is a duplicate interface for a controller that will show up with XInput,
|
|
||||||
e.g. Xbox One Elite Series 2 in Bluetooth mode.
|
|
||||||
*/
|
|
||||||
SDL_free(pNewJoystick->joystickname);
|
|
||||||
SDL_free(pNewJoystick);
|
|
||||||
return DIENUM_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
|
if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
|
||||||
SDL_free(pNewJoystick->joystickname);
|
SDL_free(pNewJoystick->joystickname);
|
||||||
SDL_free(pNewJoystick);
|
SDL_free(pNewJoystick);
|
||||||
|
|
|
@ -71,10 +71,10 @@ SDL_XINPUT_JoystickInit(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static const char *
|
||||||
GetXInputName(const Uint8 userid, BYTE SubType)
|
GetXInputName(const Uint8 userid, BYTE SubType)
|
||||||
{
|
{
|
||||||
char name[32];
|
static char name[32];
|
||||||
|
|
||||||
if (SDL_XInputUseOldJoystickMapping()) {
|
if (SDL_XInputUseOldJoystickMapping()) {
|
||||||
SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid);
|
SDL_snprintf(name, sizeof(name), "X360 Controller #%u", 1 + userid);
|
||||||
|
@ -111,7 +111,7 @@ GetXInputName(const Uint8 userid, BYTE SubType)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SDL_strdup(name);
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can't really tell what device is being used for XInput, but we can guess
|
/* We can't really tell what device is being used for XInput, but we can guess
|
||||||
|
@ -274,13 +274,7 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext)
|
||||||
}
|
}
|
||||||
pNewJoystick->SubType = SubType;
|
pNewJoystick->SubType = SubType;
|
||||||
pNewJoystick->XInputUserId = userid;
|
pNewJoystick->XInputUserId = userid;
|
||||||
|
pNewJoystick->joystickname = SDL_CreateJoystickName(vendor, product, NULL, GetXInputName(userid, SubType));
|
||||||
name = SDL_GetCustomJoystickName(vendor, product);
|
|
||||||
if (name) {
|
|
||||||
pNewJoystick->joystickname = SDL_strdup(name);
|
|
||||||
} else {
|
|
||||||
pNewJoystick->joystickname = GetXInputName(userid, SubType);
|
|
||||||
}
|
|
||||||
if (!pNewJoystick->joystickname) {
|
if (!pNewJoystick->joystickname) {
|
||||||
SDL_free(pNewJoystick);
|
SDL_free(pNewJoystick);
|
||||||
return; /* better luck next time? */
|
return; /* better luck next time? */
|
||||||
|
|
Loading…
Reference in New Issue