Module: wine Branch: master Commit: a8da3e7f607319cdf770f48e4a81db3c7f150830 URL: http://source.winehq.org/git/wine.git/?a=commit;h=a8da3e7f607319cdf770f48e4a...
Author: Maarten Lankhorst m.b.lankhorst@gmail.com Date: Tue Sep 11 18:14:57 2007 +0200
winealsa: Add support for capture notification positions.
---
dlls/winealsa.drv/dscapture.c | 78 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/dlls/winealsa.drv/dscapture.c b/dlls/winealsa.drv/dscapture.c index aa57772..8e409d7 100644 --- a/dlls/winealsa.drv/dscapture.c +++ b/dlls/winealsa.drv/dscapture.c @@ -73,6 +73,8 @@ typedef struct IDsCaptureDriverNotifyImpl const IDsDriverNotifyVtbl *lpVtbl; LONG ref; IDsCaptureDriverBufferImpl *buffer; + DSBPOSITIONNOTIFY *notifies; + DWORD nrofnotifies; } IDsCaptureDriverNotifyImpl;
struct IDsCaptureDriverBufferImpl @@ -95,6 +97,31 @@ struct IDsCaptureDriverBufferImpl snd_pcm_uframes_t mmap_buflen_frames, mmap_pos; };
+static void Capture_CheckNotify(IDsCaptureDriverNotifyImpl *This, DWORD from, DWORD len) +{ + unsigned i; + for (i = 0; i < This->nrofnotifies; ++i) { + LPDSBPOSITIONNOTIFY event = This->notifies + i; + DWORD offset = event->dwOffset; + TRACE("checking %d, position %d, event = %p\n", i, offset, event->hEventNotify); + + if (offset == DSBPN_OFFSETSTOP) { + if (!from && !len) { + SetEvent(event->hEventNotify); + TRACE("signalled event %p (%d)\n", event->hEventNotify, i); + return; + } + else return; + } + + if (offset >= from && offset < (from + len)) + { + TRACE("signalled event %p (%d)\n", event->hEventNotify, i); + SetEvent(event->hEventNotify); + } + } +} + static HRESULT WINAPI IDsCaptureDriverNotifyImpl_QueryInterface(PIDSDRIVERNOTIFY iface, REFIID riid, LPVOID *ppobj) { IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface; @@ -132,6 +159,7 @@ static ULONG WINAPI IDsCaptureDriverNotifyImpl_Release(PIDSDRIVERNOTIFY iface)
if (!refCount) { This->buffer->notify = NULL; + HeapFree(GetProcessHeap(), 0, This->notifies); HeapFree(GetProcessHeap(), 0, This); TRACE("(%p) released\n", This); } @@ -140,11 +168,46 @@ static ULONG WINAPI IDsCaptureDriverNotifyImpl_Release(PIDSDRIVERNOTIFY iface)
static HRESULT WINAPI IDsCaptureDriverNotifyImpl_SetNotificationPositions(PIDSDRIVERNOTIFY iface, DWORD howmuch, LPCDSBPOSITIONNOTIFY notify) { + DWORD len = howmuch * sizeof(DSBPOSITIONNOTIFY); + unsigned i; + LPVOID notifies; IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface; TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
- FIXME("stub\n"); - return DSERR_UNSUPPORTED; + if (!notify) { + WARN("invalid parameter\n"); + return DSERR_INVALIDPARAM; + } + + if (TRACE_ON(dsalsa)) + for (i=0;i<howmuch; ++i) + TRACE("notify at %d to %p\n", notify[i].dwOffset, notify[i].hEventNotify); + + /* **** */ + EnterCriticalSection(&This->buffer->pcm_crst); + + /* Make an internal copy of the caller-supplied array. + * Replace the existing copy if one is already present. */ + if (This->notifies) + notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->notifies, len); + else + notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); + + if (!notifies) + { + LeaveCriticalSection(&This->buffer->pcm_crst); + /* **** */ + return DSERR_OUTOFMEMORY; + } + This->notifies = notifies; + memcpy(This->notifies, notify, len); + This->nrofnotifies = howmuch; + IDsDriverBuffer_GetPosition((PIDSCDRIVERBUFFER)This->buffer, &This->playpos, NULL); + + LeaveCriticalSection(&This->buffer->pcm_crst); + /* **** */ + + return S_OK; }
static const IDsDriverNotifyVtbl dscdnvt = @@ -660,6 +723,14 @@ static HRESULT WINAPI IDsCaptureDriverBufferImpl_Start(PIDSCDRIVERBUFFER iface, FIXME("Non-looping buffers are not properly supported!\n"); CommitAll(This, TRUE);
+ if (This->notify && This->notify->nrofnotifies && This->notify->notifies) + { + DWORD playpos = realpos_to_fakepos(This, This->mmap_pos); + if (playpos) + Capture_CheckNotify(This->notify, 0, playpos); + This->notify->playpos = playpos; + } + /* **** */ LeaveCriticalSection(&This->pcm_crst); return DS_OK; @@ -676,6 +747,9 @@ static HRESULT WINAPI IDsCaptureDriverBufferImpl_Stop(PIDSCDRIVERBUFFER iface) snd_pcm_drop(This->pcm); snd_pcm_prepare(This->pcm);
+ if (This->notify && This->notify->notifies && This->notify->nrofnotifies) + Capture_CheckNotify(This->notify, 0, 0); + /* **** */ LeaveCriticalSection(&This->pcm_crst); return DS_OK;