[PATCH 7/7] dinput: Improve GetForceFeedbackState / GetEffectStatus stubs.

Rémi Bernon rbernon at codeweavers.com
Wed Dec 1 05:44:58 CST 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52062
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/dinput/device.c         | 12 ++++++++++--
 dlls/dinput/device_private.h |  1 +
 dlls/dinput/joystick_hid.c   | 22 ++++++++++++++++++++--
 dlls/dinput8/tests/hid.c     | 18 ------------------
 4 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 19fbe724b56..cca7f796fdc 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -1763,6 +1763,7 @@ static HRESULT WINAPI dinput_device_GetEffectInfo( IDirectInputDevice8W *iface,
 static HRESULT WINAPI dinput_device_GetForceFeedbackState( IDirectInputDevice8W *iface, DWORD *out )
 {
     struct dinput_device *impl = impl_from_IDirectInputDevice8W( iface );
+    HRESULT hr = DI_OK;
 
     FIXME( "iface %p, out %p semi-stub!\n", iface, out );
 
@@ -1770,9 +1771,15 @@ static HRESULT WINAPI dinput_device_GetForceFeedbackState( IDirectInputDevice8W
     *out = 0;
 
     if (!(impl->caps.dwFlags & DIDC_FORCEFEEDBACK)) return DIERR_UNSUPPORTED;
-    if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE)) return DIERR_NOTEXCLUSIVEACQUIRED;
 
-    return DI_OK;
+    EnterCriticalSection( &impl->crit );
+    if (!impl->acquired || !(impl->dwCoopLevel & DISCL_EXCLUSIVE))
+        hr = DIERR_NOTEXCLUSIVEACQUIRED;
+    else
+        *out = impl->force_feedback_state;
+    LeaveCriticalSection( &impl->crit );
+
+    return hr;
 }
 
 static HRESULT WINAPI dinput_device_SendForceFeedbackCommand( IDirectInputDevice8W *iface, DWORD command )
@@ -2146,6 +2153,7 @@ HRESULT dinput_device_alloc( SIZE_T size, const struct dinput_device_vtbl *vtbl,
     This->caps.dwFlags = DIDC_ATTACHED | DIDC_EMULATED;
     This->device_format = format;
     This->device_gain = 10000;
+    This->force_feedback_state = DIGFFS_STOPPED | DIGFFS_EMPTY;
     InitializeCriticalSection( &This->crit );
     This->dinput = dinput;
     IDirectInput_AddRef( &dinput->IDirectInput7A_iface );
diff --git a/dlls/dinput/device_private.h b/dlls/dinput/device_private.h
index e2cae26aea2..00a80b16590 100644
--- a/dlls/dinput/device_private.h
+++ b/dlls/dinput/device_private.h
@@ -112,6 +112,7 @@ struct dinput_device
 
     BOOL autocenter;
     LONG device_gain;
+    DWORD force_feedback_state;
     struct object_properties *object_properties;
 };
 
diff --git a/dlls/dinput/joystick_hid.c b/dlls/dinput/joystick_hid.c
index a1e8e30bc29..99fe98d95ce 100644
--- a/dlls/dinput/joystick_hid.c
+++ b/dlls/dinput/joystick_hid.c
@@ -221,6 +221,7 @@ struct hid_joystick_effect
     DIEFFECT params;
     DWORD modified;
     DWORD flags;
+    DWORD status;
 
     char *effect_control_buf;
     char *effect_update_buf;
@@ -2653,6 +2654,9 @@ static HRESULT WINAPI hid_joystick_effect_Start( IDirectInputEffect *iface, DWOR
         if (status != HIDP_STATUS_SUCCESS) hr = status;
         else if (WriteFile( device, impl->effect_control_buf, report_len, NULL, NULL )) hr = DI_OK;
         else hr = DIERR_INPUTLOST;
+
+        if (SUCCEEDED(hr)) impl->status |= DIEGES_PLAYING;
+        else impl->status &= ~DIEGES_PLAYING;
     }
     LeaveCriticalSection( &impl->joystick->base.crit );
 
@@ -2699,6 +2703,8 @@ static HRESULT WINAPI hid_joystick_effect_Stop( IDirectInputEffect *iface )
         if (status != HIDP_STATUS_SUCCESS) hr = status;
         else if (WriteFile( device, impl->effect_control_buf, report_len, NULL, NULL )) hr = DI_OK;
         else hr = DIERR_INPUTLOST;
+
+        impl->status &= ~DIEGES_PLAYING;
     }
     LeaveCriticalSection( &impl->joystick->base.crit );
 
