Rémi Bernon : windows.gaming.input: Use a PROPVARIANT as async operation result.

Alexandre Julliard julliard at winehq.org
Thu May 5 15:56:02 CDT 2022


Module: wine
Branch: master
Commit: b985fe636237d6f26d228f41cb9b18829abd971f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=b985fe636237d6f26d228f41cb9b18829abd971f

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Wed May  4 11:22:16 2022 +0200

windows.gaming.input: Use a PROPVARIANT as async operation result.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/windows.gaming.input/async.c          | 22 +++++++++++++++-------
 dlls/windows.gaming.input/force_feedback.c | 15 +++++++++------
 dlls/windows.gaming.input/private.h        |  4 ++--
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/dlls/windows.gaming.input/async.c b/dlls/windows.gaming.input/async.c
index 6afbca96831..cce2729f06b 100644
--- a/dlls/windows.gaming.input/async.c
+++ b/dlls/windows.gaming.input/async.c
@@ -34,14 +34,13 @@ struct async_bool
     IAsyncInfo IAsyncInfo_iface;
     LONG ref;
 
-    BOOLEAN result;
-
-    async_operation_boolean_callback callback;
+    async_operation_callback callback;
     TP_WORK *async_run_work;
     IInspectable *invoker;
 
     CRITICAL_SECTION cs;
     IWineAsyncOperationCompletedHandler *handler;
+    PROPVARIANT result;
     AsyncStatus status;
     HRESULT hr;
 };
