Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/main.c | 17 ++---------- dlls/windows.media.speech/private.h | 41 +++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 15 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..94e6e5f9b2c 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -17,23 +17,10 @@ * 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" +#include "private.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 "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(speech);
diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h new file mode 100644 index 00000000000..0af024d0a72 --- /dev/null +++ b/dlls/windows.media.speech/private.h @@ -0,0 +1,41 @@ +/* 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" + +#endif
Also return the right value when no factory was found.
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- v2: Remove unneeded macro. --- dlls/windows.media.speech/main.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-)
diff --git a/dlls/windows.media.speech/main.c b/dlls/windows.media.speech/main.c index 94e6e5f9b2c..29bacd846b0 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -24,15 +24,6 @@
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; @@ -583,15 +574,15 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **out)
HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **factory) { - TRACE("classid %s, factory %p.\n", debugstr_hstring(classid), factory); + const WCHAR *buffer = WindowsGetStringRawBuffer(classid, NULL);
- if (wcscmp(WindowsGetStringRawBuffer(classid, NULL), L"Windows.Media.SpeechSynthesis.SpeechSynthesizer")) - { - ERR("Unknown classid %s.\n", debugstr_hstring(classid)); - return CLASS_E_CLASSNOTAVAILABLE; - } + TRACE("classid %s, factory %p.\n", debugstr_w(buffer), factory);
- *factory = &windows_media_speech.IActivationFactory_iface; - IUnknown_AddRef(*factory); - return S_OK; + *factory = NULL; + + if (!wcscmp(buffer, L"Windows.Media.SpeechSynthesis.SpeechSynthesizer")) + IActivationFactory_AddRef((*factory = &windows_media_speech.IActivationFactory_iface)); + + if (*factory) return S_OK; + return CLASS_E_CLASSNOTAVAILABLE; }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
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 | 544 +---------------------- dlls/windows.media.speech/private.h | 8 + dlls/windows.media.speech/synthesizer.c | 568 ++++++++++++++++++++++++ 4 files changed, 579 insertions(+), 544 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 29bacd846b0..60aa1b1ab9e 100644 --- a/dlls/windows.media.speech/main.c +++ b/dlls/windows.media.speech/main.c @@ -24,548 +24,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); @@ -581,7 +39,7 @@ HRESULT WINAPI DllGetActivationFactory(HSTRING classid, IActivationFactory **fac *factory = NULL;
if (!wcscmp(buffer, L"Windows.Media.SpeechSynthesis.SpeechSynthesizer")) - IActivationFactory_AddRef((*factory = &windows_media_speech.IActivationFactory_iface)); + IActivationFactory_AddRef((*factory = synthesizer_factory));
if (*factory) return S_OK; return CLASS_E_CLASSNOTAVAILABLE; diff --git a/dlls/windows.media.speech/private.h b/dlls/windows.media.speech/private.h index 0af024d0a72..b1df726413d 100644 --- a/dlls/windows.media.speech/private.h +++ b/dlls/windows.media.speech/private.h @@ -38,4 +38,12 @@ #define WIDL_using_Windows_Media_SpeechSynthesis #include "windows.media.speechsynthesis.h"
+/* + * + * 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..ee3ac6c7fef --- /dev/null +++ b/dlls/windows.media.speech/synthesizer.c @@ -0,0 +1,568 @@ +/* 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" + +#include "wine/debug.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;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/synthesizer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/windows.media.speech/synthesizer.c b/dlls/windows.media.speech/synthesizer.c index ee3ac6c7fef..a307e50e6c8 100644 --- a/dlls/windows.media.speech/synthesizer.c +++ b/dlls/windows.media.speech/synthesizer.c @@ -294,7 +294,7 @@ static HRESULT STDMETHODCALLTYPE closable_QueryInterface( { struct speech_synthesizer *impl = impl_from_IClosable(iface);
- return speech_synthesizer_QueryInterface(&impl->ISpeechSynthesizer_iface, iid, out); + return ISpeechSynthesizer_QueryInterface(&impl->ISpeechSynthesizer_iface, iid, out); }
static ULONG STDMETHODCALLTYPE closable_AddRef( @@ -490,21 +490,21 @@ 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); + return IActivationFactory_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); + return IActivationFactory_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); + return IActivationFactory_Release(&impl->IActivationFactory_iface); }
static HRESULT STDMETHODCALLTYPE installed_voices_static_GetIids(
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
Signed-off-by: Bernhard Kölbl besentv@gmail.com --- v2: Use shorter name for af and rename struct. --- dlls/windows.media.speech/synthesizer.c | 62 ++++++++++++------------- 1 file changed, 31 insertions(+), 31 deletions(-)
diff --git a/dlls/windows.media.speech/synthesizer.c b/dlls/windows.media.speech/synthesizer.c index a307e50e6c8..3863e468d36 100644 --- a/dlls/windows.media.speech/synthesizer.c +++ b/dlls/windows.media.speech/synthesizer.c @@ -368,27 +368,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);
@@ -414,46 +414,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; @@ -473,37 +473,37 @@ 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); + struct synthesizer_statics *impl = impl_from_IInstalledVoicesStatic(iface); return IActivationFactory_QueryInterface(&impl->IActivationFactory_iface, iid, out); }
static ULONG STDMETHODCALLTYPE installed_voices_static_AddRef( IInstalledVoicesStatic *iface) { - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); + struct synthesizer_statics *impl = impl_from_IInstalledVoicesStatic(iface); return IActivationFactory_AddRef(&impl->IActivationFactory_iface); }
static ULONG STDMETHODCALLTYPE installed_voices_static_Release( IInstalledVoicesStatic *iface) { - struct windows_media_speech *impl = impl_from_IInstalledVoicesStatic(iface); + struct synthesizer_statics *impl = impl_from_IInstalledVoicesStatic(iface); return IActivationFactory_Release(&impl->IActivationFactory_iface); }
@@ -558,11 +558,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;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com
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. v3: Use macros for refcount and iface checking. Signed-off-by: Bernhard Kölbl besentv@gmail.com --- dlls/windows.media.speech/tests/speech.c | 128 +++++++++++++++++++++++ 1 file changed, 128 insertions(+)
diff --git a/dlls/windows.media.speech/tests/speech.c b/dlls/windows.media.speech/tests/speech.c index 38fd5c90dd0..3194a75d6d7 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,131 @@
HRESULT WINAPI (*pDllGetActivationFactory)(HSTRING, IActivationFactory **);
+static inline LONG get_ref(IUnknown *obj) +{ + IUnknown_AddRef(obj); + return IUnknown_Release(obj); +} + +#define check_refcount(obj, exp) check_refcount_(__LINE__, obj, exp) +static inline void check_refcount_(unsigned int line, void *obj, LONG exp) +{ + LONG ref = get_ref(obj); + ok_(__FILE__, line)(exp == ref, "Unexpected refcount %u, expected %u\n", ref, exp); +} + +#define check_interface(obj, iid, exp) check_interface_(__LINE__, obj, iid, exp) +static void check_interface_(unsigned int line, void *obj, const IID *iid, BOOL supported) +{ + IUnknown *iface = obj; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + +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"; + static const WCHAR *garbage_name = L"Some.Garbage.Class"; + IActivationFactory *factory = NULL, *factory2 = NULL, *factory3 = NULL, *factory4 = NULL; + ISpeechRecognizerStatics2 *recognizer_statics2 = NULL; + HSTRING str, str2, str3; + HMODULE hdll; + 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 = WindowsCreateString(garbage_name, wcslen(garbage_name), &str3); + 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); + + check_refcount(factory, 2); + + check_interface(factory, &IID_IInspectable, TRUE); + check_interface(factory, &IID_IAgileObject, TRUE); + check_interface(factory, &IID_IInstalledVoicesStatic, TRUE); + check_interface(factory, &IID_ISpeechRecognizerFactory, FALSE); + check_interface(factory, &IID_ISpeechRecognizerStatics, FALSE); + check_interface(factory, &IID_ISpeechRecognizerStatics2, FALSE); + + 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); + check_refcount(factory2, 3); + + hr = RoGetActivationFactory(str2, &IID_IActivationFactory, (void **)&factory3); + todo_wine ok(hr == S_OK || broken(hr == REGDB_E_CLASSNOTREG), "Got unexpected hr %#x.\n", hr); + + if (hr == S_OK) /* Win10+ only */ + { + check_refcount(factory3, 2); + ok(factory != factory3, "Factories pointed at factory %p factory3 %p.\n", factory, factory3); + + check_interface(factory3, &IID_IInspectable, TRUE); + check_interface(factory3, &IID_IAgileObject, TRUE); + check_interface(factory3, &IID_ISpeechRecognizerFactory, TRUE); + check_interface(factory3, &IID_ISpeechRecognizerStatics, TRUE); + + 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); + } + + check_interface(factory3, &IID_IInstalledVoicesStatic, FALSE); + + ref = IActivationFactory_Release(factory3); + ok(ref == 1, "Got unexpected refcount: %u.\n", ref); + } + + hdll = LoadLibraryW(L"windows.media.speech.dll"); + + if(hdll) + { + pDllGetActivationFactory = (void *)GetProcAddress(hdll, "DllGetActivationFactory"); + ok(!!pDllGetActivationFactory, "DllGetActivationFactory not found.\n"); + + hr = pDllGetActivationFactory(str3, &factory4); + ok((hr == CLASS_E_CLASSNOTAVAILABLE), "Got unexpected hr %#x.\n", hr); + FreeLibrary(hdll); + } + + hr = RoGetActivationFactory(str3, &IID_IActivationFactory, (void **)&factory4); + ok((hr == REGDB_E_CLASSNOTREG), "RoGetActivationFactory failed, hr %#x.\n", hr); + + 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); + WindowsDeleteString(str3); + + RoUninitialize(); +} + static void test_SpeechSynthesizer(void) { static const WCHAR *speech_synthesizer_name = L"Windows.Media.SpeechSynthesis.SpeechSynthesizer"; @@ -203,6 +330,7 @@ static void test_VoiceInformation(void)
START_TEST(speech) { + test_ActivationFactory(); test_SpeechSynthesizer(); test_VoiceInformation(); }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com