From: Bernhard Kölbl besentv@gmail.com
Also make some style improvements.
Signed-off-by: Bernhard Kölbl besentv@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
v2: Added a couple of missing spaces on if/for stmts in PATCH 3.
dlls/windows.media.speech/recognizer.c | 15 ++++++++------- dlls/windows.media.speech/tests/speech.c | 19 ++++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/dlls/windows.media.speech/recognizer.c b/dlls/windows.media.speech/recognizer.c index e5510d7677b..490493850c8 100644 --- a/dlls/windows.media.speech/recognizer.c +++ b/dlls/windows.media.speech/recognizer.c @@ -56,19 +56,20 @@ static HRESULT WINAPI recognizer_QueryInterface( ISpeechRecognizer *iface, REFII
if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || IsEqualGUID(iid, &IID_ISpeechRecognizer)) { IInspectable_AddRef((*out = &impl->ISpeechRecognizer_iface)); return S_OK; }
- if(IsEqualGUID(iid, &IID_IClosable)) + if (IsEqualGUID(iid, &IID_IClosable)) { IInspectable_AddRef((*out = &impl->IClosable_iface)); return S_OK; }
- if(IsEqualGUID(iid, &IID_ISpeechRecognizer2)) + if (IsEqualGUID(iid, &IID_ISpeechRecognizer2)) { IInspectable_AddRef((*out = &impl->ISpeechRecognizer2_iface)); return S_OK; @@ -94,7 +95,7 @@ static ULONG WINAPI recognizer_Release( ISpeechRecognizer *iface ) ULONG ref = InterlockedDecrement(&impl->ref); TRACE("iface %p, ref %lu.\n", iface, ref);
- if(!ref) + if (!ref) free(impl);
return ref; @@ -403,7 +404,7 @@ static HRESULT WINAPI activation_factory_GetTrustLevel( IActivationFactory *ifac static HRESULT WINAPI activation_factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) { struct recognizer_statics *impl = impl_from_IActivationFactory(iface); - TRACE("iface %p, instance %p\n", iface, instance); + TRACE("iface %p, instance %p.\n", iface, instance); return ISpeechRecognizerFactory_Create(&impl->ISpeechRecognizerFactory_iface, NULL, (ISpeechRecognizer **)instance); }
@@ -441,15 +442,15 @@ static HRESULT WINAPI recognizer_factory_Create( ISpeechRecognizerFactory *iface return E_OUTOFMEMORY; }
- if(language) - FIXME("ILanguage parameter unused. Stub!\n"); + if (language) + FIXME("language parameter unused. Stub!\n");
impl->ISpeechRecognizer_iface.lpVtbl = &speech_recognizer_vtbl; impl->IClosable_iface.lpVtbl = &closable_vtbl; impl->ISpeechRecognizer2_iface.lpVtbl = &speech_recognizer2_vtbl; impl->ref = 1;
- TRACE("created SpeechRecognizer %p\n", impl); + TRACE("created SpeechRecognizer %p.\n", impl);
*speechrecognizer = &impl->ISpeechRecognizer_iface; return S_OK; diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 9e4f031a55f..ce89bd3f78a 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -38,6 +38,8 @@
#include "wine/test.h"
+#define SPERR_WINRT_INTERNAL_ERROR 0x800455a0 + HRESULT WINAPI (*pDllGetActivationFactory)(HSTRING, IActivationFactory **);
static inline LONG get_ref(IUnknown *obj) @@ -148,7 +150,7 @@ static void test_ActivationFactory(void)
hdll = LoadLibraryW(L"windows.media.speech.dll");
- if(hdll) + if (hdll) { pDllGetActivationFactory = (void *)GetProcAddress(hdll, "DllGetActivationFactory"); ok(!!pDllGetActivationFactory, "DllGetActivationFactory not found.\n"); @@ -364,7 +366,7 @@ static void test_SpeechRecognizer(void) hr = RoGetActivationFactory(hstr, &IID_IActivationFactory, (void **)&factory); ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#lx.\n", hr);
- if(hr == REGDB_E_CLASSNOTREG) /* Win 8 and 8.1 */ + if (hr == REGDB_E_CLASSNOTREG) /* Win 8 and 8.1 */ { win_skip("SpeechRecognizer activation factory not available!\n"); goto done; @@ -379,7 +381,7 @@ static void test_SpeechRecognizer(void) hr = ISpeechRecognizerStatics_get_SystemSpeechLanguage(sr_statics, &language); todo_wine ok(hr == S_OK, "ISpeechRecognizerStatics_SystemSpeechLanguage failed, hr %#lx.\n", hr);
- if(hr == S_OK) + if (hr == S_OK) { hr = ILanguage_get_LanguageTag(language, &hstr_lang); ok(hr == S_OK, "ILanguage_get_LanguageTag failed, hr %#lx.\n", hr); @@ -395,7 +397,7 @@ static void test_SpeechRecognizer(void) hr = IActivationFactory_QueryInterface(factory, &IID_ISpeechRecognizerStatics2, (void **)&sr_statics2); ok(hr == S_OK || broken(hr == E_NOINTERFACE), "IActivationFactory_QueryInterface IID_ISpeechRecognizerStatics2 failed, hr %#lx.\n", hr);
- if(hr == S_OK) /* SpeechRecognizerStatics2 not implemented on Win10 1507 */ + if (hr == S_OK) /* SpeechRecognizerStatics2 not implemented on Win10 1507 */ { ref = ISpeechRecognizerStatics2_Release(sr_statics2); ok(ref == 3, "Got unexpected ref %lu.\n", ref); @@ -408,10 +410,13 @@ static void test_SpeechRecognizer(void) ok(ref == 1, "Got unexpected ref %lu.\n", ref);
hr = RoActivateInstance(hstr, &inspectable); - ok(hr == S_OK || broken(hr == 0x800455a0), "Got unexpected hr %#lx.\n", hr); + ok(hr == S_OK || broken(hr == SPERR_WINRT_INTERNAL_ERROR), "Got unexpected hr %#lx.\n", hr);
- if(hr == S_OK) + if (hr == S_OK) { + check_refcount(inspectable, 1); + check_interface(factory, &IID_IAgileObject, TRUE); + hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechRecognizer, (void **)&recognizer); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
@@ -433,7 +438,7 @@ static void test_SpeechRecognizer(void) ref = IInspectable_Release(inspectable); ok(!ref, "Got unexpected ref %lu.\n", ref); } - else if(hr == 0x800455a0) /* Not sure what this hr is... Probably if a language pack is not installed. */ + else if (hr == SPERR_WINRT_INTERNAL_ERROR) /* Not sure when this triggers. Probably if a language pack is not installed. */ { win_skip("Could not init SpeechRecognizer with default language!\n"); }
From: Bernhard Kölbl besentv@gmail.com
And its dependencies.
Signed-off-by: Bernhard Kölbl besentv@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- include/windows.media.speechrecognition.idl | 43 +++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/include/windows.media.speechrecognition.idl b/include/windows.media.speechrecognition.idl index d83547a9a02..79107aab1bf 100644 --- a/include/windows.media.speechrecognition.idl +++ b/include/windows.media.speechrecognition.idl @@ -46,6 +46,8 @@ namespace Windows { interface ISpeechRecognitionConstraint; interface ISpeechRecognitionHypothesis; interface ISpeechRecognitionHypothesisGeneratedEventArgs; + interface ISpeechRecognitionListConstraint; + interface ISpeechRecognitionListConstraintFactory; interface ISpeechRecognitionQualityDegradingEventArgs; interface ISpeechRecognitionResult; interface ISpeechRecognitionResult2; @@ -64,6 +66,7 @@ namespace Windows { runtimeclass SpeechRecognitionCompilationResult; runtimeclass SpeechRecognitionHypothesis; runtimeclass SpeechRecognitionHypothesisGeneratedEventArgs; + runtimeclass SpeechRecognitionListConstraint; runtimeclass SpeechRecognitionQualityDegradingEventArgs; runtimeclass SpeechRecognitionResult; runtimeclass SpeechRecognitionSemanticInterpretation; @@ -273,6 +276,35 @@ namespace Windows { [propget] HRESULT Hypothesis([out, retval] Windows.Media.SpeechRecognition.SpeechRecognitionHypothesis **value); }
+ [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.SpeechRecognition.SpeechRecognitionListConstraint), + uuid(09c487e9-e4ad-4526-81f2-4946fb481d98) + ] + interface ISpeechRecognitionListConstraint : IInspectable + requires + Windows.Media.SpeechRecognition.ISpeechRecognitionConstraint + { + [propget] HRESULT Commands([out, retval] Windows.Foundation.Collections.IVector<HSTRING> **value); + } + + [ + contract(Windows.Foundation.UniversalApiContract, 1.0), + exclusiveto(Windows.Media.SpeechRecognition.SpeechRecognitionListConstraint), + uuid(40f3cdc7-562a-426a-9f3b-3b4e282be1d5) + ] + interface ISpeechRecognitionListConstraintFactory : IInspectable + { + HRESULT Create( + [in] Windows.Foundation.Collections.IIterable<HSTRING> *commands, + [out, retval] Windows.Media.SpeechRecognition.SpeechRecognitionListConstraint **listconstraint); + + HRESULT CreateWithTag( + [in] Windows.Foundation.Collections.IIterable<HSTRING> *commands, + [in] HSTRING tag, + [out, retval] Windows.Media.SpeechRecognition.SpeechRecognitionListConstraint **listconstraint); + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), exclusiveto(Windows.Media.SpeechRecognition.SpeechRecognitionQualityDegradingEventArgs), @@ -498,6 +530,17 @@ namespace Windows { [default] interface Windows.Media.SpeechRecognition.ISpeechRecognitionHypothesisGeneratedEventArgs; }
+ [ + activatable(Windows.Media.SpeechRecognition.ISpeechRecognitionListConstraintFactory, Windows.Foundation.UniversalApiContract, 1.0), + contract(Windows.Foundation.UniversalApiContract, 1.0), + marshaling_behavior(agile) + ] + runtimeclass SpeechRecognitionListConstraint + { + [default] interface Windows.Media.SpeechRecognition.ISpeechRecognitionListConstraint; + interface Windows.Media.SpeechRecognition.ISpeechRecognitionConstraint; + } + [ contract(Windows.Foundation.UniversalApiContract, 1.0), marshaling_behavior(agile)
From: Bernhard Kölbl besentv@gmail.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/tests/speech.c | 375 +++++++++++++++++++++++ 1 file changed, 375 insertions(+)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index ce89bd3f78a..0a573db6f47 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -41,6 +41,7 @@ #define SPERR_WINRT_INTERNAL_ERROR 0x800455a0
HRESULT WINAPI (*pDllGetActivationFactory)(HSTRING, IActivationFactory **); +static BOOL is_win10_1507 = FALSE;
static inline LONG get_ref(IUnknown *obj) { @@ -79,6 +80,229 @@ static const char *debugstr_hstring(HSTRING hstr) return wine_dbgstr_wn(str, len); }
+struct iterator_hstring +{ + IIterator_HSTRING IIterator_HSTRING_iface; + LONG ref; + + UINT32 index; + UINT32 size; + HSTRING *values; +}; + +static inline struct iterator_hstring *impl_from_IIterator_HSTRING( IIterator_HSTRING *iface ) +{ + return CONTAINING_RECORD(iface, struct iterator_hstring, IIterator_HSTRING_iface); +} + +static HRESULT WINAPI iterator_hstring_QueryInterface( IIterator_HSTRING *iface, REFIID iid, void **out ) +{ + struct iterator_hstring *impl = impl_from_IIterator_HSTRING(iface); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IIterator_HSTRING)) + { + IInspectable_AddRef((*out = &impl->IIterator_HSTRING_iface)); + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI iterator_hstring_AddRef( IIterator_HSTRING *iface ) +{ + struct iterator_hstring *impl = impl_from_IIterator_HSTRING(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + return ref; +} + +static ULONG WINAPI iterator_hstring_Release( IIterator_HSTRING *iface ) +{ + struct iterator_hstring *impl = impl_from_IIterator_HSTRING(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + return ref; +} + +static HRESULT WINAPI iterator_hstring_GetIids( IIterator_HSTRING *iface, ULONG *iid_count, IID **iids ) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI iterator_hstring_GetRuntimeClassName( IIterator_HSTRING *iface, HSTRING *class_name ) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI iterator_hstring_GetTrustLevel( IIterator_HSTRING *iface, TrustLevel *trust_level ) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI iterator_hstring_get_Current( IIterator_HSTRING *iface, HSTRING *value ) +{ + struct iterator_hstring *impl = impl_from_IIterator_HSTRING(iface); + HRESULT hr; + + *value = NULL; + if (impl->index >= impl->size) return E_BOUNDS; + + hr = WindowsDuplicateString(impl->values[impl->index], value); + return hr; +} + +static HRESULT WINAPI iterator_hstring_get_HasCurrent( IIterator_HSTRING *iface, BOOL *value ) +{ + struct iterator_hstring *impl = impl_from_IIterator_HSTRING(iface); + + *value = impl->index < impl->size; + return S_OK; +} + +static HRESULT WINAPI iterator_hstring_MoveNext( IIterator_HSTRING *iface, BOOL *value ) +{ + struct iterator_hstring *impl = impl_from_IIterator_HSTRING(iface); + + if (impl->index < impl->size) impl->index++; + return IIterator_HSTRING_get_HasCurrent(iface, value); +} + +static HRESULT WINAPI iterator_hstring_GetMany( IIterator_HSTRING *iface, UINT32 items_size, + HSTRING *items, UINT *count ) +{ + return E_NOTIMPL; +} + +static const struct IIterator_HSTRINGVtbl iterator_hstring_vtbl = +{ + /* IUnknown methods */ + iterator_hstring_QueryInterface, + iterator_hstring_AddRef, + iterator_hstring_Release, + /* IInspectable methods */ + iterator_hstring_GetIids, + iterator_hstring_GetRuntimeClassName, + iterator_hstring_GetTrustLevel, + /* IIterator<HSTRING> methods */ + iterator_hstring_get_Current, + iterator_hstring_get_HasCurrent, + iterator_hstring_MoveNext, + iterator_hstring_GetMany +}; + +static HRESULT WINAPI iterator_hstring_create_static(struct iterator_hstring *impl, HSTRING *strings, UINT32 size) +{ + impl->IIterator_HSTRING_iface.lpVtbl = &iterator_hstring_vtbl; + impl->ref = 1; + impl->index = 0; + impl->size = size; + impl->values = strings; + + return S_OK; +} + +struct iterable_hstring +{ + IIterable_HSTRING IIterable_HSTRING_iface; + LONG ref; + + IIterator_HSTRING *iterator; +}; + +static inline struct iterable_hstring *impl_from_Iterable_HSTRING( IIterable_HSTRING *iface ) +{ + return CONTAINING_RECORD(iface, struct iterable_hstring, IIterable_HSTRING_iface); +} + +static HRESULT WINAPI iterable_hstring_QueryInterface( IIterable_HSTRING *iface, REFIID iid, void **out ) +{ + struct iterable_hstring *impl = impl_from_Iterable_HSTRING(iface); + + trace("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IIterable_HSTRING)) + { + IInspectable_AddRef((*out = &impl->IIterable_HSTRING_iface)); + return S_OK; + } + + trace("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI iterable_hstring_AddRef( IIterable_HSTRING *iface ) +{ + struct iterable_hstring *impl = impl_from_Iterable_HSTRING(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + trace("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI iterable_hstring_Release( IIterable_HSTRING *iface ) +{ + struct iterable_hstring *impl = impl_from_Iterable_HSTRING(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + trace("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static HRESULT WINAPI iterable_hstring_GetIids( IIterable_HSTRING *iface, ULONG *iid_count, IID **iids ) +{ + trace("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +static HRESULT WINAPI iterable_hstring_GetRuntimeClassName( IIterable_HSTRING *iface, HSTRING *class_name ) +{ + trace("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI iterable_hstring_GetTrustLevel( IIterable_HSTRING *iface, TrustLevel *trust_level ) +{ + trace("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT WINAPI iterable_hstring_First( IIterable_HSTRING *iface, IIterator_HSTRING **value ) +{ + struct iterable_hstring *impl = impl_from_Iterable_HSTRING(iface); + + trace("iface %p, value %p.\n", iface, value); + + IIterator_HSTRING_AddRef((*value = impl->iterator)); + return S_OK; +} + +static const struct IIterable_HSTRINGVtbl iterable_hstring_vtbl = +{ + /* IUnknown methods */ + iterable_hstring_QueryInterface, + iterable_hstring_AddRef, + iterable_hstring_Release, + /* IInspectable methods */ + iterable_hstring_GetIids, + iterable_hstring_GetRuntimeClassName, + iterable_hstring_GetTrustLevel, + /* IIterable<HSTRING> methods */ + iterable_hstring_First +}; + +static HRESULT WINAPI iterable_hstring_create_static(struct iterable_hstring *impl, struct iterator_hstring *iterator) +{ + impl->IIterable_HSTRING_iface.lpVtbl = &iterable_hstring_vtbl; + impl->ref = 1; + impl->iterator = &iterator->IIterator_HSTRING_iface; + + return S_OK; +} + static void test_ActivationFactory(void) { static const WCHAR *synthesizer_name = L"Windows.Media.SpeechSynthesis.SpeechSynthesizer"; @@ -141,6 +365,7 @@ static void test_ActivationFactory(void) ref = ISpeechRecognizerStatics2_Release(recognizer_statics2); ok(ref == 2, "Got unexpected refcount: %lu.\n", ref); } + else is_win10_1507 = TRUE;
check_interface(factory3, &IID_IInstalledVoicesStatic, FALSE);
@@ -449,10 +674,160 @@ done: RoUninitialize(); }
+static void test_SpeechRecognitionListConstraint(void) +{ + static const WCHAR *speech_recognition_list_constraint_name = L"Windows.Media.SpeechRecognition.SpeechRecognitionListConstraint"; + static const WCHAR *speech_constraints[] = { L"This is a test.", L"Number 5!", L"What time is it?" }; + static const WCHAR *speech_constraint_tag = L"test_message"; + ISpeechRecognitionListConstraintFactory *listconstraint_factory = NULL; + ISpeechRecognitionListConstraint *listconstraint = NULL; + ISpeechRecognitionConstraint *constraint = NULL; + IVector_HSTRING *hstring_vector = NULL; + IActivationFactory *factory = NULL; + IInspectable *inspectable = NULL; + struct iterator_hstring iterator_hstring; + struct iterable_hstring iterable_hstring; + HSTRING commands[3], str, tag, tag_out; + UINT32 i, vector_size = 0; + BOOLEAN enabled; + INT32 str_cmp; + HRESULT hr; + LONG ref; + + hr = RoInitialize(RO_INIT_MULTITHREADED); + ok(hr == S_OK, "RoInitialize failed, hr %#lx.\n", hr); + + hr = WindowsCreateString(speech_recognition_list_constraint_name, wcslen(speech_recognition_list_constraint_name), &str); + ok(hr == S_OK, "WindowsCreateString failed, hr %#lx.\n", hr); + + hr = WindowsCreateString(speech_constraint_tag, wcslen(speech_constraint_tag), &tag); + ok(hr == S_OK, "WindowsCreateString failed, hr %#lx.\n", hr); + + for (i = 0; i < ARRAY_SIZE(commands); i++) + { + hr = WindowsCreateString(speech_constraints[i], wcslen(speech_constraints[i]), &commands[i]); + ok(hr == S_OK, "WindowsCreateString failed, hr %#lx.\n", hr); + } + + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + todo_wine ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#lx.\n", hr); + + if (hr == REGDB_E_CLASSNOTREG) /* Win 8 and 8.1 */ + { + win_skip("SpeechRecognitionListConstraint activation factory not available!\n"); + goto done; + } + else if (!SUCCEEDED(hr)) goto done; + + hr = IActivationFactory_ActivateInstance(factory, &inspectable); + todo_wine ok(hr == E_NOTIMPL, "IActivationFactory_ActivateInstance failed, hr %#lx.\n", hr); + + todo_wine check_refcount(factory, 2); + todo_wine check_interface(factory, &IID_IInspectable, TRUE); + todo_wine check_interface(factory, &IID_IAgileObject, TRUE); + + hr = IActivationFactory_QueryInterface(factory, &IID_ISpeechRecognitionListConstraintFactory, (void **)&listconstraint_factory); + ok(hr == S_OK, "IActivationFactory_QueryInterface IID_ISpeechRecognitionListConstraintFactory failed, hr %#lx.\n", hr); + + hr = ISpeechRecognitionListConstraintFactory_Create(listconstraint_factory, NULL, &listconstraint); + todo_wine ok(hr == E_POINTER, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr); + + hr = ISpeechRecognitionListConstraintFactory_CreateWithTag(listconstraint_factory, NULL, NULL, &listconstraint); + todo_wine ok(hr == E_POINTER, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr); + + /* The create functions on Win10 1507 x32 break when handling the given iterator. Seems like a Windows bug. Skipping these tests. */ + if (broken(is_win10_1507 && (sizeof(void*) == 4))) + { + win_skip("SpeechRecognitionListConstraint object creation broken on Win10 1507 x32!\n"); + goto skip_create; + } + + iterator_hstring_create_static(&iterator_hstring, commands, ARRAY_SIZE(commands)); + iterable_hstring_create_static(&iterable_hstring, &iterator_hstring); + + hr = ISpeechRecognitionListConstraintFactory_CreateWithTag(listconstraint_factory, &iterable_hstring.IIterable_HSTRING_iface, NULL, &listconstraint); + todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr); + + ref = ISpeechRecognitionListConstraint_Release(listconstraint); + todo_wine ok(ref == 0, "Got unexpected ref %lu.\n", ref); + + iterator_hstring_create_static(&iterator_hstring, commands, ARRAY_SIZE(commands)); + iterable_hstring_create_static(&iterable_hstring, &iterator_hstring); + + hr = ISpeechRecognitionListConstraintFactory_CreateWithTag(listconstraint_factory, &iterable_hstring.IIterable_HSTRING_iface, tag, &listconstraint); + todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraintFactory_CreateWithTag failed, hr %#lx.\n", hr); + + todo_wine check_refcount(listconstraint, 1); + todo_wine check_interface(listconstraint, &IID_IInspectable, TRUE); + todo_wine check_interface(listconstraint, &IID_IAgileObject, TRUE); + + hr = ISpeechRecognitionListConstraint_QueryInterface(listconstraint, &IID_ISpeechRecognitionConstraint, (void **)&constraint); + todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + + hr = ISpeechRecognitionListConstraint_get_Commands(listconstraint, &hstring_vector); + todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraint_Commands failed, hr %#lx.\n", hr); + + hr = IVector_HSTRING_get_Size(hstring_vector, &vector_size); + todo_wine ok(hr == S_OK, "IVector_HSTRING_get_Size failed, hr %#lx.\n", hr); + todo_wine ok(vector_size == ARRAY_SIZE(commands), "Got unexpected vector_size %u.\n", vector_size); + + for (i = 0; i < vector_size; i++) + { + HSTRING str; + + hr = IVector_HSTRING_GetAt(hstring_vector, i, &str); + todo_wine ok(hr == S_OK, "IVector_HSTRING_GetAt failed, hr %#lx.\n", hr); + hr = WindowsCompareStringOrdinal(commands[i], str, &str_cmp); + todo_wine ok(hr == S_OK, "WindowsCompareStringOrdinal failed, hr %#lx.\n", hr); + todo_wine ok(!str_cmp, "Strings not equal.\n"); + + WindowsDeleteString(str); + } + + ref = IVector_HSTRING_Release(hstring_vector); + todo_wine ok(ref == 0, "Got unexpected ref %lu.\n", ref); + + hr = ISpeechRecognitionConstraint_get_Tag(constraint, &tag_out); + todo_wine ok(hr == S_OK, "ISpeechRecognitionConstraint_get_Tag failed, hr %#lx.\n", hr); + hr = WindowsCompareStringOrdinal(tag, tag_out, &str_cmp); + todo_wine ok(hr == S_OK, "WindowsCompareStringOrdinal failed, hr %#lx.\n", hr); + todo_wine ok(!str_cmp, "Strings not equal.\n"); + hr = WindowsDeleteString(tag_out); + todo_wine ok(hr == S_OK, "WindowsDeleteString failed, hr %#lx.\n", hr); + + hr = ISpeechRecognitionConstraint_put_IsEnabled(constraint, TRUE); + todo_wine ok(hr == S_OK, "ISpeechRecognitionConstraint_put_IsEnabled failed, hr %#lx.\n", hr); + hr = ISpeechRecognitionConstraint_get_IsEnabled(constraint, &enabled); + todo_wine ok(hr == S_OK, "ISpeechRecognitionConstraint_get_IsEnabled failed, hr %#lx.\n", hr); + todo_wine ok(enabled, "ListConstraint didn't get enabled.\n"); + + ref = ISpeechRecognitionConstraint_Release(constraint); + todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref); + + ref = ISpeechRecognitionListConstraint_Release(listconstraint); + todo_wine ok(ref == 0, "Got unexpected ref %lu.\n", ref); + +skip_create: + ref = ISpeechRecognitionListConstraintFactory_Release(listconstraint_factory); + todo_wine ok(ref == 2, "Got unexpected ref %lu.\n", ref); + + ref = IActivationFactory_Release(factory); + todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref); + +done: + WindowsDeleteString(str); + WindowsDeleteString(tag); + for (i = 0; i < ARRAY_SIZE(commands); i++) + WindowsDeleteString(commands[i]); + + RoUninitialize(); +} + START_TEST(speech) { test_ActivationFactory(); test_SpeechSynthesizer(); test_VoiceInformation(); test_SpeechRecognizer(); + test_SpeechRecognitionListConstraint(); }
From: Bernhard Kölbl besentv@gmail.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/Makefile.in | 1 + dlls/windows.media.speech/listconstraint.c | 183 +++++++++++++++++++++ dlls/windows.media.speech/main.c | 2 + dlls/windows.media.speech/private.h | 1 + dlls/windows.media.speech/tests/speech.c | 18 +- 5 files changed, 197 insertions(+), 8 deletions(-) create mode 100644 dlls/windows.media.speech/listconstraint.c
diff --git a/dlls/windows.media.speech/Makefile.in b/dlls/windows.media.speech/Makefile.in index 079578fb37f..2f9ca159e2a 100644 --- a/dlls/windows.media.speech/Makefile.in +++ b/dlls/windows.media.speech/Makefile.in @@ -2,6 +2,7 @@ MODULE = windows.media.speech.dll IMPORTS = combase uuid
C_SRCS = \ + listconstraint.c \ main.c \ recognizer.c \ synthesizer.c diff --git a/dlls/windows.media.speech/listconstraint.c b/dlls/windows.media.speech/listconstraint.c new file mode 100644 index 00000000000..107f9f4a3a8 --- /dev/null +++ b/dlls/windows.media.speech/listconstraint.c @@ -0,0 +1,183 @@ +/* WinRT Windows.Media.SpeechRecognition implementation + * + * Copyright 2022 Bernhard Kölbl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(speech); + +/* + * + * Statics for SpeechRecognitionListConstraint + * + */ + +struct listconstraint_statics +{ + IActivationFactory IActivationFactory_iface; + ISpeechRecognitionListConstraintFactory ISpeechRecognitionListConstraintFactory_iface; + LONG ref; +}; + +/* + * + * IActivationFactory + * + */ + +static inline struct listconstraint_statics *impl_from_IActivationFactory( IActivationFactory *iface ) +{ + return CONTAINING_RECORD(iface, struct listconstraint_statics, IActivationFactory_iface); +} + +static HRESULT WINAPI factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out ) +{ + struct listconstraint_statics *impl = impl_from_IActivationFactory(iface); + + TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IInspectable) || + IsEqualGUID(iid, &IID_IAgileObject) || + IsEqualGUID(iid, &IID_IActivationFactory)) + { + IInspectable_AddRef((*out = &impl->IActivationFactory_iface)); + return S_OK; + } + + if (IsEqualGUID(iid, &IID_ISpeechRecognitionListConstraintFactory)) + { + IInspectable_AddRef((*out = &impl->ISpeechRecognitionListConstraintFactory_iface)); + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef( IActivationFactory *iface ) +{ + struct listconstraint_statics *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI factory_Release( IActivationFactory *iface ) +{ + struct listconstraint_statics *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static HRESULT WINAPI factory_GetIids( IActivationFactory *iface, ULONG *iid_count, IID **iids ) +{ + FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name ) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level ) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT WINAPI factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance ) +{ + TRACE("iface %p, instance %p\n", iface, instance); + return E_NOTIMPL; +} + +static const struct IActivationFactoryVtbl activation_factory_vtbl = +{ + /* IUnknown methods */ + factory_QueryInterface, + factory_AddRef, + factory_Release, + /* IInspectable methods */ + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, + /* IActivationFactory methods */ + factory_ActivateInstance, +}; + +/* + * + * ISpeechRecognitionListConstraintFactory + * + */ + +DEFINE_IINSPECTABLE(constraint_factory, ISpeechRecognitionListConstraintFactory, struct listconstraint_statics, IActivationFactory_iface) + +static HRESULT WINAPI constraint_factory_Create( ISpeechRecognitionListConstraintFactory *iface, + IIterable_HSTRING *commands, + ISpeechRecognitionListConstraint** listconstraint ) +{ + TRACE("iface %p, commands %p, listconstraint %p.\n", iface, commands, listconstraint); + return E_NOTIMPL; +} + +static HRESULT WINAPI constraint_factory_CreateWithTag( ISpeechRecognitionListConstraintFactory *iface, + IIterable_HSTRING *commands, + HSTRING tag, + ISpeechRecognitionListConstraint** listconstraint ) +{ + TRACE("iface %p, commands %p, tag %p, listconstraint %p.\n", iface, commands, tag, listconstraint); + return E_NOTIMPL; +} + +static const struct ISpeechRecognitionListConstraintFactoryVtbl speech_recognition_list_constraint_factory_vtbl = +{ + /* IUnknown methods */ + constraint_factory_QueryInterface, + constraint_factory_AddRef, + constraint_factory_Release, + /* IInspectable methods */ + constraint_factory_GetIids, + constraint_factory_GetRuntimeClassName, + constraint_factory_GetTrustLevel, + /* ISpeechRecognitionListConstraintFactory methods */ + constraint_factory_Create, + constraint_factory_CreateWithTag, +}; + +/* + * + * ActivationFactory instances + * + */ + +static struct listconstraint_statics listconstraint_statics = +{ + .IActivationFactory_iface = {&activation_factory_vtbl}, + .ISpeechRecognitionListConstraintFactory_iface = {&speech_recognition_list_constraint_factory_vtbl}, + .ref = 1 +}; + +IActivationFactory *listconstraint_factory = &listconstraint_statics.IActivationFactory_iface; diff --git a/dlls/windows.media.speech/main.c b/dlls/windows.media.speech/main.c index 295af6ea135..e772a791588 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -40,6 +40,8 @@ HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **fac
if (!wcscmp(buffer, L"Windows.Media.SpeechRecognition.SpeechRecognizer")) IActivationFactory_AddRef((*factory = recognizer_factory)); + if (!wcscmp(buffer, L"Windows.Media.SpeechRecognition.SpeechRecognitionListConstraint")) + IActivationFactory_AddRef((*factory = listconstraint_factory)); if (!wcscmp(buffer, L"Windows.Media.SpeechSynthesis.SpeechSynthesizer")) IActivationFactory_AddRef((*factory = synthesizer_factory));
diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h index ece2a0934f2..c31b8825c74 100644 --- a/dlls/windows.media.speech/private.h +++ b/dlls/windows.media.speech/private.h @@ -46,6 +46,7 @@ * */
+extern IActivationFactory *listconstraint_factory; extern IActivationFactory *recognizer_factory;
/* diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 0a573db6f47..4ee56e63f3c 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -710,21 +710,20 @@ static void test_SpeechRecognitionListConstraint(void) }
hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); - todo_wine ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#lx.\n", hr); + ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#lx.\n", hr);
if (hr == REGDB_E_CLASSNOTREG) /* Win 8 and 8.1 */ { win_skip("SpeechRecognitionListConstraint activation factory not available!\n"); goto done; } - else if (!SUCCEEDED(hr)) goto done;
hr = IActivationFactory_ActivateInstance(factory, &inspectable); - todo_wine ok(hr == E_NOTIMPL, "IActivationFactory_ActivateInstance failed, hr %#lx.\n", hr); + ok(hr == E_NOTIMPL, "IActivationFactory_ActivateInstance failed, hr %#lx.\n", hr);
- todo_wine check_refcount(factory, 2); - todo_wine check_interface(factory, &IID_IInspectable, TRUE); - todo_wine check_interface(factory, &IID_IAgileObject, TRUE); + check_refcount(factory, 2); + check_interface(factory, &IID_IInspectable, TRUE); + check_interface(factory, &IID_IAgileObject, TRUE);
hr = IActivationFactory_QueryInterface(factory, &IID_ISpeechRecognitionListConstraintFactory, (void **)&listconstraint_factory); ok(hr == S_OK, "IActivationFactory_QueryInterface IID_ISpeechRecognitionListConstraintFactory failed, hr %#lx.\n", hr); @@ -748,6 +747,9 @@ static void test_SpeechRecognitionListConstraint(void) hr = ISpeechRecognitionListConstraintFactory_CreateWithTag(listconstraint_factory, &iterable_hstring.IIterable_HSTRING_iface, NULL, &listconstraint); todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr);
+ if (!SUCCEEDED(hr)) + goto skip_create; + ref = ISpeechRecognitionListConstraint_Release(listconstraint); todo_wine ok(ref == 0, "Got unexpected ref %lu.\n", ref);
@@ -809,10 +811,10 @@ static void test_SpeechRecognitionListConstraint(void)
skip_create: ref = ISpeechRecognitionListConstraintFactory_Release(listconstraint_factory); - todo_wine ok(ref == 2, "Got unexpected ref %lu.\n", ref); + ok(ref == 2, "Got unexpected ref %lu.\n", ref);
ref = IActivationFactory_Release(factory); - todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref); + ok(ref == 1, "Got unexpected ref %lu.\n", ref);
done: WindowsDeleteString(str);
From: Bernhard Kölbl besentv@gmail.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/windows.media.speech/listconstraint.c | 202 ++++++++++++++++++++- dlls/windows.media.speech/tests/speech.c | 29 +-- 2 files changed, 215 insertions(+), 16 deletions(-)
diff --git a/dlls/windows.media.speech/listconstraint.c b/dlls/windows.media.speech/listconstraint.c index 107f9f4a3a8..33fe9d4ae51 100644 --- a/dlls/windows.media.speech/listconstraint.c +++ b/dlls/windows.media.speech/listconstraint.c @@ -23,6 +23,185 @@
WINE_DEFAULT_DEBUG_CHANNEL(speech);
+/* + * + * SpeechRecognitionListConstraint + * + */ + +struct list_constraint +{ + ISpeechRecognitionListConstraint ISpeechRecognitionListConstraint_iface; + ISpeechRecognitionConstraint ISpeechRecognitionConstraint_iface; + LONG ref; +}; + +/* + * + * ISpeechRecognitionListConstraint + * + */ + +static inline struct list_constraint *impl_from_ISpeechRecognitionListConstraint( ISpeechRecognitionListConstraint *iface ) +{ + return CONTAINING_RECORD(iface, struct list_constraint, ISpeechRecognitionListConstraint_iface); +} + +static HRESULT WINAPI list_constraint_QueryInterface( ISpeechRecognitionListConstraint *iface, REFIID iid, void **out ) +{ + struct list_constraint *impl = impl_from_ISpeechRecognitionListConstraint(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_ISpeechRecognitionListConstraint)) + { + IInspectable_AddRef((*out = &impl->ISpeechRecognitionListConstraint_iface)); + return S_OK; + } + + if (IsEqualGUID(iid, &IID_ISpeechRecognitionConstraint)) + { + IInspectable_AddRef((*out = &impl->ISpeechRecognitionConstraint_iface)); + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI list_constraint_AddRef( ISpeechRecognitionListConstraint *iface ) +{ + struct list_constraint *impl = impl_from_ISpeechRecognitionListConstraint(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG WINAPI list_constraint_Release( ISpeechRecognitionListConstraint *iface ) +{ + struct list_constraint *impl = impl_from_ISpeechRecognitionListConstraint(iface); + + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + free(impl); + + return ref; +} + +static HRESULT WINAPI list_constraint_GetIids( ISpeechRecognitionListConstraint *iface, ULONG *iid_count, IID **iids ) +{ + FIXME("iface %p, iid_count %p, iids %p stub!\n", iface, iid_count, iids); + return E_NOTIMPL; +} + +static HRESULT WINAPI list_constraint_GetRuntimeClassName( ISpeechRecognitionListConstraint *iface, HSTRING *class_name ) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT WINAPI list_constraint_GetTrustLevel( ISpeechRecognitionListConstraint *iface, TrustLevel *trust_level ) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT WINAPI list_constraint_get_Commands( ISpeechRecognitionListConstraint *iface, IVector_HSTRING **value ) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static const struct ISpeechRecognitionListConstraintVtbl speech_recognition_list_constraint_vtbl = +{ + /* IUnknown methods */ + list_constraint_QueryInterface, + list_constraint_AddRef, + list_constraint_Release, + /* IInspectable methods */ + list_constraint_GetIids, + list_constraint_GetRuntimeClassName, + list_constraint_GetTrustLevel, + /* ISpeechRecognitionListConstraint methods */ + list_constraint_get_Commands +}; + +/* + * + * ISpeechRecognitionConstraint + * + */ + +DEFINE_IINSPECTABLE(constraint, ISpeechRecognitionConstraint, struct list_constraint, ISpeechRecognitionListConstraint_iface) + +static HRESULT WINAPI constraint_get_IsEnabled( ISpeechRecognitionConstraint *iface, BOOLEAN *value ) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI constraint_put_IsEnabled( ISpeechRecognitionConstraint *iface, BOOLEAN value ) +{ + FIXME("iface %p, value %u stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI constraint_get_Tag( ISpeechRecognitionConstraint *iface, HSTRING *value ) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI constraint_put_Tag( ISpeechRecognitionConstraint *iface, HSTRING value ) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI constraint_get_Type( ISpeechRecognitionConstraint *iface, SpeechRecognitionConstraintType *value ) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI constraint_get_Probability( ISpeechRecognitionConstraint *iface, SpeechRecognitionConstraintProbability *value ) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static HRESULT WINAPI constraint_put_Probability( ISpeechRecognitionConstraint *iface, SpeechRecognitionConstraintProbability value ) +{ + FIXME("iface %p, value %u stub!\n", iface, value); + return E_NOTIMPL; +} + +static const struct ISpeechRecognitionConstraintVtbl speech_recognition_constraint_vtbl = +{ + /* IUnknown methods */ + constraint_QueryInterface, + constraint_AddRef, + constraint_Release, + /* IInspectable methods */ + constraint_GetIids, + constraint_GetRuntimeClassName, + constraint_GetTrustLevel, + /* ISpeechRecognitionConstraint methods */ + constraint_get_IsEnabled, + constraint_put_IsEnabled, + constraint_get_Tag, + constraint_put_Tag, + constraint_get_Type, + constraint_get_Probability, + constraint_put_Probability +}; + /* * * Statics for SpeechRecognitionListConstraint @@ -140,7 +319,7 @@ static HRESULT WINAPI constraint_factory_Create( ISpeechRecognitionListConstrain ISpeechRecognitionListConstraint** listconstraint ) { TRACE("iface %p, commands %p, listconstraint %p.\n", iface, commands, listconstraint); - return E_NOTIMPL; + return ISpeechRecognitionListConstraintFactory_CreateWithTag(iface, commands, NULL, listconstraint); }
static HRESULT WINAPI constraint_factory_CreateWithTag( ISpeechRecognitionListConstraintFactory *iface, @@ -148,8 +327,27 @@ static HRESULT WINAPI constraint_factory_CreateWithTag( ISpeechRecognitionListCo HSTRING tag, ISpeechRecognitionListConstraint** listconstraint ) { + struct list_constraint *impl; + TRACE("iface %p, commands %p, tag %p, listconstraint %p.\n", iface, commands, tag, listconstraint); - return E_NOTIMPL; + + if (!commands) + return E_POINTER; + + if (!(impl = calloc(1, sizeof(*impl)))) + { + *listconstraint = NULL; + return E_OUTOFMEMORY; + } + + impl->ISpeechRecognitionListConstraint_iface.lpVtbl = &speech_recognition_list_constraint_vtbl; + impl->ISpeechRecognitionConstraint_iface.lpVtbl = &speech_recognition_constraint_vtbl; + impl->ref = 1; + + TRACE("created SpeechRecognitionListConstraint %p.\n", impl); + + *listconstraint = &impl->ISpeechRecognitionListConstraint_iface; + return S_OK; }
static const struct ISpeechRecognitionListConstraintFactoryVtbl speech_recognition_list_constraint_factory_vtbl = diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 4ee56e63f3c..a88b8aae3d2 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -729,10 +729,10 @@ static void test_SpeechRecognitionListConstraint(void) ok(hr == S_OK, "IActivationFactory_QueryInterface IID_ISpeechRecognitionListConstraintFactory failed, hr %#lx.\n", hr);
hr = ISpeechRecognitionListConstraintFactory_Create(listconstraint_factory, NULL, &listconstraint); - todo_wine ok(hr == E_POINTER, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr); + ok(hr == E_POINTER, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr);
hr = ISpeechRecognitionListConstraintFactory_CreateWithTag(listconstraint_factory, NULL, NULL, &listconstraint); - todo_wine ok(hr == E_POINTER, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr); + ok(hr == E_POINTER, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr);
/* The create functions on Win10 1507 x32 break when handling the given iterator. Seems like a Windows bug. Skipping these tests. */ if (broken(is_win10_1507 && (sizeof(void*) == 4))) @@ -745,30 +745,30 @@ static void test_SpeechRecognitionListConstraint(void) iterable_hstring_create_static(&iterable_hstring, &iterator_hstring);
hr = ISpeechRecognitionListConstraintFactory_CreateWithTag(listconstraint_factory, &iterable_hstring.IIterable_HSTRING_iface, NULL, &listconstraint); - todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr); - - if (!SUCCEEDED(hr)) - goto skip_create; + ok(hr == S_OK, "ISpeechRecognitionListConstraintFactory_Create failed, hr %#lx.\n", hr);
ref = ISpeechRecognitionListConstraint_Release(listconstraint); - todo_wine ok(ref == 0, "Got unexpected ref %lu.\n", ref); + ok(ref == 0, "Got unexpected ref %lu.\n", ref);
iterator_hstring_create_static(&iterator_hstring, commands, ARRAY_SIZE(commands)); iterable_hstring_create_static(&iterable_hstring, &iterator_hstring);
hr = ISpeechRecognitionListConstraintFactory_CreateWithTag(listconstraint_factory, &iterable_hstring.IIterable_HSTRING_iface, tag, &listconstraint); - todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraintFactory_CreateWithTag failed, hr %#lx.\n", hr); + ok(hr == S_OK, "ISpeechRecognitionListConstraintFactory_CreateWithTag failed, hr %#lx.\n", hr);
- todo_wine check_refcount(listconstraint, 1); - todo_wine check_interface(listconstraint, &IID_IInspectable, TRUE); - todo_wine check_interface(listconstraint, &IID_IAgileObject, TRUE); + check_refcount(listconstraint, 1); + check_interface(listconstraint, &IID_IInspectable, TRUE); + check_interface(listconstraint, &IID_IAgileObject, TRUE);
hr = ISpeechRecognitionListConstraint_QueryInterface(listconstraint, &IID_ISpeechRecognitionConstraint, (void **)&constraint); - todo_wine ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); + ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
hr = ISpeechRecognitionListConstraint_get_Commands(listconstraint, &hstring_vector); todo_wine ok(hr == S_OK, "ISpeechRecognitionListConstraint_Commands failed, hr %#lx.\n", hr);
+ if (!SUCCEEDED(hr)) + goto skip_tests; + hr = IVector_HSTRING_get_Size(hstring_vector, &vector_size); todo_wine ok(hr == S_OK, "IVector_HSTRING_get_Size failed, hr %#lx.\n", hr); todo_wine ok(vector_size == ARRAY_SIZE(commands), "Got unexpected vector_size %u.\n", vector_size); @@ -803,11 +803,12 @@ static void test_SpeechRecognitionListConstraint(void) todo_wine ok(hr == S_OK, "ISpeechRecognitionConstraint_get_IsEnabled failed, hr %#lx.\n", hr); todo_wine ok(enabled, "ListConstraint didn't get enabled.\n");
+skip_tests: ref = ISpeechRecognitionConstraint_Release(constraint); - todo_wine ok(ref == 1, "Got unexpected ref %lu.\n", ref); + ok(ref == 1, "Got unexpected ref %lu.\n", ref);
ref = ISpeechRecognitionListConstraint_Release(listconstraint); - todo_wine ok(ref == 0, "Got unexpected ref %lu.\n", ref); + ok(ref == 0, "Got unexpected ref %lu.\n", ref);
skip_create: ref = ISpeechRecognitionListConstraintFactory_Release(listconstraint_factory);