Bladeren bron

Generalized the raw input controller driver and moved XInput/WGI detection into it for XInput devices

This fixes bad report parsing for various newer Xbox controllers, and this driver is now preferred over XInput, since it handles more than 4 controllers.
Sam Lantinga 4 jaren geleden
bovenliggende
commit
5b3616c325

+ 3 - 1
VisualC/SDL/SDL.vcxproj

@@ -299,6 +299,7 @@
     <ClInclude Include="..\..\src\audio\wasapi\SDL_wasapi.h" />
     <ClInclude Include="..\..\src\audio\winmm\SDL_winmm.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_directx.h" />
+    <ClInclude Include="..\..\src\core\windows\SDL_hid.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_windows.h" />
     <ClInclude Include="..\..\src\core\windows\SDL_xinput.h" />
     <ClInclude Include="..\..\src\dynapi\SDL_dynapi.h" />
@@ -405,6 +406,7 @@
     <ClCompile Include="..\..\src\audio\winmm\SDL_winmm.c" />
     <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
     <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c" />
+    <ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
     <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
     <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
     <ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c" />
@@ -426,7 +428,7 @@
     <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
     <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
     <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
-    <ClCompile Include="..\..\src\hidapi\windows\hid.c" />
+    <ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
     <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
     <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapijoystick.c" />
     <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_gamecube.c" />

+ 17 - 10
VisualC/SDL/SDL.vcxproj.filters

@@ -231,6 +231,7 @@
     <ClInclude Include="..\..\include\SDL_vulkan.h">
       <Filter>API Headers</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\SDL_misc.h" />
     <ClInclude Include="..\..\src\audio\directsound\SDL_directsound.h" />
     <ClInclude Include="..\..\src\audio\disk\SDL_diskaudio.h" />
     <ClInclude Include="..\..\src\audio\dummy\SDL_dummyaudio.h" />
@@ -262,12 +263,15 @@
     <ClInclude Include="..\..\src\haptic\windows\SDL_dinputhaptic_c.h" />
     <ClInclude Include="..\..\src\haptic\windows\SDL_windowshaptic_c.h" />
     <ClInclude Include="..\..\src\haptic\windows\SDL_xinputhaptic_c.h" />
+    <ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
     <ClInclude Include="..\..\src\joystick\controller_type.h" />
     <ClInclude Include="..\..\src\joystick\hidapi\SDL_hidapijoystick_c.h" />
+    <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
     <ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
     <ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
     <ClInclude Include="..\..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_dinputjoystick_c.h" />
+    <ClInclude Include="..\..\src\joystick\windows\SDL_rawinputjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_windowsjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_xinputjoystick_c.h" />
     <ClInclude Include="..\..\src\libm\math_libm.h" />
@@ -294,6 +298,7 @@
     <ClInclude Include="..\..\src\sensor\dummy\SDL_dummysensor.h" />
     <ClInclude Include="..\..\src\sensor\SDL_sensor_c.h" />
     <ClInclude Include="..\..\src\sensor\SDL_syssensor.h" />
+    <ClInclude Include="..\..\src\sensor\windows\SDL_windowssensor.h" />
     <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
     <ClInclude Include="..\..\src\thread\SDL_thread_c.h" />
     <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h" />
@@ -327,10 +332,7 @@
     <ClInclude Include="..\..\src\video\windows\SDL_windowswindow.h" />
     <ClInclude Include="..\..\src\video\windows\wmmsg.h" />
     <ClInclude Include="..\..\src\video\yuv2rgb\yuv_rgb.h" />
-    <ClInclude Include="..\..\src\joystick\windows\SDL_rawinputjoystick_c.h" />
-    <ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
-    <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
-    <ClInclude Include="..\..\src\sensor\windows\SDL_windowssensor.h" />
+    <ClInclude Include="..\..\src\core\windows\SDL_hid.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c" />
@@ -348,6 +350,7 @@
     <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
     <ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c" />
     <ClCompile Include="..\..\src\audio\winmm\SDL_winmm.c" />
+    <ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
     <ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
     <ClCompile Include="..\..\src\core\windows\SDL_xinput.c" />
     <ClCompile Include="..\..\src\cpuinfo\SDL_cpuinfo.c" />
@@ -364,13 +367,16 @@
     <ClCompile Include="..\..\src\events\SDL_windowevents.c" />
     <ClCompile Include="..\..\src\file\SDL_rwops.c" />
     <ClCompile Include="..\..\src\filesystem\windows\SDL_sysfilesystem.c" />
+    <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
     <ClCompile Include="..\..\src\haptic\SDL_haptic.c" />
     <ClCompile Include="..\..\src\haptic\windows\SDL_dinputhaptic.c" />
     <ClCompile Include="..\..\src\haptic\windows\SDL_windowshaptic.c" />
     <ClCompile Include="..\..\src\haptic\windows\SDL_xinputhaptic.c" />
-    <ClCompile Include="..\..\src\hidapi\windows\hid.c" />
+    <ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
+    <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
     <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_gamecube.c" />
     <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_ps4.c" />
+    <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_ps5.c" />
     <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_rumble.c" />
     <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_switch.c" />
     <ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xbox360.c" />
@@ -382,6 +388,8 @@
     <ClCompile Include="..\..\src\joystick\virtual\SDL_virtualjoystick.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_mmjoystick.c" />
+    <ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
+    <ClCompile Include="..\..\src\joystick\windows\SDL_windows_gaming_input.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_windowsjoystick.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_xinputjoystick.c" />
     <ClCompile Include="..\..\src\libm\e_atan2.c" />
@@ -407,6 +415,8 @@
     <ClCompile Include="..\..\src\loadso\windows\SDL_sysloadso.c" />
     <ClCompile Include="..\..\src\locale\SDL_locale.c" />
     <ClCompile Include="..\..\src\locale\windows\SDL_syslocale.c" />
+    <ClCompile Include="..\..\src\misc\SDL_url.c" />
+    <ClCompile Include="..\..\src\misc\windows\SDL_sysurl.c" />
     <ClCompile Include="..\..\src\power\SDL_power.c" />
     <ClCompile Include="..\..\src\power\windows\SDL_syspower.c" />
     <ClCompile Include="..\..\src\render\direct3d\SDL_render_d3d.c" />
@@ -435,6 +445,8 @@
     <ClCompile Include="..\..\src\SDL_log.c" />
     <ClCompile Include="..\..\src\sensor\dummy\SDL_dummysensor.c" />
     <ClCompile Include="..\..\src\sensor\SDL_sensor.c" />
