From b36679b90e5df70a2b63b3eacbbd013f2afd0395 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 1 Jun 2023 08:27:56 -0700 Subject: [PATCH] Updated with upstream suggestions in https://github.com/libusb/hidapi/pull/582 --- VisualC/SDL/SDL.vcxproj | 1317 +++++----- VisualC/SDL/SDL.vcxproj.filters | 2696 +++++++++++---------- src/hidapi/SDL_hidapi_libusb.h | 180 +- src/hidapi/libusb/hid.c | 199 +- src/hidapi/libusb/hidapi_thread_pthread.h | 163 ++ src/hidapi/libusb/hidapi_thread_sdl.h | 198 ++ 6 files changed, 2400 insertions(+), 2353 deletions(-) create mode 100644 src/hidapi/libusb/hidapi_thread_pthread.h create mode 100644 src/hidapi/libusb/hidapi_thread_sdl.h 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; +}