From: Bernhard Kölbl besentv@gmail.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/async.c | 126 +++++++++++++++++++++++ dlls/windows.media.speech/private.h | 1 + dlls/windows.media.speech/recognizer.c | 2 +- dlls/windows.media.speech/tests/speech.c | 14 +-- 4 files changed, 135 insertions(+), 8 deletions(-)
diff --git a/dlls/windows.media.speech/async.c b/dlls/windows.media.speech/async.c index eceda4338b3..1abb88528ef 100644 --- a/dlls/windows.media.speech/async.c +++ b/dlls/windows.media.speech/async.c @@ -26,6 +26,132 @@ WINE_DEFAULT_DEBUG_CHANNEL(speech); #define Closed 4 #define HANDLER_NOT_SET ((void *)~(ULONG_PTR)0)
+/* + * + * IAsyncAction + * + */ + +struct async_void +{ + IAsyncAction IAsyncAction_iface; + LONG ref; +}; + +static inline struct async_void *impl_from_IAsyncAction( IAsyncAction *iface ) +{ + return CONTAINING_RECORD(iface, struct async_void, IAsyncAction_iface); +} + +HRESULT WINAPI async_void_QueryInterface( IAsyncAction *iface, REFIID iid, void **out ) +{ + struct async_void *impl = impl_from_IAsyncAction(iface); + + TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IAsyncAction)) + { + IInspectable_AddRef((*out = &impl->IAsyncAction_iface)); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +ULONG WINAPI async_void_AddRef( IAsyncAction *iface ) +{ + struct async_void *impl = impl_from_IAsyncAction(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +ULONG WINAPI async_void_Release( IAsyncAction *iface ) +{ + struct async_void *impl = impl_from_IAsyncAction(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +HRESULT WINAPI async_void_GetIids( IAsyncAction *iface, ULONG *iid_count, IID **iids ) +{ + FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +HRESULT WINAPI async_void_GetRuntimeClassName( IAsyncAction *iface, HSTRING *class_name ) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +HRESULT WINAPI async_void_GetTrustLevel( IAsyncAction *iface, TrustLevel *trust_level ) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +HRESULT WINAPI async_void_put_Completed( IAsyncAction *iface, IAsyncActionCompletedHandler *handler ) +{ + FIXME("iface %p, handler %p stub!\n", iface, handler); + return E_NOTIMPL; +} + +HRESULT WINAPI async_void_get_Completed( IAsyncAction *iface, IAsyncActionCompletedHandler **handler ) +{ + FIXME("iface %p, handler %p stub!\n", iface, handler); + return E_NOTIMPL; +} + +HRESULT WINAPI async_void_GetResults( IAsyncAction *iface ) +{ + FIXME("iface %p stub!\n", iface); + return E_NOTIMPL; +} + +static const struct IAsyncActionVtbl async_void_vtbl = +{ + /* IUnknown methods */ + async_void_QueryInterface, + async_void_AddRef, + async_void_Release, + /* IInspectable methods */ + async_void_GetIids, + async_void_GetRuntimeClassName, + async_void_GetTrustLevel, + /* IAsyncAction methods */ + async_void_put_Completed, + async_void_get_Completed, + async_void_GetResults +}; + + +HRESULT async_action_create( IAsyncAction **out ) +{ + struct async_void *impl; + + TRACE("out %p.\n", out); + + if (!(impl = calloc(1, sizeof(*impl)))) + { + *out = NULL; + return E_OUTOFMEMORY; + } + + impl->IAsyncAction_iface.lpVtbl = &async_void_vtbl; + impl->ref = 1; + + *out = &impl->IAsyncAction_iface; + TRACE("created %p\n", *out); + return S_OK; +} + /* * * IAsyncOperation<IInspectable*> diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h index 97afa4d3499..ba8e942fe5f 100644 --- a/dlls/windows.media.speech/private.h +++ b/dlls/windows.media.speech/private.h @@ -71,6 +71,7 @@ struct vector_iids
typedef HRESULT (WINAPI *async_operation_inspectable_callback)( IInspectable *invoker, IInspectable **result );
+HRESULT async_action_create( IAsyncAction **out ); HRESULT async_operation_inspectable_create( const GUID *iid, IInspectable *invoker, async_operation_inspectable_callback callback, IAsyncOperation_IInspectable **out );
diff --git a/dlls/windows.media.speech/recognizer.c b/dlls/windows.media.speech/recognizer.c index c78f69b0a67..853e9eb9830 100644 --- a/dlls/windows.media.speech/recognizer.c +++ b/dlls/windows.media.speech/recognizer.c @@ -247,7 +247,7 @@ static HRESULT WINAPI session_set_AutoStopSilenceTimeout( ISpeechContinuousRecog static HRESULT WINAPI session_StartAsync( ISpeechContinuousRecognitionSession *iface, IAsyncAction **action ) { FIXME("iface %p, action %p stub!\n", iface, action); - return E_NOTIMPL; + return async_action_create(action); }
static HRESULT WINAPI session_StartWithModeAsync( ISpeechContinuousRecognitionSession *iface, diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 91d8704f2c8..f3b28c40f51 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -1577,20 +1577,20 @@ static void test_Recognition(void) IAsyncOperation_IInspectable_Release((IAsyncOperation_IInspectable *)operation);
hr = ISpeechContinuousRecognitionSession_StartAsync(session, &action); - todo_wine ok(hr == S_OK, "ISpeechContinuousRecognitionSession_StartAsync failed, hr %#lx.\n", hr); - - if (FAILED(hr)) goto skip_action; - - await_async_void(action, &action_handler); - check_async_info((IInspectable *)action, 1, Completed, S_OK); + ok(hr == S_OK, "ISpeechContinuousRecognitionSession_StartAsync failed, hr %#lx.\n", hr);
handler = (void *)0xdeadbeef; hr = IAsyncAction_get_Completed(action, &handler); todo_wine ok(hr == S_OK, "IAsyncAction_put_Completed failed, hr %#lx.\n", hr); todo_wine ok(handler == NULL, "Handler was %p.\n", handler);
+ if (FAILED(hr)) goto skip_action; + + await_async_void(action, &action_handler); + hr = IAsyncAction_QueryInterface(action, &IID_IAsyncInfo, (void **)&info); todo_wine ok(hr == S_OK, "IAsyncAction_QueryInterface failed, hr %#lx.\n", hr); + check_async_info((IInspectable *)action, 1, Completed, S_OK);
hr = IAsyncInfo_Cancel(info); todo_wine ok(hr == S_OK, "IAsyncInfo_Cancel failed, hr %#lx.\n", hr); @@ -1660,9 +1660,9 @@ static void test_Recognition(void) todo_wine ok(action != action2, "actions were the same!\n");
IAsyncAction_Release(action2); +skip_action: IAsyncAction_Release(action);
-skip_action: hr = ISpeechContinuousRecognitionSession_remove_ResultGenerated(session, token); ok(hr == S_OK, "ISpeechContinuousRecognitionSession_remove_ResultGenerated failed, hr %#lx.\n", hr);