Signed-off-by: Rémi Bernon rbernon@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); }
[