[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