+    <ClCompile Include="..\..\src\sensor\windows\SDL_windowssensor.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_crc32.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_iconv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_malloc.c" />
@@ -488,11 +500,6 @@
     <ClCompile Include="..\..\src\video\windows\SDL_windowsvulkan.c" />
     <ClCompile Include="..\..\src\video\windows\SDL_windowswindow.c" />
     <ClCompile Include="..\..\src\video\yuv2rgb\yuv_rgb.c" />
-    <ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
-    <ClCompile Include="..\..\src\sensor\windows\SDL_windowssensor.c" />
-    <ClCompile Include="..\..\src\haptic\dummy\SDL_syshaptic.c" />
-    <ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
-    <ClCompile Include="..\..\src\joystick\windows\SDL_windows_gaming_input.c" />
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\main\windows\version.rc" />

+ 95 - 0
src/core/windows/SDL_hid.c

@@ -0,0 +1,95 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef __WINRT__
+
+#include "SDL_assert.h"
+#include "SDL_hid.h"
+
+
+HidD_GetString_t SDL_HidD_GetManufacturerString;
+HidD_GetString_t SDL_HidD_GetProductString;
+HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData;
+HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData;
+HidP_GetCaps_t SDL_HidP_GetCaps;
+HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps;
+HidP_GetValueCaps_t SDL_HidP_GetValueCaps;
+HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength;
+HidP_GetData_t SDL_HidP_GetData;
+
+static HMODULE s_pHIDDLL = 0;
+static int s_HIDDLLRefCount = 0;
+
+
+int
+WIN_LoadHIDDLL(void)
+{
+    if (s_pHIDDLL) {
+        SDL_assert(s_HIDDLLRefCount > 0);
+        s_HIDDLLRefCount++;
+        return 0;  /* already loaded */
+    }
+
+    s_pHIDDLL = LoadLibrary(L"hid.dll");
+    if (!s_pHIDDLL) {
+        return -1;
+    }
+
+    SDL_assert(s_HIDDLLRefCount == 0);
+    s_HIDDLLRefCount = 1;
+
+    SDL_HidD_GetManufacturerString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetManufacturerString");
+    SDL_HidD_GetProductString = (HidD_GetString_t)GetProcAddress(s_pHIDDLL, "HidD_GetProductString");
+    SDL_HidD_GetPreparsedData = (HidD_GetPreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_GetPreparsedData");
+    SDL_HidD_FreePreparsedData = (HidD_FreePreparsedData_t)GetProcAddress(s_pHIDDLL, "HidD_FreePreparsedData");
+    SDL_HidP_GetCaps = (HidP_GetCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetCaps");
+    SDL_HidP_GetButtonCaps = (HidP_GetButtonCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetButtonCaps");
+    SDL_HidP_GetValueCaps = (HidP_GetValueCaps_t)GetProcAddress(s_pHIDDLL, "HidP_GetValueCaps");
+    SDL_HidP_MaxDataListLength = (HidP_MaxDataListLength_t)GetProcAddress(s_pHIDDLL, "HidP_MaxDataListLength");
+    SDL_HidP_GetData = (HidP_GetData_t)GetProcAddress(s_pHIDDLL, "HidP_GetData");
+    if (!SDL_HidD_GetManufacturerString || !SDL_HidD_GetProductString || !SDL_HidD_GetPreparsedData ||
+        !SDL_HidD_FreePreparsedData || !SDL_HidP_GetCaps || !SDL_HidP_GetButtonCaps ||
+        !SDL_HidP_GetValueCaps || !SDL_HidP_MaxDataListLength || !SDL_HidP_GetData) {
+        WIN_UnloadHIDDLL();
+        return -1;
+    }
+
+    return 0;
+}
+
+void
+WIN_UnloadHIDDLL(void)
+{
+    if (s_pHIDDLL) {
+        SDL_assert(s_HIDDLLRefCount > 0);
+        if (--s_HIDDLLRefCount == 0) {
+            FreeLibrary(s_pHIDDLL);
+            s_pHIDDLL = NULL;
+        }
+    } else {
+        SDL_assert(s_HIDDLLRefCount == 0);
+    }
+}
+
+#endif /* !__WINRT__ */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 208 - 0
src/core/windows/SDL_hid.h

@@ -0,0 +1,208 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_hid_h_
+#define SDL_hid_h_
+
+#include "SDL_windows.h"
+
+#ifndef __WINRT__
+
+typedef LONG NTSTATUS;
+typedef USHORT USAGE;
+typedef struct _HIDP_PREPARSED_DATA *PHIDP_PREPARSED_DATA;
+
+typedef struct _HIDD_ATTRIBUTES
+{
+    ULONG Size;
+    USHORT VendorID;
+    USHORT ProductID;
+    USHORT VersionNumber;
+} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES;
+
+typedef enum {
+    HidP_Input = 0,
+    HidP_Output = 1,
+    HidP_Feature = 2
+} HIDP_REPORT_TYPE;
+
+typedef struct {
+    USAGE   UsagePage;
+    UCHAR   ReportID;
+    BOOLEAN IsAlias;
+    USHORT  BitField;
+    USHORT  LinkCollection;
+    USAGE   LinkUsage;
+    USAGE   LinkUsagePage;
+    BOOLEAN IsRange;
+    BOOLEAN IsStringRange;
+    BOOLEAN IsDesignatorRange;
+    BOOLEAN IsAbsolute;
+    ULONG   Reserved[ 10 ];
+    union {
+        struct {
+            USAGE   UsageMin;
+            USAGE   UsageMax;
+            USHORT  StringMin;
+            USHORT  StringMax;
+            USHORT  DesignatorMin;
+            USHORT  DesignatorMax;
+            USHORT  DataIndexMin;
+            USHORT  DataIndexMax;
+        } Range;
+        struct {
+            USAGE   Usage;
+            USAGE   Reserved1;
+            USHORT  StringIndex;
+            USHORT  Reserved2;
+            USHORT  DesignatorIndex;
+            USHORT  Reserved3;
+            USHORT  DataIndex;
+            USHORT  Reserved4;
+        } NotRange;
+    };
+} HIDP_BUTTON_CAPS, *PHIDP_BUTTON_CAPS;
+
+typedef struct {
+    USAGE   UsagePage;
+    UCHAR   ReportID;
+    BOOLEAN IsAlias;
+    USHORT  BitField;
+    USHORT  LinkCollection;
+    USAGE   LinkUsage;
+    USAGE   LinkUsagePage;
+    BOOLEAN IsRange;
+    BOOLEAN IsStringRange;
+    BOOLEAN IsDesignatorRange;
+    BOOLEAN IsAbsolute;
+    BOOLEAN HasNull;
+    UCHAR   Reserved;
+    USHORT  BitSize;
+    USHORT  ReportCount;
+    USHORT  Reserved2[ 5 ];
+    ULONG   UnitsExp;
+    ULONG   Units;
+    LONG    LogicalMin;
+    LONG    LogicalMax;
+    LONG    PhysicalMin;
+    LONG    PhysicalMax;
+    union {
+        struct {
+            USAGE   UsageMin;
+            USAGE   UsageMax;
+            USHORT  StringMin;
+            USHORT  StringMax;
+            USHORT  DesignatorMin;
+            USHORT  DesignatorMax;
+            USHORT  DataIndexMin;
+            USHORT  DataIndexMax;
+        } Range;
+        struct {
+            USAGE   Usage;
+            USAGE   Reserved1;
+            USHORT  StringIndex;
+            USHORT  Reserved2;
+            USHORT  DesignatorIndex;
+            USHORT  Reserved3;
+            USHORT  DataIndex;
+            USHORT  Reserved4;
+        } NotRange;
+    };
+} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
+
+typedef struct {
+    USAGE   Usage;
+    USAGE   UsagePage;
+    USHORT  InputReportByteLength;
+    USHORT  OutputReportByteLength;
+    USHORT  FeatureReportByteLength;
+    USHORT  Reserved[ 17 ];
+    USHORT  NumberLinkCollectionNodes;
+    USHORT  NumberInputButtonCaps;
+    USHORT  NumberInputValueCaps;
+    USHORT  NumberInputDataIndices;
+    USHORT  NumberOutputButtonCaps;
+    USHORT  NumberOutputValueCaps;
+    USHORT  NumberOutputDataIndices;
+    USHORT  NumberFeatureButtonCaps;
+    USHORT  NumberFeatureValueCaps;
+    USHORT  NumberFeatureDataIndices;
+} HIDP_CAPS, *PHIDP_CAPS;
+
+typedef struct {
+    USHORT  DataIndex;
+    USHORT  Reserved;
+    union {
+        ULONG   RawValue;
+        BOOLEAN On;
+    };
+} HIDP_DATA, *PHIDP_DATA;
+
+#define HIDP_ERROR_CODES( p1, p2 ) ((NTSTATUS)(((p1) << 28) | (0x11 << 16) | (p2)))
+#define HIDP_STATUS_SUCCESS                 HIDP_ERROR_CODES( 0x0, 0x0000 )
+#define HIDP_STATUS_NULL                    HIDP_ERROR_CODES( 0x8, 0x0001 )
+#define HIDP_STATUS_INVALID_PREPARSED_DATA  HIDP_ERROR_CODES( 0xC, 0x0001 )
+#define HIDP_STATUS_INVALID_REPORT_TYPE     HIDP_ERROR_CODES( 0xC, 0x0002 )
+#define HIDP_STATUS_INVALID_REPORT_LENGTH   HIDP_ERROR_CODES( 0xC, 0x0003 )
+#define HIDP_STATUS_USAGE_NOT_FOUND         HIDP_ERROR_CODES( 0xC, 0x0004 )
+#define HIDP_STATUS_VALUE_OUT_OF_RANGE      HIDP_ERROR_CODES( 0xC, 0x0005 )
+#define HIDP_STATUS_BAD_LOG_PHY_VALUES      HIDP_ERROR_CODES( 0xC, 0x0006 )
+#define HIDP_STATUS_BUFFER_TOO_SMALL        HIDP_ERROR_CODES( 0xC, 0x0007 )
+#define HIDP_STATUS_INTERNAL_ERROR          HIDP_ERROR_CODES( 0xC, 0x0008 )
+#define HIDP_STATUS_I8042_TRANS_UNKNOWN     HIDP_ERROR_CODES( 0xC, 0x0009 )
+#define HIDP_STATUS_INCOMPATIBLE_REPORT_ID  HIDP_ERROR_CODES( 0xC, 0x000A )
+#define HIDP_STATUS_NOT_VALUE_ARRAY         HIDP_ERROR_CODES( 0xC, 0x000B )
+#define HIDP_STATUS_IS_VALUE_ARRAY          HIDP_ERROR_CODES( 0xC, 0x000C )
+#define HIDP_STATUS_DATA_INDEX_NOT_FOUND    HIDP_ERROR_CODES( 0xC, 0x000D )
+#define HIDP_STATUS_DATA_INDEX_OUT_OF_RANGE HIDP_ERROR_CODES( 0xC, 0x000E )
+#define HIDP_STATUS_BUTTON_NOT_PRESSED      HIDP_ERROR_CODES( 0xC, 0x000F )
+#define HIDP_STATUS_REPORT_DOES_NOT_EXIST   HIDP_ERROR_CODES( 0xC, 0x0010 )
+#define HIDP_STATUS_NOT_IMPLEMENTED         HIDP_ERROR_CODES( 0xC, 0x0020 )
+
+
+extern int WIN_LoadHIDDLL(void);
+extern void WIN_UnloadHIDDLL(void);
+
+typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
+typedef BOOLEAN (WINAPI *HidD_GetPreparsedData_t)(HANDLE HidDeviceObject, PHIDP_PREPARSED_DATA *PreparsedData);
+typedef BOOLEAN (WINAPI *HidD_FreePreparsedData_t)(PHIDP_PREPARSED_DATA PreparsedData);
+typedef NTSTATUS (WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities);
+typedef NTSTATUS (WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
+typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
+typedef ULONG (WINAPI *HidP_MaxDataListLength_t)(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData);
+typedef NTSTATUS (WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DATA DataList, PULONG DataLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
+
+extern HidD_GetString_t SDL_HidD_GetManufacturerString;
+extern HidD_GetString_t SDL_HidD_GetProductString;
+extern HidD_GetPreparsedData_t SDL_HidD_GetPreparsedData;
+extern HidD_FreePreparsedData_t SDL_HidD_FreePreparsedData;
+extern HidP_GetCaps_t SDL_HidP_GetCaps;
+extern HidP_GetButtonCaps_t SDL_HidP_GetButtonCaps;
+extern HidP_GetValueCaps_t SDL_HidP_GetValueCaps;
+extern HidP_MaxDataListLength_t SDL_HidP_MaxDataListLength;
+extern HidP_GetData_t SDL_HidP_GetData;
+
+#endif /* !__WINRT__ */
+
+#endif /* SDL_hid_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 117 - 16
src/hidapi/SDL_hidapi.c

@@ -129,6 +129,67 @@ static const SDL_UDEV_Symbols *udev_ctx = NULL;
 #undef make_path
 #undef read_thread
 
+#ifdef HAVE_HIDAPI_NVAGIPMAN
+#define HAVE_DRIVER_BACKEND
+#endif
+
+#ifdef HAVE_DRIVER_BACKEND
+
+/* DRIVER HIDAPI Implementation */
+
+#define hid_device_                     DRIVER_hid_device_
+#define hid_device                      DRIVER_hid_device
+#define hid_device_info                 DRIVER_hid_device_info
+#define hid_init                        DRIVER_hid_init
+#define hid_exit                        DRIVER_hid_exit
+#define hid_enumerate                   DRIVER_hid_enumerate
+#define hid_free_enumeration            DRIVER_hid_free_enumeration
+#define hid_open                        DRIVER_hid_open
+#define hid_open_path                   DRIVER_hid_open_path
+#define hid_write                       DRIVER_hid_write
+#define hid_read_timeout                DRIVER_hid_read_timeout
+#define hid_read                        DRIVER_hid_read
+#define hid_set_nonblocking             DRIVER_hid_set_nonblocking
+#define hid_send_feature_report         DRIVER_hid_send_feature_report
+#define hid_get_feature_report          DRIVER_hid_get_feature_report
+#define hid_close                       DRIVER_hid_close
+#define hid_get_manufacturer_string     DRIVER_hid_get_manufacturer_string
+#define hid_get_product_string          DRIVER_hid_get_product_string
+#define hid_get_serial_number_string    DRIVER_hid_get_serial_number_string
+#define hid_get_indexed_string          DRIVER_hid_get_indexed_string
+#define hid_error                       DRIVER_hid_error
+
+#ifdef HAVE_HIDAPI_NVAGIPMAN
+#include "nvagipman/hid.c"
+#else
+#error Need a driver hid.c for this platform!
+#endif
+
+#undef hid_device_
+#undef hid_device
+#undef hid_device_info
+#undef hid_init
+#undef hid_exit
+#undef hid_enumerate
+#undef hid_free_enumeration
+#undef hid_open
+#undef hid_open_path
+#undef hid_write
+#undef hid_read_timeout
+#undef hid_read
+#undef hid_set_nonblocking
+#undef hid_send_feature_report
+#undef hid_get_feature_report
+#undef hid_close
+#undef hid_get_manufacturer_string
+#undef hid_get_product_string
+#undef hid_get_serial_number_string
+#undef hid_get_indexed_string
+#undef hid_error
+
+#endif /* HAVE_DRIVER_BACKEND */
+
+
 #ifdef SDL_LIBUSB_DYNAMIC
 /* libusb HIDAPI Implementation */
 
@@ -298,23 +359,21 @@ SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
 /* Shared HIDAPI Implementation */
 
 #undef HIDAPI_H__
-#include "hidapi.h"
+#include "hidapi/hidapi.h"
 
 struct hidapi_backend {
-#define F(x) typeof(x) *x
-    F(hid_write);
-    F(hid_read_timeout);
-    F(hid_read);
-    F(hid_set_nonblocking);
-    F(hid_send_feature_report);
-    F(hid_get_feature_report);
-    F(hid_close);
-    F(hid_get_manufacturer_string);
-    F(hid_get_product_string);
-    F(hid_get_serial_number_string);
-    F(hid_get_indexed_string);
-    F(hid_error);
-#undef F
+    int  (*hid_write)(hid_device* device, const unsigned char* data, size_t length);
+    int  (*hid_read_timeout)(hid_device* device, unsigned char* data, size_t length, int milliseconds);
+    int  (*hid_read)(hid_device* device, unsigned char* data, size_t length);
+    int  (*hid_set_nonblocking)(hid_device* device, int nonblock);
+    int  (*hid_send_feature_report)(hid_device* device, const unsigned char* data, size_t length);
+    int  (*hid_get_feature_report)(hid_device* device, unsigned char* data, size_t length);
+    void (*hid_close)(hid_device* device);
+    int  (*hid_get_manufacturer_string)(hid_device* device, wchar_t* string, size_t maxlen);
+    int  (*hid_get_product_string)(hid_device* device, wchar_t* string, size_t maxlen);
+    int  (*hid_get_serial_number_string)(hid_device* device, wchar_t* string, size_t maxlen);
+    int  (*hid_get_indexed_string)(hid_device* device, int string_index, wchar_t* string, size_t maxlen);
+    const wchar_t* (*hid_error)(hid_device* device);
 };
 
 #if HAVE_PLATFORM_BACKEND
@@ -334,6 +393,23 @@ static const struct hidapi_backend PLATFORM_Backend = {
 };
 #endif /* HAVE_PLATFORM_BACKEND */
 
+#if HAVE_DRIVER_BACKEND
+static const struct hidapi_backend DRIVER_Backend = {
+    (void*)DRIVER_hid_write,
+    (void*)DRIVER_hid_read_timeout,
+    (void*)DRIVER_hid_read,
+    (void*)DRIVER_hid_set_nonblocking,
+    (void*)DRIVER_hid_send_feature_report,
+    (void*)DRIVER_hid_get_feature_report,
+    (void*)DRIVER_hid_close,
+    (void*)DRIVER_hid_get_manufacturer_string,
+    (void*)DRIVER_hid_get_product_string,
+    (void*)DRIVER_hid_get_serial_number_string,
+    (void*)DRIVER_hid_get_indexed_string,
+    (void*)DRIVER_hid_error
+};
+#endif /* HAVE_DRIVER_BACKEND */
+
 #ifdef SDL_LIBUSB_DYNAMIC
 static const struct hidapi_backend LIBUSB_Backend = {
     (void*)LIBUSB_hid_write,
@@ -361,7 +437,7 @@ struct _HIDDeviceWrapper
 static HIDDeviceWrapper *
 CreateHIDDeviceWrapper(hid_device *device, const struct hidapi_backend *backend)
 {
-    HIDDeviceWrapper *ret = SDL_malloc(sizeof(*ret));
+    HIDDeviceWrapper *ret = (HIDDeviceWrapper *)SDL_malloc(sizeof(*ret));
     ret->device = device;
     ret->backend = backend;
     return ret;
@@ -540,6 +616,10 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
     struct LIBUSB_hid_device_info *usb_devs = NULL;
     struct LIBUSB_hid_device_info *usb_dev;
 #endif
+#if HAVE_DRIVER_BACKEND
+    struct DRIVER_hid_device_info* driver_devs = NULL;
+    struct DRIVER_hid_device_info* driver_dev;
+#endif
 #if HAVE_PLATFORM_BACKEND
     struct PLATFORM_hid_device_info *raw_devs = NULL;
     struct PLATFORM_hid_device_info *raw_dev;
@@ -636,6 +716,15 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsi
         return WrapHIDDevice(wrapper);
     }
 #endif /* HAVE_PLATFORM_BACKEND */
+
+#if HAVE_DRIVER_BACKEND
+    if ((pDevice = (hid_device*) DRIVER_hid_open(vendor_id, product_id, serial_number)) != NULL) {
+
+        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);
+        return WrapHIDDevice(wrapper);
+    }
+#endif /* HAVE_DRIVER_BACKEND */
+
 #ifdef SDL_LIBUSB_DYNAMIC
     if (libusb_ctx.libhandle &&
         (pDevice = (hid_device*) LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) {
@@ -644,6 +733,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsi
         return WrapHIDDevice(wrapper);
     }
 #endif /* SDL_LIBUSB_DYNAMIC */
+
     return NULL;
 }
 
@@ -663,6 +753,16 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
         return WrapHIDDevice(wrapper);
     }
 #endif /* HAVE_PLATFORM_BACKEND */
+
+#if HAVE_DRIVER_BACKEND
+    if (udev_ctx &&
+        (pDevice = (hid_device*) DRIVER_hid_open_path(path, bExclusive)) != NULL) {
+
+        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &DRIVER_Backend);
+        return WrapHIDDevice(wrapper);
+    }
+#endif /* HAVE_DRIVER_BACKEND */
+
 #ifdef SDL_LIBUSB_DYNAMIC
     if (libusb_ctx.libhandle &&
         (pDevice = (hid_device*) LIBUSB_hid_open_path(path, bExclusive)) != NULL) {
@@ -671,6 +771,7 @@ HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bEx
         return WrapHIDDevice(wrapper);
     }
 #endif /* SDL_LIBUSB_DYNAMIC */
+
     return NULL;
 }
 

+ 5 - 0
src/hidapi/windows/hid.c

@@ -409,6 +409,11 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
 			goto cont;
 		}
 
+		/* XInput devices don't get real HID reports and are better handled by the raw input driver */
+		if (strstr(device_interface_detail_data->DevicePath, "&ig_") != NULL) {
+			goto cont;
+		}
+
 		/* Make sure this device is of Setup Class "HIDClass" and has a
 		   driver bound to it. */
 		/* In the main HIDAPI tree this is a loop which will erroneously open 

+ 1 - 1
src/joystick/SDL_gamecontroller.c

@@ -616,7 +616,7 @@ static ControllerMapping_t *SDL_CreateMappingForRAWINPUTController(SDL_JoystickG
     char mapping_string[1024];
 
     SDL_strlcpy(mapping_string, "none,*,", sizeof(mapping_string));
-    SDL_strlcat(mapping_string, "a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,", sizeof(mapping_string));
+    SDL_strlcat(mapping_string, "a:b0,b:b1,x:b2,y:b3,back:b6,guide:b10,start:b7,leftstick:b8,rightstick:b9,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a1,lefty:a0,rightx:a3,righty:a2,lefttrigger:a4,righttrigger:a5,", sizeof(mapping_string));
 
     return SDL_PrivateAddMappingForGUID(guid, mapping_string,
                       &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);

+ 3 - 4
src/joystick/SDL_joystick.c

@@ -51,13 +51,12 @@
 #endif
 
 static SDL_JoystickDriver *SDL_joystick_drivers[] = {
-#ifdef SDL_JOYSTICK_RAWINPUT /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */
-    /* Also before HIDAPI, as HIDAPI wants to check if this driver is handling things */
-    &SDL_RAWINPUT_JoystickDriver,
-#endif
 #ifdef SDL_JOYSTICK_HIDAPI /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */
     &SDL_HIDAPI_JoystickDriver,
 #endif
+#ifdef SDL_JOYSTICK_RAWINPUT /* Before WINDOWS_ driver, as WINDOWS wants to check if this driver is handling things */
+    &SDL_RAWINPUT_JoystickDriver,
+#endif
 #if defined(SDL_JOYSTICK_WGI)
     &SDL_WGI_JoystickDriver,
 #endif

+ 4 - 5
src/joystick/hidapi/SDL_hidapi_gamecube.c

@@ -175,11 +175,11 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
             if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */
                 if (ctx->joysticks[i] == -1) {
                     ResetAxisRange(ctx, i);
-                    HIDAPI_JoystickConnected(device, &ctx->joysticks[i], SDL_FALSE);
+                    HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
                 }
             } else {
                 if (ctx->joysticks[i] != -1) {
-                    HIDAPI_JoystickDisconnected(device, ctx->joysticks[i], SDL_FALSE);
+                    HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]);
                     ctx->joysticks[i] = -1;
                 }
                 continue;
