mirror of https://github.com/encounter/SDL.git
Improved XInput VID/PID detection and added SDL_wcsstr() and SDL_wcsncmp()
This commit is contained in:
parent
eb8f14bb6a
commit
650964461e
|
@ -760,7 +760,7 @@ if(LIBC)
|
||||||
set(HAVE_SIGNAL_H 1)
|
set(HAVE_SIGNAL_H 1)
|
||||||
foreach(_FN
|
foreach(_FN
|
||||||
malloc calloc realloc free qsort abs memset memcpy memmove memcmp
|
malloc calloc realloc free qsort abs memset memcpy memmove memcmp
|
||||||
wcslen wcscmp
|
wcslen wcslcpy wcslcat wcsdup wcsstr wcscmp wcsncmp
|
||||||
strlen _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa
|
strlen _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa
|
||||||
_ultoa strtol strtoul strtoll strtod atoi atof strcmp strncmp
|
_ultoa strtol strtoul strtoll strtod atoi atof strcmp strncmp
|
||||||
_stricmp _strnicmp strtok_s sscanf
|
_stricmp _strnicmp strtok_s sscanf
|
||||||
|
|
|
@ -335,7 +335,7 @@ if test x$enable_libc = xyes; then
|
||||||
AC_DEFINE(HAVE_MPROTECT, 1, [ ])
|
AC_DEFINE(HAVE_MPROTECT, 1, [ ])
|
||||||
]),
|
]),
|
||||||
)
|
)
|
||||||
AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll _Exit)
|
AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat wcsdup wcsstr wcscmp wcsncmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll _Exit)
|
||||||
|
|
||||||
AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"])
|
AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"])
|
||||||
AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf)
|
AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf)
|
||||||
|
|
|
@ -96,7 +96,10 @@
|
||||||
#cmakedefine HAVE_WCSLEN 1
|
#cmakedefine HAVE_WCSLEN 1
|
||||||
#cmakedefine HAVE_WCSLCPY 1
|
#cmakedefine HAVE_WCSLCPY 1
|
||||||
#cmakedefine HAVE_WCSLCAT 1
|
#cmakedefine HAVE_WCSLCAT 1
|
||||||
|
#cmakedefine HAVE_WCSDUP 1
|
||||||
|
#cmakedefine HAVE_WCSSTR 1
|
||||||
#cmakedefine HAVE_WCSCMP 1
|
#cmakedefine HAVE_WCSCMP 1
|
||||||
|
#cmakedefine HAVE_WCSNCMP 1
|
||||||
#cmakedefine HAVE_STRLEN 1
|
#cmakedefine HAVE_STRLEN 1
|
||||||
#cmakedefine HAVE_STRLCPY 1
|
#cmakedefine HAVE_STRLCPY 1
|
||||||
#cmakedefine HAVE_STRLCAT 1
|
#cmakedefine HAVE_STRLCAT 1
|
||||||
|
|
|
@ -99,7 +99,10 @@
|
||||||
#undef HAVE_WCSLEN
|
#undef HAVE_WCSLEN
|
||||||
#undef HAVE_WCSLCPY
|
#undef HAVE_WCSLCPY
|
||||||
#undef HAVE_WCSLCAT
|
#undef HAVE_WCSLCAT
|
||||||
|
#undef HAVE_WCSDUP
|
||||||
|
#undef HAVE_WCSSTR
|
||||||
#undef HAVE_WCSCMP
|
#undef HAVE_WCSCMP
|
||||||
|
#undef HAVE_WCSNCMP
|
||||||
#undef HAVE_STRLEN
|
#undef HAVE_STRLEN
|
||||||
#undef HAVE_STRLCPY
|
#undef HAVE_STRLCPY
|
||||||
#undef HAVE_STRLCAT
|
#undef HAVE_STRLCAT
|
||||||
|
|
|
@ -453,11 +453,14 @@ extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_
|
||||||
extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
|
extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
|
||||||
extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
|
extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
|
||||||
|
|
||||||
extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr);
|
|
||||||
extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
|
extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
|
||||||
extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
|
extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
|
||||||
extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
|
extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
|
||||||
|
extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr);
|
||||||
|
extern DECLSPEC wchar_t *SDLCALL SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle);
|
||||||
|
|
||||||
extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2);
|
extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2);
|
||||||
|
extern DECLSPEC int SDLCALL SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen);
|
||||||
|
|
||||||
extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str);
|
extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str);
|
||||||
extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen);
|
extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen);
|
||||||
|
|
|
@ -235,45 +235,150 @@ SetDIerror(const char *function, HRESULT code)
|
||||||
return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code);
|
return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* Microsoft recommended implementation, but slower than checking raw devices */
|
||||||
|
#define COBJMACROS
|
||||||
|
#include <wbemidl.h>
|
||||||
|
#include <oleauto.h>
|
||||||
|
|
||||||
|
static const IID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,{ 0x89, 0x1f, 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
|
||||||
|
WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
|
||||||
|
{
|
||||||
|
IWbemLocator* pIWbemLocator = NULL;
|
||||||
|
IEnumWbemClassObject* pEnumDevices = NULL;
|
||||||
|
IWbemClassObject* pDevices[20];
|
||||||
|
IWbemServices* pIWbemServices = NULL;
|
||||||
|
BSTR bstrNamespace = NULL;
|
||||||
|
BSTR bstrDeviceID = NULL;
|
||||||
|
BSTR bstrClassName = NULL;
|
||||||
|
DWORD uReturned = 0;
|
||||||
|
SDL_bool bIsXinputDevice = SDL_FALSE;
|
||||||
|
UINT iDevice = 0;
|
||||||
|
VARIANT var;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
SDL_zero(pDevices);
|
||||||
|
|
||||||
|
// Create WMI
|
||||||
|
hr = CoCreateInstance(&CLSID_WbemLocator,
|
||||||
|
NULL,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
&IID_IWbemLocator,
|
||||||
|
(LPVOID*)&pIWbemLocator);
|
||||||
|
if (FAILED(hr) || pIWbemLocator == NULL)
|
||||||
|
goto LCleanup;
|
||||||
|
|
||||||
|
bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup;
|
||||||
|
bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == NULL) goto LCleanup;
|
||||||
|
bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == NULL) goto LCleanup;
|
||||||
|
|
||||||
|
// Connect to WMI
|
||||||
|
hr = IWbemLocator_ConnectServer(pIWbemLocator, bstrNamespace, NULL, NULL, 0L,
|
||||||
|
0L, NULL, NULL, &pIWbemServices);
|
||||||
|
if (FAILED(hr) || pIWbemServices == NULL) {
|
||||||
|
goto LCleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch security level to IMPERSONATE.
|
||||||
|
CoSetProxyBlanket((IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
|
||||||
|
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
|
||||||
|
|
||||||
|
hr = IWbemServices_CreateInstanceEnum(pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices);
|
||||||
|
if (FAILED(hr) || pEnumDevices == NULL)
|
||||||
|
goto LCleanup;
|
||||||
|
|
||||||
|
// Loop over all devices
|
||||||
|
for (;;) {
|
||||||
|
// Get 20 at a time
|
||||||
|
hr = IEnumWbemClassObject_Next(pEnumDevices, 10000, SDL_arraysize(pDevices), pDevices, &uReturned);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
goto LCleanup;
|
||||||
|
}
|
||||||
|
if (uReturned == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (iDevice = 0; iDevice < uReturned; iDevice++) {
|
||||||
|
// For each device, get its device ID
|
||||||
|
hr = IWbemClassObject_Get(pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL);
|
||||||
|
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) {
|
||||||
|
// Check if the device ID contains "IG_". If it does, then it's an XInput device
|
||||||
|
// This information can not be found from DirectInput
|
||||||
|
if (SDL_wcsstr(var.bstrVal, L"IG_")) {
|
||||||
|
char *bstrVal = WIN_StringToUTF8(var.bstrVal);
|
||||||
|
|
||||||
|
// If it does, then get the VID/PID from var.bstrVal
|
||||||
|
DWORD dwPid = 0, dwVid = 0, dwVidPid;
|
||||||
|
const char *strVid, *strPid;
|
||||||
|
strVid = SDL_strstr(bstrVal, "VID_");
|
||||||
|
if (strVid && SDL_sscanf(strVid, "VID_%4X", &dwVid) != 1)
|
||||||
|
dwVid = 0;
|
||||||
|
strPid = SDL_strstr(bstrVal, "PID_");
|
||||||
|
if (strPid && SDL_sscanf(strPid, "PID_%4X", &dwPid) != 1)
|
||||||
|
dwPid = 0;
|
||||||
|
|
||||||
|
SDL_free(bstrVal);
|
||||||
|
|
||||||
|
// Compare the VID/PID to the DInput device
|
||||||
|
dwVidPid = MAKELONG(dwVid, dwPid);
|
||||||
|
if (dwVidPid == pGuidProductFromDirectInput->Data1) {
|
||||||
|
bIsXinputDevice = SDL_TRUE;
|
||||||
|
goto LCleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IWbemClassObject_Release(pDevices[iDevice]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LCleanup:
|
||||||
|
if (bstrNamespace) {
|
||||||
|
SysFreeString(bstrNamespace);
|
||||||
|
}
|
||||||
|
if (bstrDeviceID) {
|
||||||
|
SysFreeString(bstrDeviceID);
|
||||||
|
}
|
||||||
|
if (bstrClassName) {
|
||||||
|
SysFreeString(bstrClassName);
|
||||||
|
}
|
||||||
|
for (iDevice = 0; iDevice < SDL_arraysize(pDevices); iDevice++) {
|
||||||
|
if (pDevices[iDevice]) {
|
||||||
|
IWbemClassObject_Release(pDevices[iDevice]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pEnumDevices) {
|
||||||
|
IEnumWbemClassObject_Release(pEnumDevices);
|
||||||
|
}
|
||||||
|
if (pIWbemLocator) {
|
||||||
|
IWbemLocator_Release(pIWbemLocator);
|
||||||
|
}
|
||||||
|
if (pIWbemServices) {
|
||||||
|
IWbemServices_Release(pIWbemServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bIsXinputDevice;
|
||||||
|
}
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
|
SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
|
||||||
{
|
{
|
||||||
static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
UINT i;
|
||||||
static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
|
|
||||||
|
|
||||||
static const GUID *s_XInputProductGUID[] = {
|
if (!SDL_XINPUT_Enabled()) {
|
||||||
&IID_ValveStreamingGamepad,
|
return SDL_FALSE;
|
||||||
&IID_X360WiredGamepad, /* Microsoft's wired X360 controller for Windows. */
|
}
|
||||||
&IID_X360WirelessGamepad, /* Microsoft's wireless X360 controller for Windows. */
|
|
||||||
&IID_XOneWiredGamepad, /* Microsoft's wired Xbox One controller for Windows. */
|
|
||||||
&IID_XOneWirelessGamepad, /* Microsoft's wireless Xbox One controller for Windows. */
|
|
||||||
&IID_XOneNewWirelessGamepad, /* Microsoft's updated wireless Xbox One controller (w/ 3.5 mm jack) for Windows. */
|
|
||||||
&IID_XOneSWirelessGamepad, /* Microsoft's wireless Xbox One S controller for Windows. */
|
|
||||||
&IID_XOneSBluetoothGamepad, /* Microsoft's Bluetooth Xbox One S controller for Windows. */
|
|
||||||
&IID_XOneEliteWirelessGamepad /* Microsoft's wireless Xbox One Elite controller for Windows. */
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t iDevice;
|
if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) {
|
||||||
UINT i;
|
Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1);
|
||||||
|
Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1);
|
||||||
if (!SDL_XINPUT_Enabled()) {
|
if (SDL_IsJoystickXbox360(vendor_id, product_id) || SDL_IsJoystickXboxOne(vendor_id, product_id) ||
|
||||||
return SDL_FALSE;
|
(vendor_id == 0x28DE && product_id == 0x11FF)) {
|
||||||
}
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
/* Check for well known XInput device GUIDs */
|
}
|
||||||
/* This lets us skip RAWINPUT for popular devices. Also, we need to do this for the Valve Streaming Gamepad because it's virtualized and doesn't show up in the device list. */
|
|
||||||
for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) {
|
|
||||||
if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
|
|
||||||
return SDL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
/* Go through RAWINPUT (WinXP and later) to find HID devices. */
|
||||||
/* Cache this if we end up using it. */
|
/* Cache this if we end up using it. */
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include "SDL_assert.h"
|
#include "SDL_assert.h"
|
||||||
#include "SDL_hints.h"
|
#include "SDL_hints.h"
|
||||||
|
#include "SDL_log.h"
|
||||||
#include "SDL_timer.h"
|
#include "SDL_timer.h"
|
||||||
#include "SDL_windowsjoystick_c.h"
|
#include "SDL_windowsjoystick_c.h"
|
||||||
#include "SDL_xinputjoystick_c.h"
|
#include "SDL_xinputjoystick_c.h"
|
||||||
|
@ -138,6 +139,28 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
|
||||||
return; /* oh well. */
|
return; /* oh well. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* First see if we have a cached entry for this index */
|
||||||
|
if (s_arrXInputDevicePath[userid]) {
|
||||||
|
for (i = 0; i < device_count; i++) {
|
||||||
|
RID_DEVICE_INFO rdi;
|
||||||
|
char devName[128];
|
||||||
|
UINT rdiSize = sizeof(rdi);
|
||||||
|
UINT nameSize = SDL_arraysize(devName);
|
||||||
|
|
||||||
|
rdi.cbSize = sizeof(rdi);
|
||||||
|
if (devices[i].dwType == RIM_TYPEHID &&
|
||||||
|
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
|
||||||
|
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
|
||||||
|
if (SDL_strcmp(devName, s_arrXInputDevicePath[userid]) == 0) {
|
||||||
|
*pVID = (Uint16)rdi.hid.dwVendorId;
|
||||||
|
*pPID = (Uint16)rdi.hid.dwProductId;
|
||||||
|
*pVersion = (Uint16)rdi.hid.dwVersionNumber;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < device_count; i++) {
|
for (i = 0; i < device_count; i++) {
|
||||||
RID_DEVICE_INFO rdi;
|
RID_DEVICE_INFO rdi;
|
||||||
char devName[128];
|
char devName[128];
|
||||||
|
@ -145,44 +168,50 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
|
||||||
UINT nameSize = SDL_arraysize(devName);
|
UINT nameSize = SDL_arraysize(devName);
|
||||||
|
|
||||||
rdi.cbSize = sizeof(rdi);
|
rdi.cbSize = sizeof(rdi);
|
||||||
if ((devices[i].dwType == RIM_TYPEHID) &&
|
if (devices[i].dwType == RIM_TYPEHID &&
|
||||||
(GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
|
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
|
||||||
(GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
|
GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
|
||||||
(SDL_strstr(devName, "IG_") != NULL)) {
|
#ifdef DEBUG_JOYSTICK
|
||||||
SDL_bool found = SDL_FALSE;
|
SDL_Log("Raw input device: VID = 0x%x, PID = 0x%x, %s\n", rdi.hid.dwVendorId, rdi.hid.dwProductId, devName);
|
||||||
for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) {
|
#endif
|
||||||
if (j == userid) {
|
if (SDL_strstr(devName, "IG_") != NULL) {
|
||||||
|
SDL_bool found = SDL_FALSE;
|
||||||
|
for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) {
|
||||||
|
if (!s_arrXInputDevicePath[j]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
|
||||||
|
found = SDL_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
/* We already have this device in our XInput device list */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!s_arrXInputDevicePath[j]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
|
|
||||||
found = SDL_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) {
|
|
||||||
/* We already have this device in our XInput device list */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We don't actually know if this is the right device for this
|
/* We don't actually know if this is the right device for this
|
||||||
* userid, but we'll record it so we'll at least be consistent
|
* userid, but we'll record it so we'll at least be consistent
|
||||||
* when the raw device list changes.
|
* when the raw device list changes.
|
||||||
*/
|
*/
|
||||||
*pVID = (Uint16)rdi.hid.dwVendorId;
|
*pVID = (Uint16)rdi.hid.dwVendorId;
|
||||||
*pPID = (Uint16)rdi.hid.dwProductId;
|
*pPID = (Uint16)rdi.hid.dwProductId;
|
||||||
*pVersion = (Uint16)rdi.hid.dwVersionNumber;
|
*pVersion = (Uint16)rdi.hid.dwVersionNumber;
|
||||||
if (s_arrXInputDevicePath[userid]) {
|
if (s_arrXInputDevicePath[userid]) {
|
||||||
SDL_free(s_arrXInputDevicePath[userid]);
|
SDL_free(s_arrXInputDevicePath[userid]);
|
||||||
|
}
|
||||||
|
s_arrXInputDevicePath[userid] = SDL_strdup(devName);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
s_arrXInputDevicePath[userid] = SDL_strdup(devName);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_free(devices);
|
SDL_free(devices);
|
||||||
#endif /* ifndef __WINRT__ */
|
#endif /* ifndef __WINRT__ */
|
||||||
|
|
||||||
|
/* The device wasn't in the raw HID device list, it's probably Bluetooth */
|
||||||
|
*pVID = 0x045e; /* Microsoft */
|
||||||
|
*pPID = 0x02fd; /* XBox One S Bluetooth */
|
||||||
|
*pVersion = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -421,17 +421,6 @@ SDL_strlen(const char *string)
|
||||||
#endif /* HAVE_STRLEN */
|
#endif /* HAVE_STRLEN */
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t *
|
|
||||||
SDL_wcsdup(const wchar_t *string)
|
|
||||||
{
|
|
||||||
size_t len = ((SDL_wcslen(string) + 1) * sizeof(wchar_t));
|
|
||||||
wchar_t *newstr = (wchar_t *)SDL_malloc(len);
|
|
||||||
if (newstr) {
|
|
||||||
SDL_memcpy(newstr, string, len);
|
|
||||||
}
|
|
||||||
return newstr;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
SDL_wcslen(const wchar_t * string)
|
SDL_wcslen(const wchar_t * string)
|
||||||
{
|
{
|
||||||
|
@ -477,6 +466,34 @@ SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t max
|
||||||
#endif /* HAVE_WCSLCAT */
|
#endif /* HAVE_WCSLCAT */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wchar_t *
|
||||||
|
SDL_wcsdup(const wchar_t *string)
|
||||||
|
{
|
||||||
|
size_t len = ((SDL_wcslen(string) + 1) * sizeof(wchar_t));
|
||||||
|
wchar_t *newstr = (wchar_t *)SDL_malloc(len);
|
||||||
|
if (newstr) {
|
||||||
|
SDL_memcpy(newstr, string, len);
|
||||||
|
}
|
||||||
|
return newstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar_t *
|
||||||
|
SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_WCSSTR)
|
||||||
|
return SDL_const_cast(wchar_t*,wcsstr(haystack, needle));
|
||||||
|
#else
|
||||||
|
size_t length = SDL_wcslen(needle);
|
||||||
|
while (*haystack) {
|
||||||
|
if (SDL_wcsncmp(haystack, needle, length) == 0) {
|
||||||
|
return (wchar_t *)haystack;
|
||||||
|
}
|
||||||
|
++haystack;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
#endif /* HAVE_WCSSTR */
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
SDL_wcscmp(const wchar_t *str1, const wchar_t *str2)
|
SDL_wcscmp(const wchar_t *str1, const wchar_t *str2)
|
||||||
{
|
{
|
||||||
|
@ -493,6 +510,22 @@ SDL_wcscmp(const wchar_t *str1, const wchar_t *str2)
|
||||||
#endif /* HAVE_WCSCMP */
|
#endif /* HAVE_WCSCMP */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen)
|
||||||
|
{
|
||||||
|
#if defined(HAVE_WCSNCMP)
|
||||||
|
return wcsncmp(str1, str2, maxlen);
|
||||||
|
#else
|
||||||
|
while (*str1 && *str2) {
|
||||||
|
if (*str1 != *str2)
|
||||||
|
break;
|
||||||
|
++str1;
|
||||||
|
++str2;
|
||||||
|
}
|
||||||
|
return (int)(*str1 - *str2);
|
||||||
|
#endif /* HAVE_WCSNCMP */
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen)
|
SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue