[PATCH 3/5] windows.gaming.input: Check the controller type and create Gamepad instances.

Rémi Bernon rbernon at codeweavers.com
Tue Mar 8 03:55:24 CST 2022


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/windows.gaming.input/manager.c    | 24 ++++++++++++++++++++++++
 dlls/windows.gaming.input/provider.c   | 21 +++++++++++++++++++++
 dlls/windows.gaming.input/provider.idl |  8 ++++++++
 3 files changed, 53 insertions(+)

diff --git a/dlls/windows.gaming.input/manager.c b/dlls/windows.gaming.input/manager.c
index 33f2a3c3df9..f5b5654a4c6 100644
--- a/dlls/windows.gaming.input/manager.c
+++ b/dlls/windows.gaming.input/manager.c
@@ -437,12 +437,27 @@ static HRESULT controller_create( ICustomGameControllerFactory *factory, IGameCo
 
 void manager_on_provider_created( IGameControllerProvider *provider )
 {
+    IWineGameControllerProvider *wine_provider;
     struct list *entry, *next, *list;
     struct controller *controller;
+    WineGameControllerType type;
     HRESULT hr;
 
     TRACE( "provider %p\n", provider );
 
+    if (FAILED(IGameControllerProvider_QueryInterface( provider, &IID_IWineGameControllerProvider,
+                                                       (void **)&wine_provider )))
+    {
+        FIXME( "IWineGameControllerProvider isn't implemented by provider %p\n", provider );
+        return;
+    }
+    if (FAILED(hr = IWineGameControllerProvider_get_Type( wine_provider, &type )))
+    {
+        WARN( "Failed to get controller type, hr %#lx\n", hr );
+        type = WineGameControllerType_Joystick;
+    }
+    IWineGameControllerProvider_Release( wine_provider );
+
     EnterCriticalSection( &manager_cs );
 
     if (list_empty( &controller_list )) list = &controller_list;
@@ -451,6 +466,15 @@ void manager_on_provider_created( IGameControllerProvider *provider )
     if (SUCCEEDED(controller_create( controller_factory, provider, &controller )))
         list_add_tail( &controller_list, &controller->entry );
 
+    switch (type)
+    {
+    case WineGameControllerType_Joystick: break;
+    case WineGameControllerType_Gamepad:
+        if (SUCCEEDED(controller_create( gamepad_factory, provider, &controller )))
+            list_add_tail( &controller_list, &controller->entry );
+        break;
+    }
+
     LIST_FOR_EACH_SAFE( entry, next, list )
     {
         controller = LIST_ENTRY( entry, struct controller, entry );
diff --git a/dlls/windows.gaming.input/provider.c b/dlls/windows.gaming.input/provider.c
index 9ab9682f221..b4817b42c46 100644
--- a/dlls/windows.gaming.input/provider.c
+++ b/dlls/windows.gaming.input/provider.c
@@ -125,6 +125,25 @@ static HRESULT WINAPI wine_provider_GetTrustLevel( IWineGameControllerProvider *
     return E_NOTIMPL;
 }
 
+static HRESULT WINAPI wine_provider_get_Type( IWineGameControllerProvider *iface, WineGameControllerType *value )
+{
+    struct provider *impl = impl_from_IWineGameControllerProvider( iface );
+    DIDEVICEINSTANCEW instance = {.dwSize = sizeof(DIDEVICEINSTANCEW)};
+    HRESULT hr;
+
+    TRACE( "iface %p, value %p.\n", iface, value );
+
+    if (FAILED(hr = IDirectInputDevice8_GetDeviceInfo( impl->dinput_device, &instance ))) return hr;
+
+    switch (GET_DIDEVICE_TYPE( instance.dwDevType ))
+    {
+    case DI8DEVTYPE_GAMEPAD: *value = WineGameControllerType_Gamepad; break;
+    default: *value = WineGameControllerType_Joystick; break;
+    }
+
+    return S_OK;
+}
+
 static const struct IWineGameControllerProviderVtbl wine_provider_vtbl =
 {
     wine_provider_QueryInterface,
@@ -134,6 +153,8 @@ static const struct IWineGameControllerProviderVtbl wine_provider_vtbl =
     wine_provider_GetIids,
     wine_provider_GetRuntimeClassName,
     wine_provider_GetTrustLevel,
+    /* IWineGameControllerProvider methods */
+    wine_provider_get_Type,
 };
 
 DEFINE_IINSPECTABLE( game_provider, IGameControllerProvider, struct provider, IWineGameControllerProvider_iface )
diff --git a/dlls/windows.gaming.input/provider.idl b/dlls/windows.gaming.input/provider.idl
index d6c4f1d16ec..6af700bb12d 100644
--- a/dlls/windows.gaming.input/provider.idl
+++ b/dlls/windows.gaming.input/provider.idl
@@ -31,9 +31,16 @@ import "windows.gaming.input.idl";
 import "windows.gaming.input.custom.idl";
 
 namespace Windows.Gaming.Input.Custom {
+    typedef enum WineGameControllerType WineGameControllerType;
     interface IWineGameControllerProvider;
     runtimeclass WineGameControllerProvider;
 
+    enum WineGameControllerType
+    {
+        Joystick = 0,
+        Gamepad = 1,
+    };
+
     [
         uuid(06e58977-7684-4dc5-bad1-cda52a4aa06d)
     ]
@@ -51,6 +58,7 @@ namespace Windows.Gaming.Input.Custom {
     interface IWineGameControllerProvider : IInspectable
         requires Windows.Gaming.Input.Custom.IGameControllerProvider
     {
+        [propget] HRESULT Type([out, retval] WineGameControllerType *value);
     }
 
     [
-- 
2.35.1




More information about the wine-devel mailing list