@@ -251,7 +251,7 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
             if (curSlot[0] & 0x30) { /* 0x10 - Wired, 0x20 - Wireless */
                 if (ctx->joysticks[i] == -1) {
                     ResetAxisRange(ctx, i);
-                    HIDAPI_JoystickConnected(device, &ctx->joysticks[i], SDL_FALSE);
+                    HIDAPI_JoystickConnected(device, &ctx->joysticks[i]);
                 }
                 joystick = SDL_JoystickFromInstanceID(ctx->joysticks[i]);
 
@@ -261,7 +261,7 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
                 }
             } else {
                 if (ctx->joysticks[i] != -1) {
-                    HIDAPI_JoystickDisconnected(device, ctx->joysticks[i], SDL_FALSE);
+                    HIDAPI_JoystickDisconnected(device, ctx->joysticks[i]);
                     ctx->joysticks[i] = -1;
                 }
                 continue;
@@ -432,7 +432,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
     HIDAPI_DriverGameCube_SetJoystickSensorsEnabled,
     HIDAPI_DriverGameCube_CloseJoystick,
     HIDAPI_DriverGameCube_FreeDevice,
-    NULL,
 };
 
 #endif /* SDL_JOYSTICK_HIDAPI_GAMECUBE */

+ 3 - 4
src/joystick/hidapi/SDL_hidapi_ps4.c

@@ -143,7 +143,7 @@ typedef struct {
 static SDL_bool
 HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
 {
-    return (type == SDL_CONTROLLER_TYPE_PS4);
+    return (type == SDL_CONTROLLER_TYPE_PS4) ? SDL_TRUE : SDL_FALSE;
 }
 
 static const char *
@@ -202,7 +202,7 @@ SetLedsForPlayerIndex(DS4EffectsState_t *effects, int player_index)
 static SDL_bool
 HIDAPI_DriverPS4_InitDevice(SDL_HIDAPI_Device *device)
 {
-    return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
+    return HIDAPI_JoystickConnected(device, NULL);
 }
 
 static int
@@ -769,7 +769,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
 
     if (size < 0) {
         /* Read error, device is disconnected */
-        HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
+        HIDAPI_JoystickDisconnected(device, joystick->instance_id);
     }
     return (size >= 0);
 }
@@ -807,7 +807,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
     HIDAPI_DriverPS4_SetJoystickSensorsEnabled,
     HIDAPI_DriverPS4_CloseJoystick,
     HIDAPI_DriverPS4_FreeDevice,
-    NULL
 };
 
 #endif /* SDL_JOYSTICK_HIDAPI_PS4 */

+ 3 - 4
src/joystick/hidapi/SDL_hidapi_ps5.c

