windows.networking.hostname/tests: Add IHostNameFactory::CreateHostName() tests.
[wine.git] / dlls / sapi / tts.c
blob147734cc9a98f31dc2d436917af8da3ccbc6e128
1 /*
2 * Speech API (SAPI) text-to-speech implementation.
4 * Copyright 2019 Jactry Zeng for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "objbase.h"
29 #include "sapiddk.h"
31 #include "wine/debug.h"
33 #include "sapi_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(sapi);
37 struct speech_voice
39 ISpeechVoice ISpeechVoice_iface;
40 ISpVoice ISpVoice_iface;
41 IConnectionPointContainer IConnectionPointContainer_iface;
42 LONG ref;
44 ISpStreamFormat *output;
45 ISpTTSEngine *engine;
46 USHORT volume;
47 LONG rate;
48 CRITICAL_SECTION cs;
51 static inline struct speech_voice *impl_from_ISpeechVoice(ISpeechVoice *iface)
53 return CONTAINING_RECORD(iface, struct speech_voice, ISpeechVoice_iface);
56 static inline struct speech_voice *impl_from_ISpVoice(ISpVoice *iface)
58 return CONTAINING_RECORD(iface, struct speech_voice, ISpVoice_iface);
61 static inline struct speech_voice *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
63 return CONTAINING_RECORD(iface, struct speech_voice, IConnectionPointContainer_iface);
66 static HRESULT create_default_token(const WCHAR *cat_id, ISpObjectToken **token)
68 ISpObjectTokenCategory *cat;
69 WCHAR *default_token_id = NULL;
70 HRESULT hr;
72 TRACE("(%s, %p).\n", debugstr_w(cat_id), token);
74 if (FAILED(hr = CoCreateInstance(&CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
75 &IID_ISpObjectTokenCategory, (void **)&cat)))
76 return hr;
78 if (FAILED(hr = ISpObjectTokenCategory_SetId(cat, cat_id, FALSE)) ||
79 FAILED(hr = ISpObjectTokenCategory_GetDefaultTokenId(cat, &default_token_id)))
81 ISpObjectTokenCategory_Release(cat);
82 return hr;
84 ISpObjectTokenCategory_Release(cat);
86 if (FAILED(hr = CoCreateInstance(&CLSID_SpObjectToken, NULL, CLSCTX_INPROC_SERVER,
87 &IID_ISpObjectToken, (void **)token)))
88 goto done;
90 if (FAILED(hr = ISpObjectToken_SetId(*token, NULL, default_token_id, FALSE)))
92 ISpObjectToken_Release(*token);
93 *token = NULL;
96 done:
97 CoTaskMemFree(default_token_id);
98 return hr;
101 /* ISpeechVoice interface */
102 static HRESULT WINAPI speech_voice_QueryInterface(ISpeechVoice *iface, REFIID iid, void **obj)
104 struct speech_voice *This = impl_from_ISpeechVoice(iface);
106 TRACE("(%p, %s %p).\n", iface, debugstr_guid(iid), obj);
108 if (IsEqualIID(iid, &IID_IUnknown) ||
109 IsEqualIID(iid, &IID_IDispatch) ||
110 IsEqualIID(iid, &IID_ISpeechVoice))
111 *obj = &This->ISpeechVoice_iface;
112 else if (IsEqualIID(iid, &IID_ISpVoice))
113 *obj = &This->ISpVoice_iface;
114 else if (IsEqualIID(iid, &IID_IConnectionPointContainer))
115 *obj = &This->IConnectionPointContainer_iface;
116 else
118 *obj = NULL;
119 FIXME("interface %s not implemented.\n", debugstr_guid(iid));
120 return E_NOINTERFACE;
123 IUnknown_AddRef((IUnknown *)*obj);
124 return S_OK;
127 static ULONG WINAPI speech_voice_AddRef(ISpeechVoice *iface)
129 struct speech_voice *This = impl_from_ISpeechVoice(iface);
130 ULONG ref = InterlockedIncrement(&This->ref);
132 TRACE("(%p): ref=%lu.\n", iface, ref);
134 return ref;
137 static ULONG WINAPI speech_voice_Release(ISpeechVoice *iface)
139 struct speech_voice *This = impl_from_ISpeechVoice(iface);
140 ULONG ref = InterlockedDecrement(&This->ref);
142 TRACE("(%p): ref=%lu.\n", iface, ref);
144 if (!ref)
146 if (This->output) ISpStreamFormat_Release(This->output);
147 if (This->engine) ISpTTSEngine_Release(This->engine);
148 DeleteCriticalSection(&This->cs);
150 heap_free(This);
153 return ref;
156 static HRESULT WINAPI speech_voice_GetTypeInfoCount(ISpeechVoice *iface, UINT *info)
158 FIXME("(%p, %p): stub.\n", iface, info);
160 return E_NOTIMPL;
163 static HRESULT WINAPI speech_voice_GetTypeInfo(ISpeechVoice *iface, UINT info, LCID lcid,
164 ITypeInfo **type_info)
166 FIXME("(%p, %u, %lu, %p): stub.\n", iface, info, lcid, type_info);
168 return E_NOTIMPL;
171 static HRESULT WINAPI speech_voice_GetIDsOfNames(ISpeechVoice *iface, REFIID riid, LPOLESTR *names,
172 UINT count, LCID lcid, DISPID *dispid)
174 FIXME("(%p, %s, %p, %u, %lu, %p): stub.\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
176 return E_NOTIMPL;
179 static HRESULT WINAPI speech_voice_Invoke(ISpeechVoice *iface, DISPID dispid, REFIID riid, LCID lcid,
180 WORD flags, DISPPARAMS *params, VARIANT *result,
181 EXCEPINFO *excepinfo, UINT *argerr)
183 FIXME("(%p, %ld, %s, %#lx, %#x, %p, %p, %p, %p): stub.\n", iface, dispid, debugstr_guid(riid),
184 lcid, flags, params, result, excepinfo, argerr);
186 return E_NOTIMPL;
189 static HRESULT WINAPI speech_voice_get_Status(ISpeechVoice *iface, ISpeechVoiceStatus **status)
191 FIXME("(%p, %p): stub.\n", iface, status);
193 return E_NOTIMPL;
196 static HRESULT WINAPI speech_voice_get_Voice(ISpeechVoice *iface, ISpeechObjectToken **voice)
198 FIXME("(%p, %p): stub.\n", iface, voice);
200 return E_NOTIMPL;
203 static HRESULT WINAPI speech_voice_putref_Voice(ISpeechVoice *iface, ISpeechObjectToken *voice)
205 FIXME("(%p, %p): stub.\n", iface, voice);
207 return E_NOTIMPL;
210 static HRESULT WINAPI speech_voice_get_AudioOutput(ISpeechVoice *iface, ISpeechObjectToken **output)
212 FIXME("(%p, %p): stub.\n", iface, output);
214 return E_NOTIMPL;
217 static HRESULT WINAPI speech_voice_putref_AudioOutput(ISpeechVoice *iface, ISpeechObjectToken *output)
219 FIXME("(%p, %p): stub.\n", iface, output);
221 return E_NOTIMPL;
224 static HRESULT WINAPI speech_voice_get_AudioOutputStream(ISpeechVoice *iface, ISpeechBaseStream **output)
226 FIXME("(%p, %p): stub.\n", iface, output);
228 return E_NOTIMPL;
231 static HRESULT WINAPI speech_voice_putref_AudioOutputStream(ISpeechVoice *iface, ISpeechBaseStream *output)
233 FIXME("(%p, %p): stub.\n", iface, output);
235 return E_NOTIMPL;
238 static HRESULT WINAPI speech_voice_get_Rate(ISpeechVoice *iface, LONG *rate)
240 FIXME("(%p, %p): stub.\n", iface, rate);
242 return E_NOTIMPL;
245 static HRESULT WINAPI speech_voice_put_Rate(ISpeechVoice *iface, LONG rate)
247 FIXME("(%p, %ld): stub.\n", iface, rate);
249 return E_NOTIMPL;
252 static HRESULT WINAPI speech_voice_get_Volume(ISpeechVoice *iface, LONG *volume)
254 FIXME("(%p, %p): stub.\n", iface, volume);
256 return E_NOTIMPL;
259 static HRESULT WINAPI speech_voice_put_Volume(ISpeechVoice *iface, LONG volume)
261 FIXME("(%p, %ld): stub.\n", iface, volume);
263 return E_NOTIMPL;
266 static HRESULT WINAPI speech_voice_put_AllowAudioOutputFormatChangesOnNextSet(ISpeechVoice *iface,
267 VARIANT_BOOL allow)
269 FIXME("(%p, %d): stub.\n", iface, allow);
271 return E_NOTIMPL;
274 static HRESULT WINAPI speech_voice_get_AllowAudioOutputFormatChangesOnNextSet(ISpeechVoice *iface, VARIANT_BOOL *allow)
276 FIXME("(%p, %p): stub.\n", iface, allow);
278 return E_NOTIMPL;
281 static HRESULT WINAPI speech_voice_get_EventInterests(ISpeechVoice *iface, SpeechVoiceEvents *flags)
283 FIXME("(%p, %p): stub.\n", iface, flags);
285 return E_NOTIMPL;
288 static HRESULT WINAPI speech_voice_put_EventInterests(ISpeechVoice *iface, SpeechVoiceEvents flags)
290 FIXME("(%p, %#x): stub.\n", iface, flags);
292 return E_NOTIMPL;
295 static HRESULT WINAPI speech_voice_put_Priority(ISpeechVoice *iface, SpeechVoicePriority priority)
297 FIXME("(%p, %d): stub.\n", iface, priority);
299 return E_NOTIMPL;
302 static HRESULT WINAPI speech_voice_get_Priority(ISpeechVoice *iface, SpeechVoicePriority *priority)
304 FIXME("(%p, %p): stub.\n", iface, priority);
306 return E_NOTIMPL;
309 static HRESULT WINAPI speech_voice_put_AlertBoundary(ISpeechVoice *iface, SpeechVoiceEvents boundary)
311 FIXME("(%p, %#x): stub.\n", iface, boundary);
313 return E_NOTIMPL;
316 static HRESULT WINAPI speech_voice_get_AlertBoundary(ISpeechVoice *iface, SpeechVoiceEvents *boundary)
318 FIXME("(%p, %p): stub.\n", iface, boundary);
320 return E_NOTIMPL;
323 static HRESULT WINAPI speech_voice_put_SynchronousSpeakTimeout(ISpeechVoice *iface, LONG timeout)
325 FIXME("(%p, %ld): stub.\n", iface, timeout);
327 return E_NOTIMPL;
330 static HRESULT WINAPI speech_voice_get_SynchronousSpeakTimeout(ISpeechVoice *iface, LONG *timeout)
332 FIXME("(%p, %p): stub.\n", iface, timeout);
334 return E_NOTIMPL;
337 static HRESULT WINAPI speech_voice_Speak(ISpeechVoice *iface, BSTR text, SpeechVoiceSpeakFlags flags, LONG *number)
339 FIXME("(%p, %s, %#x, %p): stub.\n", iface, debugstr_w(text), flags, number);
341 return E_NOTIMPL;
344 static HRESULT WINAPI speech_voice_SpeakStream(ISpeechVoice *iface, ISpeechBaseStream *stream,
345 SpeechVoiceSpeakFlags flags, LONG *number)
347 FIXME("(%p, %p, %#x, %p): stub.\n", iface, stream, flags, number);
349 return E_NOTIMPL;
352 static HRESULT WINAPI speech_voice_Pause(ISpeechVoice *iface)
354 FIXME("(%p): stub.\n", iface);
356 return E_NOTIMPL;
359 static HRESULT WINAPI speech_voice_Resume(ISpeechVoice *iface)
361 FIXME("(%p): stub.\n", iface);
363 return E_NOTIMPL;
366 static HRESULT WINAPI speech_voice_Skip(ISpeechVoice *iface, const BSTR type, LONG items, LONG *skipped)
368 FIXME("(%p, %s, %ld, %p): stub.\n", iface, debugstr_w(type), items, skipped);
370 return E_NOTIMPL;
373 static HRESULT WINAPI speech_voice_GetVoices(ISpeechVoice *iface, BSTR required, BSTR optional,
374 ISpeechObjectTokens **tokens)
376 FIXME("(%p, %s, %s, %p): stub.\n", iface, debugstr_w(required), debugstr_w(optional), tokens);
378 return E_NOTIMPL;
381 static HRESULT WINAPI speech_voice_GetAudioOutputs(ISpeechVoice *iface, BSTR required, BSTR optional,
382 ISpeechObjectTokens **tokens)
384 FIXME("(%p, %s, %s, %p): stub.\n", iface, debugstr_w(required), debugstr_w(optional), tokens);
386 return E_NOTIMPL;
389 static HRESULT WINAPI speech_voice_WaitUntilDone(ISpeechVoice *iface, LONG timeout, VARIANT_BOOL *done)
391 FIXME("(%p, %ld, %p): stub.\n", iface, timeout, done);
393 return E_NOTIMPL;
396 static HRESULT WINAPI speech_voice_SpeakCompleteEvent(ISpeechVoice *iface, LONG *handle)
398 FIXME("(%p, %p): stub.\n", iface, handle);
400 return E_NOTIMPL;
403 static HRESULT WINAPI speech_voice_IsUISupported(ISpeechVoice *iface, const BSTR typeui, const VARIANT *data,
404 VARIANT_BOOL *supported)
406 FIXME("(%p, %s, %p, %p): stub.\n", iface, debugstr_w(typeui), data, supported);
408 return E_NOTIMPL;
411 static HRESULT WINAPI speech_voice_DisplayUI(ISpeechVoice *iface, LONG hwnd, BSTR title,
412 const BSTR typeui, const VARIANT *data)
414 FIXME("(%p, %ld, %s, %s, %p): stub.\n", iface, hwnd, debugstr_w(title), debugstr_w(typeui), data);
416 return E_NOTIMPL;
419 static const ISpeechVoiceVtbl speech_voice_vtbl =
421 speech_voice_QueryInterface,
422 speech_voice_AddRef,
423 speech_voice_Release,
424 speech_voice_GetTypeInfoCount,
425 speech_voice_GetTypeInfo,
426 speech_voice_GetIDsOfNames,
427 speech_voice_Invoke,
428 speech_voice_get_Status,
429 speech_voice_get_Voice,
430 speech_voice_putref_Voice,
431 speech_voice_get_AudioOutput,
432 speech_voice_putref_AudioOutput,
433 speech_voice_get_AudioOutputStream,
434 speech_voice_putref_AudioOutputStream,
435 speech_voice_get_Rate,
436 speech_voice_put_Rate,
437 speech_voice_get_Volume,
438 speech_voice_put_Volume,
439 speech_voice_put_AllowAudioOutputFormatChangesOnNextSet,
440 speech_voice_get_AllowAudioOutputFormatChangesOnNextSet,
441 speech_voice_get_EventInterests,
442 speech_voice_put_EventInterests,
443 speech_voice_put_Priority,
444 speech_voice_get_Priority,
445 speech_voice_put_AlertBoundary,
446 speech_voice_get_AlertBoundary,
447 speech_voice_put_SynchronousSpeakTimeout,
448 speech_voice_get_SynchronousSpeakTimeout,
449 speech_voice_Speak,
450 speech_voice_SpeakStream,
451 speech_voice_Pause,
452 speech_voice_Resume,
453 speech_voice_Skip,
454 speech_voice_GetVoices,
455 speech_voice_GetAudioOutputs,
456 speech_voice_WaitUntilDone,
457 speech_voice_SpeakCompleteEvent,
458 speech_voice_IsUISupported,
459 speech_voice_DisplayUI,
462 /* ISpVoice interface */
463 static HRESULT WINAPI spvoice_QueryInterface(ISpVoice *iface, REFIID iid, void **obj)
465 struct speech_voice *This = impl_from_ISpVoice(iface);
467 TRACE("(%p, %s %p).\n", iface, debugstr_guid(iid), obj);
469 return ISpeechVoice_QueryInterface(&This->ISpeechVoice_iface, iid, obj);
472 static ULONG WINAPI spvoice_AddRef(ISpVoice *iface)
474 struct speech_voice *This = impl_from_ISpVoice(iface);
476 TRACE("(%p).\n", iface);
478 return ISpeechVoice_AddRef(&This->ISpeechVoice_iface);
481 static ULONG WINAPI spvoice_Release(ISpVoice *iface)
483 struct speech_voice *This = impl_from_ISpVoice(iface);
485 TRACE("(%p).\n", iface);
487 return ISpeechVoice_Release(&This->ISpeechVoice_iface);
490 static HRESULT WINAPI spvoice_SetNotifySink(ISpVoice *iface, ISpNotifySink *sink)
492 FIXME("(%p, %p): stub.\n", iface, sink);
494 return E_NOTIMPL;
497 static HRESULT WINAPI spvoice_SetNotifyWindowMessage(ISpVoice *iface, HWND hwnd, UINT msg,
498 WPARAM wparam, LPARAM lparam)
500 FIXME("(%p, %p, %u, %Ix, %Ix): stub.\n", iface, hwnd, msg, wparam, lparam);
502 return E_NOTIMPL;
505 static HRESULT WINAPI spvoice_SetNotifyCallbackFunction(ISpVoice *iface, SPNOTIFYCALLBACK *callback,
506 WPARAM wparam, LPARAM lparam)
508 FIXME("(%p, %p, %Ix, %Ix): stub.\n", iface, callback, wparam, lparam);
510 return E_NOTIMPL;
513 static HRESULT WINAPI spvoice_SetNotifyCallbackInterface(ISpVoice *iface, ISpNotifyCallback *callback,
514 WPARAM wparam, LPARAM lparam)
516 FIXME("(%p, %p, %Ix, %Ix): stub.\n", iface, callback, wparam, lparam);
518 return E_NOTIMPL;
521 static HRESULT WINAPI spvoice_SetNotifyWin32Event(ISpVoice *iface)
523 FIXME("(%p): stub.\n", iface);
525 return E_NOTIMPL;
528 static HRESULT WINAPI spvoice_WaitForNotifyEvent(ISpVoice *iface, DWORD milliseconds)
530 FIXME("(%p, %ld): stub.\n", iface, milliseconds);
532 return E_NOTIMPL;
535 static HANDLE WINAPI spvoice_GetNotifyEventHandle(ISpVoice *iface)
537 FIXME("(%p): stub.\n", iface);
539 return NULL;
542 static HRESULT WINAPI spvoice_SetInterest(ISpVoice *iface, ULONGLONG event, ULONGLONG queued)
544 FIXME("(%p, %s, %s): stub.\n", iface, wine_dbgstr_longlong(event), wine_dbgstr_longlong(queued));
546 return E_NOTIMPL;
549 static HRESULT WINAPI spvoice_GetEvents(ISpVoice *iface, ULONG count, SPEVENT *array, ULONG *fetched)
551 FIXME("(%p, %lu, %p, %p): stub.\n", iface, count, array, fetched);
553 return E_NOTIMPL;
556 static HRESULT WINAPI spvoice_GetInfo(ISpVoice *iface, SPEVENTSOURCEINFO *info)
558 FIXME("(%p, %p): stub.\n", iface, info);
560 return E_NOTIMPL;
563 static HRESULT WINAPI spvoice_SetOutput(ISpVoice *iface, IUnknown *unk, BOOL allow_format_changes)
565 struct speech_voice *This = impl_from_ISpVoice(iface);
566 ISpStreamFormat *stream = NULL;
567 ISpObjectToken *token = NULL;
568 HRESULT hr;
570 TRACE("(%p, %p, %d).\n", iface, unk, allow_format_changes);
572 if (!allow_format_changes)
573 FIXME("ignoring allow_format_changes = FALSE.\n");
575 if (!unk)
577 /* TODO: Create the default SpAudioOut token here once SpMMAudioEnum is implemented. */
578 if (FAILED(hr = CoCreateInstance(&CLSID_SpMMAudioOut, NULL, CLSCTX_INPROC_SERVER,
579 &IID_ISpStreamFormat, (void **)&stream)))
580 return hr;
582 else
584 if (FAILED(IUnknown_QueryInterface(unk, &IID_ISpStreamFormat, (void **)&stream)))
586 if (FAILED(IUnknown_QueryInterface(unk, &IID_ISpObjectToken, (void **)&token)))
587 return E_INVALIDARG;
591 if (!stream)
593 hr = ISpObjectToken_CreateInstance(token, NULL, CLSCTX_ALL, &IID_ISpStreamFormat, (void **)&stream);
594 ISpObjectToken_Release(token);
595 if (FAILED(hr))
596 return hr;
599 EnterCriticalSection(&This->cs);
601 if (This->output)
602 ISpStreamFormat_Release(This->output);
603 This->output = stream;
605 LeaveCriticalSection(&This->cs);
607 return S_OK;
610 static HRESULT WINAPI spvoice_GetOutputObjectToken(ISpVoice *iface, ISpObjectToken **token)
612 FIXME("(%p, %p): stub.\n", iface, token);
614 return E_NOTIMPL;
617 static HRESULT WINAPI spvoice_GetOutputStream(ISpVoice *iface, ISpStreamFormat **stream)
619 FIXME("(%p, %p): stub.\n", iface, stream);
621 return E_NOTIMPL;
624 static HRESULT WINAPI spvoice_Pause(ISpVoice *iface)
626 FIXME("(%p): stub.\n", iface);
628 return E_NOTIMPL;
631 static HRESULT WINAPI spvoice_Resume(ISpVoice *iface)
633 FIXME("(%p): stub.\n", iface);
635 return E_NOTIMPL;
638 static HRESULT WINAPI spvoice_SetVoice(ISpVoice *iface, ISpObjectToken *token)
640 struct speech_voice *This = impl_from_ISpVoice(iface);
641 ISpTTSEngine *engine;
642 HRESULT hr;
645 TRACE("(%p, %p).\n", iface, token);
647 if (!token)
649 if (FAILED(hr = create_default_token(SPCAT_VOICES, &token)))
650 return hr;
653 hr = ISpObjectToken_CreateInstance(token, NULL, CLSCTX_ALL, &IID_ISpTTSEngine, (void **)&engine);
654 ISpObjectToken_Release(token);
655 if (FAILED(hr))
656 return hr;
658 EnterCriticalSection(&This->cs);
660 if (This->engine)
661 ISpTTSEngine_Release(This->engine);
662 This->engine = engine;
664 LeaveCriticalSection(&This->cs);
666 return S_OK;
669 static HRESULT WINAPI spvoice_GetVoice(ISpVoice *iface, ISpObjectToken **token)
671 struct speech_voice *This = impl_from_ISpVoice(iface);
672 ISpObjectWithToken *engine_token_iface;
673 HRESULT hr;
675 TRACE("(%p, %p).\n", iface, token);
677 if (!token)
678 return E_POINTER;
680 EnterCriticalSection(&This->cs);
682 if (!This->engine)
684 LeaveCriticalSection(&This->cs);
685 return create_default_token(SPCAT_VOICES, token);
688 if (SUCCEEDED(hr = ISpTTSEngine_QueryInterface(This->engine, &IID_ISpObjectWithToken, (void **)&engine_token_iface)))
690 hr = ISpObjectWithToken_GetObjectToken(engine_token_iface, token);
691 ISpObjectWithToken_Release(engine_token_iface);
694 LeaveCriticalSection(&This->cs);
696 return hr;
699 static HRESULT WINAPI spvoice_Speak(ISpVoice *iface, const WCHAR *contents, DWORD flags, ULONG *number)
701 FIXME("(%p, %p, %#lx, %p): stub.\n", iface, contents, flags, number);
703 return E_NOTIMPL;
706 static HRESULT WINAPI spvoice_SpeakStream(ISpVoice *iface, IStream *stream, DWORD flags, ULONG *number)
708 FIXME("(%p, %p, %#lx, %p): stub.\n", iface, stream, flags, number);
710 return E_NOTIMPL;
713 static HRESULT WINAPI spvoice_GetStatus(ISpVoice *iface, SPVOICESTATUS *status, WCHAR **bookmark)
715 FIXME("(%p, %p, %p): stub.\n", iface, status, bookmark);
717 return E_NOTIMPL;
720 static HRESULT WINAPI spvoice_Skip(ISpVoice *iface, const WCHAR *type, LONG items, ULONG *skipped)
722 FIXME("(%p, %s, %ld, %p): stub.\n", iface, debugstr_w(type), items, skipped);
724 return E_NOTIMPL;
727 static HRESULT WINAPI spvoice_SetPriority(ISpVoice *iface, SPVPRIORITY priority)
729 FIXME("(%p, %d): stub.\n", iface, priority);
731 return E_NOTIMPL;
734 static HRESULT WINAPI spvoice_GetPriority(ISpVoice *iface, SPVPRIORITY *priority)
736 FIXME("(%p, %p): stub.\n", iface, priority);
738 return E_NOTIMPL;
741 static HRESULT WINAPI spvoice_SetAlertBoundary(ISpVoice *iface, SPEVENTENUM boundary)
743 FIXME("(%p, %d): stub.\n", iface, boundary);
745 return E_NOTIMPL;
748 static HRESULT WINAPI spvoice_GetAlertBoundary(ISpVoice *iface, SPEVENTENUM *boundary)
750 FIXME("(%p, %p): stub.\n", iface, boundary);
752 return E_NOTIMPL;
755 static HRESULT WINAPI spvoice_SetRate(ISpVoice *iface, LONG rate)
757 struct speech_voice *This = impl_from_ISpVoice(iface);
759 TRACE("(%p, %ld).\n", iface, rate);
761 EnterCriticalSection(&This->cs);
762 This->rate = rate;
763 LeaveCriticalSection(&This->cs);
765 return S_OK;
768 static HRESULT WINAPI spvoice_GetRate(ISpVoice *iface, LONG *rate)
770 struct speech_voice *This = impl_from_ISpVoice(iface);
772 TRACE("(%p, %p).\n", iface, rate);
774 EnterCriticalSection(&This->cs);
775 *rate = This->rate;
776 LeaveCriticalSection(&This->cs);
778 return S_OK;
781 static HRESULT WINAPI spvoice_SetVolume(ISpVoice *iface, USHORT volume)
783 struct speech_voice *This = impl_from_ISpVoice(iface);
785 TRACE("(%p, %d).\n", iface, volume);
787 if (volume > 100)
788 return E_INVALIDARG;
790 EnterCriticalSection(&This->cs);
791 This->volume = volume;
792 LeaveCriticalSection(&This->cs);
794 return S_OK;
797 static HRESULT WINAPI spvoice_GetVolume(ISpVoice *iface, USHORT *volume)
799 struct speech_voice *This = impl_from_ISpVoice(iface);
801 TRACE("(%p, %p).\n", iface, volume);
803 EnterCriticalSection(&This->cs);
804 *volume = This->volume;
805 LeaveCriticalSection(&This->cs);
807 return S_OK;
810 static HRESULT WINAPI spvoice_WaitUntilDone(ISpVoice *iface, ULONG timeout)
812 FIXME("(%p, %ld): stub.\n", iface, timeout);
814 return E_NOTIMPL;
817 static HRESULT WINAPI spvoice_SetSyncSpeakTimeout(ISpVoice *iface, ULONG timeout)
819 FIXME("(%p, %ld): stub.\n", iface, timeout);
821 return E_NOTIMPL;
824 static HRESULT WINAPI spvoice_GetSyncSpeakTimeout(ISpVoice *iface, ULONG *timeout)
826 FIXME("(%p, %p): stub.\n", iface, timeout);
828 return E_NOTIMPL;
831 static HANDLE WINAPI spvoice_SpeakCompleteEvent(ISpVoice *iface)
833 FIXME("(%p): stub.\n", iface);
835 return NULL;
838 static HRESULT WINAPI spvoice_IsUISupported(ISpVoice *iface, const WCHAR *type, void *extra,
839 ULONG count, BOOL *supported)
841 FIXME("(%p, %p, %p, %ld, %p): stub.\n", iface, type, extra, count, supported);
843 return E_NOTIMPL;
846 static HRESULT WINAPI spvoice_DisplayUI(ISpVoice *iface, HWND parent, const WCHAR *title,
847 const WCHAR *type, void *extra, ULONG count)
849 FIXME("(%p, %p, %p, %p, %p, %ld): stub.\n", iface, parent, title, type, extra, count);
851 return E_NOTIMPL;
854 static const ISpVoiceVtbl spvoice_vtbl =
856 spvoice_QueryInterface,
857 spvoice_AddRef,
858 spvoice_Release,
859 spvoice_SetNotifySink,
860 spvoice_SetNotifyWindowMessage,
861 spvoice_SetNotifyCallbackFunction,
862 spvoice_SetNotifyCallbackInterface,
863 spvoice_SetNotifyWin32Event,
864 spvoice_WaitForNotifyEvent,
865 spvoice_GetNotifyEventHandle,
866 spvoice_SetInterest,
867 spvoice_GetEvents,
868 spvoice_GetInfo,
869 spvoice_SetOutput,
870 spvoice_GetOutputObjectToken,
871 spvoice_GetOutputStream,
872 spvoice_Pause,
873 spvoice_Resume,
874 spvoice_SetVoice,
875 spvoice_GetVoice,
876 spvoice_Speak,
877 spvoice_SpeakStream,
878 spvoice_GetStatus,
879 spvoice_Skip,
880 spvoice_SetPriority,
881 spvoice_GetPriority,
882 spvoice_SetAlertBoundary,
883 spvoice_GetAlertBoundary,
884 spvoice_SetRate,
885 spvoice_GetRate,
886 spvoice_SetVolume,
887 spvoice_GetVolume,
888 spvoice_WaitUntilDone,
889 spvoice_SetSyncSpeakTimeout,
890 spvoice_GetSyncSpeakTimeout,
891 spvoice_SpeakCompleteEvent,
892 spvoice_IsUISupported,
893 spvoice_DisplayUI
896 /* IConnectionPointContainer interface */
897 static HRESULT WINAPI container_QueryInterface(IConnectionPointContainer *iface, REFIID iid, void **obj)
899 struct speech_voice *This = impl_from_IConnectionPointContainer(iface);
901 TRACE("(%p, %s %p).\n", iface, debugstr_guid(iid), obj);
903 return ISpeechVoice_QueryInterface(&This->ISpeechVoice_iface, iid, obj);
906 static ULONG WINAPI container_AddRef(IConnectionPointContainer *iface)
908 struct speech_voice *This = impl_from_IConnectionPointContainer(iface);
910 TRACE("(%p).\n", iface);
912 return ISpeechVoice_AddRef(&This->ISpeechVoice_iface);
915 static ULONG WINAPI container_Release(IConnectionPointContainer *iface)
917 struct speech_voice *This = impl_from_IConnectionPointContainer(iface);
919 TRACE("(%p).\n", iface);
921 return ISpeechVoice_Release(&This->ISpeechVoice_iface);
924 static HRESULT WINAPI container_EnumConnectionPoints(IConnectionPointContainer *iface,
925 IEnumConnectionPoints **enum_cp)
927 FIXME("(%p, %p): stub.\n", iface, enum_cp);
929 return E_NOTIMPL;
932 static HRESULT WINAPI container_FindConnectionPoint(IConnectionPointContainer *iface, REFIID riid,
933 IConnectionPoint **cp)
935 FIXME("(%p, %s, %p): stub.\n", iface, debugstr_guid(riid), cp);
937 return E_NOTIMPL;
940 const static IConnectionPointContainerVtbl container_vtbl =
942 container_QueryInterface,
943 container_AddRef,
944 container_Release,
945 container_EnumConnectionPoints,
946 container_FindConnectionPoint
949 HRESULT speech_voice_create(IUnknown *outer, REFIID iid, void **obj)
951 struct speech_voice *This = heap_alloc(sizeof(*This));
952 HRESULT hr;
954 if (!This) return E_OUTOFMEMORY;
955 This->ISpeechVoice_iface.lpVtbl = &speech_voice_vtbl;
956 This->ISpVoice_iface.lpVtbl = &spvoice_vtbl;
957 This->IConnectionPointContainer_iface.lpVtbl = &container_vtbl;
958 This->ref = 1;
960 This->output = NULL;
961 This->engine = NULL;
962 This->volume = 100;
963 This->rate = 0;
965 InitializeCriticalSection(&This->cs);
967 hr = ISpeechVoice_QueryInterface(&This->ISpeechVoice_iface, iid, obj);
969 ISpeechVoice_Release(&This->ISpeechVoice_iface);
970 return hr;