From: Ivo Ivanov logos128@gmail.com
--- dlls/dinput/tests/force_feedback.c | 11 +++++--- dlls/windows.gaming.input/force_feedback.c | 29 ++++++++++++++++++++-- 2 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/dlls/dinput/tests/force_feedback.c b/dlls/dinput/tests/force_feedback.c index a2ccdb08350..122d11dbcdd 100644 --- a/dlls/dinput/tests/force_feedback.c +++ b/dlls/dinput/tests/force_feedback.c @@ -5650,7 +5650,7 @@ static void test_windows_gaming_input(void) IVectorView_ForceFeedbackMotor *motors_view; IConditionForceEffect *condition_effect; ConditionForceEffectKind condition_kind; - ForceFeedbackEffectAxes supported_axes; + ForceFeedbackEffectAxes supported_axes, axes; IActivationFactory *activation_factory; IPeriodicForceEffect *periodic_effect; IConstantForceEffect *constant_effect; @@ -5768,12 +5768,15 @@ static void test_windows_gaming_input(void) ok( hr == S_OK, "get_IsEnabled returned %#lx\n", hr ); ok( enabled == TRUE, "got enabled %u\n", enabled );
+ /* SupportedAxes always returns ForceFeedbackEffectAxes_X on Windows, */ + /* no matter which axis is available for FFB in the Set Effects report, */ + /* or whether a X axis is declared at all. */ + supported_axes = 0xdeadbeef; hr = IForceFeedbackMotor_get_SupportedAxes( motor, &supported_axes ); - todo_wine ok( hr == S_OK, "get_SupportedAxes returned %#lx\n", hr ); - todo_wine - ok( supported_axes == ForceFeedbackEffectAxes_X, "got axes %#x\n", supported_axes ); + axes = ForceFeedbackEffectAxes_X | ForceFeedbackEffectAxes_Y | ForceFeedbackEffectAxes_Z; + ok( supported_axes == axes || broken( supported_axes == ForceFeedbackEffectAxes_X ), "got axes %#x\n", supported_axes );
set_hid_expect( file, &expect_pause, sizeof(expect_pause) ); hr = IForceFeedbackMotor_PauseAllEffects( motor ); diff --git a/dlls/windows.gaming.input/force_feedback.c b/dlls/windows.gaming.input/force_feedback.c index 198268eac24..76800ef5c1f 100644 --- a/dlls/windows.gaming.input/force_feedback.c +++ b/dlls/windows.gaming.input/force_feedback.c @@ -532,10 +532,35 @@ static HRESULT WINAPI motor_get_IsEnabled( IForceFeedbackMotor *iface, BOOLEAN * return hr; }
+static BOOL CALLBACK check_ffb_axes( const DIDEVICEOBJECTINSTANCEW *obj, void *args ) +{ + ForceFeedbackEffectAxes *value = args; + + if (obj->dwType & DIDFT_FFACTUATOR) + { + if (IsEqualIID(&obj->guidType, &GUID_XAxis)) + *value |= ForceFeedbackEffectAxes_X; + else if (IsEqualIID(&obj->guidType, &GUID_YAxis)) + *value |= ForceFeedbackEffectAxes_Y; + else if (IsEqualIID(&obj->guidType, &GUID_ZAxis)) + *value |= ForceFeedbackEffectAxes_Z; + } + return (*value == (ForceFeedbackEffectAxes_X | ForceFeedbackEffectAxes_Y | ForceFeedbackEffectAxes_Z)) ? + DIENUM_STOP : DIENUM_CONTINUE; +} + static HRESULT WINAPI motor_get_SupportedAxes( IForceFeedbackMotor *iface, enum ForceFeedbackEffectAxes *value ) { - FIXME( "iface %p, value %p stub!\n", iface, value ); - return E_NOTIMPL; + struct motor *impl = impl_from_IForceFeedbackMotor( iface ); + HRESULT hr; + + TRACE( "iface %p, value %p.\n", iface, value ); + + *value = ForceFeedbackEffectAxes_None; + if (FAILED(hr = IDirectInputDevice8_EnumObjects( impl->device, check_ffb_axes, value, DIDFT_AXIS ))) + *value = ForceFeedbackEffectAxes_None; + + return hr; }
static HRESULT WINAPI motor_load_effect_async( IUnknown *invoker, IUnknown *param, PROPVARIANT *result )