@@ -2708,7 +2714,7 @@ static HRESULT WINAPI hid_joystick_effect_Stop( IDirectInputEffect *iface )
 static HRESULT WINAPI hid_joystick_effect_GetEffectStatus( IDirectInputEffect *iface, DWORD *status )
 {
     struct hid_joystick_effect *impl = impl_from_IDirectInputEffect( iface );
-    HRESULT hr;
+    HRESULT hr = DI_OK;
 
     FIXME( "iface %p, status %p semi-stub!\n", iface, status );
 
@@ -2721,7 +2727,7 @@ static HRESULT WINAPI hid_joystick_effect_GetEffectStatus( IDirectInputEffect *i
     else if (!impl->index)
         hr = DIERR_NOTDOWNLOADED;
     else
-        hr = DI_OK;
+        *status = impl->status;
     LeaveCriticalSection( &impl->joystick->base.crit );
 
     return hr;
@@ -2945,12 +2951,22 @@ static HRESULT WINAPI hid_joystick_effect_Download( IDirectInputEffect *iface )
 
         if (!WriteFile( device, impl->effect_update_buf, report_len, NULL, NULL )) hr = DIERR_INPUTLOST;
         else impl->modified = 0;
+
+        if (SUCCEEDED(hr)) impl->joystick->base.force_feedback_state &= ~DIGFFS_EMPTY;
     }
     LeaveCriticalSection( &impl->joystick->base.crit );
 
     return hr;
 }
 
+static void check_empty_force_feedback_state( struct hid_joystick *joystick )
+{
+    struct hid_joystick_effect *effect;
+    LIST_FOR_EACH_ENTRY( effect, &joystick->effect_list, struct hid_joystick_effect, entry )
+        if (effect->index) return;
+    joystick->base.force_feedback_state |= DIGFFS_EMPTY;
+}
+
 static HRESULT WINAPI hid_joystick_effect_Unload( IDirectInputEffect *iface )
 {
     struct hid_joystick_effect *impl = impl_from_IDirectInputEffect( iface );
@@ -2986,6 +3002,7 @@ static HRESULT WINAPI hid_joystick_effect_Unload( IDirectInputEffect *iface )
 
         impl->modified = impl->flags;
         impl->index = 0;
+        check_empty_force_feedback_state( joystick );
     }
     LeaveCriticalSection( &joystick->base.crit );
 
@@ -3045,6 +3062,7 @@ static HRESULT hid_joystick_create_effect( IDirectInputDevice8W *iface, IDirectI
     impl->params.rgdwAxes = impl->axes;
     impl->params.rglDirection = impl->directions;
     impl->params.dwTriggerButton = -1;
+    impl->status = 0;
 
     *out = &impl->IDirectInputEffect_iface;
     return DI_OK;
diff --git a/dlls/dinput8/tests/hid.c b/dlls/dinput8/tests/hid.c
index bfd0185303d..d9ecf4a5dd5 100644
--- a/dlls/dinput8/tests/hid.c
+++ b/dlls/dinput8/tests/hid.c
@@ -9118,7 +9118,6 @@ static void test_device_managed_effect(void)
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED|DIGFFS_EMPTY;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9182,7 +9181,6 @@ static void test_device_managed_effect(void)
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED|DIGFFS_EMPTY;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9200,7 +9198,6 @@ static void test_device_managed_effect(void)
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9227,12 +9224,10 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect2, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, &expect_stop_2, sizeof(expect_stop_2) );
     hr = IDirectInputEffect_Stop( effect2 );
@@ -9255,14 +9250,12 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
     res = 0xdeadbeef;
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9273,14 +9266,12 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
     res = 0xdeadbeef;
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9291,14 +9282,12 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
     res = 0xdeadbeef;
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9309,14 +9298,12 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
     res = 0xdeadbeef;
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9327,14 +9314,12 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, expect_pool, sizeof(struct hid_expect) );
     res = 0xdeadbeef;
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9351,7 +9336,6 @@ static void test_device_managed_effect(void)
     hr = IDirectInputDevice8_GetForceFeedbackState( device, &res );
     ok( hr == DI_OK, "GetForceFeedbackState returned %#x\n", hr );
     flags = DIGFFS_STOPPED;
-    todo_wine
     ok( res == flags, "got state %#x\n", res );
     set_hid_expect( file, NULL, 0 );
 
@@ -9457,7 +9441,6 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
     ref = IDirectInputEffect_Release( effect );
@@ -9484,7 +9467,6 @@ static void test_device_managed_effect(void)
     res = 0xdeadbeef;
     hr = IDirectInputEffect_GetEffectStatus( effect, &res );
     ok( hr == DI_OK, "GetEffectStatus returned %#x\n", hr );
-    todo_wine
     ok( res == DIEGES_PLAYING, "got status %#x\n", res );
     set_hid_expect( file, expect_destroy, sizeof(expect_destroy) );
     ref = IDirectInputEffect_Release( effect );
-- 
2.34.0




More information about the wine-devel mailing list