Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.gaming.input/controller.c | 27 +++++++---- dlls/windows.gaming.input/provider.c | 64 ++++++++++++++++++++++++-- dlls/windows.gaming.input/provider.idl | 3 ++ 3 files changed, 80 insertions(+), 14 deletions(-)
diff --git a/dlls/windows.gaming.input/controller.c b/dlls/windows.gaming.input/controller.c index ab0183c7d4f..83e4e167ec9 100644 --- a/dlls/windows.gaming.input/controller.c +++ b/dlls/windows.gaming.input/controller.c @@ -65,6 +65,7 @@ struct controller LONG ref;
IGameControllerProvider *provider; + IWineGameControllerProvider *wine_provider; };
static inline struct controller *impl_from_IGameControllerImpl( IGameControllerImpl *iface ) @@ -120,6 +121,8 @@ static ULONG WINAPI controller_Release( IGameControllerImpl *iface )
if (!ref) { + if (impl->wine_provider) + IWineGameControllerProvider_Release( impl->wine_provider ); IGameControllerProvider_Release( impl->provider ); free( impl ); } @@ -157,6 +160,10 @@ static HRESULT WINAPI controller_Initialize( IGameControllerImpl *iface, IGameCo impl->IGameController_outer = outer; IGameControllerProvider_AddRef( (impl->provider = provider) );
+ hr = IGameControllerProvider_QueryInterface( provider, &IID_IWineGameControllerProvider, + (void **)&impl->wine_provider ); + if (FAILED(hr)) return hr; + EnterCriticalSection( &controller_cs ); if (SUCCEEDED(hr = init_controllers())) hr = IVector_RawGameController_Append( controllers, &impl->IRawGameController_iface ); @@ -210,14 +217,14 @@ DEFINE_IINSPECTABLE_OUTER( raw_controller, IRawGameController, struct controller
static HRESULT WINAPI raw_controller_get_AxisCount( IRawGameController *iface, INT32 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct controller *impl = impl_from_IRawGameController( iface ); + return IWineGameControllerProvider_get_AxisCount( impl->wine_provider, value ); }
static HRESULT WINAPI raw_controller_get_ButtonCount( IRawGameController *iface, INT32 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct controller *impl = impl_from_IRawGameController( iface ); + return IWineGameControllerProvider_get_ButtonCount( impl->wine_provider, value ); }
static HRESULT WINAPI raw_controller_get_ForceFeedbackMotors( IRawGameController *iface, IVectorView_ForceFeedbackMotor **value ) @@ -228,20 +235,20 @@ static HRESULT WINAPI raw_controller_get_ForceFeedbackMotors( IRawGameController
static HRESULT WINAPI raw_controller_get_HardwareProductId( IRawGameController *iface, UINT16 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct controller *impl = impl_from_IRawGameController( iface ); + return IGameControllerProvider_get_HardwareProductId( impl->provider, value ); }
static HRESULT WINAPI raw_controller_get_HardwareVendorId( IRawGameController *iface, UINT16 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct controller *impl = impl_from_IRawGameController( iface ); + return IGameControllerProvider_get_HardwareVendorId( impl->provider, value ); }
static HRESULT WINAPI raw_controller_get_SwitchCount( IRawGameController *iface, INT32 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct controller *impl = impl_from_IRawGameController( iface ); + return IWineGameControllerProvider_get_SwitchCount( impl->wine_provider, value ); }
static HRESULT WINAPI raw_controller_GetButtonLabel( IRawGameController *iface, INT32 index, diff --git a/dlls/windows.gaming.input/provider.c b/dlls/windows.gaming.input/provider.c index 703516ccfe2..7883ec6af68 100644 --- a/dlls/windows.gaming.input/provider.c +++ b/dlls/windows.gaming.input/provider.c @@ -143,6 +143,45 @@ static HRESULT WINAPI wine_provider_get_Type( IWineGameControllerProvider *iface return S_OK; }
+static HRESULT WINAPI wine_provider_get_AxisCount( IWineGameControllerProvider *iface, INT32 *value ) +{ + struct provider *impl = impl_from_IWineGameControllerProvider( iface ); + DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; + HRESULT hr; + + TRACE( "iface %p, value %p.\n", iface, value ); + + if (SUCCEEDED(hr = IDirectInputDevice8_GetCapabilities( impl->dinput_device, &caps ))) + *value = caps.dwAxes; + return hr; +} + +static HRESULT WINAPI wine_provider_get_ButtonCount( IWineGameControllerProvider *iface, INT32 *value ) +{ + struct provider *impl = impl_from_IWineGameControllerProvider( iface ); + DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; + HRESULT hr; + + TRACE( "iface %p, value %p.\n", iface, value ); + + if (SUCCEEDED(hr = IDirectInputDevice8_GetCapabilities( impl->dinput_device, &caps ))) + *value = caps.dwButtons; + return hr; +} + +static HRESULT WINAPI wine_provider_get_SwitchCount( IWineGameControllerProvider *iface, INT32 *value ) +{ + struct provider *impl = impl_from_IWineGameControllerProvider( iface ); + DIDEVCAPS caps = {.dwSize = sizeof(DIDEVCAPS)}; + HRESULT hr; + + TRACE( "iface %p, value %p.\n", iface, value ); + + if (SUCCEEDED(hr = IDirectInputDevice8_GetCapabilities( impl->dinput_device, &caps ))) + *value = caps.dwPOVs; + return hr; +} + static const struct IWineGameControllerProviderVtbl wine_provider_vtbl = { wine_provider_QueryInterface, @@ -154,6 +193,9 @@ static const struct IWineGameControllerProviderVtbl wine_provider_vtbl = wine_provider_GetTrustLevel, /* IWineGameControllerProvider methods */ wine_provider_get_Type, + wine_provider_get_AxisCount, + wine_provider_get_ButtonCount, + wine_provider_get_SwitchCount, };
DEFINE_IINSPECTABLE( game_provider, IGameControllerProvider, struct provider, IWineGameControllerProvider_iface ) @@ -166,14 +208,28 @@ static HRESULT WINAPI game_provider_get_FirmwareVersionInfo( IGameControllerProv
static HRESULT WINAPI game_provider_get_HardwareProductId( IGameControllerProvider *iface, UINT16 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + DIPROPDWORD vid_pid = {.diph = {.dwHeaderSize = sizeof(DIPROPHEADER), .dwSize = sizeof(DIPROPDWORD)}}; + struct provider *impl = impl_from_IGameControllerProvider( iface ); + HRESULT hr; + + TRACE( "iface %p, value %p.\n", iface, value ); + + if (SUCCEEDED(hr = IDirectInputDevice8_GetProperty( impl->dinput_device, DIPROP_VIDPID, &vid_pid.diph ))) + *value = HIWORD(vid_pid.dwData); + return hr; }
static HRESULT WINAPI game_provider_get_HardwareVendorId( IGameControllerProvider *iface, UINT16 *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + DIPROPDWORD vid_pid = {.diph = {.dwHeaderSize = sizeof(DIPROPHEADER), .dwSize = sizeof(DIPROPDWORD)}}; + struct provider *impl = impl_from_IGameControllerProvider( iface ); + HRESULT hr; + + TRACE( "iface %p, value %p.\n", iface, value ); + + if (SUCCEEDED(hr = IDirectInputDevice8_GetProperty( impl->dinput_device, DIPROP_VIDPID, &vid_pid.diph ))) + *value = LOWORD(vid_pid.dwData); + return hr; }
static HRESULT WINAPI game_provider_get_HardwareVersionInfo( IGameControllerProvider *iface, GameControllerVersionInfo *value ) diff --git a/dlls/windows.gaming.input/provider.idl b/dlls/windows.gaming.input/provider.idl index 6af700bb12d..19d5643f767 100644 --- a/dlls/windows.gaming.input/provider.idl +++ b/dlls/windows.gaming.input/provider.idl @@ -59,6 +59,9 @@ namespace Windows.Gaming.Input.Custom { requires Windows.Gaming.Input.Custom.IGameControllerProvider { [propget] HRESULT Type([out, retval] WineGameControllerType *value); + [propget] HRESULT AxisCount([out, retval] INT32 *value); + [propget] HRESULT ButtonCount([out, retval] INT32 *value); + [propget] HRESULT SwitchCount([out, retval] INT32 *value); }
[