@@ -171,7 +171,7 @@ typedef struct {
 static SDL_bool
 HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
 {
-    return (type == SDL_CONTROLLER_TYPE_PS5);
+    return (type == SDL_CONTROLLER_TYPE_PS5) ? SDL_TRUE : SDL_FALSE;
 }
 
 static const char *
@@ -220,7 +220,7 @@ SetLedsForPlayerIndex(DS5EffectsState_t *effects, int player_index)
 static SDL_bool
 HIDAPI_DriverPS5_InitDevice(SDL_HIDAPI_Device *device)
 {
-    return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
+    return HIDAPI_JoystickConnected(device, NULL);
 }
 
 static int
@@ -885,7 +885,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
 
     if (size < 0) {
         /* Read error, device is disconnected */
-        HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
+        HIDAPI_JoystickDisconnected(device, joystick->instance_id);
     }
     return (size >= 0);
 }
@@ -923,7 +923,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
     HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
     HIDAPI_DriverPS5_CloseJoystick,
     HIDAPI_DriverPS5_FreeDevice,
-    NULL
 };
 
 #endif /* SDL_JOYSTICK_HIDAPI_PS5 */

+ 2 - 3
src/joystick/hidapi/SDL_hidapi_steam.c

@@ -971,7 +971,7 @@ HIDAPI_DriverSteam_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
 static SDL_bool
 HIDAPI_DriverSteam_InitDevice(SDL_HIDAPI_Device *device)
 {
-    return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
+    return HIDAPI_JoystickConnected(device, NULL);
 }
 
 static int
@@ -1160,7 +1160,7 @@ HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
 
         if (r <= 0) {
             /* Failed to read from controller */
-            HIDAPI_JoystickDisconnected(device, device->joysticks[0], SDL_FALSE);
+            HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
             return SDL_FALSE;
         }
     }
@@ -1201,7 +1201,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
     HIDAPI_DriverSteam_SetSensorsEnabled,
     HIDAPI_DriverSteam_CloseJoystick,
     HIDAPI_DriverSteam_FreeDevice,
-    NULL
 };
 
 #endif /* SDL_JOYSTICK_HIDAPI_STEAM */

+ 3 - 4
src/joystick/hidapi/SDL_hidapi_switch.c

@@ -288,7 +288,7 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t
     if (SDL_strcmp( name, "HORI Wireless Switch Pad" ) == 0) {
         return SDL_FALSE;
     }
-    return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO);
+    return (type == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO) ? SDL_TRUE : SDL_FALSE;
 }
 
 static const char *
@@ -697,7 +697,7 @@ static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)
 static SDL_bool
 HIDAPI_DriverSwitch_InitDevice(SDL_HIDAPI_Device *device)
 {
-    return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
+    return HIDAPI_JoystickConnected(device, NULL);
 }
 
 static int
@@ -1259,7 +1259,7 @@ HIDAPI_DriverSwitch_UpdateDevice(SDL_HIDAPI_Device *device)
 
     if (size < 0) {
         /* Read error, device is disconnected */
-        HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
+        HIDAPI_JoystickDisconnected(device, joystick->instance_id);
     }
     return (size >= 0);
 }
@@ -1307,7 +1307,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
     HIDAPI_DriverSwitch_SetJoystickSensorsEnabled,
     HIDAPI_DriverSwitch_CloseJoystick,
     HIDAPI_DriverSwitch_FreeDevice,
-    NULL
 };
 
 #endif /* SDL_JOYSTICK_HIDAPI_SWITCH */

File diff suppressed because it is too large
+ 11 - 978
src/joystick/hidapi/SDL_hidapi_xbox360.c


+ 3 - 4
src/joystick/hidapi/SDL_hidapi_xbox360w.c

@@ -255,10 +255,10 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
                 if (connected) {
                     SDL_JoystickID joystickID;
 
-                    HIDAPI_JoystickConnected(device, &joystickID, SDL_FALSE);
+                    HIDAPI_JoystickConnected(device, &joystickID);
 
                 } else if (device->num_joysticks > 0) {
-                    HIDAPI_JoystickDisconnected(device, device->joysticks[0], SDL_FALSE);
+                    HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
                 }
             }
         } else if (size == 29 && data[0] == 0x00 && data[1] == 0x0f && data[2] == 0x00 && data[3] == 0xf0) {
@@ -286,7 +286,7 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
     if (joystick) {
         if (size < 0) {
             /* Read error, device is disconnected */
-            HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
+            HIDAPI_JoystickDisconnected(device, joystick->instance_id);
         }
     }
     return (size >= 0);
@@ -325,7 +325,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
     HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled,
     HIDAPI_DriverXbox360W_CloseJoystick,
     HIDAPI_DriverXbox360W_FreeDevice,
-    NULL
 };
 
 #endif /* SDL_JOYSTICK_HIDAPI_XBOX360 */