@@ -197,6 +196,7 @@ static ULONG WINAPI async_bool_Release( IAsyncOperation_boolean *iface )
     {
         IAsyncInfo_Close( &impl->IAsyncInfo_iface );
         if (impl->handler && impl->handler != HANDLER_NOT_SET) IWineAsyncOperationCompletedHandler_Release( impl->handler );
+        PropVariantClear( &impl->result );
         IInspectable_Release( impl->invoker );
         DeleteCriticalSection( &impl->cs );
         free( impl );
@@ -276,19 +276,24 @@ static HRESULT WINAPI async_bool_get_Completed( IAsyncOperation_boolean *iface,
 static HRESULT WINAPI async_bool_GetResults( IAsyncOperation_boolean *iface, BOOLEAN *results )
 {
     struct async_bool *impl = impl_from_IAsyncOperation_boolean( iface );
+    PROPVARIANT result = {.vt = VT_BOOL};
     HRESULT hr;
 
     TRACE( "iface %p, results %p.\n", iface, results );
 
     EnterCriticalSection( &impl->cs );
     if (impl->status != Completed && impl->status != Error) hr = E_ILLEGAL_METHOD_CALL;
+    else if (impl->result.vt != result.vt) hr = E_UNEXPECTED;
     else
     {
-        *results = impl->result;
+        PropVariantCopy( &result, &impl->result );
+        if (impl->result.vt == VT_UNKNOWN) PropVariantClear( &impl->result );
         hr = impl->hr;
     }
     LeaveCriticalSection( &impl->cs );
 
+    *results = result.boolVal;
+    PropVariantClear( &result );
     return hr;
 }
 
@@ -312,14 +317,15 @@ static void CALLBACK async_run_cb( TP_CALLBACK_INSTANCE *instance, void *data, T
 {
     IAsyncOperation_boolean *operation = data;
     struct async_bool *impl = impl_from_IAsyncOperation_boolean( operation );
-    BOOLEAN result = FALSE;
+    PROPVARIANT result;
     HRESULT hr;
 
+    PropVariantInit( &result );
     hr = impl->callback( impl->invoker, &result );
 
     EnterCriticalSection( &impl->cs );
     if (impl->status != Closed) impl->status = FAILED(hr) ? Error : Completed;
-    impl->result = result;
+    PropVariantCopy( &impl->result, &result );
     impl->hr = hr;
 
     if (impl->handler != NULL && impl->handler != HANDLER_NOT_SET)
@@ -335,9 +341,10 @@ static void CALLBACK async_run_cb( TP_CALLBACK_INSTANCE *instance, void *data, T
     else LeaveCriticalSection( &impl->cs );
 
     IAsyncOperation_boolean_Release( operation );
+    PropVariantClear( &result );
 }
 
-HRESULT async_operation_boolean_create( IInspectable *invoker, async_operation_boolean_callback callback,
+HRESULT async_operation_boolean_create( IInspectable *invoker, async_operation_callback callback,
                                         IAsyncOperation_boolean **out )
 {
     struct async_bool *impl;
@@ -351,6 +358,7 @@ HRESULT async_operation_boolean_create( IInspectable *invoker, async_operation_b
     impl->handler = HANDLER_NOT_SET;
     impl->callback = callback;
     impl->status = Started;
+    impl->result.vt = VT_BOOL;
 
     if (!(impl->async_run_work = CreateThreadpoolWork( async_run_cb, &impl->IAsyncOperation_boolean_iface, NULL )))
     {
diff --git a/dlls/windows.gaming.input/force_feedback.c b/dlls/windows.gaming.input/force_feedback.c
index 24810d1d787..667c6d8d81b 100644
--- a/dlls/windows.gaming.input/force_feedback.c
+++ b/dlls/windows.gaming.input/force_feedback.c
@@ -212,13 +212,14 @@ static HRESULT WINAPI motor_StopAllEffects( IForceFeedbackMotor *iface )
     return IDirectInputDevice8_SendForceFeedbackCommand( impl->device, DISFFC_STOPALL );
 }
 
-static HRESULT WINAPI motor_try_disable_async( IInspectable *iface, BOOLEAN *result )
+static HRESULT WINAPI motor_try_disable_async( IInspectable *iface, PROPVARIANT *result )
 {
     struct motor *impl = impl_from_IForceFeedbackMotor( (IForceFeedbackMotor *)iface );
     HRESULT hr;
 
     hr = IDirectInputDevice8_SendForceFeedbackCommand( impl->device, DISFFC_SETACTUATORSOFF );
-    *result = SUCCEEDED(hr);
+    result->vt = VT_BOOL;
+    result->boolVal = SUCCEEDED(hr);
 
     return hr;
 }
@@ -229,13 +230,14 @@ static HRESULT WINAPI motor_TryDisableAsync( IForceFeedbackMotor *iface, IAsyncO
     return async_operation_boolean_create( (IInspectable *)iface, motor_try_disable_async, async_op );
 }
 
-static HRESULT WINAPI motor_try_enable_async( IInspectable *iface, BOOLEAN *result )
+static HRESULT WINAPI motor_try_enable_async( IInspectable *iface, PROPVARIANT *result )
 {
     struct motor *impl = impl_from_IForceFeedbackMotor( (IForceFeedbackMotor *)iface );
     HRESULT hr;
 
     hr = IDirectInputDevice8_SendForceFeedbackCommand( impl->device, DISFFC_SETACTUATORSON );
-    *result = SUCCEEDED(hr);
+    result->vt = VT_BOOL;
+    result->boolVal = SUCCEEDED(hr);
 
     return hr;
 }
@@ -246,13 +248,14 @@ static HRESULT WINAPI motor_TryEnableAsync( IForceFeedbackMotor *iface, IAsyncOp
     return async_operation_boolean_create( (IInspectable *)iface, motor_try_enable_async, async_op );
 }
 
-static HRESULT WINAPI motor_try_reset_async( IInspectable *iface, BOOLEAN *result )
+static HRESULT WINAPI motor_try_reset_async( IInspectable *iface, PROPVARIANT *result )
 {
     struct motor *impl = impl_from_IForceFeedbackMotor( (IForceFeedbackMotor *)iface );
     HRESULT hr;
 
     hr = IDirectInputDevice8_SendForceFeedbackCommand( impl->device, DISFFC_RESET );
-    *result = SUCCEEDED(hr);
+    result->vt = VT_BOOL;
+    result->boolVal = SUCCEEDED(hr);
 
     return hr;
 }
diff --git a/dlls/windows.gaming.input/private.h b/dlls/windows.gaming.input/private.h
index 2c25aca9027..63c9c262f7a 100644
--- a/dlls/windows.gaming.input/private.h
+++ b/dlls/windows.gaming.input/private.h
@@ -67,8 +67,8 @@ extern void event_handlers_notify( struct list *list, IInspectable *element );
 
 extern HRESULT force_feedback_motor_create( IDirectInputDevice8W *device, IForceFeedbackMotor **out );
 
-typedef HRESULT (WINAPI *async_operation_boolean_callback)( IInspectable *invoker, BOOLEAN *result );
-extern HRESULT async_operation_boolean_create( IInspectable *invoker, async_operation_boolean_callback callback,
+typedef HRESULT (WINAPI *async_operation_callback)( IInspectable *invoker, PROPVARIANT *result );
+extern HRESULT async_operation_boolean_create( IInspectable *invoker, async_operation_callback callback,
                                                IAsyncOperation_boolean **out );
 
 #define DEFINE_IINSPECTABLE_( pfx, iface_type, impl_type, impl_from, iface_mem, expr )             \




More information about the wine-cvs mailing list