Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/main.c | 26 +-------------- dlls/windows.media.speech/private.h | 52 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 dlls/windows.media.speech/private.h
diff --git a/dlls/windows.media.speech/main.c b/dlls/windows.media.speech/main.c index d14d06773f7..f81c1bbfedd 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -17,35 +17,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include <stdarg.h> - -#define COBJMACROS -#include "windef.h" -#include "winbase.h" -#include "winstring.h" -#include "wine/debug.h" -#include "objbase.h" - #include "initguid.h" -#include "activation.h" - -#define WIDL_using_Windows_Foundation -#define WIDL_using_Windows_Foundation_Collections -#include "windows.foundation.h" -#define WIDL_using_Windows_Media_SpeechSynthesis -#include "windows.media.speechsynthesis.h" +#include "private.h"
WINE_DEFAULT_DEBUG_CHANNEL(speech);
-static const char *debugstr_hstring(HSTRING hstr) -{ - const WCHAR *str; - UINT32 len; - if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)"; - str = WindowsGetStringRawBuffer(hstr, &len); - return wine_dbgstr_wn(str, len); -} - struct voice_information_vector { IVectorView_VoiceInformation IVectorView_VoiceInformation_iface; diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h new file mode 100644 index 00000000000..8162ca45094 --- /dev/null +++ b/dlls/windows.media.speech/private.h @@ -0,0 +1,52 @@ +/* WinRT Windows.Media.Speech private header + * + * 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 + */ + +#ifndef __WINE_WINDOWS_MEDIA_SPEECH_PRIVATE_H +#define __WINE_WINDOWS_MEDIA_SPEECH_PRIVATE_H + +#include <stdarg.h> + +#define COBJMACROS +#include "windef.h" +#include "winbase.h" +#include "winstring.h" +#include "objbase.h" + +#include "activation.h" + +#define WIDL_using_Windows_Foundation +#define WIDL_using_Windows_Foundation_Collections +#include "windows.foundation.h" +#define WIDL_using_Windows_Globalization +#include "windows.globalization.h" +#define WIDL_using_Windows_Media_SpeechSynthesis +#include "windows.media.speechsynthesis.h" + +#include "wine/debug.h" + +static inline const char *debugstr_hstring(HSTRING hstr) +{ + const WCHAR *str; + UINT32 len; + if (hstr && !((ULONG_PTR)hstr >> 16)) return "(invalid)"; + str = WindowsGetStringRawBuffer(hstr, &len); + return wine_dbgstr_wn(str, len); +} + +#endif
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- v2: Expose synthesizer factory through extern pointer. --- dlls/windows.media.speech/Makefile.in | 3 +- dlls/windows.media.speech/main.c | 546 +---------------------- dlls/windows.media.speech/private.h | 8 + dlls/windows.media.speech/synthesizer.c | 566 ++++++++++++++++++++++++ 4 files changed, 577 insertions(+), 546 deletions(-) create mode 100644 dlls/windows.media.speech/synthesizer.c
diff --git a/dlls/windows.media.speech/Makefile.in b/dlls/windows.media.speech/Makefile.in index 9fbff8e132f..74eb7b93fea 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 = \ - main.c + main.c \ + synthesizer.c
IDL_SRCS = classes.idl diff --git a/dlls/windows.media.speech/main.c b/dlls/windows.media.speech/main.c index f81c1bbfedd..047e1ab0e90 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -22,548 +22,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(speech);
-struct voice_information_vector -{ - IVectorView_VoiceInformation IVectorView_VoiceInformation_iface; - LONG ref; -}; - -static inline struct voice_information_vector *impl_from_IVectorView_VoiceInformation(IVectorView_VoiceInformation *iface) -{ - return CONTAINING_RECORD(iface, struct voice_information_vector, IVectorView_VoiceInformation_iface); -} - -static HRESULT STDMETHODCALLTYPE vector_view_voice_information_QueryInterface( - IVectorView_VoiceInformation *iface, REFIID iid, void **out) -{ - 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_IVectorView_VoiceInformation)) - { - IUnknown_AddRef(iface); - *out = iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE vector_view_voice_information_AddRef( - IVectorView_VoiceInformation *iface) -{ - struct voice_information_vector *impl = impl_from_IVectorView_VoiceInformation(iface); - ULONG ref = InterlockedIncrement(&impl->ref); - TRACE("iface %p, ref %lu.\n", iface, ref); - return ref; -} - -static ULONG STDMETHODCALLTYPE vector_view_voice_information_Release( - IVectorView_VoiceInformation *iface) -{ - struct voice_information_vector *impl = impl_from_IVectorView_VoiceInformation(iface); - ULONG ref = InterlockedDecrement(&impl->ref); - TRACE("iface %p, ref %lu.\n", iface, ref); - return ref; -} - -static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetIids( - IVectorView_VoiceInformation *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 STDMETHODCALLTYPE vector_view_voice_information_GetRuntimeClassName( - IVectorView_VoiceInformation *iface, HSTRING *class_name) -{ - FIXME("iface %p, class_name %p stub!\n", iface, class_name); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetTrustLevel( - IVectorView_VoiceInformation *iface, TrustLevel *trust_level) -{ - FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetAt( - IVectorView_VoiceInformation *iface, UINT32 index, IVoiceInformation **value) -{ - FIXME("iface %p, index %#x, value %p stub!\n", iface, index, value); - *value = NULL; - return E_BOUNDS; -} - -static HRESULT STDMETHODCALLTYPE vector_view_voice_information_get_Size( - IVectorView_VoiceInformation *iface, UINT32 *value) -{ - FIXME("iface %p, value %p stub!\n", iface, value); - *value = 0; - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE vector_view_voice_information_IndexOf( - IVectorView_VoiceInformation *iface, IVoiceInformation *element, UINT32 *index, BOOLEAN *found) -{ - FIXME("iface %p, element %p, index %p, found %p stub!\n", iface, element, index, found); - *index = 0; - *found = FALSE; - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetMany( - IVectorView_VoiceInformation *iface, UINT32 start_index, - UINT32 items_size, IVoiceInformation **items, UINT *value) -{ - FIXME("iface %p, start_index %#x, items %p, value %p stub!\n", iface, start_index, items, value); - *value = 0; - return S_OK; -} - -static const struct IVectorView_VoiceInformationVtbl vector_view_voice_information_vtbl = -{ - vector_view_voice_information_QueryInterface, - vector_view_voice_information_AddRef, - vector_view_voice_information_Release, - /* IInspectable methods */ - vector_view_voice_information_GetIids, - vector_view_voice_information_GetRuntimeClassName, - vector_view_voice_information_GetTrustLevel, - /* IVectorView<VoiceInformation> methods */ - vector_view_voice_information_GetAt, - vector_view_voice_information_get_Size, - vector_view_voice_information_IndexOf, - vector_view_voice_information_GetMany, -}; - -static struct voice_information_vector all_voices = -{ - {&vector_view_voice_information_vtbl}, - 0 -}; - -struct speech_synthesizer -{ - ISpeechSynthesizer ISpeechSynthesizer_iface; - IClosable IClosable_iface; - LONG ref; -}; - -static inline struct speech_synthesizer *impl_from_ISpeechSynthesizer(ISpeechSynthesizer *iface) -{ - return CONTAINING_RECORD(iface, struct speech_synthesizer, ISpeechSynthesizer_iface); -} - -static inline struct speech_synthesizer *impl_from_IClosable(IClosable *iface) -{ - return CONTAINING_RECORD(iface, struct speech_synthesizer, IClosable_iface); -} - -static HRESULT STDMETHODCALLTYPE speech_synthesizer_QueryInterface( - ISpeechSynthesizer *iface, REFIID iid, void **out) -{ - struct speech_synthesizer *impl = impl_from_ISpeechSynthesizer(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_ISpeechSynthesizer)) - { - IUnknown_AddRef(iface); - *out = iface; - return S_OK; - } - - if (IsEqualGUID(iid, &IID_IClosable)) - { - IUnknown_AddRef(iface); - *out = &impl->IClosable_iface; - return S_OK; - } - - FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE speech_synthesizer_AddRef( - ISpeechSynthesizer *iface) -{ - struct speech_synthesizer *impl = impl_from_ISpeechSynthesizer(iface); - ULONG ref = InterlockedIncrement(&impl->ref); - - TRACE("iface %p, ref %lu.\n", iface, ref); - - return ref; -} - -static ULONG STDMETHODCALLTYPE speech_synthesizer_Release( - ISpeechSynthesizer *iface) -{ - struct speech_synthesizer *impl = impl_from_ISpeechSynthesizer(iface); - ULONG ref = InterlockedDecrement(&impl->ref); - - TRACE("iface %p, ref %lu.\n", iface, ref); - - if (!ref) - free(impl); - - return ref; -} - -static HRESULT STDMETHODCALLTYPE speech_synthesizer_GetIids( - ISpeechSynthesizer *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 STDMETHODCALLTYPE speech_synthesizer_GetRuntimeClassName( - ISpeechSynthesizer *iface, HSTRING *class_name) -{ - FIXME("iface %p, class_name %p stub.\n", iface, class_name); - - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE speech_synthesizer_GetTrustLevel( - ISpeechSynthesizer *iface, TrustLevel *trust_level) -{ - FIXME("iface %p, trust_level %p stub.\n", iface, trust_level); - - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE speech_synthesizer_SynthesizeTextToStreamAsync(ISpeechSynthesizer *iface, - HSTRING text, IAsyncOperation_SpeechSynthesisStream **operation) -{ - FIXME("iface %p, text %p, operation %p stub.\n", iface, text, operation); - - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE speech_synthesizer_SynthesizeSsmlToStreamAsync(ISpeechSynthesizer *iface, - HSTRING ssml, IAsyncOperation_SpeechSynthesisStream **operation) -{ - FIXME("iface %p, text %p, operation %p stub.\n", iface, ssml, operation); - - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE speech_synthesizer_put_Voice(ISpeechSynthesizer *iface, IVoiceInformation *value) -{ - FIXME("iface %p, value %p stub.\n", iface, value); - - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE speech_synthesizer_get_Voice(ISpeechSynthesizer *iface, IVoiceInformation **value) -{ - FIXME("iface %p, value %p stub.\n", iface, value); - - return E_NOTIMPL; -} - -static const struct ISpeechSynthesizerVtbl speech_synthesizer_vtbl = -{ - /* IUnknown methods */ - speech_synthesizer_QueryInterface, - speech_synthesizer_AddRef, - speech_synthesizer_Release, - /* IInspectable methods */ - speech_synthesizer_GetIids, - speech_synthesizer_GetRuntimeClassName, - speech_synthesizer_GetTrustLevel, - /* ISpeechSynthesizer methods */ - speech_synthesizer_SynthesizeTextToStreamAsync, - speech_synthesizer_SynthesizeSsmlToStreamAsync, - speech_synthesizer_put_Voice, - speech_synthesizer_get_Voice, -}; - -static HRESULT STDMETHODCALLTYPE closable_QueryInterface( - IClosable *iface, REFIID iid, void **out) -{ - struct speech_synthesizer *impl = impl_from_IClosable(iface); - - return speech_synthesizer_QueryInterface(&impl->ISpeechSynthesizer_iface, iid, out); -} - -static ULONG STDMETHODCALLTYPE closable_AddRef( - IClosable *iface) -{ - struct speech_synthesizer *impl = impl_from_IClosable(iface); - ULONG ref = InterlockedIncrement(&impl->ref); - - TRACE("iface %p, ref %lu.\n", iface, ref); - - return ref; -} - -static ULONG STDMETHODCALLTYPE closable_Release( - IClosable *iface) -{ - struct speech_synthesizer *impl = impl_from_IClosable(iface); - ULONG ref = InterlockedDecrement(&impl->ref); - - TRACE("iface %p, ref %lu.\n", iface, ref); - - if (!ref) - free(impl); - - return ref; -} - -static HRESULT STDMETHODCALLTYPE closable_GetIids( - IClosable *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 STDMETHODCALLTYPE closable_GetRuntimeClassName( - IClosable *iface, HSTRING *class_name) -{ - FIXME("iface %p, class_name %p stub.\n", iface, class_name); - - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE closable_GetTrustLevel( - IClosable *iface, TrustLevel *trust_level) -{ - FIXME("iface %p, trust_level %p stub.\n", iface, trust_level); - - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE closable_Close( - IClosable *iface) -{ - FIXME("iface %p stub.\n", iface); - - return E_NOTIMPL; -} - -static const struct IClosableVtbl closable_vtbl = -{ - /* IUnknown methods */ - closable_QueryInterface, - closable_AddRef, - closable_Release, - /* IInspectable methods */ - closable_GetIids, - closable_GetRuntimeClassName, - closable_GetTrustLevel, - /* IClosable methods */ - closable_Close, -}; - -struct windows_media_speech -{ - IActivationFactory IActivationFactory_iface; - IInstalledVoicesStatic IInstalledVoicesStatic_iface; - LONG ref; -}; - -static inline struct windows_media_speech *impl_from_IActivationFactory(IActivationFactory *iface) -{ - return CONTAINING_RECORD(iface, struct windows_media_speech, IActivationFactory_iface); -} - -static inline struct windows_media_speech *impl_from_IInstalledVoicesStatic(IInstalledVoicesStatic *iface) -{ - return CONTAINING_RECORD(iface, struct windows_media_speech, IInstalledVoicesStatic_iface); -} - -static HRESULT STDMETHODCALLTYPE windows_media_speech_QueryInterface( - IActivationFactory *iface, REFIID iid, void **out) -{ - struct windows_media_speech *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)) - { - IUnknown_AddRef(iface); - *out = iface; - return S_OK; - } - - if (IsEqualGUID(iid, &IID_IInstalledVoicesStatic)) - { - IUnknown_AddRef(iface); - *out = &impl->IInstalledVoicesStatic_iface; - return S_OK; - } - - FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - *out = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE windows_media_speech_AddRef( - IActivationFactory *iface) -{ - struct windows_media_speech *impl = impl_from_IActivationFactory(iface); - ULONG ref = InterlockedIncrement(&impl->ref); - TRACE("iface %p, ref %lu.\n", iface, ref); - return ref; -} - -static ULONG STDMETHODCALLTYPE windows_media_speech_Release( - IActivationFactory *iface) -{ - struct windows_media_speech *impl = impl_from_IActivationFactory(iface); - ULONG ref = InterlockedDecrement(&impl->ref); - TRACE("iface %p, ref %lu.\n", iface, ref); - return ref; -} - -static HRESULT STDMETHODCALLTYPE windows_media_speech_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 STDMETHODCALLTYPE windows_media_speech_GetRuntimeClassName( - IActivationFactory *iface, HSTRING *class_name) -{ - FIXME("iface %p, class_name %p stub!\n", iface, class_name); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE windows_media_speech_GetTrustLevel( - IActivationFactory *iface, TrustLevel *trust_level) -{ - FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE windows_media_speech_ActivateInstance( - IActivationFactory *iface, IInspectable **instance) -{ - struct speech_synthesizer *obj; - - TRACE("iface %p, instance %p.\n", iface, instance); - - if (!(obj = calloc(1, sizeof(*obj)))) - { - *instance = NULL; - return E_OUTOFMEMORY; - } - - obj->ISpeechSynthesizer_iface.lpVtbl = &speech_synthesizer_vtbl; - obj->IClosable_iface.lpVtbl = &closable_vtbl; - obj->ref = 1; - *instance = (IInspectable *)&obj->ISpeechSynthesizer_iface; - return S_OK; -} - -static const struct IActivationFactoryVtbl activation_factory_vtbl = -{ - windows_media_speech_QueryInterface, - windows_media_speech_AddRef, - windows_media_speech_Release, - /* IInspectable methods */ - windows_media_speech_GetIids, - windows_media_speech_GetRuntimeClassName, - windows_media_speech_GetTrustLevel, - /* IActivationFactory methods */ - windows_media_speech_ActivateInstance, -}; - -static HRESULT STDMETHODCALLTYPE installed_voices_static_QueryInterface( - IInstalledVoicesStatic *iface, REFIID iid, void **out) -{ - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); - return windows_media_speech_QueryInterface(&impl->IActivationFactory_iface, iid, out); -} - -static ULONG STDMETHODCALLTYPE installed_voices_static_AddRef( - IInstalledVoicesStatic *iface) -{ - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); - return windows_media_speech_AddRef(&impl->IActivationFactory_iface); -} - -static ULONG STDMETHODCALLTYPE installed_voices_static_Release( - IInstalledVoicesStatic *iface) -{ - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); - return windows_media_speech_Release(&impl->IActivationFactory_iface); -} - -static HRESULT STDMETHODCALLTYPE installed_voices_static_GetIids( - IInstalledVoicesStatic *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 STDMETHODCALLTYPE installed_voices_static_GetRuntimeClassName( - IInstalledVoicesStatic *iface, HSTRING *class_name) -{ - FIXME("iface %p, class_name %p stub!\n", iface, class_name); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE installed_voices_static_GetTrustLevel( - IInstalledVoicesStatic *iface, TrustLevel *trust_level) -{ - FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); - return E_NOTIMPL; -} - -static HRESULT STDMETHODCALLTYPE installed_voices_static_get_AllVoices( - IInstalledVoicesStatic *iface, IVectorView_VoiceInformation **value) -{ - TRACE("iface %p, value %p.\n", iface, value); - *value = &all_voices.IVectorView_VoiceInformation_iface; - IVectorView_VoiceInformation_AddRef(*value); - return S_OK; -} - -static HRESULT STDMETHODCALLTYPE installed_voices_static_get_DefaultVoice( - IInstalledVoicesStatic *iface, IVoiceInformation **value) -{ - FIXME("iface %p, value %p stub!\n", iface, value); - return E_NOTIMPL; -} - -static const struct IInstalledVoicesStaticVtbl installed_voices_static_vtbl = -{ - installed_voices_static_QueryInterface, - installed_voices_static_AddRef, - installed_voices_static_Release, - /* IInspectable methods */ - installed_voices_static_GetIids, - installed_voices_static_GetRuntimeClassName, - installed_voices_static_GetTrustLevel, - /* IInstalledVoicesStatic methods */ - installed_voices_static_get_AllVoices, - installed_voices_static_get_DefaultVoice, -}; - -static struct windows_media_speech windows_media_speech = -{ - {&activation_factory_vtbl}, - {&installed_voices_static_vtbl}, - 1 -}; - HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out) { FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out); @@ -580,7 +38,5 @@ HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **fac return CLASS_E_CLASSNOTAVAILABLE; }
- *factory = &windows_media_speech.IActivationFactory_iface; - IUnknown_AddRef(*factory); - return S_OK; + return IActivationFactory_QueryInterface(synthesizer_factory, &IID_IActivationFactory, (void**)factory); } diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h index 8162ca45094..1cb1a511c0d 100644 --- a/dlls/windows.media.speech/private.h +++ b/dlls/windows.media.speech/private.h @@ -49,4 +49,12 @@ static inline const char *debugstr_hstring(HSTRING hstr) return wine_dbgstr_wn(str, len); }
+/* + * + * Windows.Media.SpeechSynthesis + * + */ + +extern IActivationFactory *synthesizer_factory; + #endif diff --git a/dlls/windows.media.speech/synthesizer.c b/dlls/windows.media.speech/synthesizer.c new file mode 100644 index 00000000000..45b16ad6dac --- /dev/null +++ b/dlls/windows.media.speech/synthesizer.c @@ -0,0 +1,566 @@ +/* WinRT Windows.Media.Speech implementation + * + * Copyright 2021 Rémi Bernon for CodeWeavers + * + * 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" + +WINE_DEFAULT_DEBUG_CHANNEL(speech); + +struct voice_information_vector +{ + IVectorView_VoiceInformation IVectorView_VoiceInformation_iface; + LONG ref; +}; + +static inline struct voice_information_vector *impl_from_IVectorView_VoiceInformation(IVectorView_VoiceInformation *iface) +{ + return CONTAINING_RECORD(iface, struct voice_information_vector, IVectorView_VoiceInformation_iface); +} + +static HRESULT STDMETHODCALLTYPE vector_view_voice_information_QueryInterface( + IVectorView_VoiceInformation *iface, REFIID iid, void **out) +{ + 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_IVectorView_VoiceInformation)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE vector_view_voice_information_AddRef( + IVectorView_VoiceInformation *iface) +{ + struct voice_information_vector *impl = impl_from_IVectorView_VoiceInformation(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE vector_view_voice_information_Release( + IVectorView_VoiceInformation *iface) +{ + struct voice_information_vector *impl = impl_from_IVectorView_VoiceInformation(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetIids( + IVectorView_VoiceInformation *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 STDMETHODCALLTYPE vector_view_voice_information_GetRuntimeClassName( + IVectorView_VoiceInformation *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetTrustLevel( + IVectorView_VoiceInformation *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetAt( + IVectorView_VoiceInformation *iface, UINT32 index, IVoiceInformation **value) +{ + FIXME("iface %p, index %#x, value %p stub!\n", iface, index, value); + *value = NULL; + return E_BOUNDS; +} + +static HRESULT STDMETHODCALLTYPE vector_view_voice_information_get_Size( + IVectorView_VoiceInformation *iface, UINT32 *value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + *value = 0; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE vector_view_voice_information_IndexOf( + IVectorView_VoiceInformation *iface, IVoiceInformation *element, UINT32 *index, BOOLEAN *found) +{ + FIXME("iface %p, element %p, index %p, found %p stub!\n", iface, element, index, found); + *index = 0; + *found = FALSE; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE vector_view_voice_information_GetMany( + IVectorView_VoiceInformation *iface, UINT32 start_index, + UINT32 items_size, IVoiceInformation **items, UINT *value) +{ + FIXME("iface %p, start_index %#x, items %p, value %p stub!\n", iface, start_index, items, value); + *value = 0; + return S_OK; +} + +static const struct IVectorView_VoiceInformationVtbl vector_view_voice_information_vtbl = +{ + vector_view_voice_information_QueryInterface, + vector_view_voice_information_AddRef, + vector_view_voice_information_Release, + /* IInspectable methods */ + vector_view_voice_information_GetIids, + vector_view_voice_information_GetRuntimeClassName, + vector_view_voice_information_GetTrustLevel, + /* IVectorView<VoiceInformation> methods */ + vector_view_voice_information_GetAt, + vector_view_voice_information_get_Size, + vector_view_voice_information_IndexOf, + vector_view_voice_information_GetMany, +}; + +static struct voice_information_vector all_voices = +{ + {&vector_view_voice_information_vtbl}, + 0 +}; + +struct speech_synthesizer +{ + ISpeechSynthesizer ISpeechSynthesizer_iface; + IClosable IClosable_iface; + LONG ref; +}; + +static inline struct speech_synthesizer *impl_from_ISpeechSynthesizer(ISpeechSynthesizer *iface) +{ + return CONTAINING_RECORD(iface, struct speech_synthesizer, ISpeechSynthesizer_iface); +} + +static inline struct speech_synthesizer *impl_from_IClosable(IClosable *iface) +{ + return CONTAINING_RECORD(iface, struct speech_synthesizer, IClosable_iface); +} + +static HRESULT STDMETHODCALLTYPE speech_synthesizer_QueryInterface( + ISpeechSynthesizer *iface, REFIID iid, void **out) +{ + struct speech_synthesizer *impl = impl_from_ISpeechSynthesizer(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_ISpeechSynthesizer)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + if (IsEqualGUID(iid, &IID_IClosable)) + { + IUnknown_AddRef(iface); + *out = &impl->IClosable_iface; + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE speech_synthesizer_AddRef( + ISpeechSynthesizer *iface) +{ + struct speech_synthesizer *impl = impl_from_ISpeechSynthesizer(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + return ref; +} + +static ULONG STDMETHODCALLTYPE speech_synthesizer_Release( + ISpeechSynthesizer *iface) +{ + struct speech_synthesizer *impl = impl_from_ISpeechSynthesizer(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + free(impl); + + return ref; +} + +static HRESULT STDMETHODCALLTYPE speech_synthesizer_GetIids( + ISpeechSynthesizer *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 STDMETHODCALLTYPE speech_synthesizer_GetRuntimeClassName( + ISpeechSynthesizer *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub.\n", iface, class_name); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE speech_synthesizer_GetTrustLevel( + ISpeechSynthesizer *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub.\n", iface, trust_level); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE speech_synthesizer_SynthesizeTextToStreamAsync(ISpeechSynthesizer *iface, + HSTRING text, IAsyncOperation_SpeechSynthesisStream **operation) +{ + FIXME("iface %p, text %p, operation %p stub.\n", iface, text, operation); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE speech_synthesizer_SynthesizeSsmlToStreamAsync(ISpeechSynthesizer *iface, + HSTRING ssml, IAsyncOperation_SpeechSynthesisStream **operation) +{ + FIXME("iface %p, text %p, operation %p stub.\n", iface, ssml, operation); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE speech_synthesizer_put_Voice(ISpeechSynthesizer *iface, IVoiceInformation *value) +{ + FIXME("iface %p, value %p stub.\n", iface, value); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE speech_synthesizer_get_Voice(ISpeechSynthesizer *iface, IVoiceInformation **value) +{ + FIXME("iface %p, value %p stub.\n", iface, value); + + return E_NOTIMPL; +} + +static const struct ISpeechSynthesizerVtbl speech_synthesizer_vtbl = +{ + /* IUnknown methods */ + speech_synthesizer_QueryInterface, + speech_synthesizer_AddRef, + speech_synthesizer_Release, + /* IInspectable methods */ + speech_synthesizer_GetIids, + speech_synthesizer_GetRuntimeClassName, + speech_synthesizer_GetTrustLevel, + /* ISpeechSynthesizer methods */ + speech_synthesizer_SynthesizeTextToStreamAsync, + speech_synthesizer_SynthesizeSsmlToStreamAsync, + speech_synthesizer_put_Voice, + speech_synthesizer_get_Voice, +}; + +static HRESULT STDMETHODCALLTYPE closable_QueryInterface( + IClosable *iface, REFIID iid, void **out) +{ + struct speech_synthesizer *impl = impl_from_IClosable(iface); + + return speech_synthesizer_QueryInterface(&impl->ISpeechSynthesizer_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE closable_AddRef( + IClosable *iface) +{ + struct speech_synthesizer *impl = impl_from_IClosable(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + return ref; +} + +static ULONG STDMETHODCALLTYPE closable_Release( + IClosable *iface) +{ + struct speech_synthesizer *impl = impl_from_IClosable(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + + TRACE("iface %p, ref %lu.\n", iface, ref); + + if (!ref) + free(impl); + + return ref; +} + +static HRESULT STDMETHODCALLTYPE closable_GetIids( + IClosable *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 STDMETHODCALLTYPE closable_GetRuntimeClassName( + IClosable *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub.\n", iface, class_name); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE closable_GetTrustLevel( + IClosable *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub.\n", iface, trust_level); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE closable_Close( + IClosable *iface) +{ + FIXME("iface %p stub.\n", iface); + + return E_NOTIMPL; +} + +static const struct IClosableVtbl closable_vtbl = +{ + /* IUnknown methods */ + closable_QueryInterface, + closable_AddRef, + closable_Release, + /* IInspectable methods */ + closable_GetIids, + closable_GetRuntimeClassName, + closable_GetTrustLevel, + /* IClosable methods */ + closable_Close, +}; + +struct windows_media_speech +{ + IActivationFactory IActivationFactory_iface; + IInstalledVoicesStatic IInstalledVoicesStatic_iface; + LONG ref; +}; + +static inline struct windows_media_speech *impl_from_IActivationFactory(IActivationFactory *iface) +{ + return CONTAINING_RECORD(iface, struct windows_media_speech, IActivationFactory_iface); +} + +static inline struct windows_media_speech *impl_from_IInstalledVoicesStatic(IInstalledVoicesStatic *iface) +{ + return CONTAINING_RECORD(iface, struct windows_media_speech, IInstalledVoicesStatic_iface); +} + +static HRESULT STDMETHODCALLTYPE windows_media_speech_QueryInterface( + IActivationFactory *iface, REFIID iid, void **out) +{ + struct windows_media_speech *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)) + { + IUnknown_AddRef(iface); + *out = iface; + return S_OK; + } + + if (IsEqualGUID(iid, &IID_IInstalledVoicesStatic)) + { + IUnknown_AddRef(iface); + *out = &impl->IInstalledVoicesStatic_iface; + return S_OK; + } + + FIXME("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE windows_media_speech_AddRef( + IActivationFactory *iface) +{ + struct windows_media_speech *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedIncrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static ULONG STDMETHODCALLTYPE windows_media_speech_Release( + IActivationFactory *iface) +{ + struct windows_media_speech *impl = impl_from_IActivationFactory(iface); + ULONG ref = InterlockedDecrement(&impl->ref); + TRACE("iface %p, ref %lu.\n", iface, ref); + return ref; +} + +static HRESULT STDMETHODCALLTYPE windows_media_speech_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 STDMETHODCALLTYPE windows_media_speech_GetRuntimeClassName( + IActivationFactory *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE windows_media_speech_GetTrustLevel( + IActivationFactory *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE windows_media_speech_ActivateInstance( + IActivationFactory *iface, IInspectable **instance) +{ + struct speech_synthesizer *obj; + + TRACE("iface %p, instance %p.\n", iface, instance); + + if (!(obj = calloc(1, sizeof(*obj)))) + { + *instance = NULL; + return E_OUTOFMEMORY; + } + + obj->ISpeechSynthesizer_iface.lpVtbl = &speech_synthesizer_vtbl; + obj->IClosable_iface.lpVtbl = &closable_vtbl; + obj->ref = 1; + *instance = (IInspectable *)&obj->ISpeechSynthesizer_iface; + return S_OK; +} + +static const struct IActivationFactoryVtbl activation_factory_vtbl = +{ + windows_media_speech_QueryInterface, + windows_media_speech_AddRef, + windows_media_speech_Release, + /* IInspectable methods */ + windows_media_speech_GetIids, + windows_media_speech_GetRuntimeClassName, + windows_media_speech_GetTrustLevel, + /* IActivationFactory methods */ + windows_media_speech_ActivateInstance, +}; + +static HRESULT STDMETHODCALLTYPE installed_voices_static_QueryInterface( + IInstalledVoicesStatic *iface, REFIID iid, void **out) +{ + struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); + return windows_media_speech_QueryInterface(&impl->IActivationFactory_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE installed_voices_static_AddRef( + IInstalledVoicesStatic *iface) +{ + struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); + return windows_media_speech_AddRef(&impl->IActivationFactory_iface); +} + +static ULONG STDMETHODCALLTYPE installed_voices_static_Release( + IInstalledVoicesStatic *iface) +{ + struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); + return windows_media_speech_Release(&impl->IActivationFactory_iface); +} + +static HRESULT STDMETHODCALLTYPE installed_voices_static_GetIids( + IInstalledVoicesStatic *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 STDMETHODCALLTYPE installed_voices_static_GetRuntimeClassName( + IInstalledVoicesStatic *iface, HSTRING *class_name) +{ + FIXME("iface %p, class_name %p stub!\n", iface, class_name); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE installed_voices_static_GetTrustLevel( + IInstalledVoicesStatic *iface, TrustLevel *trust_level) +{ + FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE installed_voices_static_get_AllVoices( + IInstalledVoicesStatic *iface, IVectorView_VoiceInformation **value) +{ + TRACE("iface %p, value %p.\n", iface, value); + *value = &all_voices.IVectorView_VoiceInformation_iface; + IVectorView_VoiceInformation_AddRef(*value); + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE installed_voices_static_get_DefaultVoice( + IInstalledVoicesStatic *iface, IVoiceInformation **value) +{ + FIXME("iface %p, value %p stub!\n", iface, value); + return E_NOTIMPL; +} + +static const struct IInstalledVoicesStaticVtbl installed_voices_static_vtbl = +{ + installed_voices_static_QueryInterface, + installed_voices_static_AddRef, + installed_voices_static_Release, + /* IInspectable methods */ + installed_voices_static_GetIids, + installed_voices_static_GetRuntimeClassName, + installed_voices_static_GetTrustLevel, + /* IInstalledVoicesStatic methods */ + installed_voices_static_get_AllVoices, + installed_voices_static_get_DefaultVoice, +}; + +static struct windows_media_speech windows_media_speech = +{ + {&activation_factory_vtbl}, + {&installed_voices_static_vtbl}, + 1 +}; + +IActivationFactory *synthesizer_factory = &windows_media_speech.IActivationFactory_iface;
On 3/6/22 18:30, Bernhard Kölbl wrote:
- HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out) { FIXME("clsid %s, riid %s, out %p stub!\n", debugstr_guid(clsid), debugstr_guid(riid), out);
@@ -580,7 +38,5 @@ HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **fac return CLASS_E_CLASSNOTAVAILABLE; }
- *factory = &windows_media_speech.IActivationFactory_iface;
- IUnknown_AddRef(*factory);
- return S_OK;
- return IActivationFactory_QueryInterface(synthesizer_factory, &IID_IActivationFactory, (void**)factory); }
As discussed elsewhere, this should return the HRESULT on success only, and handle the error case differently to return the appropriate error.
Note that if you reorder your patches to rewrite DllGetClassObject first, as you're then requesting the HSTRING buffer pointer, you could then drop the debugstr_hstring helper.
It's alright to keep it if you need it for something else later (though maybe best to drop it now and add it back later), but you can still simply call debugstr_w with the buffer pointer here.
Am So., 6. März 2022 um 21:30 Uhr schrieb Rémi Bernon rbernon@codeweavers.com:
As discussed elsewhere, this should return the HRESULT on success only, and handle the error case differently to return the appropriate error.
Yes, as discussed elsewhere I'll change this back to only call AddRef instead of QueryInterface like your implementation in Windows.Gaming.Input.
Note that if you reorder your patches to rewrite DllGetClassObject first, as you're then requesting the HSTRING buffer pointer, you could then drop the debugstr_hstring helper.
It's alright to keep it if you need it for something else later (though maybe best to drop it now and add it back later), but you can still simply call debugstr_w with the buffer pointer here.
Yes, the helper will be reused later quite a lot, but I could drop it for now.
Bernhard
-- Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- v2: Remove unneeded macro. --- dlls/windows.media.speech/main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/windows.media.speech/main.c b/dlls/windows.media.speech/main.c index 047e1ab0e90..d81cfad9ffe 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -30,13 +30,15 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out)
HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory) { + const WCHAR *buffer = WindowsGetStringRawBuffer(classid, NULL); + TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory);
- if (wcscmp(WindowsGetStringRawBuffer(classid, NULL), L"Windows.Media.SpeechSynthesis.SpeechSynthesizer")) + if (!wcscmp(buffer, L"Windows.Media.SpeechSynthesis.SpeechSynthesizer")) { - ERR("Unknown classid %s.\n", debugstr_hstring(classid)); - return CLASS_E_CLASSNOTAVAILABLE; + return IActivationFactory_QueryInterface(synthesizer_factory, &IID_IActivationFactory, (void**)factory);; }
- return IActivationFactory_QueryInterface(synthesizer_factory, &IID_IActivationFactory, (void**)factory); + ERR("Unknown classid %s.\n", debugstr_hstring(classid)); + return CLASS_E_CLASSNOTAVAILABLE; }
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- v2: Use shorter name for af and rename struct. --- dlls/windows.media.speech/synthesizer.c | 68 ++++++++++++------------- 1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/dlls/windows.media.speech/synthesizer.c b/dlls/windows.media.speech/synthesizer.c index 45b16ad6dac..8d0b5ca64ce 100644 --- a/dlls/windows.media.speech/synthesizer.c +++ b/dlls/windows.media.speech/synthesizer.c @@ -366,27 +366,27 @@ static const struct IClosableVtbl closable_vtbl = closable_Close, };
-struct windows_media_speech +struct synthesizer_statics { IActivationFactory IActivationFactory_iface; IInstalledVoicesStatic IInstalledVoicesStatic_iface; LONG ref; };
-static inline struct windows_media_speech *impl_from_IActivationFactory(IActivationFactory *iface) +static inline struct synthesizer_statics *impl_from_IActivationFactory(IActivationFactory *iface) { - return CONTAINING_RECORD(iface, struct windows_media_speech, IActivationFactory_iface); + return CONTAINING_RECORD(iface, struct synthesizer_statics, IActivationFactory_iface); }
-static inline struct windows_media_speech *impl_from_IInstalledVoicesStatic(IInstalledVoicesStatic *iface) +static inline struct synthesizer_statics *impl_from_IInstalledVoicesStatic(IInstalledVoicesStatic *iface) { - return CONTAINING_RECORD(iface, struct windows_media_speech, IInstalledVoicesStatic_iface); + return CONTAINING_RECORD(iface, struct synthesizer_statics, IInstalledVoicesStatic_iface); }
-static HRESULT STDMETHODCALLTYPE windows_media_speech_QueryInterface( +static HRESULT STDMETHODCALLTYPE factory_QueryInterface( IActivationFactory *iface, REFIID iid, void **out) { - struct windows_media_speech *impl = impl_from_IActivationFactory(iface); + struct synthesizer_statics *impl = impl_from_IActivationFactory(iface);
TRACE("iface %p, iid %s, out %p stub!\n", iface, debugstr_guid(iid), out);
@@ -412,46 +412,46 @@ static HRESULT STDMETHODCALLTYPE windows_media_speech_QueryInterface( return E_NOINTERFACE; }
-static ULONG STDMETHODCALLTYPE windows_media_speech_AddRef( +static ULONG STDMETHODCALLTYPE factory_AddRef( IActivationFactory *iface) { - struct windows_media_speech *impl = impl_from_IActivationFactory(iface); + struct synthesizer_statics *impl = impl_from_IActivationFactory(iface); ULONG ref = InterlockedIncrement(&impl->ref); TRACE("iface %p, ref %lu.\n", iface, ref); return ref; }
-static ULONG STDMETHODCALLTYPE windows_media_speech_Release( +static ULONG STDMETHODCALLTYPE factory_Release( IActivationFactory *iface) { - struct windows_media_speech *impl = impl_from_IActivationFactory(iface); + struct synthesizer_statics *impl = impl_from_IActivationFactory(iface); ULONG ref = InterlockedDecrement(&impl->ref); TRACE("iface %p, ref %lu.\n", iface, ref); return ref; }
-static HRESULT STDMETHODCALLTYPE windows_media_speech_GetIids( +static HRESULT STDMETHODCALLTYPE 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 STDMETHODCALLTYPE windows_media_speech_GetRuntimeClassName( +static HRESULT STDMETHODCALLTYPE factory_GetRuntimeClassName( IActivationFactory *iface, HSTRING *class_name) { FIXME("iface %p, class_name %p stub!\n", iface, class_name); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE windows_media_speech_GetTrustLevel( +static HRESULT STDMETHODCALLTYPE factory_GetTrustLevel( IActivationFactory *iface, TrustLevel *trust_level) { FIXME("iface %p, trust_level %p stub!\n", iface, trust_level); return E_NOTIMPL; }
-static HRESULT STDMETHODCALLTYPE windows_media_speech_ActivateInstance( +static HRESULT STDMETHODCALLTYPE factory_ActivateInstance( IActivationFactory *iface, IInspectable **instance) { struct speech_synthesizer *obj; @@ -471,38 +471,38 @@ static HRESULT STDMETHODCALLTYPE windows_media_speech_ActivateInstance( return S_OK; }
-static const struct IActivationFactoryVtbl activation_factory_vtbl = +static const struct IActivationFactoryVtbl factory_vtbl = { - windows_media_speech_QueryInterface, - windows_media_speech_AddRef, - windows_media_speech_Release, + factory_QueryInterface, + factory_AddRef, + factory_Release, /* IInspectable methods */ - windows_media_speech_GetIids, - windows_media_speech_GetRuntimeClassName, - windows_media_speech_GetTrustLevel, + factory_GetIids, + factory_GetRuntimeClassName, + factory_GetTrustLevel, /* IActivationFactory methods */ - windows_media_speech_ActivateInstance, + factory_ActivateInstance, };
static HRESULT STDMETHODCALLTYPE installed_voices_static_QueryInterface( IInstalledVoicesStatic *iface, REFIID iid, void **out) { - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); - return windows_media_speech_QueryInterface(&impl->IActivationFactory_iface, iid, out); + struct synthesizer_statics *impl = impl_from_IInstalledVoicesStatic(iface); + return factory_QueryInterface(&impl->IActivationFactory_iface, iid, out); }
static ULONG STDMETHODCALLTYPE installed_voices_static_AddRef( IInstalledVoicesStatic *iface) { - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); - return windows_media_speech_AddRef(&impl->IActivationFactory_iface); + struct synthesizer_statics *impl = impl_from_IInstalledVoicesStatic(iface); + return factory_AddRef(&impl->IActivationFactory_iface); }
static ULONG STDMETHODCALLTYPE installed_voices_static_Release( IInstalledVoicesStatic *iface) { - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); - return windows_media_speech_Release(&impl->IActivationFactory_iface); + struct synthesizer_statics *impl = impl_from_IInstalledVoicesStatic(iface); + return factory_Release(&impl->IActivationFactory_iface); }
static HRESULT STDMETHODCALLTYPE installed_voices_static_GetIids( @@ -556,11 +556,11 @@ static const struct IInstalledVoicesStaticVtbl installed_voices_static_vtbl = installed_voices_static_get_DefaultVoice, };
-static struct windows_media_speech windows_media_speech = +static struct synthesizer_statics synthesizer_statics = { - {&activation_factory_vtbl}, - {&installed_voices_static_vtbl}, - 1 + .IActivationFactory_iface = {&factory_vtbl}, + .IInstalledVoicesStatic_iface = {&installed_voices_static_vtbl}, + .ref = 1 };
-IActivationFactory *synthesizer_factory = &windows_media_speech.IActivationFactory_iface; +IActivationFactory *synthesizer_factory = &synthesizer_statics.IActivationFactory_iface;
To test, if the ifaces are static and if each activatable class has it's own activation factory.
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- v2: Rename some variables. --- dlls/windows.media.speech/tests/speech.c | 120 +++++++++++++++++++++++ 1 file changed, 120 insertions(+)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 38fd5c90dd0..e7dab073e31 100644 --- a/dlls/windows.media.speech/tests/speech.c +++ b/dlls/windows.media.speech/tests/speech.c @@ -29,6 +29,8 @@ #define WIDL_using_Windows_Foundation #define WIDL_using_Windows_Foundation_Collections #include "windows.foundation.h" +#define WIDL_using_Windows_Media_SpeechRecognition +#include "windows.media.speechrecognition.h" #define WIDL_using_Windows_Media_SpeechSynthesis #include "windows.media.speechsynthesis.h"
@@ -36,6 +38,123 @@
HRESULT WINAPI (*pDllGetActivationFactory)(HSTRING, IActivationFactory **);
+static void test_ActivationFactory(void) +{ + static const WCHAR *synthesizer_name = L"Windows.Media.SpeechSynthesis.SpeechSynthesizer"; + static const WCHAR *recognizer_name = L"Windows.Media.SpeechRecognition.SpeechRecognizer"; + IInspectable *inspectable = NULL, *inspectable2 = NULL; + IAgileObject *agile_object = NULL, *agile_object2 = NULL; + IActivationFactory *factory = NULL, *factory2 = NULL, *factory3 = NULL; + ISpeechRecognizerFactory *recognizer_factory = NULL; + ISpeechRecognizerStatics *recognizer_statics = NULL; + ISpeechRecognizerStatics2 *recognizer_statics2 = NULL; + IInstalledVoicesStatic *installed_voices = NULL; + HSTRING str, str2; + HRESULT hr; + ULONG ref; + + hr = RoInitialize(RO_INIT_MULTITHREADED); + ok(hr == S_OK, "RoInitialize failed, hr %#x.\n", hr); + + hr = WindowsCreateString(synthesizer_name, wcslen(synthesizer_name), &str); + ok(hr == S_OK, "WindowsCreateString failed, hr %#x.\n", hr); + + hr = WindowsCreateString(recognizer_name, wcslen(recognizer_name), &str2); + ok(hr == S_OK, "WindowsCreateString failed, hr %#x.\n", hr); + + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory); + ok(hr == S_OK, "RoGetActivationFactory failed, hr %#x.\n", hr); + + ref = IActivationFactory_AddRef(factory); + ok(ref == 3, "Got unexpected refcount: %u.\n", ref); + + ref = IActivationFactory_Release(factory); + ok(ref == 2, "Got unexpected refcount: %u.\n", ref); + + hr = IActivationFactory_QueryInterface(factory, &IID_ISpeechRecognizerFactory, (void**)&recognizer_factory); + ok(hr == E_NOINTERFACE, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IInspectable, (void**)&inspectable); + ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IAgileObject, (void**)&agile_object); + ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + hr = IActivationFactory_QueryInterface(factory, &IID_IInstalledVoicesStatic, (void**)&installed_voices); + ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + ref = IInstalledVoicesStatic_Release(installed_voices); + ok(ref == 4, "Got unexpected refcount: %u.\n", ref); + + ref = IAgileObject_Release(agile_object); + ok(ref == 3, "Got unexpected refcount: %u.\n", ref); + + ref = IInspectable_Release(inspectable); + ok(ref == 2, "Got unexpected refcount: %u.\n", ref); + + hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory2); + ok(hr == S_OK, "RoGetActivationFactory failed, hr %#x.\n", hr); + ok(factory == factory2, "Factories pointed at factory %p factory2 %p.\n", factory, factory2); + + hr = RoGetActivationFactory(str2, &IID_IActivationFactory, (void **)&factory3); + todo_wine ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#x.\n", hr); + + if(hr == S_OK) /* Win10+ only */ + { + ok(factory != factory3, "Factories pointed at factory %p factory3 %p.\n", factory, factory3); + + hr = IActivationFactory_QueryInterface(factory3, &IID_IInspectable, (void**)&inspectable2); + ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + hr = IActivationFactory_QueryInterface(factory3, &IID_IAgileObject, (void**)&agile_object2); + ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + hr = IActivationFactory_QueryInterface(factory3, &IID_ISpeechRecognizerFactory, (void**)&recognizer_factory); + ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + hr = IActivationFactory_QueryInterface(factory3, &IID_ISpeechRecognizerStatics, (void**)&recognizer_statics); + ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + ref = ISpeechRecognizerStatics_Release(recognizer_statics); + ok(ref == 5, "Got unexpected refcount: %u.\n", ref); + + ref = ISpeechRecognizerFactory_Release(recognizer_factory); + ok(ref == 4, "Got unexpected refcount: %u.\n", ref); + + ref = IAgileObject_Release(agile_object2); + ok(ref == 3, "Got unexpected refcount: %u.\n", ref); + + ref = IInspectable_Release(inspectable2); + ok(ref == 2, "Got unexpected refcount: %u.\n", ref); + + hr = IActivationFactory_QueryInterface(factory3, &IID_ISpeechRecognizerStatics2, (void**)&recognizer_statics2); + ok(hr == S_OK || broken(hr == E_NOINTERFACE), "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + if(hr == S_OK) /* ISpeechRecognizerStatics2 not available in Win10 1507 */ + { + ref = ISpeechRecognizerStatics2_Release(recognizer_statics2); + ok(ref == 2, "Got unexpected refcount: %u.\n", ref); + } + + hr = IActivationFactory_QueryInterface(factory3, &IID_IInstalledVoicesStatic, (void**)&installed_voices); + ok(hr == E_NOINTERFACE, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr); + + ref = IActivationFactory_Release(factory3); + ok(ref == 1, "Got unexpected refcount: %u.\n", ref); + } + + ref = IActivationFactory_Release(factory2); + ok(ref == 2, "Got unexpected refcount: %u.\n", ref); + + ref = IActivationFactory_Release(factory); + ok(ref == 1, "Got unexpected refcount: %u.\n", ref); + + WindowsDeleteString(str); + WindowsDeleteString(str2); + + RoUninitialize(); +} + static void test_SpeechSynthesizer(void) { static const WCHAR *speech_synthesizer_name = L"Windows.Media.SpeechSynthesis.SpeechSynthesizer"; @@ -203,6 +322,7 @@ static void test_VoiceInformation(void)
START_TEST(speech) { + test_ActivationFactory(); test_SpeechSynthesizer(); test_VoiceInformation(); }
On 3/6/22 18:30, Bernhard Kölbl wrote:
- hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory2);
- ok(hr == S_OK, "RoGetActivationFactory failed, hr %#x.\n", hr);
- ok(factory == factory2, "Factories pointed at factory %p factory2 %p.\n", factory, factory2);
- hr = RoGetActivationFactory(str2, &IID_IActivationFactory, (void **)&factory3);
- todo_wine ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#x.\n", hr);
- if(hr == S_OK) /* Win10+ only */
I think that at least most recently added code uses a space after if.
- {
ok(factory != factory3, "Factories pointed at factory %p factory3 %p.\n", factory, factory3);
hr = IActivationFactory_QueryInterface(factory3, &IID_IInspectable, (void**)&inspectable2);
ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr);
hr = IActivationFactory_QueryInterface(factory3, &IID_IAgileObject, (void**)&agile_object2);
ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr);
hr = IActivationFactory_QueryInterface(factory3, &IID_ISpeechRecognizerFactory, (void**)&recognizer_factory);
ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr);
hr = IActivationFactory_QueryInterface(factory3, &IID_ISpeechRecognizerStatics, (void**)&recognizer_statics);
ok(hr == S_OK, "IActivationFactory_QueryInterface failed, hr %#x.\n", hr);
ref = ISpeechRecognizerStatics_Release(recognizer_statics);
ok(ref == 5, "Got unexpected refcount: %u.\n", ref);
ref = ISpeechRecognizerFactory_Release(recognizer_factory);
ok(ref == 4, "Got unexpected refcount: %u.\n", ref);
ref = IAgileObject_Release(agile_object2);
ok(ref == 3, "Got unexpected refcount: %u.\n", ref);
ref = IInspectable_Release(inspectable2);
ok(ref == 2, "Got unexpected refcount: %u.\n", ref);
hr = IActivationFactory_QueryInterface(factory3, &IID_ISpeechRecognizerStatics2, (void**)&recognizer_statics2);
ok(hr == S_OK || broken(hr == E_NOINTERFACE), "IActivationFactory_QueryInterface failed, hr %#x.\n", hr);
if(hr == S_OK) /* ISpeechRecognizerStatics2 not available in Win10 1507 */
Same here.
(Otherwise, I still think it'd make the test simpler and shorter if you used some check_interface / check_ref helpers, especially if you want to check refcount extensively)