+ 5 - 6
src/joystick/hidapi/SDL_hidapi_xboxone.c

@@ -291,7 +291,7 @@ HIDAPI_DriverXboxOne_IsSupportedDevice(const char *name, SDL_GameControllerType
         return SDL_FALSE;
     }
 #endif
-    return (type == SDL_CONTROLLER_TYPE_XBOXONE);
+    return (type == SDL_CONTROLLER_TYPE_XBOXONE) ? SDL_TRUE : SDL_FALSE;
 }
 
 static const char *
@@ -303,7 +303,7 @@ HIDAPI_DriverXboxOne_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
 static SDL_bool
 HIDAPI_DriverXboxOne_InitDevice(SDL_HIDAPI_Device *device)
 {
-    return HIDAPI_JoystickConnected(device, NULL, SDL_FALSE);
+    return HIDAPI_JoystickConnected(device, NULL);
 }
 
 static int
@@ -852,7 +852,7 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
         !ControllerSendsWaitingForInit(device->vendor_id, device->product_id)) {
         if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->start_time + CONTROLLER_INIT_DELAY_MS)) {
             if (!SendControllerInit(device, ctx)) {
-                HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
+                HIDAPI_JoystickDisconnected(device, joystick->instance_id);
                 return SDL_FALSE;
             }
             ctx->initialized = SDL_TRUE;
@@ -918,7 +918,7 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
                     SDL_Log("Delay after init: %ums\n", SDL_GetTicks() - ctx->start_time);
 #endif
                     if (!SendControllerInit(device, ctx)) {
-                        HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
+                        HIDAPI_JoystickDisconnected(device, joystick->instance_id);
                         return SDL_FALSE;
                     }
                     ctx->initialized = SDL_TRUE;
@@ -973,7 +973,7 @@ HIDAPI_DriverXboxOne_UpdateDevice(SDL_HIDAPI_Device *device)
 
     if (size < 0) {
         /* Read error, device is disconnected */
-        HIDAPI_JoystickDisconnected(device, joystick->instance_id, SDL_FALSE);
+        HIDAPI_JoystickDisconnected(device, joystick->instance_id);
     }
     return (size >= 0);
 }
@@ -1011,7 +1011,6 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
     HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled,
     HIDAPI_DriverXboxOne_CloseJoystick,
     HIDAPI_DriverXboxOne_FreeDevice,
-    NULL
 };
 
 #endif /* SDL_JOYSTICK_HIDAPI_XBOXONE */

+ 6 - 29
src/joystick/hidapi/SDL_hidapijoystick.c

@@ -443,13 +443,6 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
         return NULL;
     }
 
-#ifdef SDL_JOYSTICK_RAWINPUT
-    if (RAWINPUT_IsDevicePresent(device->vendor_id, device->product_id, device->version)) {
-        /* The RAWINPUT driver is taking care of this device */
-        return NULL;
-    }
-#endif
-
 	if (device->vendor_id != USB_VENDOR_VALVE) {
         if (device->usage_page && device->usage_page != USAGE_PAGE_GENERIC_DESKTOP) {
             return NULL;
@@ -535,7 +528,7 @@ HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
 
     /* Disconnect any joysticks */
     while (device->num_joysticks) {
-        HIDAPI_JoystickDisconnected(device, device->joysticks[0], SDL_FALSE);
+        HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
     }
 
     device->driver->FreeDevice(device);
@@ -608,11 +601,6 @@ HIDAPI_JoystickInit(void)
         return -1;
     }
 
-#ifdef __WINDOWS__
-    /* On Windows, turns out HIDAPI for Xbox controllers doesn't allow background input, so off by default */
-    SDL_SetHintWithPriority(SDL_HINT_JOYSTICK_HIDAPI_XBOX, "0", SDL_HINT_DEFAULT);
-#endif
-
     for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
         SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
         SDL_AddHintCallback(driver->hint, SDL_HIDAPIDriverHintChanged, NULL);
@@ -629,7 +617,7 @@ HIDAPI_JoystickInit(void)
 }
 
 SDL_bool
-HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID, SDL_bool is_external)
+HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID)
 {
     SDL_JoystickID joystickID;
     SDL_JoystickID *joysticks = (SDL_JoystickID *)SDL_realloc(device->joysticks, (device->num_joysticks + 1)*sizeof(*device->joysticks));
@@ -640,9 +628,7 @@ HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID,
     joystickID = SDL_GetNextJoystickInstanceID();
     device->joysticks = joysticks;
     device->joysticks[device->num_joysticks++] = joystickID;
-    if (!is_external) {
-        ++SDL_HIDAPI_numjoysticks;
-    }
+    ++SDL_HIDAPI_numjoysticks;
 
     SDL_PrivateJoystickAdded(joystickID);
 
@@ -653,14 +639,14 @@ HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID,
 }
 
 void
-HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID, SDL_bool is_external)
+HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID)
 {
     int i, size;
 
     for (i = 0; i < device->num_joysticks; ++i) {
         if (device->joysticks[i] == joystickID) {
             SDL_Joystick *joystick = SDL_JoystickFromInstanceID(joystickID);
-            if (joystick && !is_external) {
+            if (joystick) {
                 HIDAPI_JoystickClose(joystick);
             }
 
@@ -668,9 +654,7 @@ HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID
             SDL_memmove(&device->joysticks[i], &device->joysticks[i+1], size);
             --device->num_joysticks;
 
-            if (!is_external) {
-                --SDL_HIDAPI_numjoysticks;
-            }
+            --SDL_HIDAPI_numjoysticks;
             if (device->num_joysticks == 0) {
                 SDL_free(device->joysticks);
                 device->joysticks = NULL;
@@ -932,7 +916,6 @@ HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, cons
 static void
 HIDAPI_JoystickDetect(void)
 {
-    int i;
     if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) {
         HIDAPI_UpdateDiscovery();
         if (SDL_HIDAPI_discovery.m_bHaveDevicesChanged) {
@@ -942,12 +925,6 @@ HIDAPI_JoystickDetect(void)
         }
         SDL_AtomicUnlock(&SDL_HIDAPI_spinlock);
     }
-    for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
-        SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
-        if (driver->enabled && driver->PostUpdate) {
-            driver->PostUpdate();
-        }
-    }
 }
 
 void

+ 2 - 11
src/joystick/hidapi/SDL_hidapijoystick_c.h

@@ -38,11 +38,6 @@
 #define SDL_JOYSTICK_HIDAPI_XBOXONE
 #define SDL_JOYSTICK_HIDAPI_GAMECUBE
 
-#ifdef __WINDOWS__
-/* On Windows, Xbox One controllers are handled by the Xbox 360 driver */
-#undef SDL_JOYSTICK_HIDAPI_XBOXONE
-#endif
-
 #if defined(__IPHONEOS__) || defined(__TVOS__) || defined(__ANDROID__)
 /* Very basic Steam Controller support on mobile devices */
 #define SDL_JOYSTICK_HIDAPI_STEAM
@@ -102,10 +97,6 @@ typedef struct _SDL_HIDAPI_DeviceDriver
     int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled);
     void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
     void (*FreeDevice)(SDL_HIDAPI_Device *device);
-    void (*PostUpdate)(void);
-#ifdef SDL_JOYSTICK_RAWINPUT
-    void (*HandleStatePacketFromRAWINPUT)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 *data, int size);
-#endif
 
 } SDL_HIDAPI_DeviceDriver;
 
@@ -124,8 +115,8 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube;
 extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name);
 
 extern void HIDAPI_UpdateDevices(void);
-extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID, SDL_bool is_external);
-extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID, SDL_bool is_external);
+extern SDL_bool HIDAPI_JoystickConnected(SDL_HIDAPI_Device *device, SDL_JoystickID *pJoystickID);
+extern void HIDAPI_JoystickDisconnected(SDL_HIDAPI_Device *device, SDL_JoystickID joystickID);
 
 extern void HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size);
 

+ 23 - 0
src/joystick/usb_ids.h

@@ -53,6 +53,29 @@
 #define USB_PRODUCT_XBOX_ONE_SERIES_X                   0x0b12
 #define USB_PRODUCT_XBOX_ONE_SERIES_X_BLUETOOTH         0x0b13
 
+/* USB usage pages */
+#define USB_USAGEPAGE_GENERIC_DESKTOP   0x0001
+#define USB_USAGEPAGE_BUTTON            0x0009
+
+/* USB usages for USAGE_PAGE_GENERIC_DESKTOP */
+#define USB_USAGE_GENERIC_POINTER               0x0001
+#define USB_USAGE_GENERIC_MOUSE                 0x0002
+#define USB_USAGE_GENERIC_JOYSTICK              0x0004
+#define USB_USAGE_GENERIC_GAMEPAD               0x0005
+#define USB_USAGE_GENERIC_KEYBOARD              0x0006
+#define USB_USAGE_GENERIC_KEYPAD                0x0007
+#define USB_USAGE_GENERIC_MULTIAXISCONTROLLER   0x0008
+#define USB_USAGE_GENERIC_X                     0x0030
+#define USB_USAGE_GENERIC_Y                     0x0031
+#define USB_USAGE_GENERIC_Z                     0x0032
+#define USB_USAGE_GENERIC_RX                    0x0033
+#define USB_USAGE_GENERIC_RY                    0x0034
+#define USB_USAGE_GENERIC_RZ                    0x0035
+#define USB_USAGE_GENERIC_SLIDER                0x0036
+#define USB_USAGE_GENERIC_DIAL                  0x0037
+#define USB_USAGE_GENERIC_WHEEL                 0x0038
+#define USB_USAGE_GENERIC_HAT                   0x0039
+
 #endif /* usb_ids_h_ */
 
 /* vi: set ts=4 sw=4 expandtab: */

File diff suppressed because it is too large
+ 837 - 224
src/joystick/windows/SDL_rawinputjoystick.c


+ 3 - 0
src/joystick/windows/SDL_rawinputjoystick_c.h

@@ -20,6 +20,9 @@
 */
 #include "../../SDL_internal.h"
 
+/* Return true if the RawInput driver is enabled */
+extern SDL_bool RAWINPUT_IsEnabled();
+
 /* Return true if a RawInput device is present and supported as a joystick */
 extern SDL_bool RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version);
 

+ 7 - 0
src/joystick/windows/SDL_windows_gaming_input.c

@@ -26,6 +26,7 @@
 #include "SDL_events.h"
 #include "../SDL_sysjoystick.h"
 #include "../hidapi/SDL_hidapijoystick_c.h"
+#include "SDL_rawinputjoystick_c.h"
 
 #include "../../core/windows/SDL_windows.h"
 #define COBJMACROS
@@ -247,6 +248,12 @@ static HRESULT STDMETHODCALLTYPE IEventHandler_CRawGameControllerVtbl_InvokeAdde
         }
 #endif
 
+#ifdef SDL_JOYSTICK_RAWINPUT
+        if (!ignore_joystick && RAWINPUT_IsDevicePresent(vendor, product, version)) {
+            ignore_joystick = SDL_TRUE;
+        }
+#endif
+
         if (!ignore_joystick && SDL_DINPUT_JoystickPresent(vendor, product, version)) {
             ignore_joystick = SDL_TRUE;
         }

+ 6 - 1
src/joystick/windows/SDL_xinputjoystick.c

@@ -65,6 +65,11 @@ SDL_XINPUT_JoystickInit(void)
 {
     s_bXInputEnabled = SDL_GetHintBoolean(SDL_HINT_XINPUT_ENABLED, SDL_TRUE);
 
+    if (RAWINPUT_IsEnabled()) {
+        /* The raw input driver handles more than 4 controllers, so prefer that when available */
+        s_bXInputEnabled = SDL_FALSE;
+    }
+
     if (s_bXInputEnabled && WIN_LoadXInputDLL() < 0) {
         s_bXInputEnabled = SDL_FALSE;  /* oh well. */
     }
@@ -208,7 +213,7 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
         }
     }
     SDL_free(devices);
-#endif  /* ifndef __WINRT__ */
+#endif  /* !__WINRT__ */
 
     /* The device wasn't in the raw HID device list, it's probably Bluetooth */
     *pVID = 0x045e; /* Microsoft */

Some files were not shown because too many files changed in this diff