Browse Source

First pass at Windows sensor implementation

Sam Lantinga 5 years ago
parent
commit
3180ba81af

+ 7 - 0
CMakeLists.txt

@@ -1417,6 +1417,13 @@ elseif(WINDOWS)
     set(HAVE_SDL_THREADS TRUE)
     set(HAVE_SDL_THREADS TRUE)
   endif()
   endif()
 
 
+  if(SDL_SENSOR)
+    set(SDL_SENSOR_WINDOWS 1)
+    set(HAVE_SDL_SENSORS TRUE)
+    file(GLOB WINDOWS_SENSOR_SOURCES ${SDL2_SOURCE_DIR}/src/sensor/windows/*.c)
+    set(SOURCE_FILES ${SOURCE_FILES} ${WINDOWS_SENSOR_SOURCES})
+  endif()
+
   if(SDL_POWER)
   if(SDL_POWER)
     set(SDL_POWER_WINDOWS 1)
     set(SDL_POWER_WINDOWS 1)
     set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/power/windows/SDL_syspower.c)
     set(SOURCE_FILES ${SOURCE_FILES} ${SDL2_SOURCE_DIR}/src/power/windows/SDL_syspower.c)

+ 11 - 0
VisualC/SDL.sln

@@ -52,6 +52,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testvulkan", "tests\testvul
 EndProject
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testyuv", "tests\testyuv\testyuv.vcxproj", "{40FB7794-D3C3-4CFE-BCF4-A80C97635682}"
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testyuv", "tests\testyuv\testyuv.vcxproj", "{40FB7794-D3C3-4CFE-BCF4-A80C97635682}"
 EndProject
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsensor", "tests\testsensor\testsensor.vcxproj", "{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}"
+EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
 		Debug|Win32 = Debug|Win32
@@ -260,6 +262,14 @@ Global
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|Win32.Build.0 = Release|Win32
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|Win32.Build.0 = Release|Win32
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|x64.ActiveCfg = Release|x64
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|x64.ActiveCfg = Release|x64
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|x64.Build.0 = Release|x64
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682}.Release|x64.Build.0 = Release|x64
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|Win32.Build.0 = Debug|Win32
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|x64.ActiveCfg = Debug|x64
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Debug|x64.Build.0 = Debug|x64
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|Win32.ActiveCfg = Release|Win32
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|Win32.Build.0 = Release|Win32
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|x64.ActiveCfg = Release|x64
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}.Release|x64.Build.0 = Release|x64
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE
@@ -287,5 +297,6 @@ Global
 		{55812185-D13C-4022-9C81-32E0F4A08306} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
 		{55812185-D13C-4022-9C81-32E0F4A08306} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
 		{0D604DFD-AAB6-442C-9368-F91A344146AB} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
 		{0D604DFD-AAB6-442C-9368-F91A344146AB} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
 		{40FB7794-D3C3-4CFE-BCF4-A80C97635682} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
+		{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4} = {D69D5741-611F-4E14-8541-1FEE94F50B5A}
 	EndGlobalSection
 	EndGlobalSection
 EndGlobal
 EndGlobal

+ 2 - 0
VisualC/SDL/SDL.vcxproj

@@ -352,6 +352,7 @@
     <ClInclude Include="..\..\src\sensor\dummy\SDL_dummysensor.h" />
     <ClInclude Include="..\..\src\sensor\dummy\SDL_dummysensor.h" />
     <ClInclude Include="..\..\src\sensor\SDL_sensor_c.h" />
     <ClInclude Include="..\..\src\sensor\SDL_sensor_c.h" />
     <ClInclude Include="..\..\src\sensor\SDL_syssensor.h" />
     <ClInclude Include="..\..\src\sensor\SDL_syssensor.h" />
+    <ClInclude Include="..\..\src\sensor\windows\SDL_windowssensor.h" />
     <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
     <ClInclude Include="..\..\src\thread\SDL_systhread.h" />
     <ClInclude Include="..\..\src\thread\SDL_thread_c.h" />
     <ClInclude Include="..\..\src\thread\SDL_thread_c.h" />
     <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h" />
     <ClInclude Include="..\..\src\thread\windows\SDL_systhread_c.h" />
@@ -487,6 +488,7 @@
     <ClCompile Include="..\..\src\SDL_log.c" />
     <ClCompile Include="..\..\src\SDL_log.c" />
     <ClCompile Include="..\..\src\sensor\dummy\SDL_dummysensor.c" />
     <ClCompile Include="..\..\src\sensor\dummy\SDL_dummysensor.c" />
     <ClCompile Include="..\..\src\sensor\SDL_sensor.c" />
     <ClCompile Include="..\..\src\sensor\SDL_sensor.c" />
+    <ClCompile Include="..\..\src\sensor\windows\SDL_windowssensor.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_getenv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_iconv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_iconv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_malloc.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_malloc.c" />

+ 2 - 0
VisualC/SDL/SDL.vcxproj.filters

@@ -326,6 +326,7 @@
     <ClInclude Include="..\..\src\joystick\windows\SDL_rawinputjoystick_c.h" />
     <ClInclude Include="..\..\src\joystick\windows\SDL_rawinputjoystick_c.h" />
     <ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
     <ClInclude Include="..\..\src\hidapi\hidapi\hidapi.h" />
     <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
     <ClInclude Include="..\..\src\joystick\SDL_gamecontrollerdb.h" />
+    <ClInclude Include="..\..\src\sensor\windows\SDL_windowssensor.h" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c" />
     <ClCompile Include="..\..\src\atomic\SDL_atomic.c" />
@@ -482,6 +483,7 @@
     <ClCompile Include="..\..\src\video\windows\SDL_windowswindow.c" />
     <ClCompile Include="..\..\src\video\windows\SDL_windowswindow.c" />
     <ClCompile Include="..\..\src\video\yuv2rgb\yuv_rgb.c" />
     <ClCompile Include="..\..\src\video\yuv2rgb\yuv_rgb.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
     <ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
+    <ClCompile Include="..\..\src\sensor\windows\SDL_windowssensor.c" />
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\main\windows\version.rc" />
     <ResourceCompile Include="..\..\src\main\windows\version.rc" />

+ 199 - 0
VisualC/tests/testsensor/testsensor.vcxproj

@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C4E04D18-EF76-4B42-B4C2-16A1BACDC0A4}</ProjectGuid>
+    <RootNamespace>testsensor</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC70.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\$(Configuration)\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>.\Debug/testsensor.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(SolutionDir)/../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Debug/testsensor.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>$(SolutionDir)/../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>.\Release/testsensor.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(SolutionDir)/../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>.\Release/testsensor.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <AdditionalIncludeDirectories>$(SolutionDir)/../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalUsingDirectories>%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <WarningLevel>Level3</WarningLevel>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x0409</Culture>
+    </ResourceCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\SDL\SDL.vcxproj">
+      <Project>{81ce8daf-ebb2-4761-8e45-b71abcca8c68}</Project>
+      <Private>false</Private>
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </ProjectReference>
+    <ProjectReference Include="..\..\SDLmain\SDLmain.vcxproj">
+      <Project>{da956fd3-e142-46f2-9dd5-c78bebb56b7a}</Project>
+      <Private>false</Private>
+      <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
+      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\test\testsensor.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 10 - 0
configure

@@ -25018,6 +25018,15 @@ $as_echo "#define SDL_HAPTIC_DINPUT 1" >>confdefs.h
                 have_haptic=yes
                 have_haptic=yes
             fi
             fi
         fi
         fi
+        # Set up files for the sensor library
+        if test x$enable_sensor = xyes; then
+
+$as_echo "#define SDL_SENSOR_WINDOWS 1" >>confdefs.h
+
+            SOURCES="$SOURCES $srcdir/src/sensor/windows/*.c"
+            have_sensor=yes
+        fi
+        # Set up files for the power library
         if test x$enable_power = xyes; then
         if test x$enable_power = xyes; then
 
 
 $as_echo "#define SDL_POWER_WINDOWS 1" >>confdefs.h
 $as_echo "#define SDL_POWER_WINDOWS 1" >>confdefs.h
@@ -25025,6 +25034,7 @@ $as_echo "#define SDL_POWER_WINDOWS 1" >>confdefs.h
             SOURCES="$SOURCES $srcdir/src/power/windows/SDL_syspower.c"
             SOURCES="$SOURCES $srcdir/src/power/windows/SDL_syspower.c"
             have_power=yes
             have_power=yes
         fi
         fi
+        # Set up files for the filesystem library
         if test x$enable_filesystem = xyes; then
         if test x$enable_filesystem = xyes; then
 
 
 $as_echo "#define SDL_FILESYSTEM_WINDOWS 1" >>confdefs.h
 $as_echo "#define SDL_FILESYSTEM_WINDOWS 1" >>confdefs.h

+ 8 - 0
configure.ac

@@ -3739,11 +3739,19 @@ AS_HELP_STRING([--enable-render-d3d], [enable the Direct3D render driver [[defau
                 have_haptic=yes
                 have_haptic=yes
             fi
             fi
         fi
         fi
+        # Set up files for the sensor library
+        if test x$enable_sensor = xyes; then
+            AC_DEFINE(SDL_SENSOR_WINDOWS, 1, [ ])
+            SOURCES="$SOURCES $srcdir/src/sensor/windows/*.c"
+            have_sensor=yes
+        fi
+        # Set up files for the power library
         if test x$enable_power = xyes; then
         if test x$enable_power = xyes; then
             AC_DEFINE(SDL_POWER_WINDOWS, 1, [ ])
             AC_DEFINE(SDL_POWER_WINDOWS, 1, [ ])
             SOURCES="$SOURCES $srcdir/src/power/windows/SDL_syspower.c"
             SOURCES="$SOURCES $srcdir/src/power/windows/SDL_syspower.c"
             have_power=yes
             have_power=yes
         fi
         fi
+        # Set up files for the filesystem library
         if test x$enable_filesystem = xyes; then
         if test x$enable_filesystem = xyes; then
             AC_DEFINE(SDL_FILESYSTEM_WINDOWS, 1, [ ])
             AC_DEFINE(SDL_FILESYSTEM_WINDOWS, 1, [ ])
             SOURCES="$SOURCES $srcdir/src/filesystem/windows/SDL_sysfilesystem.c"
             SOURCES="$SOURCES $srcdir/src/filesystem/windows/SDL_sysfilesystem.c"

+ 2 - 2
include/SDL_config_windows.h

@@ -201,8 +201,8 @@ typedef unsigned int uintptr_t;
 #define SDL_HAPTIC_DINPUT   1
 #define SDL_HAPTIC_DINPUT   1
 #define SDL_HAPTIC_XINPUT   1
 #define SDL_HAPTIC_XINPUT   1
 
 
-/* Enable the dummy sensor driver */
-#define SDL_SENSOR_DUMMY  1
+/* Enable the sensor driver */
+#define SDL_SENSOR_WINDOWS  1
 
 
 /* Enable various shared object loading systems */
 /* Enable various shared object loading systems */
 #define SDL_LOADSO_WINDOWS  1
 #define SDL_LOADSO_WINDOWS  1

+ 13 - 0
include/SDL_sensor.h

@@ -121,6 +121,19 @@ typedef enum
 
 
 /* Function prototypes */
 /* Function prototypes */
 
 
+/**
+ * Locking for multi-threaded access to the sensor API
+ *
+ * If you are using the sensor API or handling events from multiple threads
+ * you should use these locking functions to protect access to the sensors.
+ *
+ * In particular, you are guaranteed that the sensor list won't change, so
+ * the API functions that take a sensor index will be valid, and sensor
+ * events will not be delivered.
+ */
+extern DECLSPEC void SDLCALL SDL_LockSensors(void);
+extern DECLSPEC void SDLCALL SDL_UnlockSensors(void);
+
 /**
 /**
  *  \brief Count the number of sensors attached to the system right now
  *  \brief Count the number of sensors attached to the system right now
  */
  */

+ 2 - 0
src/dynapi/SDL_dynapi_overrides.h

@@ -757,3 +757,5 @@
 #define SDL_JoystickSetVirtualButton SDL_JoystickSetVirtualButton_REAL
 #define SDL_JoystickSetVirtualButton SDL_JoystickSetVirtualButton_REAL
 #define SDL_JoystickSetVirtualHat SDL_JoystickSetVirtualHat_REAL
 #define SDL_JoystickSetVirtualHat SDL_JoystickSetVirtualHat_REAL
 #define SDL_GetErrorMsg SDL_GetErrorMsg_REAL
 #define SDL_GetErrorMsg SDL_GetErrorMsg_REAL
+#define SDL_LockSensors SDL_LockSensors_REAL
+#define SDL_UnlockSensors SDL_UnlockSensors_REAL

+ 2 - 0
src/dynapi/SDL_dynapi_procs.h

@@ -816,3 +816,5 @@ SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualAxis,(SDL_Joystick *a, int b, Sint16 c
 SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualButton,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualButton,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualHat,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_JoystickSetVirtualHat,(SDL_Joystick *a, int b, Uint8 c),(a,b,c),return)
 SDL_DYNAPI_PROC(char*,SDL_GetErrorMsg,(char *a, int b),(a,b),return)
 SDL_DYNAPI_PROC(char*,SDL_GetErrorMsg,(char *a, int b),(a,b),return)
+SDL_DYNAPI_PROC(void,SDL_LockSensors,(void),(),)
+SDL_DYNAPI_PROC(void,SDL_UnlockSensors,(void),(),)

+ 5 - 2
src/sensor/SDL_sensor.c

@@ -39,6 +39,9 @@ static SDL_SensorDriver *SDL_sensor_drivers[] = {
 #ifdef SDL_SENSOR_COREMOTION
 #ifdef SDL_SENSOR_COREMOTION
     &SDL_COREMOTION_SensorDriver,
     &SDL_COREMOTION_SensorDriver,
 #endif
 #endif
+#ifdef SDL_SENSOR_WINDOWS
+	&SDL_WINDOWS_SensorDriver,
+#endif
 #if defined(SDL_SENSOR_DUMMY) || defined(SDL_SENSOR_DISABLED)
 #if defined(SDL_SENSOR_DUMMY) || defined(SDL_SENSOR_DISABLED)
     &SDL_DUMMY_SensorDriver
     &SDL_DUMMY_SensorDriver
 #endif
 #endif
@@ -48,7 +51,7 @@ static SDL_bool SDL_updating_sensor = SDL_FALSE;
 static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
 static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
 static SDL_atomic_t SDL_next_sensor_instance_id;
 static SDL_atomic_t SDL_next_sensor_instance_id;
 
 
-static void
+void
 SDL_LockSensors(void)
 SDL_LockSensors(void)
 {
 {
     if (SDL_sensor_lock) {
     if (SDL_sensor_lock) {
@@ -56,7 +59,7 @@ SDL_LockSensors(void)
     }
     }
 }
 }
 
 
-static void
+void
 SDL_UnlockSensors(void)
 SDL_UnlockSensors(void)
 {
 {
     if (SDL_sensor_lock) {
     if (SDL_sensor_lock) {

+ 2 - 1
src/sensor/SDL_syssensor.h

@@ -98,8 +98,9 @@ typedef struct _SDL_SensorDriver
 /* The available sensor drivers */
 /* The available sensor drivers */
 extern SDL_SensorDriver SDL_ANDROID_SensorDriver;
 extern SDL_SensorDriver SDL_ANDROID_SensorDriver;
 extern SDL_SensorDriver SDL_COREMOTION_SensorDriver;
 extern SDL_SensorDriver SDL_COREMOTION_SensorDriver;
+extern SDL_SensorDriver SDL_WINDOWS_SensorDriver;
 extern SDL_SensorDriver SDL_DUMMY_SensorDriver;
 extern SDL_SensorDriver SDL_DUMMY_SensorDriver;
 
 
-#endif /* SDL_syssensor_c_h_ */
+#endif /* SDL_syssensor_h_ */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 1 - 0
src/sensor/android/SDL_androidsensor.c

@@ -18,6 +18,7 @@
      misrepresented as being the original software.
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
+#include "../../SDL_internal.h"
 
 
 #include "SDL_config.h"
 #include "SDL_config.h"
 
 

+ 1 - 0
src/sensor/dummy/SDL_dummysensor.c

@@ -18,6 +18,7 @@
      misrepresented as being the original software.
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
   3. This notice may not be removed or altered from any source distribution.
 */
 */
+#include "../../SDL_internal.h"
 
 
 #include "SDL_config.h"
 #include "SDL_config.h"
 
 

+ 480 - 0
src/sensor/windows/SDL_windowssensor.c

@@ -0,0 +1,480 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#include "SDL_config.h"
+
+#if defined(SDL_SENSOR_WINDOWS)
+
+#include "SDL_error.h"
+#include "SDL_mutex.h"
+#include "SDL_sensor.h"
+#include "SDL_windowssensor.h"
+#include "../SDL_syssensor.h"
+#include "../../core/windows/SDL_windows.h"
+
+#define COBJMACROS
+#include <InitGuid.h>
+#include <SensorsApi.h>
+#include <Sensors.h>
+
+DEFINE_GUID(CLSID_SensorManager, 0x77A1C827, 0xFCD2, 0x4689, 0x89, 0x15, 0x9D, 0x61, 0x3C, 0xC5, 0xFA, 0x3E);
+DEFINE_GUID(IID_SensorManager, 0xBD77DB67, 0x45A8, 0x42DC, 0x8D, 0x00, 0x6D, 0xCF, 0x15, 0xF8, 0x37, 0x7A);
+DEFINE_GUID(IID_SensorManagerEvents, 0x9B3B0B86, 0x266A, 0x4AAD, 0xB2, 0x1F, 0xFD, 0xE5, 0x50, 0x10, 0x01, 0xB7);
+DEFINE_GUID(IID_SensorEvents, 0x5D8DCC91, 0x4641, 0x47E7, 0xB7, 0xC3, 0xB7, 0x4F, 0x48, 0xA6, 0xC3, 0x91);
+
+DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 10); //[VT_R8]
+DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 11); //[VT_R8]
+DEFINE_PROPERTYKEY(SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, 0X3F8A69A2, 0X7C5, 0X4E48, 0XA9, 0X65, 0XCD, 0X79, 0X7A, 0XAB, 0X56, 0XD5, 12); //[VT_R8]
+
+typedef struct
+{
+	SDL_SensorID id;
+	ISensor *sensor;
+	SENSOR_ID sensor_id;
+	char *name;
+	SDL_SensorType type;
+	SDL_Sensor *sensor_opened;
+
+} SDL_Windows_Sensor;
+
+static SDL_bool SDL_windowscoinit;
+static ISensorManager *SDL_sensor_manager;
+static int SDL_num_sensors;
+static SDL_Windows_Sensor *SDL_sensors;
+
+static int ConnectSensor(ISensor *sensor);
+static int DisconnectSensor(ISensor *sensor);
+
+static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_QueryInterface(ISensorManagerEvents * This, REFIID riid, void **ppvObject)
+{
+	if (!ppvObject) {
+		return E_INVALIDARG;
+	}
+
+	*ppvObject = NULL;
+	if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_SensorManagerEvents)) {
+		*ppvObject = This;
+		return S_OK;
+	}
+	return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_AddRef(ISensorManagerEvents * This)
+{
+	return 1;
+}
+
+static ULONG STDMETHODCALLTYPE ISensorManagerEventsVtbl_Release(ISensorManagerEvents * This)
+{
+	return 1;
+}
+
+static HRESULT STDMETHODCALLTYPE ISensorManagerEventsVtbl_OnSensorEnter(ISensorManagerEvents * This, ISensor *pSensor, SensorState state)
+{
+	ConnectSensor(pSensor);
+	return S_OK;
+}
+
+static ISensorManagerEventsVtbl sensor_manager_events_vtbl = {
+	ISensorManagerEventsVtbl_QueryInterface,
+	ISensorManagerEventsVtbl_AddRef,
+	ISensorManagerEventsVtbl_Release,
+	ISensorManagerEventsVtbl_OnSensorEnter
+};
+static ISensorManagerEvents sensor_manager_events = {
+	&sensor_manager_events_vtbl
+};
+
+static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_QueryInterface(ISensorEvents * This, REFIID riid, void **ppvObject)
+{
+	if (!ppvObject) {
+		return E_INVALIDARG;
+	}
+
+	*ppvObject = NULL;
+	if (WIN_IsEqualIID(riid, &IID_IUnknown) || WIN_IsEqualIID(riid, &IID_SensorEvents)) {
+		*ppvObject = This;
+		return S_OK;
+	}
+	return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_AddRef(ISensorEvents * This)
+{
+	return 1;
+}
+
+static ULONG STDMETHODCALLTYPE ISensorEventsVtbl_Release(ISensorEvents * This)
+{
+	return 1;
+}
+
+static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnStateChanged(ISensorEvents * This, ISensor *pSensor, SensorState state)
+{
+#ifdef DEBUG_SENSORS
+	int i;
+
+	SDL_LockSensors();
+	for (i = 0; i < SDL_num_sensors; ++i) {
+		if (pSensor == SDL_sensors[i].sensor) {
+			SDL_Log("Sensor %s state changed to %d\n", SDL_sensors[i].name, state);
+		}
+	}
+	SDL_UnlockSensors();
+#endif
+	return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnDataUpdated(ISensorEvents * This, ISensor *pSensor, ISensorDataReport *pNewData)
+{
+	int i;
+
+	SDL_LockSensors();
+	for (i = 0; i < SDL_num_sensors; ++i) {
+		if (pSensor == SDL_sensors[i].sensor) {
+			if (SDL_sensors[i].sensor_opened) {
+				HRESULT hrX, hrY, hrZ;
+				PROPVARIANT valueX, valueY, valueZ;
+
+#ifdef DEBUG_SENSORS
+				SDL_Log("Sensor %s data updated\n", SDL_sensors[i].name);
+#endif
+				switch (SDL_sensors[i].type) {
+				case SDL_SENSOR_ACCEL:
+					hrX = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_X_G, &valueX);
+					hrY = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Y_G, &valueY);
+					hrZ = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ACCELERATION_Z_G, &valueZ);
+					if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) &&
+						valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) {
+						float values[3];
+
+						values[0] = (float)valueX.dblVal;
+						values[1] = (float)valueY.dblVal;
+						values[2] = (float)valueZ.dblVal;
+						SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, values, 3);
+					}
+					break;
+				case SDL_SENSOR_GYRO:
+					hrX = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_X_DEGREES_PER_SECOND, &valueX);
+					hrY = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Y_DEGREES_PER_SECOND, &valueY);
+					hrZ = ISensorDataReport_GetSensorValue(pNewData, &SENSOR_DATA_TYPE_ANGULAR_VELOCITY_Z_DEGREES_PER_SECOND, &valueZ);
+					if (SUCCEEDED(hrX) && SUCCEEDED(hrY) && SUCCEEDED(hrZ) &&
+						valueX.vt == VT_R8 && valueY.vt == VT_R8 && valueZ.vt == VT_R8) {
+						float values[3];
+
+						values[0] = (float)(valueX.dblVal * (M_PI / 180.0));
+						values[1] = (float)(valueY.dblVal * (M_PI / 180.0));
+						values[2] = (float)(valueZ.dblVal * (M_PI / 180.0));
+						SDL_PrivateSensorUpdate(SDL_sensors[i].sensor_opened, values, 3);
+					}
+					break;
+				default:
+					/* FIXME: Need to know how to interpret the data for this sensor */
+					break;
+				}
+			}
+			break;
+		}
+	}
+	SDL_UnlockSensors();
+
+	return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnEvent(ISensorEvents * This, ISensor *pSensor, REFGUID eventID, IPortableDeviceValues *pEventData)
+{
+#ifdef DEBUG_SENSORS
+	int i;
+
+	SDL_LockSensors();
+	for (i = 0; i < SDL_num_sensors; ++i) {
+		if (pSensor == SDL_sensors[i].sensor) {
+			SDL_Log("Sensor %s event occurred\n", SDL_sensors[i].name);
+		}
+	}
+	SDL_UnlockSensors();
+#endif
+	return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE ISensorEventsVtbl_OnLeave(ISensorEvents * This, REFSENSOR_ID ID)
+{
+	int i;
+
+	SDL_LockSensors();
+	for (i = 0; i < SDL_num_sensors; ++i) {
+		if (WIN_IsEqualIID(ID, &SDL_sensors[i].sensor_id)) {
+#ifdef DEBUG_SENSORS
+			SDL_Log("Sensor %s disconnected\n", SDL_sensors[i].name);
+#endif
+			DisconnectSensor(SDL_sensors[i].sensor);
+		}
+	}
+	SDL_UnlockSensors();
+
+	return S_OK;
+}
+
+static ISensorEventsVtbl sensor_events_vtbl = {
+	ISensorEventsVtbl_QueryInterface,
+	ISensorEventsVtbl_AddRef,
+	ISensorEventsVtbl_Release,
+	ISensorEventsVtbl_OnStateChanged,
+	ISensorEventsVtbl_OnDataUpdated,
+	ISensorEventsVtbl_OnEvent,
+	ISensorEventsVtbl_OnLeave
+};
+static ISensorEvents sensor_events = {
+	&sensor_events_vtbl
+};
+
+static int ConnectSensor(ISensor *sensor)
+{
+	SDL_Windows_Sensor *new_sensor, *new_sensors;
+	HRESULT hr;
+	SENSOR_ID sensor_id;
+	SENSOR_TYPE_ID type_id;
+	SDL_SensorType type;
+	BSTR bstr_name = NULL;
+	char *name;
+
+	hr = ISensor_GetID(sensor, &sensor_id);
+	if (FAILED(hr)) {
+		return SDL_SetError("Couldn't get sensor ID: 0x%.4x", hr);
+	}
+
+	hr = ISensor_GetType(sensor, &type_id);
+	if (FAILED(hr)) {
+		return SDL_SetError("Couldn't get sensor type: 0x%.4x", hr);
+	}
+
+	if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_ACCELEROMETER_3D)) {
+		type = SDL_SENSOR_ACCEL;
+	} else if (WIN_IsEqualIID(&type_id, &SENSOR_TYPE_GYROMETER_3D)) {
+		type = SDL_SENSOR_GYRO;
+	} else {
+		return SDL_SetError("Unknown sensor type");
+	}
+
+	hr = ISensor_GetFriendlyName(sensor, &bstr_name);
+	if (SUCCEEDED(hr) && bstr_name) {
+		name = WIN_StringToUTF8(bstr_name);
+	} else {
+		name = SDL_strdup("Unknown Sensor");
+	}
+	if (!name) {
+		return SDL_OutOfMemory();
+	}
+
+	SDL_LockSensors();
+	new_sensors = (SDL_Windows_Sensor *)SDL_realloc(SDL_sensors, (SDL_num_sensors + 1) * sizeof(SDL_Windows_Sensor));
+	if (new_sensors == NULL) {
+		SDL_UnlockSensors();
+		return SDL_OutOfMemory();
+	}
+
+	ISensor_AddRef(sensor);
+	ISensor_SetEventSink(sensor, &sensor_events);
+
+	SDL_sensors = new_sensors;
+	new_sensor = &SDL_sensors[SDL_num_sensors];
+	++SDL_num_sensors;
+
+	new_sensor->id = SDL_GetNextSensorInstanceID();
+	new_sensor->sensor = sensor;
+	new_sensor->type = type;
+	new_sensor->name = name;
+
+	SDL_UnlockSensors();
+
+	return 0;
+}
+
+static int DisconnectSensor(ISensor *sensor)
+{
+	SDL_Windows_Sensor *old_sensor;
+	int i;
+
+	SDL_LockSensors();
+	for (i = 0; i < SDL_num_sensors; ++i) {
+		old_sensor = &SDL_sensors[i];
+		if (sensor == old_sensor->sensor) {
+			ISensor_SetEventSink(sensor, NULL);
+			ISensor_Release(sensor);
+			SDL_free(old_sensor->name);
+			--SDL_num_sensors;
+			if (i < SDL_num_sensors) {
+				SDL_memmove(&SDL_sensors[i], &SDL_sensors[i + 1], (SDL_num_sensors - i) * sizeof(SDL_sensors[i]));
+			}
+			break;
+		}
+	}
+	SDL_UnlockSensors();
+
+	return 0;
+}
+
+static int
+SDL_WINDOWS_SensorInit(void)
+{
+	HRESULT hr;
+	ISensorCollection *sensor_collection = NULL;
+
+	while (!IsDebuggerPresent()) Sleep(100);
+
+	if (WIN_CoInitialize() == S_OK) {
+		SDL_windowscoinit = SDL_TRUE;
+	}
+
+	hr = CoCreateInstance(&CLSID_SensorManager, NULL, CLSCTX_INPROC_SERVER, &IID_SensorManager, &SDL_sensor_manager);
+	if (FAILED(hr)) {
+		return SDL_SetError("Couldn't create the sensor manager: 0x%.4x", hr);
+	}
+
+	hr = ISensorManager_SetEventSink(SDL_sensor_manager, &sensor_manager_events);
+	if (FAILED(hr)) {
+		ISensorManager_Release(SDL_sensor_manager);
+		return SDL_SetError("Couldn't set the sensor manager event sink: 0x%.4x", hr);
+	}
+
+	hr = ISensorManager_GetSensorsByCategory(SDL_sensor_manager, &SENSOR_CATEGORY_ALL, &sensor_collection);
+	if (SUCCEEDED(hr)) {
+		ULONG i, count;
+
+		hr = ISensorCollection_GetCount(sensor_collection, &count);
+		if (SUCCEEDED(hr)) {
+			for (i = 0; i < count; ++i) {
+				ISensor *sensor;
+
+				hr = ISensorCollection_GetAt(sensor_collection, i, &sensor);
+				if (SUCCEEDED(hr)) {
+					SensorState state;
+
+					hr = ISensor_GetState(sensor, &state);
+					if (SUCCEEDED(hr)) {
+						ISensorManagerEventsVtbl_OnSensorEnter(&sensor_manager_events, sensor, state);
+					}
+					ISensorManager_Release(sensor);
+				}
+			}
+		}
+		ISensorCollection_Release(sensor_collection);
+	}
+    return 0;
+}
+
+static int
+SDL_WINDOWS_SensorGetCount(void)
+{
+    return SDL_num_sensors;
+}
+
+static void
+SDL_WINDOWS_SensorDetect(void)
+{
+}
+
+static const char *
+SDL_WINDOWS_SensorGetDeviceName(int device_index)
+{
+    return SDL_sensors[device_index].name;
+}
+
+static SDL_SensorType
+SDL_WINDOWS_SensorGetDeviceType(int device_index)
+{
+	return SDL_sensors[device_index].type;
+}
+
+static int
+SDL_WINDOWS_SensorGetDeviceNonPortableType(int device_index)
+{
+    return -1;
+}
+
+static SDL_SensorID
+SDL_WINDOWS_SensorGetDeviceInstanceID(int device_index)
+{
+    return SDL_sensors[device_index].id;
+}
+
+static int
+SDL_WINDOWS_SensorOpen(SDL_Sensor *sensor, int device_index)
+{
+	SDL_sensors[device_index].sensor_opened = sensor;
+    return 0;
+}
+
+static void
+SDL_WINDOWS_SensorUpdate(SDL_Sensor *sensor)
+{
+}
+
+static void
+SDL_WINDOWS_SensorClose(SDL_Sensor *sensor)
+{
+	int i;
+
+	for (i = 0; i < SDL_num_sensors; ++i) {
+		if (sensor == SDL_sensors[i].sensor_opened) {
+			SDL_sensors[i].sensor_opened = NULL;
+			break;
+		}
+	}
+}
+
+static void
+SDL_WINDOWS_SensorQuit(void)
+{
+	while (SDL_num_sensors > 0) {
+		DisconnectSensor(SDL_sensors[0].sensor);
+	}
+
+	if (SDL_sensor_manager) {
+		ISensorManager_SetEventSink(SDL_sensor_manager, NULL);
+		ISensorManager_Release(SDL_sensor_manager);
+		SDL_sensor_manager = NULL;
+	}
+
+	if (SDL_windowscoinit) {
+		WIN_CoUninitialize();
+	}
+}
+
+SDL_SensorDriver SDL_WINDOWS_SensorDriver =
+{
+    SDL_WINDOWS_SensorInit,
+    SDL_WINDOWS_SensorGetCount,
+    SDL_WINDOWS_SensorDetect,
+    SDL_WINDOWS_SensorGetDeviceName,
+    SDL_WINDOWS_SensorGetDeviceType,
+    SDL_WINDOWS_SensorGetDeviceNonPortableType,
+    SDL_WINDOWS_SensorGetDeviceInstanceID,
+    SDL_WINDOWS_SensorOpen,
+    SDL_WINDOWS_SensorUpdate,
+    SDL_WINDOWS_SensorClose,
+    SDL_WINDOWS_SensorQuit,
+};
+
+#endif /* SDL_SENSOR_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 23 - 0
src/sensor/windows/SDL_windowssensor.h

@@ -0,0 +1,23 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2020 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+/* vi: set ts=4 sw=4 expandtab: */