[PATCH 2/3] sapi: Implement ISpVoice stub.

Jactry Zeng jzeng at codeweavers.com
Thu Nov 14 10:18:49 CST 2019


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 dlls/sapi/tests/tts.c |  24 ++-
 dlls/sapi/tts.c       | 329 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 352 insertions(+), 1 deletion(-)

diff --git a/dlls/sapi/tests/tts.c b/dlls/sapi/tests/tts.c
index 8d13ed0053..2d62a9651d 100644
--- a/dlls/sapi/tests/tts.c
+++ b/dlls/sapi/tests/tts.c
@@ -36,7 +36,8 @@ static void _expect_ref(IUnknown *obj, ULONG ref, int line)
 
 static void test_interfaces(void)
 {
-    ISpeechVoice *speech_voice;
+    ISpeechVoice *speech_voice, *speech_voice2;
+    ISpVoice *spvoice, *spvoice2;
     IDispatch *dispatch;
     IUnknown *unk;
     HRESULT hr;
@@ -60,6 +61,27 @@ static void test_interfaces(void)
     EXPECT_REF(speech_voice, 1);
     IUnknown_Release(unk);
 
+    hr = CoCreateInstance(&CLSID_SpVoice, NULL, CLSCTX_INPROC_SERVER,
+                          &IID_ISpVoice, (void **)&spvoice);
+    ok(hr == S_OK, "Failed to create ISpVoice interface: %#x.\n", hr);
+    EXPECT_REF(spvoice, 1);
+    EXPECT_REF(speech_voice, 1);
+
+    hr = ISpVoice_QueryInterface(spvoice, &IID_ISpeechVoice, (void **)&speech_voice2);
+    ok(hr == S_OK, "ISpVoice_QueryInterface failed: %#x.\n", hr);
+    EXPECT_REF(speech_voice2, 2);
+    EXPECT_REF(spvoice, 2);
+    EXPECT_REF(speech_voice, 1);
+    ISpeechVoice_Release(speech_voice2);
+
+    hr = ISpeechVoice_QueryInterface(speech_voice, &IID_ISpVoice, (void **)&spvoice2);
+    ok(hr == S_OK, "ISpeechVoice_QueryInterface failed: %#x.\n", hr);
+    EXPECT_REF(speech_voice, 2);
+    EXPECT_REF(spvoice2, 2);
+    EXPECT_REF(spvoice, 1);
+    ISpVoice_Release(spvoice2);
+    ISpVoice_Release(spvoice);
+
     ISpeechVoice_Release(speech_voice);
 }
 
diff --git a/dlls/sapi/tts.c b/dlls/sapi/tts.c
index 4000db11f5..8f1ecd1894 100644
--- a/dlls/sapi/tts.c
+++ b/dlls/sapi/tts.c
@@ -37,6 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(sapi);
 struct speech_voice
 {
     ISpeechVoice ISpeechVoice_iface;
+    ISpVoice ISpVoice_iface;
     LONG ref;
 };
 
@@ -45,6 +46,11 @@ static inline struct speech_voice *impl_from_ISpeechVoice(ISpeechVoice *iface)
     return CONTAINING_RECORD(iface, struct speech_voice, ISpeechVoice_iface);
 }
 
