ReactOS 0.4.16-dev-197-g92996da
buffer.c
Go to the documentation of this file.
1/* DirectSound
2 *
3 * Copyright 1998 Marcus Meissner
4 * Copyright 1998 Rob Riggs
5 * Copyright 2000-2002 TransGaming Technologies, Inc.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include "dsound_private.h"
23
24/*******************************************************************************
25 * IDirectSoundNotify
26 */
27
29{
30 /* IUnknown fields */
31 const IDirectSoundNotifyVtbl *lpVtbl;
34};
35
39
42) {
44 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
45
46 if (This->dsb == NULL) {
47 WARN("invalid parameter\n");
48 return E_INVALIDARG;
49 }
50
52}
53
55{
58 TRACE("(%p) ref was %d\n", This, ref - 1);
59 return ref;
60}
61
63{
66 TRACE("(%p) ref was %d\n", This, ref + 1);
67
68 if (!ref) {
69 This->dsb->notify = NULL;
72 TRACE("(%p) released\n", This);
73 }
74 return ref;
75}
76
79) {
81 TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
82
83 if (howmuch > 0 && notify == NULL) {
84 WARN("invalid parameter: notify == NULL\n");
85 return DSERR_INVALIDPARAM;
86 }
87
88 if (TRACE_ON(dsound)) {
89 unsigned int i;
90 for (i=0;i<howmuch;i++)
91 TRACE("notify at %d to %p\n",
92 notify[i].dwOffset,notify[i].hEventNotify);
93 }
94
95 if (This->dsb->hwnotify) {
97 hres = IDsDriverNotify_SetNotificationPositions(This->dsb->hwnotify, howmuch, notify);
98 if (hres != DS_OK)
99 WARN("IDsDriverNotify_SetNotificationPositions failed\n");
100 return hres;
101 } else if (howmuch > 0) {
102 /* Make an internal copy of the caller-supplied array.
103 * Replace the existing copy if one is already present. */
104 HeapFree(GetProcessHeap(), 0, This->dsb->notifies);
105 This->dsb->notifies = HeapAlloc(GetProcessHeap(), 0,
106 howmuch * sizeof(DSBPOSITIONNOTIFY));
107
108 if (This->dsb->notifies == NULL) {
109 WARN("out of memory\n");
110 return DSERR_OUTOFMEMORY;
111 }
112 CopyMemory(This->dsb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
113 This->dsb->nrofnotifies = howmuch;
114 } else {
115 HeapFree(GetProcessHeap(), 0, This->dsb->notifies);
116 This->dsb->notifies = NULL;
117 This->dsb->nrofnotifies = 0;
118 }
119
120 return S_OK;
121}
122
123static const IDirectSoundNotifyVtbl dsnvt =
124{
129};
130
134{
136 TRACE("(%p,%p)\n",dsb,pdsn);
137
138 dsn = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*dsn));
139
140 if (dsn == NULL) {
141 WARN("out of memory\n");
142 return DSERR_OUTOFMEMORY;
143 }
144
145 dsn->ref = 0;
146 dsn->lpVtbl = &dsnvt;
147 dsn->dsb = dsb;
148 dsb->notify = dsn;
150
151 *pdsn = dsn;
152 return DS_OK;
153}
154
157{
158 TRACE("(%p)\n",pdsn);
159
161
162 return DS_OK;
163}
164
165/*******************************************************************************
166 * IDirectSoundBuffer
167 */
168
169static inline IDirectSoundBufferImpl *impl_from_IDirectSoundBuffer8(IDirectSoundBuffer8 *iface)
170{
171 return CONTAINING_RECORD(iface, IDirectSoundBufferImpl, IDirectSoundBuffer8_iface);
172}
173
175{
176 return This->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER ? TRUE : FALSE;
177}
178
179static HRESULT WINAPI IDirectSoundBufferImpl_SetFormat(IDirectSoundBuffer8 *iface,
180 LPCWAVEFORMATEX wfex)
181{
183
184 TRACE("(%p,%p)\n", iface, wfex);
185
187 return primarybuffer_SetFormat(This->device, wfex);
188 else {
189 WARN("not available for secondary buffers.\n");
190 return DSERR_INVALIDCALL;
191 }
192}
193
194static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume(IDirectSoundBuffer8 *iface, LONG vol)
195{
197 LONG oldVol;
198
200
201 TRACE("(%p,%d)\n",This,vol);
202
203 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
204 WARN("control unavailable: This->dsbd.dwFlags = 0x%08x\n", This->dsbd.dwFlags);
206 }
207
208 if ((vol > DSBVOLUME_MAX) || (vol < DSBVOLUME_MIN)) {
209 WARN("invalid parameter: vol = %d\n", vol);
210 return DSERR_INVALIDPARAM;
211 }
212
213 /* **** */
215
216 if (This->dsbd.dwFlags & DSBCAPS_CTRL3D) {
217 oldVol = This->ds3db_lVolume;
218 This->ds3db_lVolume = vol;
219 if (vol != oldVol)
220 /* recalc 3d volume, which in turn recalcs the pans */
222 } else {
223 oldVol = This->volpan.lVolume;
224 This->volpan.lVolume = vol;
225 if (vol != oldVol)
226 DSOUND_RecalcVolPan(&(This->volpan));
227 }
228
229 if (vol != oldVol) {
230 if (This->hwbuf) {
231 hres = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
232 if (hres != DS_OK)
233 WARN("IDsDriverBuffer_SetVolumePan failed\n");
234 }
235 }
236
237 RtlReleaseResource(&This->lock);
238 /* **** */
239
240 return hres;
241}
242
243static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume(IDirectSoundBuffer8 *iface, LONG *vol)
244{
246
247 TRACE("(%p,%p)\n",This,vol);
248
249 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
250 WARN("control unavailable\n");
252 }
253
254 if (vol == NULL) {
255 WARN("invalid parameter: vol == NULL\n");
256 return DSERR_INVALIDPARAM;
257 }
258
259 *vol = This->volpan.lVolume;
260
261 return DS_OK;
262}
263
264static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *iface, DWORD freq)
265{
267 DWORD oldFreq;
268
269 TRACE("(%p,%d)\n",This,freq);
270
271 if (is_primary_buffer(This)) {
272 WARN("not available for primary buffers.\n");
274 }
275
276 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLFREQUENCY)) {
277 WARN("control unavailable\n");
279 }
280
281 if (freq == DSBFREQUENCY_ORIGINAL)
282 freq = This->pwfx->nSamplesPerSec;
283
284 if ((freq < DSBFREQUENCY_MIN) || (freq > DSBFREQUENCY_MAX)) {
285 WARN("invalid parameter: freq = %d\n", freq);
286 return DSERR_INVALIDPARAM;
287 }
288
289 /* **** */
291
292 oldFreq = This->freq;
293 This->freq = freq;
294 if (freq != oldFreq) {
295 This->freqAdjust = ((DWORD64)This->freq << DSOUND_FREQSHIFT) / This->device->pwfx->nSamplesPerSec;
296 This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign;
298 DSOUND_MixToTemporary(This, 0, This->buflen, FALSE);
299 }
300
301 RtlReleaseResource(&This->lock);
302 /* **** */
303
304 return DS_OK;
305}
306
307static HRESULT WINAPI IDirectSoundBufferImpl_Play(IDirectSoundBuffer8 *iface, DWORD reserved1,
309{
312
313 TRACE("(%p,%08x,%08x,%08x)\n",This,reserved1,reserved2,flags);
314
315 /* **** */
317
318 This->playflags = flags;
319 if (This->state == STATE_STOPPED && !This->hwbuf) {
320 This->leadin = TRUE;
321 This->state = STATE_STARTING;
322 } else if (This->state == STATE_STOPPING)
323 This->state = STATE_PLAYING;
324 if (This->hwbuf) {
325 hres = IDsDriverBuffer_Play(This->hwbuf, 0, 0, This->playflags);
326 if (hres != DS_OK)
327 WARN("IDsDriverBuffer_Play failed\n");
328 else
329 This->state = STATE_PLAYING;
330 }
331
332 RtlReleaseResource(&This->lock);
333 /* **** */
334
335 return hres;
336}
337
338static HRESULT WINAPI IDirectSoundBufferImpl_Stop(IDirectSoundBuffer8 *iface)
339{
342
343 TRACE("(%p)\n",This);
344
345 /* **** */
347
348 if (This->state == STATE_PLAYING)
349 This->state = STATE_STOPPING;
350 else if (This->state == STATE_STARTING)
351 {
352 This->state = STATE_STOPPED;
353 DSOUND_CheckEvent(This, 0, 0);
354 }
355 if (This->hwbuf) {
357 if (hres != DS_OK)
358 WARN("IDsDriverBuffer_Stop failed\n");
359 else
360 This->state = STATE_STOPPED;
361 }
362
363 RtlReleaseResource(&This->lock);
364 /* **** */
365
366 return hres;
367}
368
369static ULONG WINAPI IDirectSoundBufferImpl_AddRef(IDirectSoundBuffer8 *iface)
370{
373
374 TRACE("(%p) ref was %d\n", This, ref - 1);
375
376 if(ref == 1)
377 InterlockedIncrement(&This->numIfaces);
378
379 return ref;
380}
381
382static ULONG WINAPI IDirectSoundBufferImpl_Release(IDirectSoundBuffer8 *iface)
383{
386
387 TRACE("(%p) ref was %d\n", This, ref + 1);
388
389 if (!ref && !InterlockedDecrement(&This->numIfaces)) {
392 else
394 }
395 return ref;
396}
397
399 DWORD *playpos, DWORD *writepos)
400{
403
404 TRACE("(%p,%p,%p)\n",This,playpos,writepos);
405
407 if (This->hwbuf) {
408 hres=IDsDriverBuffer_GetPosition(This->hwbuf,playpos,writepos);
409 if (hres != DS_OK) {
410 WARN("IDsDriverBuffer_GetPosition failed\n");
411 return hres;
412 }
413 } else {
414 DWORD pos = This->sec_mixpos;
415
416 /* sanity */
417 if (pos >= This->buflen){
418 FIXME("Bad play position. playpos: %d, buflen: %d\n", pos, This->buflen);
419 pos %= This->buflen;
420 }
421
422 if (playpos)
423 *playpos = pos;
424 if (writepos)
425 *writepos = pos;
426 }
427 if (writepos && This->state != STATE_STOPPED && (!This->hwbuf || !(This->device->drvdesc.dwFlags & DSDDESC_DONTNEEDWRITELEAD))) {
428 /* apply the documented 10ms lead to writepos */
429 *writepos += This->writelead;
430 *writepos %= This->buflen;
431 }
432 RtlReleaseResource(&This->lock);
433
434 TRACE("playpos = %d, writepos = %d, buflen=%d (%p, time=%d)\n",
435 playpos?*playpos:-1, writepos?*writepos:-1, This->buflen, This, GetTickCount());
436
437 return DS_OK;
438}
439
440static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus(IDirectSoundBuffer8 *iface, DWORD *status)
441{
443
444 TRACE("(%p,%p), thread is %04x\n",This,status,GetCurrentThreadId());
445
446 if (status == NULL) {
447 WARN("invalid parameter: status = NULL\n");
448 return DSERR_INVALIDPARAM;
449 }
450
451 *status = 0;
453 if ((This->state == STATE_STARTING) || (This->state == STATE_PLAYING)) {
455 if (This->playflags & DSBPLAY_LOOPING)
457 }
458 RtlReleaseResource(&This->lock);
459
460 TRACE("status=%x\n", *status);
461 return DS_OK;
462}
463
464
465static HRESULT WINAPI IDirectSoundBufferImpl_GetFormat(IDirectSoundBuffer8 *iface,
466 LPWAVEFORMATEX lpwf, DWORD wfsize, DWORD *wfwritten)
467{
469 DWORD size;
470
471 TRACE("(%p,%p,%d,%p)\n",This,lpwf,wfsize,wfwritten);
472
473 size = sizeof(WAVEFORMATEX) + This->pwfx->cbSize;
474
475 if (lpwf) { /* NULL is valid */
476 if (wfsize >= size) {
477 CopyMemory(lpwf,This->pwfx,size);
478 if (wfwritten)
479 *wfwritten = size;
480 } else {
481 WARN("invalid parameter: wfsize too small\n");
482 CopyMemory(lpwf,This->pwfx,wfsize);
483 if (wfwritten)
484 *wfwritten = wfsize;
485 return DSERR_INVALIDPARAM;
486 }
487 } else {
488 if (wfwritten)
489 *wfwritten = sizeof(WAVEFORMATEX) + This->pwfx->cbSize;
490 else {
491 WARN("invalid parameter: wfwritten == NULL\n");
492 return DSERR_INVALIDPARAM;
493 }
494 }
495
496 return DS_OK;
497}
498
499static HRESULT WINAPI IDirectSoundBufferImpl_Lock(IDirectSoundBuffer8 *iface, DWORD writecursor,
500 DWORD writebytes, void **lplpaudioptr1, DWORD *audiobytes1, void **lplpaudioptr2,
501 DWORD *audiobytes2, DWORD flags)
502{
505
506 TRACE("(%p,%d,%d,%p,%p,%p,%p,0x%08x) at %d\n", This, writecursor, writebytes, lplpaudioptr1,
507 audiobytes1, lplpaudioptr2, audiobytes2, flags, GetTickCount());
508
509 if (!audiobytes1)
510 return DSERR_INVALIDPARAM;
511
512 /* when this flag is set, writecursor is meaningless and must be calculated */
514 /* GetCurrentPosition does too much magic to duplicate here */
516 if (hres != DS_OK) {
517 WARN("IDirectSoundBufferImpl_GetCurrentPosition failed\n");
518 return hres;
519 }
520 }
521
522 /* when this flag is set, writebytes is meaningless and must be set */
524 writebytes = This->buflen;
525
526 if (writecursor >= This->buflen) {
527 WARN("Invalid parameter, writecursor: %u >= buflen: %u\n",
528 writecursor, This->buflen);
529 return DSERR_INVALIDPARAM;
530 }
531
532 if (writebytes > This->buflen) {
533 WARN("Invalid parameter, writebytes: %u > buflen: %u\n",
534 writebytes, This->buflen);
535 return DSERR_INVALIDPARAM;
536 }
537
538 /* **** */
540
541 if (!(This->device->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
543 lplpaudioptr1, audiobytes1,
544 lplpaudioptr2, audiobytes2,
545 writecursor, writebytes,
546 0);
547 if (hres != DS_OK) {
548 WARN("IDsDriverBuffer_Lock failed\n");
549 RtlReleaseResource(&This->lock);
550 return hres;
551 }
552 } else {
553 if (writecursor+writebytes <= This->buflen) {
554 *(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
555 if (This->sec_mixpos >= writecursor && This->sec_mixpos < writecursor + writebytes && This->state == STATE_PLAYING)
556 WARN("Overwriting mixing position, case 1\n");
557 *audiobytes1 = writebytes;
558 if (lplpaudioptr2)
559 *(LPBYTE*)lplpaudioptr2 = NULL;
560 if (audiobytes2)
561 *audiobytes2 = 0;
562 TRACE("Locked %p(%i bytes) and %p(%i bytes) writecursor=%d\n",
563 *(LPBYTE*)lplpaudioptr1, *audiobytes1, lplpaudioptr2 ? *(LPBYTE*)lplpaudioptr2 : NULL, audiobytes2 ? *audiobytes2: 0, writecursor);
564 TRACE("->%d.0\n",writebytes);
565 } else {
566 DWORD remainder = writebytes + writecursor - This->buflen;
567 *(LPBYTE*)lplpaudioptr1 = This->buffer->memory+writecursor;
568 *audiobytes1 = This->buflen-writecursor;
569 if (This->sec_mixpos >= writecursor && This->sec_mixpos < writecursor + writebytes && This->state == STATE_PLAYING)
570 WARN("Overwriting mixing position, case 2\n");
571 if (lplpaudioptr2)
572 *(LPBYTE*)lplpaudioptr2 = This->buffer->memory;
573 if (audiobytes2)
574 *audiobytes2 = writebytes-(This->buflen-writecursor);
575 if (audiobytes2 && This->sec_mixpos < remainder && This->state == STATE_PLAYING)
576 WARN("Overwriting mixing position, case 3\n");
577 TRACE("Locked %p(%i bytes) and %p(%i bytes) writecursor=%d\n", *(LPBYTE*)lplpaudioptr1, *audiobytes1, lplpaudioptr2 ? *(LPBYTE*)lplpaudioptr2 : NULL, audiobytes2 ? *audiobytes2: 0, writecursor);
578 }
579 }
580
581 RtlReleaseResource(&This->lock);
582 /* **** */
583
584 return DS_OK;
585}
586
588 DWORD newpos)
589{
592 DWORD oldpos;
593
594 TRACE("(%p,%d)\n",This,newpos);
595
596 /* **** */
598
599 oldpos = This->sec_mixpos;
600
601 /* start mixing from this new location instead */
602 newpos %= This->buflen;
603 newpos -= newpos%This->pwfx->nBlockAlign;
604 This->sec_mixpos = newpos;
605
606 /* at this point, do not attempt to reset buffers, mess with primary mix position,
607 or anything like that to reduce latency. The data already prebuffered cannot be changed */
608
609 /* position HW buffer if applicable, else just start mixing from new location instead */
610 if (This->hwbuf) {
611 hres = IDsDriverBuffer_SetPosition(This->hwbuf, This->buf_mixpos);
612 if (hres != DS_OK)
613 WARN("IDsDriverBuffer_SetPosition failed\n");
614 }
615 else if (oldpos != newpos)
616 /* FIXME: Perhaps add a call to DSOUND_MixToTemporary here? Not sure it's needed */
617 This->buf_mixpos = DSOUND_secpos_to_bufpos(This, newpos, 0, NULL);
618
619 RtlReleaseResource(&This->lock);
620 /* **** */
621
622 return hres;
623}
624
625static HRESULT WINAPI IDirectSoundBufferImpl_SetPan(IDirectSoundBuffer8 *iface, LONG pan)
626{
629
630 TRACE("(%p,%d)\n",This,pan);
631
632 if ((pan > DSBPAN_RIGHT) || (pan < DSBPAN_LEFT)) {
633 WARN("invalid parameter: pan = %d\n", pan);
634 return DSERR_INVALIDPARAM;
635 }
636
637 /* You cannot use both pan and 3D controls */
638 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN) ||
639 (This->dsbd.dwFlags & DSBCAPS_CTRL3D)) {
640 WARN("control unavailable\n");
642 }
643
644 /* **** */
646
647 if (This->volpan.lPan != pan) {
648 This->volpan.lPan = pan;
649 DSOUND_RecalcVolPan(&(This->volpan));
650
651 if (This->hwbuf) {
652 hres = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
653 if (hres != DS_OK)
654 WARN("IDsDriverBuffer_SetVolumePan failed\n");
655 }
656 }
657
658 RtlReleaseResource(&This->lock);
659 /* **** */
660
661 return hres;
662}
663
664static HRESULT WINAPI IDirectSoundBufferImpl_GetPan(IDirectSoundBuffer8 *iface, LONG *pan)
665{
667
668 TRACE("(%p,%p)\n",This,pan);
669
670 if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
671 WARN("control unavailable\n");
673 }
674
675 if (pan == NULL) {
676 WARN("invalid parameter: pan = NULL\n");
677 return DSERR_INVALIDPARAM;
678 }
679
680 *pan = This->volpan.lPan;
681
682 return DS_OK;
683}
684
685static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(IDirectSoundBuffer8 *iface, void *p1, DWORD x1,
686 void *p2, DWORD x2)
687{
690
691 TRACE("(%p,%p,%d,%p,%d)\n", This,p1,x1,p2,x2);
692
693 /* **** */
695
696 if (!(This->device->drvdesc.dwFlags & DSDDESC_DONTNEEDSECONDARYLOCK) && This->hwbuf) {
697 hres = IDsDriverBuffer_Unlock(This->hwbuf, p1, x1, p2, x2);
698 if (hres != DS_OK)
699 WARN("IDsDriverBuffer_Unlock failed\n");
700 }
701
702 RtlReleaseResource(&This->lock);
703 /* **** */
704
705 if (!p2)
706 x2 = 0;
707
708 if (!This->hwbuf && (x1 || x2))
709 {
710 RtlAcquireResourceShared(&This->device->buffer_list_lock, TRUE);
711 LIST_FOR_EACH_ENTRY(iter, &This->buffer->buffers, IDirectSoundBufferImpl, entry )
712 {
713 RtlAcquireResourceShared(&iter->lock, TRUE);
714 if (x1)
715 {
716 if(x1 + (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory > iter->buflen)
718 else
719 DSOUND_MixToTemporary(iter, (DWORD_PTR)p1 - (DWORD_PTR)iter->buffer->memory, x1, FALSE);
720 }
721 if (x2)
722 DSOUND_MixToTemporary(iter, 0, x2, FALSE);
723 RtlReleaseResource(&iter->lock);
724 }
725 RtlReleaseResource(&This->device->buffer_list_lock);
726 }
727
728 return hres;
729}
730
731static HRESULT WINAPI IDirectSoundBufferImpl_Restore(IDirectSoundBuffer8 *iface)
732{
734
735 FIXME("(%p):stub\n",This);
736 return DS_OK;
737}
738
739static HRESULT WINAPI IDirectSoundBufferImpl_GetFrequency(IDirectSoundBuffer8 *iface, DWORD *freq)
740{
742
743 TRACE("(%p,%p)\n",This,freq);
744
745 if (freq == NULL) {
746 WARN("invalid parameter: freq = NULL\n");
747 return DSERR_INVALIDPARAM;
748 }
749
750 *freq = This->freq;
751 TRACE("-> %d\n", *freq);
752
753 return DS_OK;
754}
755
756static HRESULT WINAPI IDirectSoundBufferImpl_SetFX(IDirectSoundBuffer8 *iface, DWORD dwEffectsCount,
757 LPDSEFFECTDESC pDSFXDesc, DWORD *pdwResultCodes)
758{
760 DWORD u;
761
762 FIXME("(%p,%u,%p,%p): stub\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes);
763
764 if (pdwResultCodes)
765 for (u=0; u<dwEffectsCount; u++) pdwResultCodes[u] = DSFXR_UNKNOWN;
766
767 WARN("control unavailable\n");
769}
770
772 DWORD dwFlags, DWORD dwEffectsCount, DWORD *pdwResultCodes)
773{
775 DWORD u;
776
777 FIXME("(%p,%08u,%u,%p): stub, faking success\n",This,dwFlags,dwEffectsCount,pdwResultCodes);
778
779 if (pdwResultCodes)
780 for (u=0; u<dwEffectsCount; u++) pdwResultCodes[u] = DSFXR_UNKNOWN;
781
782 WARN("control unavailable\n");
783 return DS_OK;
784}
785
786static HRESULT WINAPI IDirectSoundBufferImpl_GetObjectInPath(IDirectSoundBuffer8 *iface,
787 REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, void **ppObject)
788{
790
791 FIXME("(%p,%s,%u,%s,%p): stub\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject);
792
793 WARN("control unavailable\n");
795}
796
797static HRESULT WINAPI IDirectSoundBufferImpl_Initialize(IDirectSoundBuffer8 *iface,
798 IDirectSound *dsound, LPCDSBUFFERDESC dbsd)
799{
801
802 WARN("(%p) already initialized\n", This);
804}
805
806static HRESULT WINAPI IDirectSoundBufferImpl_GetCaps(IDirectSoundBuffer8 *iface, LPDSBCAPS caps)
807{
809
810 TRACE("(%p)->(%p)\n",This,caps);
811
812 if (caps == NULL) {
813 WARN("invalid parameter: caps == NULL\n");
814 return DSERR_INVALIDPARAM;
815 }
816
817 if (caps->dwSize < sizeof(*caps)) {
818 WARN("invalid parameter: caps->dwSize = %d\n",caps->dwSize);
819 return DSERR_INVALIDPARAM;
820 }
821
822 caps->dwFlags = This->dsbd.dwFlags;
823 if (This->hwbuf) caps->dwFlags |= DSBCAPS_LOCHARDWARE;
824 else caps->dwFlags |= DSBCAPS_LOCSOFTWARE;
825
826 caps->dwBufferBytes = This->buflen;
827
828 /* According to windows, this is zero*/
829 caps->dwUnlockTransferRate = 0;
830 caps->dwPlayCpuOverhead = 0;
831
832 return DS_OK;
833}
834
836 void **ppobj)
837{
839
840 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
841
842 if (ppobj == NULL) {
843 WARN("invalid parameter\n");
844 return E_INVALIDARG;
845 }
846
847 *ppobj = NULL; /* assume failure */
848
849 if ( IsEqualGUID(riid, &IID_IUnknown) ||
850 IsEqualGUID(riid, &IID_IDirectSoundBuffer) ||
851 IsEqualGUID(riid, &IID_IDirectSoundBuffer8) ) {
853 *ppobj = iface;
854 return S_OK;
855 }
856
857 if ( IsEqualGUID( &IID_IDirectSoundNotify, riid ) ) {
858 if (!This->notify)
860 if (This->notify) {
862 *ppobj = This->notify;
863 return S_OK;
864 }
865 WARN("IID_IDirectSoundNotify\n");
866 return E_NOINTERFACE;
867 }
868
869 if ( IsEqualGUID( &IID_IDirectSound3DBuffer, riid ) ) {
870 if (!This->ds3db)
872 if (This->ds3db) {
874 *ppobj = This->ds3db;
875 return S_OK;
876 }
877 WARN("IID_IDirectSound3DBuffer\n");
878 return E_NOINTERFACE;
879 }
880
881 if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
882 ERR("app requested IDirectSound3DListener on secondary buffer\n");
883 return E_NOINTERFACE;
884 }
885
887 if (!This->iks)
889 if (This->iks) {
891 *ppobj = This->iks;
892 return S_OK;
893 }
894 WARN("IID_IKsPropertySet\n");
895 return E_NOINTERFACE;
896 }
897
898 FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
899
900 return E_NOINTERFACE;
901}
902
903static const IDirectSoundBuffer8Vtbl dsbvt =
904{
929};
930
934 LPCDSBUFFERDESC dsbd)
935{
937 LPWAVEFORMATEX wfex = dsbd->lpwfxFormat;
938 HRESULT err = DS_OK;
939 DWORD capf = 0;
940 int use_hw;
941 TRACE("(%p,%p,%p)\n",device,pdsb,dsbd);
942
943 if (dsbd->dwBufferBytes < DSBSIZE_MIN || dsbd->dwBufferBytes > DSBSIZE_MAX) {
944 WARN("invalid parameter: dsbd->dwBufferBytes = %d\n", dsbd->dwBufferBytes);
945 *pdsb = NULL;
946 return DSERR_INVALIDPARAM; /* FIXME: which error? */
947 }
948
949 dsb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
950
951 if (dsb == 0) {
952 WARN("out of memory\n");
953 *pdsb = NULL;
954 return DSERR_OUTOFMEMORY;
955 }
956
957 TRACE("Created buffer at %p\n", dsb);
958
959 dsb->ref = 1;
960 dsb->numIfaces = 1;
961 dsb->device = device;
962 dsb->IDirectSoundBuffer8_iface.lpVtbl = &dsbvt;
963 dsb->iks = NULL;
964
965 /* size depends on version */
966 CopyMemory(&dsb->dsbd, dsbd, dsbd->dwSize);
967
968 dsb->pwfx = DSOUND_CopyFormat(wfex);
969 if (dsb->pwfx == NULL) {
970 HeapFree(GetProcessHeap(),0,dsb);
971 *pdsb = NULL;
972 return DSERR_OUTOFMEMORY;
973 }
974
975 if (dsbd->dwBufferBytes % dsbd->lpwfxFormat->nBlockAlign)
976 dsb->buflen = dsbd->dwBufferBytes +
977 (dsbd->lpwfxFormat->nBlockAlign -
978 (dsbd->dwBufferBytes % dsbd->lpwfxFormat->nBlockAlign));
979 else
980 dsb->buflen = dsbd->dwBufferBytes;
981
982 dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec;
983 dsb->notify = NULL;
984 dsb->notifies = NULL;
985 dsb->nrofnotifies = 0;
986 dsb->hwnotify = 0;
987
988 /* Check necessary hardware mixing capabilities */
989 if (wfex->nChannels==2) capf |= DSCAPS_SECONDARYSTEREO;
990 else capf |= DSCAPS_SECONDARYMONO;
991 if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT;
992 else capf |= DSCAPS_SECONDARY8BIT;
993
994 use_hw = !!(dsbd->dwFlags & DSBCAPS_LOCHARDWARE);
995 TRACE("use_hw = %d, capf = 0x%08x, device->drvcaps.dwFlags = 0x%08x\n", use_hw, capf, device->drvcaps.dwFlags);
996 if (use_hw && ((device->drvcaps.dwFlags & capf) != capf || !device->driver))
997 {
998 if (device->driver)
999 WARN("Format not supported for hardware buffer\n");
1000 HeapFree(GetProcessHeap(),0,dsb->pwfx);
1001 HeapFree(GetProcessHeap(),0,dsb);
1002 *pdsb = NULL;
1003 if ((device->drvcaps.dwFlags & capf) != capf)
1004 return DSERR_BADFORMAT;
1005 return DSERR_GENERIC;
1006 }
1007
1008 /* FIXME: check hardware sample rate mixing capabilities */
1009 /* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) */
1010 /* FIXME: check whether any hardware buffers are left */
1011 /* FIXME: handle DSDHEAP_CREATEHEAP for hardware buffers */
1012
1013 /* Allocate an empty buffer */
1014 dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
1015 if (dsb->buffer == NULL) {
1016 WARN("out of memory\n");
1017 HeapFree(GetProcessHeap(),0,dsb->pwfx);
1018 HeapFree(GetProcessHeap(),0,dsb);
1019 *pdsb = NULL;
1020 return DSERR_OUTOFMEMORY;
1021 }
1022
1023 /* Allocate system memory for buffer if applicable */
1024 if ((device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) {
1025 dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen);
1026 if (dsb->buffer->memory == NULL) {
1027 WARN("out of memory\n");
1028 HeapFree(GetProcessHeap(),0,dsb->pwfx);
1029 HeapFree(GetProcessHeap(),0,dsb->buffer);
1030 HeapFree(GetProcessHeap(),0,dsb);
1031 *pdsb = NULL;
1032 return DSERR_OUTOFMEMORY;
1033 }
1034 }
1035
1036 /* Allocate the hardware buffer */
1037 if (use_hw) {
1038 err = IDsDriver_CreateSoundBuffer(device->driver,wfex,dsbd->dwFlags,0,
1039 &(dsb->buflen),&(dsb->buffer->memory),
1040 (LPVOID*)&(dsb->hwbuf));
1041 if (FAILED(err))
1042 {
1043 WARN("Failed to create hardware secondary buffer: %08x\n", err);
1044 if (device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)
1046 HeapFree(GetProcessHeap(),0,dsb->buffer);
1047 HeapFree(GetProcessHeap(),0,dsb->pwfx);
1048 HeapFree(GetProcessHeap(),0,dsb);
1049 *pdsb = NULL;
1050 return DSERR_GENERIC;
1051 }
1052 }
1053
1054 dsb->buffer->ref = 1;
1055 list_init(&dsb->buffer->buffers);
1056 list_add_head(&dsb->buffer->buffers, &dsb->entry);
1057 FillMemory(dsb->buffer->memory, dsb->buflen, dsbd->lpwfxFormat->wBitsPerSample == 8 ? 128 : 0);
1058
1059 /* It's not necessary to initialize values to zero since */
1060 /* we allocated this structure with HEAP_ZERO_MEMORY... */
1061 dsb->buf_mixpos = dsb->sec_mixpos = 0;
1062 dsb->state = STATE_STOPPED;
1063
1064 dsb->freqAdjust = ((DWORD64)dsb->freq << DSOUND_FREQSHIFT) / device->pwfx->nSamplesPerSec;
1065 dsb->nAvgBytesPerSec = dsb->freq *
1066 dsbd->lpwfxFormat->nBlockAlign;
1067
1068 /* calculate fragment size and write lead */
1070
1071 if (dsb->dsbd.dwFlags & DSBCAPS_CTRL3D) {
1072 dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER);
1073 dsb->ds3db_ds3db.vPosition.x = 0.0;
1074 dsb->ds3db_ds3db.vPosition.y = 0.0;
1075 dsb->ds3db_ds3db.vPosition.z = 0.0;
1076 dsb->ds3db_ds3db.vVelocity.x = 0.0;
1077 dsb->ds3db_ds3db.vVelocity.y = 0.0;
1078 dsb->ds3db_ds3db.vVelocity.z = 0.0;
1081 dsb->ds3db_ds3db.vConeOrientation.x = 0.0;
1082 dsb->ds3db_ds3db.vConeOrientation.y = 0.0;
1083 dsb->ds3db_ds3db.vConeOrientation.z = 0.0;
1088
1089 dsb->ds3db_need_recalc = FALSE;
1091 } else
1092 DSOUND_RecalcVolPan(&(dsb->volpan));
1093
1095
1096 /* register buffer if not primary */
1097 if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) {
1099 if (err != DS_OK) {
1101 HeapFree(GetProcessHeap(),0,dsb->buffer);
1102 RtlDeleteResource(&dsb->lock);
1103 HeapFree(GetProcessHeap(),0,dsb->pwfx);
1104 HeapFree(GetProcessHeap(),0,dsb);
1105 dsb = NULL;
1106 }
1107 }
1108
1109 *pdsb = dsb;
1110 return err;
1111}
1112
1114{
1116 RtlDeleteResource(&This->lock);
1117
1118 if (This->hwbuf)
1120 if (!This->hwbuf || (This->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY)) {
1121 This->buffer->ref--;
1122 list_remove(&This->entry);
1123 if (This->buffer->ref == 0) {
1124 HeapFree(GetProcessHeap(), 0, This->buffer->memory);
1125 HeapFree(GetProcessHeap(), 0, This->buffer);
1126 }
1127 }
1128
1129 HeapFree(GetProcessHeap(), 0, This->tmp_buffer);
1130 HeapFree(GetProcessHeap(), 0, This->notifies);
1131 HeapFree(GetProcessHeap(), 0, This->pwfx);
1133
1134 TRACE("(%p) released\n", This);
1135}
1136
1139{
1140 TRACE("(%p)\n",pdsb);
1141
1142 /* This keeps the *_Destroy functions from possibly deleting
1143 * this object until it is ready to be deleted */
1145
1146 if (pdsb->iks) {
1147 WARN("iks not NULL\n");
1149 pdsb->iks = NULL;
1150 }
1151
1152 if (pdsb->ds3db) {
1153 WARN("ds3db not NULL\n");
1155 pdsb->ds3db = NULL;
1156 }
1157
1158 if (pdsb->notify) {
1159 WARN("notify not NULL\n");
1161 pdsb->notify = NULL;
1162 }
1163
1165
1166 return S_OK;
1167}
1168
1171 IDirectSoundBufferImpl **ppdsb,
1173{
1175 HRESULT hres = DS_OK;
1176 TRACE("(%p,%p,%p)\n", device, ppdsb, pdsb);
1177
1178 dsb = HeapAlloc(GetProcessHeap(),0,sizeof(*dsb));
1179 if (dsb == NULL) {
1180 WARN("out of memory\n");
1181 *ppdsb = NULL;
1182 return DSERR_OUTOFMEMORY;
1183 }
1184 CopyMemory(dsb, pdsb, sizeof(*dsb));
1185
1186 dsb->pwfx = DSOUND_CopyFormat(pdsb->pwfx);
1187 if (dsb->pwfx == NULL) {
1188 HeapFree(GetProcessHeap(),0,dsb);
1189 *ppdsb = NULL;
1190 return DSERR_OUTOFMEMORY;
1191 }
1192
1193 if (pdsb->hwbuf) {
1194 TRACE("duplicating hardware buffer\n");
1195
1197 (LPVOID *)&dsb->hwbuf);
1198 if (FAILED(hres)) {
1199 WARN("IDsDriver_DuplicateSoundBuffer failed (%08x)\n", hres);
1200 HeapFree(GetProcessHeap(),0,dsb->pwfx);
1201 HeapFree(GetProcessHeap(),0,dsb);
1202 *ppdsb = NULL;
1203 return hres;
1204 }
1205 }
1206
1207 dsb->buffer->ref++;
1208 list_add_head(&dsb->buffer->buffers, &dsb->entry);
1209 dsb->ref = 1;
1210 dsb->numIfaces = 1;
1211 dsb->state = STATE_STOPPED;
1212 dsb->buf_mixpos = dsb->sec_mixpos = 0;
1213 dsb->notify = NULL;
1214 dsb->notifies = NULL;
1215 dsb->nrofnotifies = 0;
1216 dsb->device = device;
1217 dsb->ds3db = NULL;
1218 dsb->iks = NULL; /* FIXME? */
1219 dsb->tmp_buffer = NULL;
1221 DSOUND_MixToTemporary(dsb, 0, dsb->buflen, FALSE);
1222
1224
1225 /* register buffer */
1227 if (hres != DS_OK) {
1228 RtlDeleteResource(&dsb->lock);
1230 list_remove(&dsb->entry);
1231 dsb->buffer->ref--;
1232 HeapFree(GetProcessHeap(),0,dsb->pwfx);
1233 HeapFree(GetProcessHeap(),0,dsb);
1234 dsb = NULL;
1235 }
1236
1237 *ppdsb = dsb;
1238 return hres;
1239}
1240
1241/*******************************************************************************
1242 * IKsBufferPropertySet
1243 */
1244
1245/* IUnknown methods */
1247 LPKSPROPERTYSET iface,
1248 REFIID riid,
1249 LPVOID *ppobj )
1250{
1252 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
1253
1255}
1256
1258{
1261 TRACE("(%p) ref was %d\n", This, ref - 1);
1262 return ref;
1263}
1264
1266{
1269 TRACE("(%p) ref was %d\n", This, ref + 1);
1270
1271 if (!ref) {
1272 This->dsb->iks = 0;
1275 TRACE("(%p) released\n", This);
1276 }
1277 return ref;
1278}
1279
1281 LPKSPROPERTYSET iface,
1282 REFGUID guidPropSet,
1283 ULONG dwPropID,
1284 LPVOID pInstanceData,
1285 ULONG cbInstanceData,
1286 LPVOID pPropData,
1287 ULONG cbPropData,
1288 PULONG pcbReturned )
1289{
1292 TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
1293 This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
1294
1295 if (This->dsb->hwbuf) {
1296 IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
1297
1298 if (ps) {
1299 DSPROPERTY prop;
1300 HRESULT hres;
1301
1302 prop.s.Set = *guidPropSet;
1303 prop.s.Id = dwPropID;
1304 prop.s.Flags = 0; /* unused */
1305 prop.s.InstanceId = (ULONG_PTR)This->dsb->device;
1306
1307
1308 hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
1309
1311
1312 return hres;
1313 }
1314 }
1315
1316 return E_PROP_ID_UNSUPPORTED;
1317}
1318
1320 LPKSPROPERTYSET iface,
1321 REFGUID guidPropSet,
1322 ULONG dwPropID,
1323 LPVOID pInstanceData,
1324 ULONG cbInstanceData,
1325 LPVOID pPropData,
1326 ULONG cbPropData )
1327{
1330 TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
1331
1332 if (This->dsb->hwbuf) {
1333 IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
1334
1335 if (ps) {
1336 DSPROPERTY prop;
1337 HRESULT hres;
1338
1339 prop.s.Set = *guidPropSet;
1340 prop.s.Id = dwPropID;
1341 prop.s.Flags = 0; /* unused */
1342 prop.s.InstanceId = (ULONG_PTR)This->dsb->device;
1343 hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData);
1344
1346
1347 return hres;
1348 }
1349 }
1350
1351 return E_PROP_ID_UNSUPPORTED;
1352}
1353
1355 LPKSPROPERTYSET iface,
1356 REFGUID guidPropSet,
1357 ULONG dwPropID,
1358 PULONG pTypeSupport )
1359{
1362 TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
1363
1364 if (This->dsb->hwbuf) {
1365 IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
1366
1367 if (ps) {
1368 HRESULT hres;
1369
1370 hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport);
1371
1373
1374 return hres;
1375 }
1376 }
1377
1378 return E_PROP_ID_UNSUPPORTED;
1379}
1380
1381static const IKsPropertySetVtbl iksbvt = {
1388};
1389
1393{
1395 TRACE("(%p,%p)\n",dsb,piks);
1396 *piks = NULL;
1397
1398 iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
1399 if (iks == 0) {
1400 WARN("out of memory\n");
1401 *piks = NULL;
1402 return DSERR_OUTOFMEMORY;
1403 }
1404
1405 iks->ref = 0;
1406 iks->dsb = dsb;
1407 dsb->iks = iks;
1408 iks->lpVtbl = &iksbvt;
1409
1411
1412 *piks = iks;
1413 return S_OK;
1414}
1415
1418{
1419 TRACE("(%p)\n",piks);
1420
1422
1423 return S_OK;
1424}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
const GUID IID_IUnknown
const GUID IID_IKsPropertySet
Definition: controlnode.cpp:13
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const IDirectSoundNotifyVtbl dsnvt
Definition: buffer.c:123
HRESULT IKsBufferPropertySetImpl_Create(IDirectSoundBufferImpl *dsb, IKsBufferPropertySetImpl **piks)
Definition: buffer.c:1390
static HRESULT WINAPI IDirectSoundBufferImpl_Stop(IDirectSoundBuffer8 *iface)
Definition: buffer.c:338
static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport(LPKSPROPERTYSET iface, REFGUID guidPropSet, ULONG dwPropID, PULONG pTypeSupport)
Definition: buffer.c:1354
HRESULT IDirectSoundBufferImpl_Destroy(IDirectSoundBufferImpl *pdsb)
Definition: buffer.c:1137
HRESULT IKsBufferPropertySetImpl_Destroy(IKsBufferPropertySetImpl *piks)
Definition: buffer.c:1416
static ULONG WINAPI IDirectSoundNotifyImpl_Release(LPDIRECTSOUNDNOTIFY iface)
Definition: buffer.c:62
static BOOL is_primary_buffer(IDirectSoundBufferImpl *This)
Definition: buffer.c:174
static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *iface, DWORD freq)
Definition: buffer.c:264
static HRESULT IDirectSoundNotifyImpl_Create(IDirectSoundBufferImpl *dsb, IDirectSoundNotifyImpl **pdsn)
Definition: buffer.c:131
static HRESULT WINAPI IDirectSoundBufferImpl_Initialize(IDirectSoundBuffer8 *iface, IDirectSound *dsound, LPCDSBUFFERDESC dbsd)
Definition: buffer.c:797
static HRESULT WINAPI IDirectSoundBufferImpl_SetPan(IDirectSoundBuffer8 *iface, LONG pan)
Definition: buffer.c:625
static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface)
Definition: buffer.c:1265
static HRESULT WINAPI IDirectSoundBufferImpl_AcquireResources(IDirectSoundBuffer8 *iface, DWORD dwFlags, DWORD dwEffectsCount, DWORD *pdwResultCodes)
Definition: buffer.c:771
static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface)
Definition: buffer.c:1257
static HRESULT WINAPI IDirectSoundBufferImpl_Play(IDirectSoundBuffer8 *iface, DWORD reserved1, DWORD reserved2, DWORD flags)
Definition: buffer.c:307
static HRESULT WINAPI IDirectSoundBufferImpl_SetVolume(IDirectSoundBuffer8 *iface, LONG vol)
Definition: buffer.c:194
static HRESULT WINAPI IDirectSoundBufferImpl_Restore(IDirectSoundBuffer8 *iface)
Definition: buffer.c:731
static HRESULT WINAPI IDirectSoundBufferImpl_GetFrequency(IDirectSoundBuffer8 *iface, DWORD *freq)
Definition: buffer.c:739
static HRESULT WINAPI IDirectSoundBufferImpl_GetCurrentPosition(IDirectSoundBuffer8 *iface, DWORD *playpos, DWORD *writepos)
Definition: buffer.c:398
static HRESULT WINAPI IDirectSoundBufferImpl_GetStatus(IDirectSoundBuffer8 *iface, DWORD *status)
Definition: buffer.c:440
static IDirectSoundBufferImpl * impl_from_IDirectSoundBuffer8(IDirectSoundBuffer8 *iface)
Definition: buffer.c:169
static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface(LPKSPROPERTYSET iface, REFIID riid, LPVOID *ppobj)
Definition: buffer.c:1246
static HRESULT WINAPI IDirectSoundBufferImpl_SetCurrentPosition(IDirectSoundBuffer8 *iface, DWORD newpos)
Definition: buffer.c:587
static HRESULT WINAPI IDirectSoundBufferImpl_GetCaps(IDirectSoundBuffer8 *iface, LPDSBCAPS caps)
Definition: buffer.c:806
static HRESULT IDirectSoundNotifyImpl_Destroy(IDirectSoundNotifyImpl *pdsn)
Definition: buffer.c:155
static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(LPDIRECTSOUNDNOTIFY iface, DWORD howmuch, LPCDSBPOSITIONNOTIFY notify)
Definition: buffer.c:77
static HRESULT WINAPI IDirectSoundBufferImpl_SetFX(IDirectSoundBuffer8 *iface, DWORD dwEffectsCount, LPDSEFFECTDESC pDSFXDesc, DWORD *pdwResultCodes)
Definition: buffer.c:756
static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(LPDIRECTSOUNDNOTIFY iface, REFIID riid, LPVOID *ppobj)
Definition: buffer.c:40
HRESULT IDirectSoundBufferImpl_Create(DirectSoundDevice *device, IDirectSoundBufferImpl **pdsb, LPCDSBUFFERDESC dsbd)
Definition: buffer.c:931
static HRESULT WINAPI IDirectSoundBufferImpl_SetFormat(IDirectSoundBuffer8 *iface, LPCWAVEFORMATEX wfex)
Definition: buffer.c:179
static HRESULT WINAPI IDirectSoundBufferImpl_Unlock(IDirectSoundBuffer8 *iface, void *p1, DWORD x1, void *p2, DWORD x2)
Definition: buffer.c:685
static HRESULT WINAPI IKsBufferPropertySetImpl_Get(LPKSPROPERTYSET iface, REFGUID guidPropSet, ULONG dwPropID, LPVOID pInstanceData, ULONG cbInstanceData, LPVOID pPropData, ULONG cbPropData, PULONG pcbReturned)
Definition: buffer.c:1280
HRESULT IDirectSoundBufferImpl_Duplicate(DirectSoundDevice *device, IDirectSoundBufferImpl **ppdsb, IDirectSoundBufferImpl *pdsb)
Definition: buffer.c:1169
static const IDirectSoundBuffer8Vtbl dsbvt
Definition: buffer.c:903
static HRESULT WINAPI IDirectSoundBufferImpl_QueryInterface(IDirectSoundBuffer8 *iface, REFIID riid, void **ppobj)
Definition: buffer.c:835
static HRESULT WINAPI IDirectSoundBufferImpl_GetFormat(IDirectSoundBuffer8 *iface, LPWAVEFORMATEX lpwf, DWORD wfsize, DWORD *wfwritten)
Definition: buffer.c:465
static ULONG WINAPI IDirectSoundBufferImpl_AddRef(IDirectSoundBuffer8 *iface)
Definition: buffer.c:369
static ULONG WINAPI IDirectSoundBufferImpl_Release(IDirectSoundBuffer8 *iface)
Definition: buffer.c:382
static HRESULT WINAPI IDirectSoundBufferImpl_GetVolume(IDirectSoundBuffer8 *iface, LONG *vol)
Definition: buffer.c:243
static HRESULT WINAPI IKsBufferPropertySetImpl_Set(LPKSPROPERTYSET iface, REFGUID guidPropSet, ULONG dwPropID, LPVOID pInstanceData, ULONG cbInstanceData, LPVOID pPropData, ULONG cbPropData)
Definition: buffer.c:1319
static HRESULT WINAPI IDirectSoundBufferImpl_GetPan(IDirectSoundBuffer8 *iface, LONG *pan)
Definition: buffer.c:664
static HRESULT WINAPI IDirectSoundBufferImpl_GetObjectInPath(IDirectSoundBuffer8 *iface, REFGUID rguidObject, DWORD dwIndex, REFGUID rguidInterface, void **ppObject)
Definition: buffer.c:786
static HRESULT WINAPI IDirectSoundBufferImpl_Lock(IDirectSoundBuffer8 *iface, DWORD writecursor, DWORD writebytes, void **lplpaudioptr1, DWORD *audiobytes1, void **lplpaudioptr2, DWORD *audiobytes2, DWORD flags)
Definition: buffer.c:499
static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(LPDIRECTSOUNDNOTIFY iface)
Definition: buffer.c:54
void secondarybuffer_destroy(IDirectSoundBufferImpl *This)
Definition: buffer.c:1113
static const IKsPropertySetVtbl iksbvt
Definition: buffer.c:1381
HRESULT DirectSoundDevice_RemoveBuffer(DirectSoundDevice *device, IDirectSoundBufferImpl *pDSB)
Definition: dsound.c:1796
HRESULT DirectSoundDevice_AddBuffer(DirectSoundDevice *device, IDirectSoundBufferImpl *pDSB)
Definition: dsound.c:1761
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define TRACE_ON(x)
Definition: compat.h:75
#define HeapFree(x, y, z)
Definition: compat.h:735
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
#define ULONG_PTR
Definition: config.h:101
#define IDsDriverBuffer_Stop(p)
Definition: dsdriver.h:204
struct IDsDriverPropertySet * PIDSDRIVERPROPERTYSET
Definition: dsdriver.h:39
#define IDsDriver_CreateSoundBuffer(p, a, b, c, d, e, f)
Definition: dsdriver.h:163
#define IDsDriverBuffer_Play(p, a, b, c)
Definition: dsdriver.h:203
#define IDsDriverBuffer_Unlock(p, a, b, c, d)
Definition: dsdriver.h:197
#define IDsDriverPropertySet_Set(p, a, b, c, d, e)
Definition: dsdriver.h:231
#define DSDDESC_DONTNEEDWRITELEAD
Definition: dsdriver.h:55
#define IDsDriverBuffer_Release(p)
Definition: dsdriver.h:194
#define IDsDriverBuffer_SetVolumePan(p, a)
Definition: dsdriver.h:200
#define DSDDESC_DONTNEEDSECONDARYLOCK
Definition: dsdriver.h:54
#define IDsDriverNotify_SetNotificationPositions(p, a, b)
Definition: dsdriver.h:291
#define DSDDESC_USESYSTEMMEMORY
Definition: dsdriver.h:52
#define IDsDriverPropertySet_Get(p, a, b, c, d, e, f)
Definition: dsdriver.h:230
#define IDsDriver_DuplicateSoundBuffer(p, a, b)
Definition: dsdriver.h:164
#define IDsDriverPropertySet_QuerySupport(p, a, b, c)
Definition: dsdriver.h:232
#define IDsDriver_QueryInterface(p, a, b)
Definition: dsdriver.h:155
#define IDsDriverBuffer_GetPosition(p, a, b)
Definition: dsdriver.h:202
#define IDsDriverPropertySet_Release(p)
Definition: dsdriver.h:228
#define IDsDriverBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsdriver.h:196
#define IDsDriverBuffer_SetPosition(p, a)
Definition: dsdriver.h:201
#define DSERR_BADFORMAT
Definition: dsound.h:126
#define DSCAPS_SECONDARYSTEREO
Definition: dsound.h:151
#define DSERR_ALREADYINITIALIZED
Definition: dsound.h:129
#define IDirectSoundBuffer_AddRef(p)
Definition: dsound.h:573
#define DSBCAPS_CTRLVOLUME
Definition: dsound.h:213
struct IDirectSoundBuffer * LPDIRECTSOUNDBUFFER
Definition: dsound.h:76
#define DSERR_CONTROLUNAVAIL
Definition: dsound.h:120
#define DSCAPS_SECONDARYMONO
Definition: dsound.h:150
#define DS3D_DEFAULTCONEANGLE
Definition: dsound.h:934
#define IDirectSoundNotify_AddRef(p)
Definition: dsound.h:893
@ DSFXR_UNKNOWN
Definition: dsound.h:272
#define DSBFREQUENCY_MAX
Definition: dsound.h:232
struct IDirectSound3DBuffer * LPDIRECTSOUND3DBUFFER
Definition: dsound.h:89
#define DSCAPS_SECONDARY8BIT
Definition: dsound.h:152
#define DSERR_OUTOFMEMORY
Definition: dsound.h:125
#define DSBCAPS_CTRLPAN
Definition: dsound.h:212
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define DSBPAN_LEFT
Definition: dsound.h:226
#define DSBLOCK_FROMWRITECURSOR
Definition: dsound.h:203
#define DSBSTATUS_LOOPING
Definition: dsound.h:198
#define DSBVOLUME_MAX
Definition: dsound.h:229
#define DSBFREQUENCY_ORIGINAL
Definition: dsound.h:233
#define DSBSIZE_MAX
Definition: dsound.h:225
#define DS3D_DEFAULTMINDISTANCE
Definition: dsound.h:929
#define DSERR_INVALIDCALL
Definition: dsound.h:122
#define DSCAPS_SECONDARY16BIT
Definition: dsound.h:153
#define DSBCAPS_LOCSOFTWARE
Definition: dsound.h:209
#define DSBSTATUS_PLAYING
Definition: dsound.h:196
#define DS_OK
Definition: dsound.h:116
#define DSBVOLUME_MIN
Definition: dsound.h:230
#define DSBSIZE_MIN
Definition: dsound.h:224
#define DSERR_INVALIDPARAM
Definition: dsound.h:121
#define DSBCAPS_CTRLFREQUENCY
Definition: dsound.h:211
#define IDirectSound3DBuffer_AddRef(p)
Definition: dsound.h:1072
#define DSBCAPS_CTRL3D
Definition: dsound.h:210
#define IKsPropertySet_AddRef(p)
Definition: dsound.h:1149
struct IDirectSoundNotify * LPDIRECTSOUNDNOTIFY
Definition: dsound.h:82
#define IDirectSoundBuffer8_AddRef(p)
Definition: dsound.h:659
#define DS3D_DEFAULTCONEOUTSIDEVOLUME
Definition: dsound.h:936
#define DS3DMODE_NORMAL
Definition: dsound.h:910
struct IDirectSoundBuffer8 * LPDIRECTSOUNDBUFFER8
Definition: dsound.h:79
#define DSBPLAY_LOOPING
Definition: dsound.h:189
struct _DS3DBUFFER DS3DBUFFER
#define DSERR_GENERIC
Definition: dsound.h:123
#define IDirectSoundBuffer_QueryInterface(p, a, b)
Definition: dsound.h:572
#define DS3D_DEFAULTMAXDISTANCE
Definition: dsound.h:930
#define IDirectSoundBuffer_Release(p)
Definition: dsound.h:574
#define DSBPAN_RIGHT
Definition: dsound.h:228
#define DSBFREQUENCY_MIN
Definition: dsound.h:231
#define DSBCAPS_LOCHARDWARE
Definition: dsound.h:208
#define DSBCAPS_PRIMARYBUFFER
Definition: dsound.h:206
#define STATE_STOPPING
DWORD DSOUND_secpos_to_bufpos(const IDirectSoundBufferImpl *dsb, DWORD secpos, DWORD secmixpos, DWORD *overshot) DECLSPEC_HIDDEN
Definition: mixer.c:99
HRESULT IDirectSound3DBufferImpl_Create(IDirectSoundBufferImpl *dsb, IDirectSound3DBufferImpl **pds3db) DECLSPEC_HIDDEN
Definition: sound3d.c:667
#define STATE_PLAYING
void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN
Definition: sound3d.c:141
#define STATE_STARTING
HRESULT primarybuffer_SetFormat(DirectSoundDevice *device, LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN
Definition: primary.c:460
#define STATE_STOPPED
#define DSOUND_FREQSHIFT
LPWAVEFORMATEX DSOUND_CopyFormat(LPCWAVEFORMATEX wfex) DECLSPEC_HIDDEN
Definition: primary.c:437
void DSOUND_MixToTemporary(const IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD mixlen, BOOL inmixer) DECLSPEC_HIDDEN
Definition: mixer.c:332
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) DECLSPEC_HIDDEN
Definition: mixer.c:27
HRESULT IDirectSound3DBufferImpl_Destroy(IDirectSound3DBufferImpl *pds3db) DECLSPEC_HIDDEN
Definition: sound3d.c:709
void DSOUND_CheckEvent(const IDirectSoundBufferImpl *dsb, DWORD playpos, int len) DECLSPEC_HIDDEN
Definition: mixer.c:221
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) DECLSPEC_HIDDEN
Definition: mixer.c:162
void primarybuffer_destroy(IDirectSoundBufferImpl *This) DECLSPEC_HIDDEN
Definition: primary.c:763
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
uint8_t reserved2[12]
Definition: fsck.fat.h:23
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
if(dx< 0)
Definition: linetemp.h:194
double __cdecl remainder(double, double)
Definition: remainder.c:75
HRESULT hres
Definition: protocol.c:465
int notify
Definition: msacm.c:1366
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceShared(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
NTSYSAPI VOID NTAPI RtlInitializeResource(_In_ PRTL_RESOURCE Resource)
NTSYSAPI BOOLEAN NTAPI RtlAcquireResourceExclusive(_In_ PRTL_RESOURCE Resource, _In_ BOOLEAN Wait)
NTSYSAPI VOID NTAPI RtlDeleteResource(_In_ PRTL_RESOURCE Resource)
NTSYSAPI VOID NTAPI RtlReleaseResource(_In_ PRTL_RESOURCE Resource)
_In_ DWORD _In_ DWORD dwOffset
Definition: ntgdi.h:2033
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define err(...)
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define TRACE(s)
Definition: solgame.cpp:4
struct list buffers
IDirectSoundNotifyImpl * notify
IDirectSound3DBufferImpl * ds3db
IKsBufferPropertySetImpl * iks
PIDSDRIVERBUFFER hwbuf
DirectSoundDevice * device
LPDSBPOSITIONNOTIFY notifies
IDirectSoundBuffer8 IDirectSoundBuffer8_iface
PIDSDRIVERNOTIFY hwnotify
IDirectSoundBufferImpl * dsb
Definition: buffer.c:33
const IDirectSoundNotifyVtbl * lpVtbl
Definition: buffer.c:31
IDirectSoundBufferImpl * dsb
const IKsPropertySetVtbl * lpVtbl
DWORD dwInsideConeAngle
Definition: dsound.h:1029
D3DVECTOR vConeOrientation
Definition: dsound.h:1031
DWORD dwOutsideConeAngle
Definition: dsound.h:1030
DWORD dwMode
Definition: dsound.h:1035
DWORD dwSize
Definition: dsound.h:1026
D3DVECTOR vPosition
Definition: dsound.h:1027
D3DVECTOR vVelocity
Definition: dsound.h:1028
LONG lConeOutsideVolume
Definition: dsound.h:1032
D3DVALUE flMinDistance
Definition: dsound.h:1033
D3DVALUE flMaxDistance
Definition: dsound.h:1034
DWORD dwUnlockTransferRate
Definition: dsound.h:242
DWORD dwPlayCpuOverhead
Definition: dsound.h:243
DWORD dwBufferBytes
Definition: dsound.h:241
DWORD dwFlags
Definition: dsound.h:240
DWORD dwSize
Definition: dsound.h:239
DWORD dwSize
Definition: dsound.h:288
DWORD dwFlags
Definition: dsound.h:289
DWORD dwBufferBytes
Definition: dsound.h:290
LPWAVEFORMATEX lpwfxFormat
Definition: dsound.h:292
Definition: scsiwmi.h:51
WORD nBlockAlign
Definition: mmreg.h:82
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nChannels
Definition: mmreg.h:79
WORD wBitsPerSample
Definition: mmreg.h:83
Definition: devices.h:37
Definition: send.c:48
Definition: ps.c:97
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint64_t DWORD64
Definition: typedefs.h:67
unsigned char * LPBYTE
Definition: typedefs.h:53
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
ULONG InstanceId
Definition: dsdriver.h:120
GUID Set
Definition: dsdriver.h:117
ULONG Flags
Definition: dsdriver.h:119
ULONG Id
Definition: dsdriver.h:118
#define E_PROP_ID_UNSUPPORTED
Definition: vfwmsgs.h:173
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define CopyMemory
Definition: winbase.h:1734
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364