mirror of
https://github.com/reactos/wine.git
synced 2025-02-03 10:43:30 +00:00
winealsa: Add support for capture notification positions.
This commit is contained in:
parent
30dee3a87a
commit
a8da3e7f60
@ -73,6 +73,8 @@ typedef struct IDsCaptureDriverNotifyImpl
|
|||||||
const IDsDriverNotifyVtbl *lpVtbl;
|
const IDsDriverNotifyVtbl *lpVtbl;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
IDsCaptureDriverBufferImpl *buffer;
|
IDsCaptureDriverBufferImpl *buffer;
|
||||||
|
DSBPOSITIONNOTIFY *notifies;
|
||||||
|
DWORD nrofnotifies;
|
||||||
} IDsCaptureDriverNotifyImpl;
|
} IDsCaptureDriverNotifyImpl;
|
||||||
|
|
||||||
struct IDsCaptureDriverBufferImpl
|
struct IDsCaptureDriverBufferImpl
|
||||||
@ -95,6 +97,31 @@ struct IDsCaptureDriverBufferImpl
|
|||||||
snd_pcm_uframes_t mmap_buflen_frames, mmap_pos;
|
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)
|
static HRESULT WINAPI IDsCaptureDriverNotifyImpl_QueryInterface(PIDSDRIVERNOTIFY iface, REFIID riid, LPVOID *ppobj)
|
||||||
{
|
{
|
||||||
IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
|
IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
|
||||||
@ -132,6 +159,7 @@ static ULONG WINAPI IDsCaptureDriverNotifyImpl_Release(PIDSDRIVERNOTIFY iface)
|
|||||||
|
|
||||||
if (!refCount) {
|
if (!refCount) {
|
||||||
This->buffer->notify = NULL;
|
This->buffer->notify = NULL;
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->notifies);
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
TRACE("(%p) released\n", 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)
|
static HRESULT WINAPI IDsCaptureDriverNotifyImpl_SetNotificationPositions(PIDSDRIVERNOTIFY iface, DWORD howmuch, LPCDSBPOSITIONNOTIFY notify)
|
||||||
{
|
{
|
||||||
|
DWORD len = howmuch * sizeof(DSBPOSITIONNOTIFY);
|
||||||
|
unsigned i;
|
||||||
|
LPVOID notifies;
|
||||||
IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
|
IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
|
||||||
TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
|
TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);
|
||||||
|
|
||||||
FIXME("stub\n");
|
if (!notify) {
|
||||||
return DSERR_UNSUPPORTED;
|
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 =
|
static const IDsDriverNotifyVtbl dscdnvt =
|
||||||
@ -660,6 +723,14 @@ static HRESULT WINAPI IDsCaptureDriverBufferImpl_Start(PIDSCDRIVERBUFFER iface,
|
|||||||
FIXME("Non-looping buffers are not properly supported!\n");
|
FIXME("Non-looping buffers are not properly supported!\n");
|
||||||
CommitAll(This, TRUE);
|
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);
|
LeaveCriticalSection(&This->pcm_crst);
|
||||||
return DS_OK;
|
return DS_OK;
|
||||||
@ -676,6 +747,9 @@ static HRESULT WINAPI IDsCaptureDriverBufferImpl_Stop(PIDSCDRIVERBUFFER iface)
|
|||||||
snd_pcm_drop(This->pcm);
|
snd_pcm_drop(This->pcm);
|
||||||
snd_pcm_prepare(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);
|
LeaveCriticalSection(&This->pcm_crst);
|
||||||
return DS_OK;
|
return DS_OK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user