+static inline struct speech_voice *impl_from_ISpVoice(ISpVoice *iface)
+{
+    return CONTAINING_RECORD(iface, struct speech_voice, ISpVoice_iface);
+}
+
 /* ISpeechVoice interface */
 static HRESULT WINAPI speech_voice_QueryInterface(ISpeechVoice *iface, REFIID iid, void **obj)
 {
@@ -56,6 +62,8 @@ static HRESULT WINAPI speech_voice_QueryInterface(ISpeechVoice *iface, REFIID ii
         IsEqualIID(iid, &IID_IDispatch) ||
         IsEqualIID(iid, &IID_ISpeechVoice))
         *obj = &This->ISpeechVoice_iface;
+    else if (IsEqualIID(iid, &IID_ISpVoice))
+        *obj = &This->ISpVoice_iface;
     else
     {
         *obj = NULL;
@@ -398,6 +406,326 @@ static const ISpeechVoiceVtbl speech_voice_vtbl =
     speech_voice_DisplayUI,
 };
 
+/* ISpVoice interface */
+static HRESULT WINAPI spvoice_QueryInterface(ISpVoice *iface, REFIID iid, void **obj)
+{
+    struct speech_voice *This = impl_from_ISpVoice(iface);
+
+    TRACE("(%p, %s %p).\n", iface, debugstr_guid(iid), obj);
+
+    return ISpeechVoice_QueryInterface(&This->ISpeechVoice_iface, iid, obj);
+}
+
+static ULONG WINAPI spvoice_AddRef(ISpVoice *iface)
+{
+    struct speech_voice *This = impl_from_ISpVoice(iface);
+
+    TRACE("(%p).\n", iface);
+
+    return ISpeechVoice_AddRef(&This->ISpeechVoice_iface);
+}
+
+static ULONG WINAPI spvoice_Release(ISpVoice *iface)
+{
+    struct speech_voice *This = impl_from_ISpVoice(iface);
+
+    TRACE("(%p).\n", iface);
+
+    return ISpeechVoice_Release(&This->ISpeechVoice_iface);
+}
+
+static HRESULT WINAPI spvoice_SetNotifySink(ISpVoice *iface, ISpNotifySink *sink)
+{
+    FIXME("(%p, %p): stub.\n", iface, sink);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetNotifyWindowMessage(ISpVoice *iface, HWND hwnd, UINT msg,
+                                                     WPARAM wparam, LPARAM lparam)
+{
+    FIXME("(%p, %p, %u, %lx, %lx): stub.\n", iface, hwnd, msg, wparam, lparam);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetNotifyCallbackFunction(ISpVoice *iface, SPNOTIFYCALLBACK *callback,
+                                                        WPARAM wparam, LPARAM lparam)
+{
+    FIXME("(%p, %p, %lx, %lx): stub.\n", iface, callback, wparam, lparam);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetNotifyCallbackInterface(ISpVoice *iface, ISpNotifyCallback *callback,
+                                                         WPARAM wparam, LPARAM lparam)
+{
+    FIXME("(%p, %p, %lx, %lx): stub.\n", iface, callback, wparam, lparam);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetNotifyWin32Event(ISpVoice *iface)
+{
+    FIXME("(%p): stub.\n", iface);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_WaitForNotifyEvent(ISpVoice *iface, DWORD milliseconds)
+{
+    FIXME("(%p, %d): stub.\n", iface, milliseconds);
+
+    return E_NOTIMPL;
+}
+
+static HANDLE WINAPI spvoice_GetNotifyEventHandle(ISpVoice *iface)
+{
+    FIXME("(%p): stub.\n", iface);
+
+    return NULL;
+}
+
+static HRESULT WINAPI spvoice_SetInterest(ISpVoice *iface, ULONGLONG event, ULONGLONG queued)
+{
+    FIXME("(%p, %s, %s): stub.\n", iface, wine_dbgstr_longlong(event), wine_dbgstr_longlong(queued));
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetEvents(ISpVoice *iface, ULONG count, SPEVENT *array, ULONG *fetched)
+{
+    FIXME("(%p, %u, %p, %p): stub.\n", iface, count, array, fetched);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetInfo(ISpVoice *iface, SPEVENTSOURCEINFO *info)
+{
+    FIXME("(%p, %p): stub.\n", iface, info);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetOutput(ISpVoice *iface, IUnknown *unk, BOOL changes)
+{
+    FIXME("(%p, %p, %d: stub.\n)", iface, unk, changes);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetOutputObjectToken(ISpVoice *iface, ISpObjectToken **token)
+{
+    FIXME("(%p, %p): stub.\n", iface, token);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetOutputStream(ISpVoice *iface, ISpStreamFormat **stream)
+{
+    FIXME("(%p, %p): stub.\n", iface, stream);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_Pause(ISpVoice *iface)
+{
+    FIXME("(%p): stub.\n", iface);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_Resume(ISpVoice *iface)
+{
+    FIXME("(%p): stub.\n", iface);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetVoice(ISpVoice *iface, ISpObjectToken *token)
+{
+    FIXME("(%p, %p): stub.\n", iface, token);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetVoice(ISpVoice *iface, ISpObjectToken **token)
+{
+    FIXME("(%p, %p): stub.\n", iface, token);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_Speak(ISpVoice *iface, const WCHAR *contents, DWORD flags, ULONG *number)
+{
+    FIXME("(%p, %p, %#x, %p): stub.\n", iface, contents, flags, number);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SpeakStream(ISpVoice *iface, IStream *stream, DWORD flags, ULONG *number)
+{
+    FIXME("(%p, %p, %#x, %p): stub.\n", iface, stream, flags, number);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetStatus(ISpVoice *iface, SPVOICESTATUS *status, WCHAR **bookmark)
+{
+    FIXME("(%p, %p, %p): stub.\n", iface, status, bookmark);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_Skip(ISpVoice *iface, const WCHAR *type, LONG items, ULONG *skipped)
+{
+    FIXME("(%p, %s, %d, %p): stub.\n", iface, debugstr_w(type), items, skipped);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetPriority(ISpVoice *iface, SPVPRIORITY priority)
+{
+    FIXME("(%p, %d): stub.\n", iface, priority);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetPriority(ISpVoice *iface, SPVPRIORITY *priority)
+{
+    FIXME("(%p, %p): stub.\n", iface, priority);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetAlertBoundary(ISpVoice *iface, SPEVENTENUM boundary)
+{
+    FIXME("(%p, %d): stub.\n", iface, boundary);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetAlertBoundary(ISpVoice *iface, SPEVENTENUM *boundary)
+{
+    FIXME("(%p, %p): stub.\n", iface, boundary);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetRate(ISpVoice *iface, LONG adjust)
+{
+    FIXME("(%p, %d): stub.\n", iface, adjust);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetRate(ISpVoice *iface, LONG *adjust)
+{
+    FIXME("(%p, %p): stub.\n", iface, adjust);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetVolume(ISpVoice *iface, USHORT volume)
+{
+    FIXME("(%p, %d): stub.\n", iface, volume);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetVolume(ISpVoice *iface, USHORT *volume)
+{
+    FIXME("(%p, %p): stub.\n", iface, volume);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_WaitUntilDone(ISpVoice *iface, ULONG timeout)
+{
+    FIXME("(%p, %d): stub.\n", iface, timeout);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_SetSyncSpeakTimeout(ISpVoice *iface, ULONG timeout)
+{
+    FIXME("(%p, %d): stub.\n", iface, timeout);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_GetSyncSpeakTimeout(ISpVoice *iface, ULONG *timeout)
+{
+    FIXME("(%p, %p): stub.\n", iface, timeout);
+
+    return E_NOTIMPL;
+}
+
+static HANDLE WINAPI spvoice_SpeakCompleteEvent(ISpVoice *iface)
+{
+    FIXME("(%p): stub.\n", iface);
+
+    return NULL;
+}
+
+static HRESULT WINAPI spvoice_IsUISupported(ISpVoice *iface, const WCHAR *type, void *extra,
+                                            ULONG count, BOOL *supported)
+{
+    FIXME("(%p, %p, %p, %d, %p): stub.\n", iface, type, extra, count, supported);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI spvoice_DisplayUI(ISpVoice *iface, HWND parent, const WCHAR *title,
+                                        const WCHAR *type, void *extra, ULONG count)
+{
+    FIXME("(%p, %p, %p, %p, %p, %d): stub.\n", iface, parent, title, type, extra, count);
+
+    return E_NOTIMPL;
+}
+
+static const ISpVoiceVtbl spvoice_vtbl =
+{
+    spvoice_QueryInterface,
+    spvoice_AddRef,
+    spvoice_Release,
+    spvoice_SetNotifySink,
+    spvoice_SetNotifyWindowMessage,
+    spvoice_SetNotifyCallbackFunction,
+    spvoice_SetNotifyCallbackInterface,
+    spvoice_SetNotifyWin32Event,
+    spvoice_WaitForNotifyEvent,
+    spvoice_GetNotifyEventHandle,
+    spvoice_SetInterest,
+    spvoice_GetEvents,
+    spvoice_GetInfo,
+    spvoice_SetOutput,
+    spvoice_GetOutputObjectToken,
+    spvoice_GetOutputStream,
+    spvoice_Pause,
+    spvoice_Resume,
+    spvoice_SetVoice,
+    spvoice_GetVoice,
+    spvoice_Speak,
+    spvoice_SpeakStream,
+    spvoice_GetStatus,
+    spvoice_Skip,
+    spvoice_SetPriority,
+    spvoice_GetPriority,
+    spvoice_SetAlertBoundary,
+    spvoice_GetAlertBoundary,
+    spvoice_SetRate,
+    spvoice_GetRate,
+    spvoice_SetVolume,
+    spvoice_GetVolume,
+    spvoice_WaitUntilDone,
+    spvoice_SetSyncSpeakTimeout,
+    spvoice_GetSyncSpeakTimeout,
+    spvoice_SpeakCompleteEvent,
+    spvoice_IsUISupported,
+    spvoice_DisplayUI
+};
+
 HRESULT speech_voice_create(IUnknown *outer, REFIID iid, void **obj)
 {
     struct speech_voice *This = heap_alloc(sizeof(*This));
@@ -405,6 +733,7 @@ HRESULT speech_voice_create(IUnknown *outer, REFIID iid, void **obj)
 
     if (!This) return E_OUTOFMEMORY;
     This->ISpeechVoice_iface.lpVtbl = &speech_voice_vtbl;
+    This->ISpVoice_iface.lpVtbl = &spvoice_vtbl;
     This->ref = 1;
 
     hr = ISpeechVoice_QueryInterface(&This->ISpeechVoice_iface, iid, obj);
-- 
2.24.0





More information about the wine-devel mailing list