[PATCH 5/5] windows.media.speech: Implement Completed event.

Bernhard Kölbl besentv at gmail.com
Wed Mar 16 11:31:04 CDT 2022


Signed-off-by: Bernhard Kölbl <besentv at gmail.com>
---
 dlls/windows.media.speech/recognizer.c   | 14 ++--
 dlls/windows.media.speech/tests/speech.c | 85 ++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/dlls/windows.media.speech/recognizer.c b/dlls/windows.media.speech/recognizer.c
index 7f4c7429929..da219d6bd0a 100644
--- a/dlls/windows.media.speech/recognizer.c
+++ b/dlls/windows.media.speech/recognizer.c
@@ -34,6 +34,7 @@ struct session
     ISpeechContinuousRecognitionSession ISpeechContinuousRecognitionSession_iface;
     LONG ref;
 
+    struct list completed_handlers;
     struct list result_handlers;
 };
 
@@ -83,6 +84,7 @@ static ULONG WINAPI session_Release( ISpeechContinuousRecognitionSession *iface
 
     if (!ref)
     {
+        typed_event_handlers_clear(&impl->completed_handlers);
         typed_event_handlers_clear(&impl->result_handlers);
         free(impl);
     }
@@ -162,14 +164,17 @@ static HRESULT WINAPI session_add_Completed( ISpeechContinuousRecognitionSession
                                              ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgs *handler,
                                              EventRegistrationToken *token )
 {
-    FIXME("iface %p, handler %p, token %p stub!\n", iface, handler, token);
-    return E_NOTIMPL;
+    struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface);
+    TRACE("iface %p, handler %p, token %p.\n", iface, handler, token);
+    if (!handler) return E_INVALIDARG;
+    return typed_event_handlers_append(&impl->completed_handlers, (ITypedEventHandler_IInspectable_IInspectable *)handler, token);
 }
 
 static HRESULT WINAPI session_remove_Completed( ISpeechContinuousRecognitionSession *iface, EventRegistrationToken token )
 {
-    FIXME("iface %p, token.value %#I64x stub!\n", iface, token.value);
-    return E_NOTIMPL;
+    struct session *impl = impl_from_ISpeechContinuousRecognitionSession(iface);
+    TRACE("iface %p, token.value %#I64x.\n", iface, token.value);
+    return typed_event_handlers_remove(&impl->completed_handlers, &token);
 }
 
 static HRESULT WINAPI session_add_ResultGenerated( ISpeechContinuousRecognitionSession *iface,
@@ -645,6 +650,7 @@ static HRESULT WINAPI recognizer_factory_Create( ISpeechRecognizerFactory *iface
 
     session->ISpeechContinuousRecognitionSession_iface.lpVtbl = &session_vtbl;
     session->ref = 1;
+    list_init(&session->completed_handlers);
     list_init(&session->result_handlers);
 
     impl->ISpeechRecognizer_iface.lpVtbl = &speech_recognizer_vtbl;
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c
index 80e5d9af634..fc0a8d762c1 100644
--- a/dlls/windows.media.speech/tests/speech.c
+++ b/dlls/windows.media.speech/tests/speech.c
@@ -46,6 +46,12 @@
 #define impl_from_IHandler_RecognitionResult impl_from_ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionResultGeneratedEventArgs
 #define IHandler_RecognitionResult_iface ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionResultGeneratedEventArgs_iface
 
+#define IHandler_RecognitionCompleted ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgs
+#define IHandler_RecognitionCompletedVtbl ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgsVtbl
+#define IID_IHandler_RecognitionCompleted IID_ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgs
+#define impl_from_IHandler_RecognitionCompleted impl_from_ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgs
+#define IHandler_RecognitionCompleted_iface ITypedEventHandler_SpeechContinuousRecognitionSession_SpeechContinuousRecognitionCompletedEventArgs_iface
+
 HRESULT WINAPI (*pDllGetActivationFactory)(HSTRING, IActivationFactory **);
 static BOOL is_win10_1507 = FALSE;
 
@@ -86,6 +92,72 @@ static const char *debugstr_hstring(HSTRING hstr)
     return wine_dbgstr_wn(str, len);
 }
 
+struct completed_event_handler
+{
+    IHandler_RecognitionCompleted IHandler_RecognitionCompleted_iface;
+    LONG ref;
+};
+
+static inline struct completed_event_handler *impl_from_IHandler_RecognitionCompleted( IHandler_RecognitionCompleted *iface )
+{
+    return CONTAINING_RECORD(iface, struct completed_event_handler, IHandler_RecognitionCompleted_iface);
+}
+
+HRESULT WINAPI completed_event_handler_QueryInterface( IHandler_RecognitionCompleted *iface, REFIID iid, void **out )
+{
+    if (IsEqualGUID(iid, &IID_IUnknown) ||
+        IsEqualGUID(iid, &IID_IHandler_RecognitionCompleted))
+    {
+        IUnknown_AddRef(iface);
+        *out = iface;
+        return S_OK;
+    }
+
+    trace("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid));
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+ULONG WINAPI completed_event_handler_AddRef( IHandler_RecognitionCompleted *iface )
+{
+    struct completed_event_handler *impl = impl_from_IHandler_RecognitionCompleted(iface);
+    ULONG ref = InterlockedIncrement(&impl->ref);
+    return ref;
+}
+
+ULONG WINAPI completed_event_handler_Release( IHandler_RecognitionCompleted *iface )
+{
+    struct completed_event_handler *impl = impl_from_IHandler_RecognitionCompleted(iface);
+    ULONG ref = InterlockedDecrement(&impl->ref);
+    return ref;
+}
+
+HRESULT WINAPI completed_event_handler_Invoke( IHandler_RecognitionCompleted *iface,
+                                               ISpeechContinuousRecognitionSession *sender,
+                                               ISpeechContinuousRecognitionCompletedEventArgs *args )
+{
+    trace("iface %p, sender %p, args %p.\n", iface, sender, args);
+    return S_OK;
+}
+
+static const struct IHandler_RecognitionCompletedVtbl completed_event_handler_vtbl =
+{
+    /* IUnknown methods */
+    completed_event_handler_QueryInterface,
+    completed_event_handler_AddRef,
+    completed_event_handler_Release,
+    /* ITypedEventHandler<SpeechContinuousRecognitionSession*, SpeechContinuousRecognitionCompletedEventArgs* > methods */
+    completed_event_handler_Invoke
+};
+
+static HRESULT WINAPI completed_event_handler_create_static( struct completed_event_handler *impl )
+{
+    impl->IHandler_RecognitionCompleted_iface.lpVtbl = &completed_event_handler_vtbl;
+    impl->ref = 1;
+
+    return S_OK;
+}
+
 struct recognition_result_handler
 {
     IHandler_RecognitionResult IHandler_RecognitionResult_iface;
@@ -651,6 +723,7 @@ static void test_SpeechRecognizer(void)
     IInspectable *inspectable = NULL;
     IClosable *closable = NULL;
     ILanguage *language = NULL;
+    struct completed_event_handler completed_handler;
     struct recognition_result_handler result_handler;
     EventRegistrationToken token = { .value = 0 };
     HSTRING hstr, hstr_lang;
@@ -728,6 +801,18 @@ static void test_SpeechRecognizer(void)
         check_refcount(session, 2);
         check_refcount(inspectable, 3);
 
+        hr = ISpeechContinuousRecognitionSession_add_Completed(session, NULL, &token);
+        ok(hr == E_INVALIDARG, "ISpeechContinuousRecognitionSession_add_ResultGenerated failed, hr %#lx.\n", hr);
+
+        token.value = 0xdeadbeef;
+        completed_event_handler_create_static(&completed_handler);
+        hr = ISpeechContinuousRecognitionSession_add_Completed(session, &completed_handler.IHandler_RecognitionCompleted_iface, &token);
+        ok(hr == S_OK, "ISpeechContinuousRecognitionSession_add_ResultGenerated failed, hr %#lx.\n", hr);
+        ok(token.value != 0xdeadbeef, "Got unexpexted token: %#I64x.\n", token.value);
+
+        hr = ISpeechContinuousRecognitionSession_remove_Completed(session, token);
+        ok(hr == S_OK, "ISpeechContinuousRecognitionSession_remove_ResultGenerated failed, hr %#lx.\n", hr);
+
         hr = ISpeechContinuousRecognitionSession_add_ResultGenerated(session, NULL, &token);
         ok(hr == E_INVALIDARG, "ISpeechContinuousRecognitionSession_add_ResultGenerated failed, hr %#lx.\n", hr);
 
-- 
2.35.1




More information about the wine-devel mailing list