diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index a111aaeb33..1a98f8f164 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -1,658 +1,659 @@
-
-
-
-
- Debug
- Win32
-
-
- Debug
- x64
-
-
- Release
- Win32
-
-
- Release
- x64
-
-
-
- SDL3
- {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}
- SDL
- 10.0
-
-
-
- DynamicLibrary
- $(DefaultPlatformToolset)
-
-
- DynamicLibrary
- $(DefaultPlatformToolset)
-
-
- DynamicLibrary
- $(DefaultPlatformToolset)
-
-
- DynamicLibrary
- $(DefaultPlatformToolset)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <_ProjectFileVersion>10.0.40219.1
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
- $(SolutionDir)$(Platform)\$(Configuration)\
- $(Platform)\$(Configuration)\
- AllRules.ruleset
-
-
- AllRules.ruleset
-
-
- AllRules.ruleset
-
-
- AllRules.ruleset
-
-
- C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)
-
-
- $(ProjectDir)/../../src;$(IncludePath)
-
-
- $(ProjectDir)/../../src;$(IncludePath)
-
-
- $(ProjectDir)/../../src;$(IncludePath)
-
-
- $(ProjectDir)/../../src;$(IncludePath)
-
-
-
-
-
-
-
- _DEBUG;%(PreprocessorDefinitions)
- true
- true
- Win32
- .\Debug/SDL.tlb
-
-
- Disabled
- $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
- %(AdditionalUsingDirectories)
- DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
- false
- StreamingSIMDExtensions
- Level3
- OldStyle
- true
- OnlyExplicitInline
- Use
- SDL_internal.h
-
-
- _DEBUG;%(PreprocessorDefinitions)
-
-
- setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
- true
- true
- Windows
-
-
-
-
- _DEBUG;%(PreprocessorDefinitions)
- true
- true
- X64
- .\Debug/SDL.tlb
-
-
- Disabled
- $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
- %(AdditionalUsingDirectories)
- DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
- false
- Level3
- OldStyle
- true
- OnlyExplicitInline
- Use
- SDL_internal.h
-
-
- _DEBUG;%(PreprocessorDefinitions)
-
-
- setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
- true
- true
- Windows
-
-
-
-
-
-
-
-
- NDEBUG;%(PreprocessorDefinitions)
- true
- true
- Win32
- .\Release/SDL.tlb
-
-
- $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
- %(AdditionalUsingDirectories)
- DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
- false
- StreamingSIMDExtensions
- Level3
- ProgramDatabase
- true
- OnlyExplicitInline
- Use
- SDL_internal.h
-
-
- NDEBUG;%(PreprocessorDefinitions)
-
-
- setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
- true
- true
- Windows
- true
- true
-
-
-
-
- NDEBUG;%(PreprocessorDefinitions)
- true
- true
- X64
- .\Release/SDL.tlb
-
-
- $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
- %(AdditionalUsingDirectories)
- DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
- false
- Level3
- ProgramDatabase
- true
- OnlyExplicitInline
- Use
- SDL_internal.h
-
-
- NDEBUG;%(PreprocessorDefinitions)
-
-
- setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
- true
- true
- Windows
- true
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Create
- Create
- Create
- Create
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- NotUsing
- NotUsing
- NotUsing
- NotUsing
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ SDL3
+ {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}
+ SDL
+ 10.0
+
+
+
+ DynamicLibrary
+ $(DefaultPlatformToolset)
+
+
+ DynamicLibrary
+ $(DefaultPlatformToolset)
+
+
+ DynamicLibrary
+ $(DefaultPlatformToolset)
+
+
+ DynamicLibrary
+ $(DefaultPlatformToolset)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.40219.1
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;C:\projects\libusb-1.0.26-binaries\VS2015-Win32\lib;$(LibraryPath)
+
+
+ $(ProjectDir)/../../src;$(IncludePath)
+ C:\projects\libusb-1.0.26\libusb;$(ExternalIncludePath)
+
+
+ $(ProjectDir)/../../src;$(IncludePath)
+
+
+ $(ProjectDir)/../../src;$(IncludePath)
+
+
+ $(ProjectDir)/../../src;$(IncludePath)
+
+
+
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ Win32
+ .\Debug/SDL.tlb
+
+
+ Disabled
+ $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
+ %(AdditionalUsingDirectories)
+ DLL_EXPORT;_DEBUG;_WINDOWS;HAVE_LIBUSB;SDL_LIBUSB_DYNAMIC="libusb-1.0.dll";%(PreprocessorDefinitions)
+ false
+ StreamingSIMDExtensions
+ Level3
+ OldStyle
+ true
+ OnlyExplicitInline
+ Use
+ SDL_internal.h
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
+ true
+ true
+ Windows
+
+
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ X64
+ .\Debug/SDL.tlb
+
+
+ Disabled
+ $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
+ %(AdditionalUsingDirectories)
+ DLL_EXPORT;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ false
+ Level3
+ OldStyle
+ true
+ OnlyExplicitInline
+ Use
+ SDL_internal.h
+
+
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
+ true
+ true
+ Windows
+
+
+
+
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ Win32
+ .\Release/SDL.tlb
+
+
+ $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
+ %(AdditionalUsingDirectories)
+ DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ false
+ StreamingSIMDExtensions
+ Level3
+ ProgramDatabase
+ true
+ OnlyExplicitInline
+ Use
+ SDL_internal.h
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
+ true
+ true
+ Windows
+ true
+ true
+
+
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+ true
+ true
+ X64
+ .\Release/SDL.tlb
+
+
+ $(ProjectDir)/../../include;%(AdditionalIncludeDirectories)
+ %(AdditionalUsingDirectories)
+ DLL_EXPORT;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ false
+ Level3
+ ProgramDatabase
+ true
+ OnlyExplicitInline
+ Use
+ SDL_internal.h
+
+
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ setupapi.lib;winmm.lib;imm32.lib;version.lib;%(AdditionalDependencies)
+ true
+ true
+ Windows
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index cb03064bfe..3cc797bb7d 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -1,1347 +1,1349 @@
-
-
-
-
- {395b3af0-33d0-411b-b153-de1676bf1ef8}
-
-
- {5a3e3167-75be-414f-8947-a5306df372b2}
-
-
- {546d9ed1-988e-49d3-b1a5-e5b3d19de6c1}
-
-
- {a56247ff-5108-4960-ba6a-6814fd1554ec}
-
-
- {8880dfad-2a06-4e84-ab6e-6583641ad2d1}
-
-
- {2b996a7f-f3e9-4300-a97f-2c907bcd89a9}
-
-
- {5713d682-2bc7-4da4-bcf0-262a98f142eb}
-
-
- {5e27e19f-b3f8-4e2d-b323-b00b2040ec86}
-
-
- {a3ab9cff-8495-4a5c-8af6-27e43199a712}
-
-
- {377061e4-3856-4f05-b916-0d3b360df0f6}
-
-
- {226a6643-1c65-4c7f-92aa-861313d974bb}
-
-
- {ef859522-a7fe-4a00-a511-d6a9896adf5b}
-
-
- {01fd2642-4493-4316-b548-fb829f4c9125}
-
-
- {cce7558f-590a-4f0a-ac0d-e579f76e588e}
-
-
- {7a53c9e4-d4bd-40ed-9265-1625df685121}
-
-
- {4c7a051c-ce7c-426c-bf8c-9187827f9052}
-
-
- {97e2f79f-311b-42ea-81b2-e801649fdd93}
-
-
- {baf97c8c-7e90-41e5-bff8-14051b8d3956}
-
-
- {45e50d3a-56c9-4352-b811-0c60c49a2431}
-
-
- {9d86e0ef-d6f6-4db2-bfc5-b3529406fa8d}
-
-
- {b35fa13c-6ed2-4680-8c56-c7d71b76ceab}
-
-
- {61b61b31-9e26-4171-a3bb-b969f1889726}
-
-
- {f63aa216-6ee7-4143-90d3-32be3787f276}
-
-
- {90bee923-89df-417f-a6c3-3e260a7dd54d}
-
-
- {4c8ad943-c2fb-4014-9ca3-041e0ad08426}
-
-
- {3d68ae70-a9ff-46cf-be69-069f0b02aca0}
-
-
- {ebc2fca3-3c26-45e3-815e-3e0581d5e226}
-
-
- {47c445a2-7014-4e15-9660-7c89a27dddcf}
-
-
- {d008487d-6ed0-4251-848b-79a68e3c1459}
-
-
- {c9e8273e-13ae-47dc-bef8-8ad8e64c9a3d}
-
-
- {0b8e136d-56ae-47e7-9981-e863a57ac616}
-
-
- {bf3febd3-9328-43e8-b196-0fd3be8177dd}
-
-
- {1a62dc68-52d2-4c07-9d81-d94dfe1d0d12}
-
-
- {e9f01b22-34b3-4380-ade6-0e96c74e9c90}
-
-
- {f674f22f-7841-4f3a-974e-c36b2d4823fc}
-
-
- {d7ad92de-4e55-4202-9b2b-1bd9a35fe4dc}
-
-
- {8311d79d-9ad5-4369-99fe-b2fb2659d402}
-
-
- {6c4dfb80-fdf9-497c-a6ff-3cd8f22efde9}
-
-
- {4810e35c-33cb-4da2-bfaf-452da20d3c9a}
-
-
- {2cf93f1d-81fd-4bdc-998c-5e2fa43988bc}
-
-
- {5752b7ab-2344-4f38-95ab-b5d3bc150315}
-
-
- {7a0eae3d-f113-4914-b926-6816d1929250}
-
-
- {ee602cbf-96a2-4b0b-92a9-51d38a727411}
-
-
- {a812185b-9060-4a1c-8431-be4f66894626}
-
-
- {31c16cdf-adc4-4950-8293-28ba530f3882}
-
-
- {add61b53-8144-47d6-bd67-3420a87c4905}
-
-
- {e7cdcf36-b462-49c7-98b7-07ea7b3687f4}
-
-
- {82588eef-dcaa-4f69-b2a9-e675940ce54c}
-
-
- {560239c3-8fa1-4d23-a81a-b8408b2f7d3f}
-
-
- {81711059-7575-4ece-9e68-333b63e992c4}
-
-
- {1e44970f-7535-4bfb-b8a5-ea0cea0349e0}
-
-
- {1dd91224-1176-492b-a2cb-e26153394db0}
-
-
- {e3ecfe50-cf22-41d3-8983-2fead5164b47}
-
-
- {5521d22f-1e52-47a6-8c52-06a3b6bdefd7}
-
-
- {4755f3a6-49ac-46d6-86be-21f5c21f2197}
-
-
- {f48c2b17-1bee-4fec-a7c8-24cf619abe08}
-
-
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
-
-
-
- API Headers
-
-
- API Headers
-
-
- API Headers
-
-
- audio
-
-
- audio
-
-
- audio
-
-
- audio
-
-
- core\windows
-
-
- core\windows
-
-
- core\windows
-
-
- core\windows
-
-
- core\windows
-
-
- dynapi
-
-
- dynapi
-
-
- dynapi
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- haptic
-
-
- haptic
-
-
- joystick
-
-
- joystick
-
-
- joystick
-
-
- joystick
-
-
- joystick
-
-
- joystick
-
-
- libm
-
-
- libm
-
-
- hidapi\hidapi
-
-
- locale
-
-
- misc
-
-
- audio\directsound
-
-
- audio\disk
-
-
- audio\dummy
-
-
- audio\wasapi
-
-
- haptic\windows
-
-
- haptic\windows
-
-
- haptic\windows
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\windows
-
-
- joystick\windows
-
-
- joystick\windows
-
-
- joystick\windows
-
-
- joystick\virtual
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video\dummy
-
-
- video\dummy
-
-
- video\dummy
-
-
- video\yuv2rgb
-
-
- video\yuv2rgb
-
-
- video\yuv2rgb
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- timer
-
-
- thread
-
-
- thread
-
-
- thread\windows
-
-
- thread\windows
-
-
- thread\generic
-
-
- sensor
-
-
- sensor
-
-
- sensor\dummy
-
-
- sensor\windows
-
-
- render
-
-
- render
-
-
- render
-
-
- render\direct3d
-
-
- render\direct3d11
-
-
- render\opengl
-
-
- render\opengl
-
-
- render\opengles2
-
-
- render\opengles2
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- power
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
- video\khronos\vulkan
-
-
-
-
-
-
- render\direct3d12
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- audio
-
-
- audio
-
-
- audio
-
-
- audio
-
-
- audio
-
-
- audio
-
-
- atomic
-
-
- atomic
-
-
- core\windows
-
-
- core\windows
-
-
- core\windows
-
-
- core\windows
-
-
- cpuinfo
-
-
- dynapi
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- events
-
-
- file
-
-
- filesystem\windows
-
-
- haptic
-
-
- hidapi
-
-
- joystick
-
-
- joystick
-
-
- joystick
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- libm
-
-
- loadso\windows
-
-
- misc
-
-
- misc\windows
-
-
- locale\windows
-
-
- locale
-
-
- audio\directsound
-
-
- audio\disk
-
-
- audio\dummy
-
-
- audio\wasapi
-
-
- audio\wasapi
-
-
- haptic\windows
-
-
- haptic\windows
-
-
- haptic\windows
-
-
- haptic\dummy
-
-
- joystick\dummy
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\hidapi
-
-
- joystick\windows
-
-
- joystick\windows
-
-
- joystick\windows
-
-
- joystick\windows
-
-
- joystick\windows
-
-
- joystick\virtual
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video
-
-
- video\dummy
-
-
- video\dummy
-
-
- video\dummy
-
-
- video\yuv2rgb
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- video\windows
-
-
- timer
-
-
- timer\windows
-
-
- thread
-
-
- thread\windows
-
-
- thread\windows
-
-
- thread\windows
-
-
- thread\windows
-
-
- thread\windows
-
-
- thread\windows
-
-
- thread\generic
-
-
- stdlib
-
-
- stdlib
-
-
- stdlib
-
-
- stdlib
-
-
- stdlib
-
-
- stdlib
-
-
- stdlib
-
-
- stdlib
-
-
- stdlib
-
-
- sensor
-
-
- sensor\dummy
-
-
- sensor\windows
-
-
- render
-
-
- render
-
-
- render
-
-
- render\direct3d
-
-
- render\direct3d
-
-
- render\direct3d11
-
-
- render\direct3d11
-
-
- render\opengl
-
-
- render\opengl
-
-
- render\opengles2
-
-
- render\opengles2
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- render\software
-
-
- power
-
-
-
- power\windows
-
-
- render\direct3d12
-
-
- render\direct3d12
-
-
- core\windows
-
-
- stdlib
-
-
-
-
-
-
+
+
+
+
+ {395b3af0-33d0-411b-b153-de1676bf1ef8}
+
+
+ {5a3e3167-75be-414f-8947-a5306df372b2}
+
+
+ {546d9ed1-988e-49d3-b1a5-e5b3d19de6c1}
+
+
+ {a56247ff-5108-4960-ba6a-6814fd1554ec}
+
+
+ {8880dfad-2a06-4e84-ab6e-6583641ad2d1}
+
+
+ {2b996a7f-f3e9-4300-a97f-2c907bcd89a9}
+
+
+ {5713d682-2bc7-4da4-bcf0-262a98f142eb}
+
+
+ {5e27e19f-b3f8-4e2d-b323-b00b2040ec86}
+
+
+ {a3ab9cff-8495-4a5c-8af6-27e43199a712}
+
+
+ {377061e4-3856-4f05-b916-0d3b360df0f6}
+
+
+ {226a6643-1c65-4c7f-92aa-861313d974bb}
+
+
+ {ef859522-a7fe-4a00-a511-d6a9896adf5b}
+
+
+ {01fd2642-4493-4316-b548-fb829f4c9125}
+
+
+ {cce7558f-590a-4f0a-ac0d-e579f76e588e}
+
+
+ {7a53c9e4-d4bd-40ed-9265-1625df685121}
+
+
+ {4c7a051c-ce7c-426c-bf8c-9187827f9052}
+
+
+ {97e2f79f-311b-42ea-81b2-e801649fdd93}
+
+
+ {baf97c8c-7e90-41e5-bff8-14051b8d3956}
+
+
+ {45e50d3a-56c9-4352-b811-0c60c49a2431}
+
+
+ {9d86e0ef-d6f6-4db2-bfc5-b3529406fa8d}
+
+
+ {b35fa13c-6ed2-4680-8c56-c7d71b76ceab}
+
+
+ {61b61b31-9e26-4171-a3bb-b969f1889726}
+
+
+ {f63aa216-6ee7-4143-90d3-32be3787f276}
+
+
+ {90bee923-89df-417f-a6c3-3e260a7dd54d}
+
+
+ {4c8ad943-c2fb-4014-9ca3-041e0ad08426}
+
+
+ {3d68ae70-a9ff-46cf-be69-069f0b02aca0}
+
+
+ {ebc2fca3-3c26-45e3-815e-3e0581d5e226}
+
+
+ {47c445a2-7014-4e15-9660-7c89a27dddcf}
+
+
+ {d008487d-6ed0-4251-848b-79a68e3c1459}
+
+
+ {c9e8273e-13ae-47dc-bef8-8ad8e64c9a3d}
+
+
+ {0b8e136d-56ae-47e7-9981-e863a57ac616}
+
+
+ {bf3febd3-9328-43e8-b196-0fd3be8177dd}
+
+
+ {1a62dc68-52d2-4c07-9d81-d94dfe1d0d12}
+
+
+ {e9f01b22-34b3-4380-ade6-0e96c74e9c90}
+
+
+ {f674f22f-7841-4f3a-974e-c36b2d4823fc}
+
+
+ {d7ad92de-4e55-4202-9b2b-1bd9a35fe4dc}
+
+
+ {8311d79d-9ad5-4369-99fe-b2fb2659d402}
+
+
+ {6c4dfb80-fdf9-497c-a6ff-3cd8f22efde9}
+
+
+ {4810e35c-33cb-4da2-bfaf-452da20d3c9a}
+
+
+ {2cf93f1d-81fd-4bdc-998c-5e2fa43988bc}
+
+
+ {5752b7ab-2344-4f38-95ab-b5d3bc150315}
+
+
+ {7a0eae3d-f113-4914-b926-6816d1929250}
+
+
+ {ee602cbf-96a2-4b0b-92a9-51d38a727411}
+
+
+ {a812185b-9060-4a1c-8431-be4f66894626}
+
+
+ {31c16cdf-adc4-4950-8293-28ba530f3882}
+
+
+ {add61b53-8144-47d6-bd67-3420a87c4905}
+
+
+ {e7cdcf36-b462-49c7-98b7-07ea7b3687f4}
+
+
+ {82588eef-dcaa-4f69-b2a9-e675940ce54c}
+
+
+ {560239c3-8fa1-4d23-a81a-b8408b2f7d3f}
+
+
+ {81711059-7575-4ece-9e68-333b63e992c4}
+
+
+ {1e44970f-7535-4bfb-b8a5-ea0cea0349e0}
+
+
+ {1dd91224-1176-492b-a2cb-e26153394db0}
+
+
+ {e3ecfe50-cf22-41d3-8983-2fead5164b47}
+
+
+ {5521d22f-1e52-47a6-8c52-06a3b6bdefd7}
+
+
+ {4755f3a6-49ac-46d6-86be-21f5c21f2197}
+
+
+ {f48c2b17-1bee-4fec-a7c8-24cf619abe08}
+
+
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+
+
+
+ API Headers
+
+
+ API Headers
+
+
+ API Headers
+
+
+ audio
+
+
+ audio
+
+
+ audio
+
+
+ audio
+
+
+ core\windows
+
+
+ core\windows
+
+
+ core\windows
+
+
+ core\windows
+
+
+ core\windows
+
+
+ dynapi
+
+
+ dynapi
+
+
+ dynapi
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ haptic
+
+
+ haptic
+
+
+ joystick
+
+
+ joystick
+
+
+ joystick
+
+
+ joystick
+
+
+ joystick
+
+
+ joystick
+
+
+ libm
+
+
+ libm
+
+
+ hidapi\hidapi
+
+
+ locale
+
+
+ misc
+
+
+ audio\directsound
+
+
+ audio\disk
+
+
+ audio\dummy
+
+
+ audio\wasapi
+
+
+ haptic\windows
+
+
+ haptic\windows
+
+
+ haptic\windows
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\windows
+
+
+ joystick\windows
+
+
+ joystick\windows
+
+
+ joystick\windows
+
+
+ joystick\virtual
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video\dummy
+
+
+ video\dummy
+
+
+ video\dummy
+
+
+ video\yuv2rgb
+
+
+ video\yuv2rgb
+
+
+ video\yuv2rgb
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ timer
+
+
+ thread
+
+
+ thread
+
+
+ thread\windows
+
+
+ thread\windows
+
+
+ thread\generic
+
+
+ sensor
+
+
+ sensor
+
+
+ sensor\dummy
+
+
+ sensor\windows
+
+
+ render
+
+
+ render
+
+
+ render
+
+
+ render\direct3d
+
+
+ render\direct3d11
+
+
+ render\opengl
+
+
+ render\opengl
+
+
+ render\opengles2
+
+
+ render\opengles2
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ power
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+ video\khronos\vulkan
+
+
+
+
+
+
+ render\direct3d12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ audio
+
+
+ audio
+
+
+ audio
+
+
+ audio
+
+
+ audio
+
+
+ audio
+
+
+ atomic
+
+
+ atomic
+
+
+ core\windows
+
+
+ core\windows
+
+
+ core\windows
+
+
+ core\windows
+
+
+ cpuinfo
+
+
+ dynapi
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ events
+
+
+ file
+
+
+ filesystem\windows
+
+
+ haptic
+
+
+ hidapi
+
+
+ joystick
+
+
+ joystick
+
+
+ joystick
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ libm
+
+
+ loadso\windows
+
+
+ misc
+
+
+ misc\windows
+
+
+ locale\windows
+
+
+ locale
+
+
+ audio\directsound
+
+
+ audio\disk
+
+
+ audio\dummy
+
+
+ audio\wasapi
+
+
+ audio\wasapi
+
+
+ haptic\windows
+
+
+ haptic\windows
+
+
+ haptic\windows
+
+
+ haptic\dummy
+
+
+ joystick\dummy
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\hidapi
+
+
+ joystick\windows
+
+
+ joystick\windows
+
+
+ joystick\windows
+
+
+ joystick\windows
+
+
+ joystick\windows
+
+
+ joystick\virtual
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video
+
+
+ video\dummy
+
+
+ video\dummy
+
+
+ video\dummy
+
+
+ video\yuv2rgb
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ video\windows
+
+
+ timer
+
+
+ timer\windows
+
+
+ thread
+
+
+ thread\windows
+
+
+ thread\windows
+
+
+ thread\windows
+
+
+ thread\windows
+
+
+ thread\windows
+
+
+ thread\windows
+
+
+ thread\generic
+
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
+
+ sensor
+
+
+ sensor\dummy
+
+
+ sensor\windows
+
+
+ render
+
+
+ render
+
+
+ render
+
+
+ render\direct3d
+
+
+ render\direct3d
+
+
+ render\direct3d11
+
+
+ render\direct3d11
+
+
+ render\opengl
+
+
+ render\opengl
+
+
+ render\opengles2
+
+
+ render\opengles2
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ render\software
+
+
+ power
+
+
+
+ power\windows
+
+
+ render\direct3d12
+
+
+ render\direct3d12
+
+
+ core\windows
+
+
+ stdlib
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/hidapi/SDL_hidapi_libusb.h b/src/hidapi/SDL_hidapi_libusb.h
index c3dc83d4cf..6a978ce92b 100644
--- a/src/hidapi/SDL_hidapi_libusb.h
+++ b/src/hidapi/SDL_hidapi_libusb.h
@@ -53,185 +53,7 @@ static int SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
#define libusb_get_string_descriptor SDL_libusb_get_string_descriptor
#endif /* __FreeBSD__ */
-#define HIDAPI_THREAD_STATE_DEFINED
-
-/* Barrier implementation because Android/Bionic don't have pthread_barrier.
- This implementation came from Brent Priddy and was posted on
- StackOverflow. It is used with his permission. */
-
-typedef struct _SDL_ThreadBarrier
-{
- SDL_Mutex *mutex;
- SDL_Condition *cond;
- Uint32 count;
- Uint32 trip_count;
-} SDL_ThreadBarrier;
-
-static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count)
-{
- SDL_assert(barrier != NULL);
- SDL_assert(count != 0);
-
- barrier->mutex = SDL_CreateMutex();
- if (barrier->mutex == NULL) {
- return -1; /* Error set by CreateMutex */
- }
- barrier->cond = SDL_CreateCondition();
- if (barrier->cond == NULL) {
- return -1; /* Error set by CreateCond */
- }
-
- barrier->trip_count = count;
- barrier->count = 0;
-
- return 0;
-}
-
-static void SDL_DestroyThreadBarrier(SDL_ThreadBarrier *barrier)
-{
- SDL_DestroyCondition(barrier->cond);
- SDL_DestroyMutex(barrier->mutex);
-}
-
-static int SDL_WaitThreadBarrier(SDL_ThreadBarrier *barrier)
-{
- SDL_LockMutex(barrier->mutex);
- barrier->count += 1;
- if (barrier->count >= barrier->trip_count) {
- barrier->count = 0;
- SDL_BroadcastCondition(barrier->cond);
- SDL_UnlockMutex(barrier->mutex);
- return 1;
- }
- SDL_WaitCondition(barrier->cond, barrier->mutex);
- SDL_UnlockMutex(barrier->mutex);
- return 0;
-}
-
-#include "../thread/SDL_systhread.h"
-
-#define THREAD_STATE_WAIT_TIMED_OUT SDL_MUTEX_TIMEDOUT
-
-typedef struct
-{
- SDL_Thread *thread;
- SDL_Mutex *mutex; /* Protects input_reports */
- SDL_Condition *condition;
- SDL_ThreadBarrier barrier; /* Ensures correct startup sequence */
-
-} hid_device_thread_state;
-
-static void thread_state_init(hid_device_thread_state *state)
-{
- state->mutex = SDL_CreateMutex();
- state->condition = SDL_CreateCondition();
- SDL_CreateThreadBarrier(&state->barrier, 2);
-}
-
-static void thread_state_free(hid_device_thread_state *state)
-{
- SDL_DestroyThreadBarrier(&state->barrier);
- SDL_DestroyCondition(state->condition);
- SDL_DestroyMutex(state->mutex);
-}
-
-static void thread_state_push_cleanup(void (*routine)(void *), void *arg)
-{
- /* There isn't an equivalent in SDL, and it's only useful for threads calling hid_read_timeout() */
-}
-
-static void thread_state_pop_cleanup(int execute)
-{
-}
-
-static void thread_state_lock(hid_device_thread_state *state)
-{
- SDL_LockMutex(state->mutex);
-}
-
-static void thread_state_unlock(hid_device_thread_state *state)
-{
- SDL_UnlockMutex(state->mutex);
-}
-
-static void thread_state_wait_condition(hid_device_thread_state *state)
-{
- SDL_WaitCondition(state->condition, state->mutex);
-}
-
-static int thread_state_wait_condition_timeout(hid_device_thread_state *state, struct timespec *ts)
-{
- Uint64 end_time;
- Sint64 timeout_ns;
- Sint32 timeout_ms;
-
- end_time = ts->tv_sec;
- end_time *= 1000000000L;
- end_time += ts->tv_nsec;
- timeout_ns = (Sint64)(end_time - SDL_GetTicksNS());
- if (timeout_ns <= 0) {
- timeout_ms = 0;
- } else {
- timeout_ms = (Sint32)SDL_NS_TO_MS(timeout_ns);
- }
- return SDL_WaitConditionTimeout(state->condition, state->mutex, timeout_ms);
-}
-
-static void thread_state_signal_condition(hid_device_thread_state *state)
-{
- SDL_SignalCondition(state->condition);
-}
-
-static void thread_state_broadcast_condition(hid_device_thread_state *state)
-{
- SDL_BroadcastCondition(state->condition);
-}
-
-static void thread_state_wait_barrier(hid_device_thread_state *state)
-{
- SDL_WaitThreadBarrier(&state->barrier);
-}
-
-typedef struct
-{
- void *(*func)(void*);
- void *func_arg;
-
-} RunInputThreadParam;
-
-static int RunInputThread(void *param)
-{
- RunInputThreadParam *data = (RunInputThreadParam *)param;
- void *(*func)(void*) = data->func;
- void *func_arg = data->func_arg;
- SDL_free(data);
- func(func_arg);
- return 0;
-}
-
-static void thread_state_create_thread(hid_device_thread_state *state, void *(*func)(void*), void *func_arg)
-{
- RunInputThreadParam *param = (RunInputThreadParam *)malloc(sizeof(*param));
- /* Note that the hidapi code didn't check for thread creation failure.
- * We'll crash if malloc() fails
- */
- param->func = func;
- param->func_arg = func_arg;
- state->thread = SDL_CreateThreadInternal(RunInputThread, "libusb", 0, param);
-}
-
-static void thread_state_join_thread(hid_device_thread_state *state)
-{
- SDL_WaitThread(state->thread, NULL);
-}
-
-static void thread_state_get_current_time(struct timespec *ts)
-{
- Uint64 ns = SDL_GetTicksNS();
-
- ts->tv_sec = ns / 1000000000L;
- ts->tv_nsec = ns % 1000000000L;
-}
+#define HIDAPI_THREAD_MODEL_INCLUDE "hidapi_thread_sdl.h"
#undef HIDAPI_H__
#include "libusb/hid.c"
diff --git a/src/hidapi/libusb/hid.c b/src/hidapi/libusb/hid.c
index 25f7a53961..df33dcce97 100644
--- a/src/hidapi/libusb/hid.c
+++ b/src/hidapi/libusb/hid.c
@@ -52,6 +52,11 @@
#include "hidapi_libusb.h"
+#ifndef HIDAPI_THREAD_MODEL_INCLUDE
+#define HIDAPI_THREAD_MODEL_INCLUDE "hidapi_thread_pthread.h"
+#endif
+#include HIDAPI_THREAD_MODEL_INCLUDE
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -81,150 +86,6 @@ struct input_report {
struct input_report *next;
};
-#ifndef HIDAPI_THREAD_STATE_DEFINED
-
-#include
-
-#if defined(__ANDROID__) && __ANDROID_API__ < __ANDROID_API_N__
-
-/* Barrier implementation because Android/Bionic don't have pthread_barrier.
- This implementation came from Brent Priddy and was posted on
- StackOverflow. It is used with his permission. */
-typedef int pthread_barrierattr_t;
-typedef struct pthread_barrier {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int count;
- int trip_count;
-} pthread_barrier_t;
-
-static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
-{
- if(count == 0) {
- errno = EINVAL;
- return -1;
- }
-
- if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
- return -1;
- }
- if(pthread_cond_init(&barrier->cond, 0) < 0) {
- pthread_mutex_destroy(&barrier->mutex);
- return -1;
- }
- barrier->trip_count = count;
- barrier->count = 0;
-
- return 0;
-}
-
-static int pthread_barrier_destroy(pthread_barrier_t *barrier)
-{
- pthread_cond_destroy(&barrier->cond);
- pthread_mutex_destroy(&barrier->mutex);
- return 0;
-}
-
-static int pthread_barrier_wait(pthread_barrier_t *barrier)
-{
- pthread_mutex_lock(&barrier->mutex);
- ++(barrier->count);
- if(barrier->count >= barrier->trip_count)
- {
- barrier->count = 0;
- pthread_cond_broadcast(&barrier->cond);
- pthread_mutex_unlock(&barrier->mutex);
- return 1;
- }
- else
- {
- pthread_cond_wait(&barrier->cond, &(barrier->mutex));
- pthread_mutex_unlock(&barrier->mutex);
- return 0;
- }
-}
-
-#endif
-
-#define THREAD_STATE_WAIT_TIMED_OUT ETIMEDOUT
-
-typedef struct
-{
- pthread_t thread;
- pthread_mutex_t mutex; /* Protects input_reports */
- pthread_cond_t condition;
- pthread_barrier_t barrier; /* Ensures correct startup sequence */
-
-} hid_device_thread_state;
-
-static void thread_state_init(hid_device_thread_state *state)
-{
- pthread_mutex_init(&state->mutex, NULL);
- pthread_cond_init(&state->condition, NULL);
- pthread_barrier_init(&state->barrier, NULL, 2);
-}
-
-static void thread_state_free(hid_device_thread_state *state)
-{
- pthread_barrier_destroy(&state->barrier);
- pthread_cond_destroy(&state->condition);
- pthread_mutex_destroy(&state->mutex);
-}
-
-#define thread_state_push_cleanup pthread_cleanup_push
-#define thread_state_pop_cleanup pthread_cleanup_pop
-
-static void thread_state_lock(hid_device_thread_state *state)
-{
- pthread_mutex_lock(&state->mutex);
-}
-
-static void thread_state_unlock(hid_device_thread_state *state)
-{
- pthread_mutex_unlock(&state->mutex);
-}
-
-static void thread_state_wait_condition(hid_device_thread_state *state)
-{
- pthread_cond_wait(&state->condition, &state->mutex);
-}
-
-static int thread_state_wait_condition_timeout(hid_device_thread_state *state, struct timespec *ts)
-{
- return pthread_cond_timedwait(&state->condition, &state->mutex, ts);
-}
-
-static void thread_state_signal_condition(hid_device_thread_state *state)
-{
- pthread_cond_signal(&state->condition);
-}
-
-static void thread_state_broadcast_condition(hid_device_thread_state *state)
-{
- pthread_cond_broadcast(&state->condition);
-}
-
-static void thread_state_wait_barrier(hid_device_thread_state *state)
-{
- pthread_barrier_wait(&state->barrier);
-}
-
-static void thread_state_create_thread(hid_device_thread_state *state, void *(*func)(void*), void *func_arg)
-{
- pthread_create(&state->thread, NULL, func, func_arg);
-}
-
-static void thread_state_join_thread(hid_device_thread_state *state)
-{
- pthread_join(state->thread, NULL);
-}
-
-static void thread_state_get_current_time(struct timespec *ts)
-{
- clock_gettime(CLOCK_REALTIME, ts);
-}
-
-#endif /* !HIDAPI_THREAD_STATE_DEFINED */
struct hid_device_ {
/* Handle to the actual device. */
@@ -255,7 +116,7 @@ struct hid_device_ {
int blocking; /* boolean */
/* Read thread objects */
- hid_device_thread_state thread_state;
+ hidapi_thread_state thread_state;
int shutdown_thread;
int transfer_loop_finished;
struct libusb_transfer *transfer;
@@ -289,7 +150,7 @@ static hid_device *new_hid_device(void)
hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device));
dev->blocking = 1;
- thread_state_init(&dev->thread_state);
+ hidapi_thread_state_init(&dev->thread_state);
return dev;
}
@@ -297,7 +158,7 @@ static hid_device *new_hid_device(void)
static void free_hid_device(hid_device *dev)
{
/* Clean up the thread objects */
- thread_state_free(&dev->thread_state);
+ hidapi_thread_state_destroy(&dev->thread_state);
hid_free_enumeration(dev->device_info);
@@ -1229,13 +1090,13 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
rpt->len = transfer->actual_length;
rpt->next = NULL;
- thread_state_lock(&dev->thread_state);
+ hidapi_thread_mutex_lock(&dev->thread_state);
/* Attach the new report object to the end of the list. */
if (dev->input_reports == NULL) {
/* The list is empty. Put it at the root. */
dev->input_reports = rpt;
- thread_state_signal_condition(&dev->thread_state);
+ hidapi_thread_cond_signal(&dev->thread_state);
}
else {
/* Find the end of the list and attach. */
@@ -1254,7 +1115,7 @@ static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer)
return_data(dev, NULL, 0);
}
}
- thread_state_unlock(&dev->thread_state);
+ hidapi_thread_mutex_unlock(&dev->thread_state);
}
else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
dev->shutdown_thread = 1;
@@ -1313,7 +1174,7 @@ static void *read_thread(void *param)
}
/* Notify the main thread that the read thread is up and running. */
- thread_state_wait_barrier(&dev->thread_state);
+ hidapi_thread_barrier_wait(&dev->thread_state);
/* Handle all the events. */
while (!dev->shutdown_thread) {
@@ -1345,15 +1206,15 @@ static void *read_thread(void *param)
make sure that a thread which is about to go to sleep waiting on
the condition actually will go to sleep before the condition is
signaled. */
- thread_state_lock(&dev->thread_state);
- thread_state_broadcast_condition(&dev->thread_state);
- thread_state_unlock(&dev->thread_state);
+ hidapi_thread_mutex_lock(&dev->thread_state);
+ hidapi_thread_cond_broadcast(&dev->thread_state);
+ hidapi_thread_mutex_unlock(&dev->thread_state);
/* The dev->transfer->buffer and dev->transfer objects are cleaned up
in hid_close(). They are not cleaned up here because this thread
could end either due to a disconnect or due to a user
call to hid_close(). In both cases the objects can be safely
- cleaned up after the call to thread_state_join() (in hid_close()), but
+ cleaned up after the call to hidapi_thread_join() (in hid_close()), but
since hid_close() calls libusb_cancel_transfer(), on these objects,
they can not be cleaned up here. */
@@ -1536,10 +1397,10 @@ static int hidapi_initialize_device(hid_device *dev, const struct libusb_interfa
calculate_device_quirks(dev, desc.idVendor, desc.idProduct);
- thread_state_create_thread(&dev->thread_state, read_thread, dev);
+ hidapi_thread_create(&dev->thread_state, read_thread, dev);
/* Wait here for the read thread to be initialized. */
- thread_state_wait_barrier(&dev->thread_state);
+ hidapi_thread_barrier_wait(&dev->thread_state);
return 1;
}
@@ -1764,7 +1625,7 @@ static int return_data(hid_device *dev, unsigned char *data, size_t length)
static void cleanup_mutex(void *param)
{
hid_device *dev = param;
- thread_state_unlock(&dev->thread_state);
+ hidapi_thread_mutex_unlock(&dev->thread_state);
}
@@ -1780,8 +1641,8 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
/* error: variable ‘bytes_read’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] */
int bytes_read; /* = -1; */
- thread_state_lock(&dev->thread_state);
- thread_state_push_cleanup(cleanup_mutex, dev);
+ hidapi_thread_mutex_lock(&dev->thread_state);
+ hidapi_thread_cleanup_push(cleanup_mutex, dev);
bytes_read = -1;
@@ -1802,7 +1663,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
if (milliseconds == -1) {
/* Blocking */
while (!dev->input_reports && !dev->shutdown_thread) {
- thread_state_wait_condition(&dev->thread_state);
+ hidapi_thread_cond_wait(&dev->thread_state);
}
if (dev->input_reports) {
bytes_read = return_data(dev, data, length);
@@ -1812,7 +1673,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
/* Non-blocking, but called with timeout. */
int res;
struct timespec ts;
- thread_state_get_current_time(&ts);
+ hidapi_thread_gettime(&ts);
ts.tv_sec += milliseconds / 1000;
ts.tv_nsec += (milliseconds % 1000) * 1000000;
if (ts.tv_nsec >= 1000000000L) {
@@ -1821,7 +1682,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
}
while (!dev->input_reports && !dev->shutdown_thread) {
- res = thread_state_wait_condition_timeout(&dev->thread_state, &ts);
+ res = hidapi_thread_cond_timedwait(&dev->thread_state, &ts);
if (res == 0) {
if (dev->input_reports) {
bytes_read = return_data(dev, data, length);
@@ -1832,7 +1693,7 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
or the read thread was shutdown. Run the
loop again (ie: don't break). */
}
- else if (res == THREAD_STATE_WAIT_TIMED_OUT) {
+ else if (res == HIDAPI_THREAD_TIMED_OUT) {
/* Timed out. */
bytes_read = 0;
break;
@@ -1850,8 +1711,8 @@ int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t
}
ret:
- thread_state_unlock(&dev->thread_state);
- thread_state_pop_cleanup(0);
+ hidapi_thread_mutex_unlock(&dev->thread_state);
+ hidapi_thread_cleanup_pop(0);
return bytes_read;
}
@@ -1969,7 +1830,7 @@ void HID_API_EXPORT hid_close(hid_device *dev)
libusb_cancel_transfer(dev->transfer);
/* Wait for read_thread() to end. */
- thread_state_join_thread(&dev->thread_state);
+ hidapi_thread_join(&dev->thread_state);
/* Clean up the Transfer objects allocated in read_thread(). */
free(dev->transfer->buffer);
@@ -1992,11 +1853,11 @@ void HID_API_EXPORT hid_close(hid_device *dev)
libusb_close(dev->device_handle);
/* Clear out the queue of received reports. */
- thread_state_lock(&dev->thread_state);
+ hidapi_thread_mutex_lock(&dev->thread_state);
while (dev->input_reports) {
return_data(dev, NULL, 0);
}
- thread_state_unlock(&dev->thread_state);
+ hidapi_thread_mutex_unlock(&dev->thread_state);
free_hid_device(dev);
}
diff --git a/src/hidapi/libusb/hidapi_thread_pthread.h b/src/hidapi/libusb/hidapi_thread_pthread.h
new file mode 100644
index 0000000000..720ee676d2
--- /dev/null
+++ b/src/hidapi/libusb/hidapi_thread_pthread.h
@@ -0,0 +1,163 @@
+/*******************************************************
+ HIDAPI - Multi-Platform library for
+ communication with HID devices.
+
+ Alan Ott
+ Signal 11 Software
+
+ libusb/hidapi Team
+
+ Copyright 2022, All Rights Reserved.
+
+ At the discretion of the user of this library,
+ this software may be licensed under the terms of the
+ GNU General Public License v3, a BSD-Style license, or the
+ original HIDAPI license as outlined in the LICENSE.txt,
+ LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
+ files located at the root of the source distribution.
+ These files may also be found in the public source
+ code repository located at:
+ https://github.com/libusb/hidapi .
+********************************************************/
+
+#include
+
+#if defined(__ANDROID__) && __ANDROID_API__ < __ANDROID_API_N__
+
+/* Barrier implementation because Android/Bionic don't have pthread_barrier.
+ This implementation came from Brent Priddy and was posted on
+ StackOverflow. It is used with his permission. */
+typedef int pthread_barrierattr_t;
+typedef struct pthread_barrier {
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int count;
+ int trip_count;
+} pthread_barrier_t;
+
+static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
+{
+ if(count == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
+ return -1;
+ }
+ if(pthread_cond_init(&barrier->cond, 0) < 0) {
+ pthread_mutex_destroy(&barrier->mutex);
+ return -1;
+ }
+ barrier->trip_count = count;
+ barrier->count = 0;
+
+ return 0;
+}
+
+static int pthread_barrier_destroy(pthread_barrier_t *barrier)
+{
+ pthread_cond_destroy(&barrier->cond);
+ pthread_mutex_destroy(&barrier->mutex);
+ return 0;
+}
+
+static int pthread_barrier_wait(pthread_barrier_t *barrier)
+{
+ pthread_mutex_lock(&barrier->mutex);
+ ++(barrier->count);
+ if(barrier->count >= barrier->trip_count)
+ {
+ barrier->count = 0;
+ pthread_cond_broadcast(&barrier->cond);
+ pthread_mutex_unlock(&barrier->mutex);
+ return 1;
+ }
+ else
+ {
+ pthread_cond_wait(&barrier->cond, &(barrier->mutex));
+ pthread_mutex_unlock(&barrier->mutex);
+ return 0;
+ }
+}
+
+#endif
+
+#define HIDAPI_THREAD_TIMED_OUT ETIMEDOUT
+
+typedef struct
+{
+ pthread_t thread;
+ pthread_mutex_t mutex; /* Protects input_reports */
+ pthread_cond_t condition;
+ pthread_barrier_t barrier; /* Ensures correct startup sequence */
+
+} hidapi_thread_state;
+
+static void hidapi_thread_state_init(hidapi_thread_state *state)
+{
+ pthread_mutex_init(&state->mutex, NULL);
+ pthread_cond_init(&state->condition, NULL);
+ pthread_barrier_init(&state->barrier, NULL, 2);
+}
+
+static void hidapi_thread_state_destroy(hidapi_thread_state *state)
+{
+ pthread_barrier_destroy(&state->barrier);
+ pthread_cond_destroy(&state->condition);
+ pthread_mutex_destroy(&state->mutex);
+}
+
+#define hidapi_thread_cleanup_push pthread_cleanup_push
+#define hidapi_thread_cleanup_pop pthread_cleanup_pop
+
+static void hidapi_thread_mutex_lock(hidapi_thread_state *state)
+{
+ pthread_mutex_lock(&state->mutex);
+}
+
+static void hidapi_thread_mutex_unlock(hidapi_thread_state *state)
+{
+ pthread_mutex_unlock(&state->mutex);
+}
+
+static void hidapi_thread_cond_wait(hidapi_thread_state *state)
+{
+ pthread_cond_wait(&state->condition, &state->mutex);
+}
+
+static int hidapi_thread_cond_timedwait(hidapi_thread_state *state, struct timespec *ts)
+{
+ return pthread_cond_timedwait(&state->condition, &state->mutex, ts);
+}
+
+static void hidapi_thread_cond_signal(hidapi_thread_state *state)
+{
+ pthread_cond_signal(&state->condition);
+}
+
+static void hidapi_thread_cond_broadcast(hidapi_thread_state *state)
+{
+ pthread_cond_broadcast(&state->condition);
+}
+
+static void hidapi_thread_barrier_wait(hidapi_thread_state *state)
+{
+ pthread_barrier_wait(&state->barrier);
+}
+
+static void hidapi_thread_create(hidapi_thread_state *state, void *(*func)(void*), void *func_arg)
+{
+ pthread_create(&state->thread, NULL, func, func_arg);
+}
+
+static void hidapi_thread_join(hidapi_thread_state *state)
+{
+ pthread_join(state->thread, NULL);
+}
+
+static void hidapi_thread_gettime(struct timespec *ts)
+{
+ clock_gettime(CLOCK_REALTIME, ts);
+}
+
diff --git a/src/hidapi/libusb/hidapi_thread_sdl.h b/src/hidapi/libusb/hidapi_thread_sdl.h
new file mode 100644
index 0000000000..4c9d04e802
--- /dev/null
+++ b/src/hidapi/libusb/hidapi_thread_sdl.h
@@ -0,0 +1,198 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2023 Sam Lantinga
+
+ 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.
+*/
+
+/* Barrier implementation because Android/Bionic don't have pthread_barrier.
+ This implementation came from Brent Priddy and was posted on
+ StackOverflow. It is used with his permission. */
+
+typedef struct _SDL_ThreadBarrier
+{
+ SDL_Mutex *mutex;
+ SDL_Condition *cond;
+ Uint32 count;
+ Uint32 trip_count;
+} SDL_ThreadBarrier;
+
+static int SDL_CreateThreadBarrier(SDL_ThreadBarrier *barrier, Uint32 count)
+{
+ SDL_assert(barrier != NULL);
+ SDL_assert(count != 0);
+
+ barrier->mutex = SDL_CreateMutex();
+ if (barrier->mutex == NULL) {
+ return -1; /* Error set by CreateMutex */
+ }
+ barrier->cond = SDL_CreateCondition();
+ if (barrier->cond == NULL) {
+ return -1; /* Error set by CreateCond */
+ }
+
+ barrier->trip_count = count;
+ barrier->count = 0;
+
+ return 0;
+}
+
+static void SDL_DestroyThreadBarrier(SDL_ThreadBarrier *barrier)
+{
+ SDL_DestroyCondition(barrier->cond);
+ SDL_DestroyMutex(barrier->mutex);
+}
+
+static int SDL_WaitThreadBarrier(SDL_ThreadBarrier *barrier)
+{
+ SDL_LockMutex(barrier->mutex);
+ barrier->count += 1;
+ if (barrier->count >= barrier->trip_count) {
+ barrier->count = 0;
+ SDL_BroadcastCondition(barrier->cond);
+ SDL_UnlockMutex(barrier->mutex);
+ return 1;
+ }
+ SDL_WaitCondition(barrier->cond, barrier->mutex);
+ SDL_UnlockMutex(barrier->mutex);
+ return 0;
+}
+
+#include "../../thread/SDL_systhread.h"
+
+#define HIDAPI_THREAD_TIMED_OUT SDL_MUTEX_TIMEDOUT
+
+typedef struct
+{
+ SDL_Thread *thread;
+ SDL_Mutex *mutex; /* Protects input_reports */
+ SDL_Condition *condition;
+ SDL_ThreadBarrier barrier; /* Ensures correct startup sequence */
+
+} hidapi_thread_state;
+
+static void hidapi_thread_state_init(hidapi_thread_state *state)
+{
+ state->mutex = SDL_CreateMutex();
+ state->condition = SDL_CreateCondition();
+ SDL_CreateThreadBarrier(&state->barrier, 2);
+}
+
+static void hidapi_thread_state_destroy(hidapi_thread_state *state)
+{
+ SDL_DestroyThreadBarrier(&state->barrier);
+ SDL_DestroyCondition(state->condition);
+ SDL_DestroyMutex(state->mutex);
+}
+
+static void hidapi_thread_cleanup_push(void (*routine)(void *), void *arg)
+{
+ /* There isn't an equivalent in SDL, and it's only useful for threads calling hid_read_timeout() */
+}
+
+static void hidapi_thread_cleanup_pop(int execute)
+{
+}
+
+static void hidapi_thread_mutex_lock(hidapi_thread_state *state)
+{
+ SDL_LockMutex(state->mutex);
+}
+
+static void hidapi_thread_mutex_unlock(hidapi_thread_state *state)
+{
+ SDL_UnlockMutex(state->mutex);
+}
+
+static void hidapi_thread_cond_wait(hidapi_thread_state *state)
+{
+ SDL_WaitCondition(state->condition, state->mutex);
+}
+
+static int hidapi_thread_cond_timedwait(hidapi_thread_state *state, struct timespec *ts)
+{
+ Uint64 end_time;
+ Sint64 timeout_ns;
+ Sint32 timeout_ms;
+
+ end_time = ts->tv_sec;
+ end_time *= 1000000000L;
+ end_time += ts->tv_nsec;
+ timeout_ns = (Sint64)(end_time - SDL_GetTicksNS());
+ if (timeout_ns <= 0) {
+ timeout_ms = 0;
+ } else {
+ timeout_ms = (Sint32)SDL_NS_TO_MS(timeout_ns);
+ }
+ return SDL_WaitConditionTimeout(state->condition, state->mutex, timeout_ms);
+}
+
+static void hidapi_thread_cond_signal(hidapi_thread_state *state)
+{
+ SDL_SignalCondition(state->condition);
+}
+
+static void hidapi_thread_cond_broadcast(hidapi_thread_state *state)
+{
+ SDL_BroadcastCondition(state->condition);
+}
+
+static void hidapi_thread_barrier_wait(hidapi_thread_state *state)
+{
+ SDL_WaitThreadBarrier(&state->barrier);
+}
+
+typedef struct
+{
+ void *(*func)(void*);
+ void *func_arg;
+
+} RunInputThreadParam;
+
+static int RunInputThread(void *param)
+{
+ RunInputThreadParam *data = (RunInputThreadParam *)param;
+ void *(*func)(void*) = data->func;
+ void *func_arg = data->func_arg;
+ SDL_free(data);
+ func(func_arg);
+ return 0;
+}
+
+static void hidapi_thread_create(hidapi_thread_state *state, void *(*func)(void*), void *func_arg)
+{
+ RunInputThreadParam *param = (RunInputThreadParam *)malloc(sizeof(*param));
+ /* Note that the hidapi code didn't check for thread creation failure.
+ * We'll crash if malloc() fails
+ */
+ param->func = func;
+ param->func_arg = func_arg;
+ state->thread = SDL_CreateThreadInternal(RunInputThread, "libusb", 0, param);
+}
+
+static void hidapi_thread_join(hidapi_thread_state *state)
+{
+ SDL_WaitThread(state->thread, NULL);
+}
+
+static void hidapi_thread_gettime(struct timespec *ts)
+{
+ Uint64 ns = SDL_GetTicksNS();
+
+ ts->tv_sec = ns / 1000000000L;
+ ts->tv_nsec = ns % 1000000000L;
+}