Maarten Lankhorst : winealsa: Add support for capture notification positions.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Sep 12 07:50:35 CDT 2007


Module: wine
Branch: master
Commit: a8da3e7f607319cdf770f48e4a81db3c7f150830
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a8da3e7f607319cdf770f48e4a81db3c7f150830

Author: Maarten Lankhorst <m.b.lankhorst at 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;




More information about the wine-cvs mailing list