windows.media.speech: Add stub SpeechSynthesizer class.

Signed-off-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Paul Gofman 2021-11-30 15:55:24 +03:00 committed by Alexandre Julliard
parent 850083d088
commit a3ef7a13c8
2 changed files with 311 additions and 6 deletions

View File

@ -171,6 +171,226 @@ static struct voice_information_vector all_voices =
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 %u.\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 %u.\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 %u.\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 %u.\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;
@ -259,8 +479,21 @@ static HRESULT STDMETHODCALLTYPE windows_media_speech_GetTrustLevel(
static HRESULT STDMETHODCALLTYPE windows_media_speech_ActivateInstance(
IActivationFactory *iface, IInspectable **instance)
{
FIXME("iface %p, instance %p stub!\n", iface, instance);
return E_NOTIMPL;
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 =
@ -364,6 +597,13 @@ 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);
if (wcscmp(WindowsGetStringRawBuffer(classid, NULL), L"Windows.Media.SpeechSynthesis.SpeechSynthesizer"))
{
ERR("Unknown classid %s.\n", debugstr_hstring(classid));
return CLASS_E_CLASSNOTAVAILABLE;
}
*factory = &windows_media_speech.IActivationFactory_iface;
IUnknown_AddRef(*factory);
return S_OK;

View File

@ -34,19 +34,26 @@
#include "wine/test.h"
HRESULT WINAPI (*pDllGetActivationFactory)(HSTRING, IActivationFactory **);
static void test_SpeechSynthesizer(void)
{
static const WCHAR *speech_synthesizer_name = L"Windows.Media.SpeechSynthesis.SpeechSynthesizer";
static const WCHAR *speech_synthesizer_name2 = L"windows.media.speechsynthesis.speechsynthesizer";
static const WCHAR *unknown_class_name = L"Unknown.Class";
IActivationFactory *factory = NULL, *factory2 = NULL;
IVectorView_VoiceInformation *voices = NULL;
IInstalledVoicesStatic *voices_static = NULL;
IActivationFactory *factory = NULL;
IVoiceInformation *voice;
IInspectable *inspectable = NULL, *tmp_inspectable = NULL;
IAgileObject *agile_object = NULL, *tmp_agile_object = NULL;
HSTRING str;
ISpeechSynthesizer *synthesizer;
IClosable *closable;
HMODULE hdll;
HSTRING str, str2;
HRESULT hr;
UINT32 size;
ULONG ref;
hr = RoInitialize(RO_INIT_MULTITHREADED);
ok(hr == S_OK, "RoInitialize failed, hr %#x\n", hr);
@ -54,9 +61,46 @@ static void test_SpeechSynthesizer(void)
hr = WindowsCreateString(speech_synthesizer_name, wcslen(speech_synthesizer_name), &str);
ok(hr == S_OK, "WindowsCreateString failed, hr %#x\n", hr);
hdll = LoadLibraryW(L"windows.media.speech.dll");
if (hdll)
{
pDllGetActivationFactory = (void *)GetProcAddress(hdll, "DllGetActivationFactory");
ok(!!pDllGetActivationFactory, "DllGetActivationFactory not found.\n");
hr = WindowsCreateString(unknown_class_name, wcslen(unknown_class_name), &str2);
ok(hr == S_OK, "WindowsCreateString failed, hr %#x\n", hr);
hr = pDllGetActivationFactory(str2, &factory);
ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
WindowsDeleteString(str2);
hr = WindowsCreateString(speech_synthesizer_name2, wcslen(speech_synthesizer_name2), &str2);
ok(hr == S_OK, "WindowsCreateString failed, hr %#x\n", hr);
hr = pDllGetActivationFactory(str2, &factory2);
ok(hr == CLASS_E_CLASSNOTAVAILABLE, "Got unexpected hr %#x.\n", hr);
WindowsDeleteString(str2);
hr = pDllGetActivationFactory(str, &factory2);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
}
else
{
win_skip("Failed to load library, err %u.\n", GetLastError());
}
hr = RoGetActivationFactory(str, &IID_IActivationFactory, (void **)&factory);
ok(hr == S_OK, "RoGetActivationFactory failed, hr %#x\n", hr);
if (hdll)
{
ok(factory == factory2, "Got unexpected factory %p, factory2 %p.\n", factory, factory2);
IActivationFactory_Release(factory2);
FreeLibrary(hdll);
}
hr = IActivationFactory_QueryInterface(factory, &IID_IInspectable, (void **)&inspectable);
ok(hr == S_OK, "IActivationFactory_QueryInterface IID_IInspectable failed, hr %#x\n", hr);
@ -107,8 +151,29 @@ static void test_SpeechSynthesizer(void)
IAgileObject_Release(agile_object);
IInspectable_Release(inspectable);
IActivationFactory_Release(factory);
hr = IActivationFactory_QueryInterface(factory, &IID_ISpeechSynthesizer, (void **)&synthesizer);
ok(hr == E_NOINTERFACE, "Got unexpected hr %#x.\n", hr);
hr = RoActivateInstance(str, &inspectable);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = IInspectable_QueryInterface(inspectable, &IID_ISpeechSynthesizer, (void **)&synthesizer);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
hr = IInspectable_QueryInterface(inspectable, &IID_IClosable, (void **)&closable);
ok(hr == S_OK, "Got unexpected hr %#x.\n", hr);
ref = IClosable_Release(closable);
ok(ref == 2, "Got unexpected ref %u.\n", ref);
ref = ISpeechSynthesizer_Release(synthesizer);
ok(ref == 1, "Got unexpected ref %u.\n", ref);
ref = IInspectable_Release(inspectable);
ok(!ref, "Got unexpected ref %u.\n", ref);
IActivationFactory_Release(factory);
WindowsDeleteString(str);
RoUninitialize();