/*
 * Sample Wine Driver for Open Sound System (featured in Linux and FreeBSD)
 *
 * Copyright 1994 Martin Ayotte
 *           1999 Eric Pouech (async playing in waveOut/waveIn)
 *	     2000 Eric Pouech (loops in waveOut)
 *           2002 Eric Pouech (full duplex)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#ifdef HAVE_SYS_POLL_H
# include <sys/poll.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "mmddk.h"
#include "mmreg.h"
#include "dsound.h"
#include "dsdriver.h"
#include "oss.h"
#include "wine/debug.h"

#include "audio.h"

WINE_DEFAULT_DEBUG_CHANNEL(wave);

#ifdef HAVE_OSS

/*======================================================================*
 *                  Low level DSOUND definitions                        *
 *======================================================================*/

typedef struct IDsDriverPropertySetImpl IDsDriverPropertySetImpl;
typedef struct IDsDriverNotifyImpl IDsDriverNotifyImpl;
typedef struct IDsDriverImpl IDsDriverImpl;
typedef struct IDsDriverBufferImpl IDsDriverBufferImpl;

struct IDsDriverPropertySetImpl
{
    /* IUnknown fields */
    IDsDriverPropertySetVtbl   *lpVtbl;
    DWORD                       ref;

    IDsDriverBufferImpl*        buffer;
};

struct IDsDriverNotifyImpl
{
    /* IUnknown fields */
    IDsDriverNotifyVtbl        *lpVtbl;
    DWORD                       ref;

    /* IDsDriverNotifyImpl fields */
    LPDSBPOSITIONNOTIFY         notifies;
    int                         nrofnotifies;

    IDsDriverBufferImpl*        buffer;
};

struct IDsDriverImpl
{
    /* IUnknown fields */
    IDsDriverVtbl              *lpVtbl;
    DWORD                       ref;

    /* IDsDriverImpl fields */
    UINT                        wDevID;
    IDsDriverBufferImpl*        primary;

    int                         nrofsecondaries;
    IDsDriverBufferImpl**       secondaries;
};

struct IDsDriverBufferImpl
{
    /* IUnknown fields */
    IDsDriverBufferVtbl        *lpVtbl;
    DWORD                       ref;

    /* IDsDriverBufferImpl fields */
    IDsDriverImpl*              drv;
    DWORD                       buflen;
    WAVEFORMATPCMEX             wfex;
    LPBYTE                      mapping;
    DWORD                       maplen;
    int                         fd;
    DWORD                       dwFlags;

    /* IDsDriverNotifyImpl fields */
    IDsDriverNotifyImpl*        notify;
    int                         notify_index;

    /* IDsDriverPropertySetImpl fields */
    IDsDriverPropertySetImpl*   property_set;
};

static HRESULT WINAPI IDsDriverPropertySetImpl_Create(
    IDsDriverBufferImpl * dsdb,
    IDsDriverPropertySetImpl **pdsdps);

static HRESULT WINAPI IDsDriverNotifyImpl_Create(
    IDsDriverBufferImpl * dsdb,
    IDsDriverNotifyImpl **pdsdn);

/*======================================================================*
 *                  Low level DSOUND property set implementation        *
 *======================================================================*/

static HRESULT WINAPI IDsDriverPropertySetImpl_QueryInterface(
    PIDSDRIVERPROPERTYSET iface,
    REFIID riid,
    LPVOID *ppobj)
{
    IDsDriverPropertySetImpl *This = (IDsDriverPropertySetImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriverPropertySet) ) {
        IDsDriverPropertySet_AddRef(iface);
        *ppobj = (LPVOID)This;
        return DS_OK;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );

    *ppobj = 0;
    return E_NOINTERFACE;
}

static ULONG WINAPI IDsDriverPropertySetImpl_AddRef(PIDSDRIVERPROPERTYSET iface)
{
    IDsDriverPropertySetImpl *This = (IDsDriverPropertySetImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsDriverPropertySetImpl_Release(PIDSDRIVERPROPERTYSET iface)
{
    IDsDriverPropertySetImpl *This = (IDsDriverPropertySetImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount + 1);

    if (!refCount) {
        IDsDriverBuffer_Release((PIDSDRIVERBUFFER)This->buffer);
        HeapFree(GetProcessHeap(),0,This);
        TRACE("(%p) released\n",This);
    }
    return refCount;
}

static HRESULT WINAPI IDsDriverPropertySetImpl_Get(
    PIDSDRIVERPROPERTYSET iface,
    PDSPROPERTY pDsProperty,
    LPVOID pPropertyParams,
    ULONG cbPropertyParams,
    LPVOID pPropertyData,
    ULONG cbPropertyData,
    PULONG pcbReturnedData )
{
    IDsDriverPropertySetImpl *This = (IDsDriverPropertySetImpl *)iface;
    FIXME("(%p,%p,%p,%lx,%p,%lx,%p)\n",This,pDsProperty,pPropertyParams,cbPropertyParams,pPropertyData,cbPropertyData,pcbReturnedData);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsDriverPropertySetImpl_Set(
    PIDSDRIVERPROPERTYSET iface,
    PDSPROPERTY pDsProperty,
    LPVOID pPropertyParams,
    ULONG cbPropertyParams,
    LPVOID pPropertyData,
    ULONG cbPropertyData )
{
    IDsDriverPropertySetImpl *This = (IDsDriverPropertySetImpl *)iface;
    FIXME("(%p,%p,%p,%lx,%p,%lx)\n",This,pDsProperty,pPropertyParams,cbPropertyParams,pPropertyData,cbPropertyData);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsDriverPropertySetImpl_QuerySupport(
    PIDSDRIVERPROPERTYSET iface,
    REFGUID PropertySetId,
    ULONG PropertyId,
    PULONG pSupport )
{
    IDsDriverPropertySetImpl *This = (IDsDriverPropertySetImpl *)iface;
    FIXME("(%p,%s,%lx,%p)\n",This,debugstr_guid(PropertySetId),PropertyId,pSupport);
    return DSERR_UNSUPPORTED;
}

IDsDriverPropertySetVtbl dsdpsvt =
{
    IDsDriverPropertySetImpl_QueryInterface,
    IDsDriverPropertySetImpl_AddRef,
    IDsDriverPropertySetImpl_Release,
    IDsDriverPropertySetImpl_Get,
    IDsDriverPropertySetImpl_Set,
    IDsDriverPropertySetImpl_QuerySupport,
};

/*======================================================================*
 *                  Low level DSOUND notify implementation              *
 *======================================================================*/

static HRESULT WINAPI IDsDriverNotifyImpl_QueryInterface(
    PIDSDRIVERNOTIFY iface,
    REFIID riid,
    LPVOID *ppobj)
{
    IDsDriverNotifyImpl *This = (IDsDriverNotifyImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriverNotify) ) {
        IDsDriverNotify_AddRef(iface);
        *ppobj = This;
        return DS_OK;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );

    *ppobj = 0;
    return E_NOINTERFACE;
}

static ULONG WINAPI IDsDriverNotifyImpl_AddRef(PIDSDRIVERNOTIFY iface)
{
    IDsDriverNotifyImpl *This = (IDsDriverNotifyImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsDriverNotifyImpl_Release(PIDSDRIVERNOTIFY iface)
{
    IDsDriverNotifyImpl *This = (IDsDriverNotifyImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount + 1);

    if (!refCount) {
        IDsDriverBuffer_Release((PIDSDRIVERBUFFER)This->buffer);
        HeapFree(GetProcessHeap(), 0, This->notifies);
        HeapFree(GetProcessHeap(),0,This);
        TRACE("(%p) released\n",This);
    }
    return refCount;
}

static HRESULT WINAPI IDsDriverNotifyImpl_SetNotificationPositions(
    PIDSDRIVERNOTIFY iface,
    DWORD howmuch,
    LPCDSBPOSITIONNOTIFY notify)
{
    IDsDriverNotifyImpl *This = (IDsDriverNotifyImpl *)iface;
    TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);

    if (!notify) {
        WARN("invalid parameter\n");
        return DSERR_INVALIDPARAM;
    }

    if (TRACE_ON(wave)) {
        int i;
        for (i=0;i<howmuch;i++)
            TRACE("notify at %ld to 0x%08lx\n",
                notify[i].dwOffset,(DWORD)notify[i].hEventNotify);
    }

    /* Make an internal copy of the caller-supplied array.
     * Replace the existing copy if one is already present. */
    if (This->notifies)
        This->notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
        This->notifies, howmuch * sizeof(DSBPOSITIONNOTIFY));
    else
        This->notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
        howmuch * sizeof(DSBPOSITIONNOTIFY));

    memcpy(This->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
    This->nrofnotifies = howmuch;

    return S_OK;
}

IDsDriverNotifyVtbl dsdnvt =
{
    IDsDriverNotifyImpl_QueryInterface,
    IDsDriverNotifyImpl_AddRef,
    IDsDriverNotifyImpl_Release,
    IDsDriverNotifyImpl_SetNotificationPositions,
};

/*======================================================================*
 *                  Low level DSOUND implementation                     *
 *======================================================================*/

static HRESULT DSDB_MapBuffer(IDsDriverBufferImpl *dsdb)
{
    TRACE("(%p), format=%ldx%dx%d\n", dsdb, dsdb->wfex.Format.nSamplesPerSec,
          dsdb->wfex.Format.wBitsPerSample, dsdb->wfex.Format.nChannels);
    if (!dsdb->mapping) {
        dsdb->mapping = mmap(NULL, dsdb->maplen, PROT_WRITE, MAP_SHARED,
                             dsdb->fd, 0);
        if (dsdb->mapping == (LPBYTE)-1) {
            ERR("Could not map sound device for direct access (%s)\n", strerror(errno));
            ERR("Use: \"HardwareAcceleration\" = \"Emulation\" in the [dsound] section of your config file.\n");
            return DSERR_GENERIC;
        }
        TRACE("The sound device has been mapped for direct access at %p, size=%ld\n", dsdb->mapping, dsdb->maplen);

	/* for some reason, es1371 and sblive! sometimes have junk in here.
	 * clear it, or we get junk noise */
	/* some libc implementations are buggy: their memset reads from the buffer...
	 * to work around it, we have to zero the block by hand. We don't do the expected:
	 * memset(dsdb->mapping,0, dsdb->maplen);
	 */
	{
            unsigned char*      p1 = dsdb->mapping;
            unsigned            len = dsdb->maplen;
	    unsigned char	silence = (dsdb->wfex.Format.wBitsPerSample == 8) ? 128 : 0;
	    unsigned long	ulsilence = (dsdb->wfex.Format.wBitsPerSample == 8) ? 0x80808080 : 0;

	    if (len >= 16) /* so we can have at least a 4 long area to store... */
	    {
		/* the mmap:ed value is (at least) dword aligned
		 * so, start filling the complete unsigned long:s
		 */
		int		b = len >> 2;
		unsigned long*	p4 = (unsigned long*)p1;

		while (b--) *p4++ = ulsilence;
		/* prepare for filling the rest */
		len &= 3;
		p1 = (unsigned char*)p4;
	    }
	    /* in all cases, fill the remaining bytes */
	    while (len-- != 0) *p1++ = silence;
	}
    }
    return DS_OK;
}

static HRESULT DSDB_UnmapBuffer(IDsDriverBufferImpl *dsdb)
{
    TRACE("(%p)\n",dsdb);
    if (dsdb->mapping) {
        if (munmap(dsdb->mapping, dsdb->maplen) < 0) {
            ERR("(%p): Could not unmap sound device (%s)\n", dsdb, strerror(errno));
            return DSERR_GENERIC;
        }
        dsdb->mapping = NULL;
        TRACE("(%p): sound device unmapped\n", dsdb);
    }
    return DS_OK;
}

static HRESULT WINAPI IDsDriverBufferImpl_QueryInterface(PIDSDRIVERBUFFER iface, REFIID riid, LPVOID *ppobj)
{
    IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface;
    TRACE("(%p,%s,%p)\n",iface,debugstr_guid(riid),*ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriverBuffer) ) {
	IDsDriverBuffer_AddRef(iface);
	*ppobj = (LPVOID)This;
	return DS_OK;
    }

    if ( IsEqualGUID( &IID_IDsDriverNotify, riid ) ) {
        if (!This->notify)
            IDsDriverNotifyImpl_Create(This, &(This->notify));
        if (This->notify) {
            IDsDriverNotify_AddRef((PIDSDRIVERNOTIFY)This->notify);
            *ppobj = (LPVOID)This->notify;
            return DS_OK;
        }
        *ppobj = 0;
        return E_FAIL;
    }

    if ( IsEqualGUID( &IID_IDsDriverPropertySet, riid ) ) {
        if (!This->property_set)
            IDsDriverPropertySetImpl_Create(This, &(This->property_set));
        if (This->property_set) {
            IDsDriverPropertySet_AddRef((PIDSDRIVERPROPERTYSET)This->property_set);
            *ppobj = (LPVOID)This->property_set;
            return DS_OK;
        }
	*ppobj = 0;
	return E_FAIL;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );

    *ppobj = 0;

    return E_NOINTERFACE;
}

static ULONG WINAPI IDsDriverBufferImpl_AddRef(PIDSDRIVERBUFFER iface)
{
    IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsDriverBufferImpl_Release(PIDSDRIVERBUFFER iface)
{
    IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount + 1);

    if (refCount)
        return refCount;

    if (This == This->drv->primary)
	This->drv->primary = NULL;
    else {
        int i;
        for (i = 0; i < This->drv->nrofsecondaries; i++)
            if (This->drv->secondaries[i] == This)
                break;
        if (i < This->drv->nrofsecondaries) {
            /* Put the last buffer of the list in the (now empty) position */
            This->drv->secondaries[i] = This->drv->secondaries[This->drv->nrofsecondaries - 1];
            This->drv->nrofsecondaries--;
            This->drv->secondaries = HeapReAlloc(GetProcessHeap(),0,
                This->drv->secondaries,
                sizeof(PIDSDRIVERBUFFER)*This->drv->nrofsecondaries);
            TRACE("(%p) buffer count is now %d\n", This, This->drv->nrofsecondaries);
        }

        WOutDev[This->drv->wDevID].ossdev->ds_caps.dwFreeHwMixingAllBuffers++;
        WOutDev[This->drv->wDevID].ossdev->ds_caps.dwFreeHwMixingStreamingBuffers++;
    }

    DSDB_UnmapBuffer(This);
    HeapFree(GetProcessHeap(),0,This);
    TRACE("(%p) released\n",This);
    return 0;
}

static HRESULT WINAPI IDsDriverBufferImpl_Lock(PIDSDRIVERBUFFER iface,
					       LPVOID*ppvAudio1,LPDWORD pdwLen1,
					       LPVOID*ppvAudio2,LPDWORD pdwLen2,
					       DWORD dwWritePosition,DWORD dwWriteLen,
					       DWORD dwFlags)
{
    /* IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface; */
    /* since we (GetDriverDesc flags) have specified DSDDESC_DONTNEEDPRIMARYLOCK,
     * and that we don't support secondary buffers, this method will never be called */
    TRACE("(%p): stub\n",iface);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsDriverBufferImpl_Unlock(PIDSDRIVERBUFFER iface,
						 LPVOID pvAudio1,DWORD dwLen1,
						 LPVOID pvAudio2,DWORD dwLen2)
{
    /* IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface; */
    TRACE("(%p): stub\n",iface);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsDriverBufferImpl_SetFormat(PIDSDRIVERBUFFER iface,
						    LPWAVEFORMATEX pwfx)
{
    /* IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface; */

    TRACE("(%p,%p)\n",iface,pwfx);
    /* On our request (GetDriverDesc flags), DirectSound has by now used
     * waveOutClose/waveOutOpen to set the format...
     * unfortunately, this means our mmap() is now gone...
     * so we need to somehow signal to our DirectSound implementation
     * that it should completely recreate this HW buffer...
     * this unexpected error code should do the trick... */
    return DSERR_BUFFERLOST;
}

static HRESULT WINAPI IDsDriverBufferImpl_SetFrequency(PIDSDRIVERBUFFER iface, DWORD dwFreq)
{
    /* IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface; */
    TRACE("(%p,%ld): stub\n",iface,dwFreq);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsDriverBufferImpl_SetVolumePan(PIDSDRIVERBUFFER iface, PDSVOLUMEPAN pVolPan)
{
    DWORD vol;
    IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface;
    TRACE("(%p,%p)\n",This,pVolPan);

    vol = pVolPan->dwTotalLeftAmpFactor | (pVolPan->dwTotalRightAmpFactor << 16);

    if (wodSetVolume(This->drv->wDevID, vol) != MMSYSERR_NOERROR) {
	WARN("wodSetVolume failed\n");
	return DSERR_INVALIDPARAM;
    }

    return DS_OK;
}

static HRESULT WINAPI IDsDriverBufferImpl_SetPosition(PIDSDRIVERBUFFER iface, DWORD dwNewPos)
{
    /* IDsDriverImpl *This = (IDsDriverImpl *)iface; */
    TRACE("(%p,%ld): stub\n",iface,dwNewPos);
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsDriverBufferImpl_GetPosition(PIDSDRIVERBUFFER iface,
						      LPDWORD lpdwPlay, LPDWORD lpdwWrite)
{
    IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface;
    count_info info;
    DWORD ptr;

    TRACE("(%p)\n",iface);
    if (WOutDev[This->drv->wDevID].state == WINE_WS_CLOSED) {
	ERR("device not open, but accessing?\n");
	return DSERR_UNINITIALIZED;
    }
    if (ioctl(This->fd, SNDCTL_DSP_GETOPTR, &info) < 0) {
        ERR("ioctl(%s, SNDCTL_DSP_GETOPTR) failed (%s)\n",
            WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
	return DSERR_GENERIC;
    }
    ptr = info.ptr & ~3; /* align the pointer, just in case */
    if (lpdwPlay) *lpdwPlay = ptr;
    if (lpdwWrite) {
	/* add some safety margin (not strictly necessary, but...) */
	if (WOutDev[This->drv->wDevID].ossdev->duplex_out_caps.dwSupport & WAVECAPS_SAMPLEACCURATE)
	    *lpdwWrite = ptr + 32;
	else
	    *lpdwWrite = ptr + WOutDev[This->drv->wDevID].dwFragmentSize;
	while (*lpdwWrite > This->buflen)
	    *lpdwWrite -= This->buflen;
    }
    TRACE("playpos=%ld, writepos=%ld\n", lpdwPlay?*lpdwPlay:0, lpdwWrite?*lpdwWrite:0);
    return DS_OK;
}

static HRESULT WINAPI IDsDriverBufferImpl_Play(PIDSDRIVERBUFFER iface, DWORD dwRes1, DWORD dwRes2, DWORD dwFlags)
{
    IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface;
    int enable;
    TRACE("(%p,%lx,%lx,%lx)\n",iface,dwRes1,dwRes2,dwFlags);
    WOutDev[This->drv->wDevID].ossdev->bOutputEnabled = TRUE;
    enable = getEnables(WOutDev[This->drv->wDevID].ossdev);
    if (ioctl(This->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
	if (errno == EINVAL) {
	    /* Don't give up yet. OSS trigger support is inconsistent. */
	    if (WOutDev[This->drv->wDevID].ossdev->open_count == 1) {
		/* try the opposite input enable */
		if (WOutDev[This->drv->wDevID].ossdev->bInputEnabled == FALSE)
		    WOutDev[This->drv->wDevID].ossdev->bInputEnabled = TRUE;
		else
		    WOutDev[This->drv->wDevID].ossdev->bInputEnabled = FALSE;
		/* try it again */
    		enable = getEnables(WOutDev[This->drv->wDevID].ossdev);
                if (ioctl(This->fd, SNDCTL_DSP_SETTRIGGER, &enable) >= 0)
		    return DS_OK;
	    }
	}
        ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n",
            WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
	WOutDev[This->drv->wDevID].ossdev->bOutputEnabled = FALSE;
	return DSERR_GENERIC;
    }
    return DS_OK;
}

static HRESULT WINAPI IDsDriverBufferImpl_Stop(PIDSDRIVERBUFFER iface)
{
    IDsDriverBufferImpl *This = (IDsDriverBufferImpl *)iface;
    int enable;
    TRACE("(%p)\n",iface);
    /* no more playing */
    WOutDev[This->drv->wDevID].ossdev->bOutputEnabled = FALSE;
    enable = getEnables(WOutDev[This->drv->wDevID].ossdev);
    if (ioctl(This->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
	ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
	return DSERR_GENERIC;
    }
#if 0
    /* the play position must be reset to the beginning of the buffer */
    if (ioctl(This->fd, SNDCTL_DSP_RESET, 0) < 0) {
	ERR("ioctl(%s, SNDCTL_DSP_RESET) failed (%s)\n", WOutDev[This->drv->wDevID].ossdev->dev_name, strerror(errno));
	return DSERR_GENERIC;
    }
#endif
    /* Most OSS drivers just can't stop the playback without closing the device...
     * so we need to somehow signal to our DirectSound implementation
     * that it should completely recreate this HW buffer...
     * this unexpected error code should do the trick... */
    /* FIXME: ...unless we are doing full duplex, then it's not nice to close the device */
    if (WOutDev[This->drv->wDevID].ossdev->open_count == 1)
	return DSERR_BUFFERLOST;

    return DS_OK;
}

static IDsDriverBufferVtbl dsdbvt =
{
    IDsDriverBufferImpl_QueryInterface,
    IDsDriverBufferImpl_AddRef,
    IDsDriverBufferImpl_Release,
    IDsDriverBufferImpl_Lock,
    IDsDriverBufferImpl_Unlock,
    IDsDriverBufferImpl_SetFormat,
    IDsDriverBufferImpl_SetFrequency,
    IDsDriverBufferImpl_SetVolumePan,
    IDsDriverBufferImpl_SetPosition,
    IDsDriverBufferImpl_GetPosition,
    IDsDriverBufferImpl_Play,
    IDsDriverBufferImpl_Stop
};

static HRESULT WINAPI IDsDriverImpl_QueryInterface(PIDSDRIVER iface, REFIID riid, LPVOID *ppobj)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriver) ) {
	IDsDriver_AddRef(iface);
	*ppobj = (LPVOID)This;
	return DS_OK;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );

    *ppobj = 0;

    return E_NOINTERFACE;
}

static ULONG WINAPI IDsDriverImpl_AddRef(PIDSDRIVER iface)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsDriverImpl_Release(PIDSDRIVER iface)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %ld\n", This, refCount + 1);

    if (!refCount) {
        HeapFree(GetProcessHeap(),0,This);
        TRACE("(%p) released\n",This);
    }
    return refCount;
}

static HRESULT WINAPI IDsDriverImpl_GetDriverDesc(PIDSDRIVER iface,
                                                  PDSDRIVERDESC pDesc)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    TRACE("(%p,%p)\n",iface,pDesc);

    /* copy version from driver */
    memcpy(pDesc, &(WOutDev[This->wDevID].ossdev->ds_desc), sizeof(DSDRIVERDESC));

    pDesc->dwFlags |= DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT |
        DSDDESC_USESYSTEMMEMORY | DSDDESC_DONTNEEDPRIMARYLOCK |
        DSDDESC_DONTNEEDSECONDARYLOCK;
    pDesc->dnDevNode		= WOutDev[This->wDevID].waveDesc.dnDevNode;
    pDesc->wVxdId		= 0;
    pDesc->wReserved		= 0;
    pDesc->ulDeviceNum		= This->wDevID;
    pDesc->dwHeapType		= DSDHEAP_NOHEAP;
    pDesc->pvDirectDrawHeap	= NULL;
    pDesc->dwMemStartAddress	= 0;
    pDesc->dwMemEndAddress	= 0;
    pDesc->dwMemAllocExtra	= 0;
    pDesc->pvReserved1		= NULL;
    pDesc->pvReserved2		= NULL;
    return DS_OK;
}

static HRESULT WINAPI IDsDriverImpl_Open(PIDSDRIVER iface)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    int enable;
    TRACE("(%p)\n",iface);

    /* make sure the card doesn't start playing before we want it to */
    WOutDev[This->wDevID].ossdev->bOutputEnabled = FALSE;
    enable = getEnables(WOutDev[This->wDevID].ossdev);
    if (ioctl(WOutDev[This->wDevID].ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
	ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n",WOutDev[This->wDevID].ossdev->dev_name, strerror(errno));
	return DSERR_GENERIC;
    }
    return DS_OK;
}

static HRESULT WINAPI IDsDriverImpl_Close(PIDSDRIVER iface)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    TRACE("(%p)\n",iface);
    if (This->primary) {
	ERR("problem with DirectSound: primary not released\n");
	return DSERR_GENERIC;
    }
    return DS_OK;
}

static HRESULT WINAPI IDsDriverImpl_GetCaps(PIDSDRIVER iface, PDSDRIVERCAPS pCaps)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    TRACE("(%p,%p)\n",iface,pCaps);
    memcpy(pCaps, &(WOutDev[This->wDevID].ossdev->ds_caps), sizeof(DSDRIVERCAPS));
    return DS_OK;
}

static HRESULT WINAPI DSD_CreatePrimaryBuffer(PIDSDRIVER iface,
                                              LPWAVEFORMATEX pwfx,
                                              DWORD dwFlags,
                                              DWORD dwCardAddress,
                                              LPDWORD pdwcbBufferSize,
                                              LPBYTE *ppbBuffer,
                                              LPVOID *ppvObj)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    IDsDriverBufferImpl** ippdsdb = (IDsDriverBufferImpl**)ppvObj;
    HRESULT err;
    audio_buf_info info;
    int enable = 0;
    TRACE("(%p,%p,%lx,%lx,%p,%p,%p)\n",iface,pwfx,dwFlags,dwCardAddress,pdwcbBufferSize,ppbBuffer,ppvObj);

    if (This->primary)
	return DSERR_ALLOCATED;
    if (dwFlags & (DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN))
	return DSERR_CONTROLUNAVAIL;

    *ippdsdb = (IDsDriverBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDsDriverBufferImpl));
    if (*ippdsdb == NULL)
	return DSERR_OUTOFMEMORY;
    (*ippdsdb)->lpVtbl  = &dsdbvt;
    (*ippdsdb)->ref	= 1;
    (*ippdsdb)->drv	= This;
    copy_format(pwfx, &(*ippdsdb)->wfex);
    (*ippdsdb)->fd      = WOutDev[This->wDevID].ossdev->fd;
    (*ippdsdb)->dwFlags = dwFlags;

    /* check how big the DMA buffer is now */
    if (ioctl((*ippdsdb)->fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
        ERR("ioctl(%s, SNDCTL_DSP_GETOSPACE) failed (%s)\n",
            WOutDev[This->wDevID].ossdev->dev_name, strerror(errno));
	HeapFree(GetProcessHeap(),0,*ippdsdb);
	*ippdsdb = NULL;
	return DSERR_GENERIC;
    }
    (*ippdsdb)->maplen = (*ippdsdb)->buflen = info.fragstotal * info.fragsize;

    /* map the DMA buffer */
    err = DSDB_MapBuffer(*ippdsdb);
    if (err != DS_OK) {
	HeapFree(GetProcessHeap(),0,*ippdsdb);
	*ippdsdb = NULL;
	return err;
    }

    /* primary buffer is ready to go */
    *pdwcbBufferSize    = (*ippdsdb)->maplen;
    *ppbBuffer          = (*ippdsdb)->mapping;

    /* some drivers need some extra nudging after mapping */
    WOutDev[This->wDevID].ossdev->bOutputEnabled = FALSE;
    enable = getEnables(WOutDev[This->wDevID].ossdev);
    if (ioctl((*ippdsdb)->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) {
        ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n",
            WOutDev[This->wDevID].ossdev->dev_name, strerror(errno));
	return DSERR_GENERIC;
    }

    This->primary = *ippdsdb;

    return DS_OK;
}

static HRESULT WINAPI DSD_CreateSecondaryBuffer(PIDSDRIVER iface,
                                                LPWAVEFORMATEX pwfx,
                                                DWORD dwFlags,
                                                DWORD dwCardAddress,
                                                LPDWORD pdwcbBufferSize,
                                                LPBYTE *ppbBuffer,
                                                LPVOID *ppvObj)
{
    IDsDriverImpl *This = (IDsDriverImpl *)iface;
    IDsDriverBufferImpl** ippdsdb = (IDsDriverBufferImpl**)ppvObj;
    FIXME("(%p,%p,%lx,%lx,%p,%p,%p): stub\n",This,pwfx,dwFlags,dwCardAddress,pdwcbBufferSize,ppbBuffer,ppvObj);

    *ippdsdb = 0;
    return DSERR_UNSUPPORTED;
}

static HRESULT WINAPI IDsDriverImpl_CreateSoundBuffer(PIDSDRIVER iface,
                                                      LPWAVEFORMATEX pwfx,
                                                      DWORD dwFlags,
                                                      DWORD dwCardAddress,
                                                      LPDWORD pdwcbBufferSize,
                                                      LPBYTE *ppbBuffer,
                                                      LPVOID *ppvObj)
{
    TRACE("(%p,%p,%lx,%lx,%p,%p,%p)\n",iface,pwfx,dwFlags,dwCardAddress,pdwcbBufferSize,ppbBuffer,ppvObj);

    if (dwFlags & DSBCAPS_PRIMARYBUFFER)
        return DSD_CreatePrimaryBuffer(iface,pwfx,dwFlags,dwCardAddress,pdwcbBufferSize,ppbBuffer,ppvObj);

    return DSD_CreateSecondaryBuffer(iface,pwfx,dwFlags,dwCardAddress,pdwcbBufferSize,ppbBuffer,ppvObj);
}

static HRESULT WINAPI IDsDriverImpl_DuplicateSoundBuffer(PIDSDRIVER iface,
							 PIDSDRIVERBUFFER pBuffer,
							 LPVOID *ppvObj)
{
    /* IDsDriverImpl *This = (IDsDriverImpl *)iface; */
    TRACE("(%p,%p): stub\n",iface,pBuffer);
    return DSERR_INVALIDCALL;
}

static IDsDriverVtbl dsdvt =
{
    IDsDriverImpl_QueryInterface,
    IDsDriverImpl_AddRef,
    IDsDriverImpl_Release,
    IDsDriverImpl_GetDriverDesc,
    IDsDriverImpl_Open,
    IDsDriverImpl_Close,
    IDsDriverImpl_GetCaps,
    IDsDriverImpl_CreateSoundBuffer,
    IDsDriverImpl_DuplicateSoundBuffer
};

static HRESULT WINAPI IDsDriverPropertySetImpl_Create(
    IDsDriverBufferImpl * dsdb,
    IDsDriverPropertySetImpl **pdsdps)
{
    IDsDriverPropertySetImpl * dsdps;
    TRACE("(%p,%p)\n",dsdb,pdsdps);

    dsdps = (IDsDriverPropertySetImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dsdps));
    if (dsdps == NULL) {
        WARN("out of memory\n");
        return DSERR_OUTOFMEMORY;
    }

    dsdps->ref = 0;
    dsdps->lpVtbl = &dsdpsvt;
    dsdps->buffer = dsdb;
    dsdb->property_set = dsdps;
    IDsDriverBuffer_AddRef((PIDSDRIVER)dsdb);

    *pdsdps = dsdps;
    return DS_OK;
}

static HRESULT WINAPI IDsDriverNotifyImpl_Create(
    IDsDriverBufferImpl * dsdb,
    IDsDriverNotifyImpl **pdsdn)
{
    IDsDriverNotifyImpl * dsdn;
    TRACE("(%p,%p)\n",dsdb,pdsdn);

    dsdn = (IDsDriverNotifyImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(dsdn));

    if (dsdn == NULL) {
        WARN("out of memory\n");
        return DSERR_OUTOFMEMORY;
    }

    dsdn->ref = 0;
    dsdn->lpVtbl = &dsdnvt;
    dsdn->buffer = dsdb;
    dsdb->notify = dsdn;
    IDsDriverBuffer_AddRef((PIDSDRIVER)dsdb);

    *pdsdn = dsdn;
    return DS_OK;
}

DWORD wodDsCreate(UINT wDevID, PIDSDRIVER* drv)
{
    IDsDriverImpl** idrv = (IDsDriverImpl**)drv;
    TRACE("(%d,%p)\n",wDevID,drv);

    /* the HAL isn't much better than the HEL if we can't do mmap() */
    if (!(WOutDev[wDevID].ossdev->duplex_out_caps.dwSupport & WAVECAPS_DIRECTSOUND)) {
	ERR("DirectSound flag not set\n");
	MESSAGE("This sound card's driver does not support direct access\n");
	MESSAGE("The (slower) DirectSound HEL mode will be used instead.\n");
	return MMSYSERR_NOTSUPPORTED;
    }

    *idrv = (IDsDriverImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDsDriverImpl));
    if (!*idrv)
	return MMSYSERR_NOMEM;
    (*idrv)->lpVtbl          = &dsdvt;
    (*idrv)->ref             = 1;
    (*idrv)->wDevID          = wDevID;
    (*idrv)->primary         = NULL;
    (*idrv)->nrofsecondaries = 0;
    (*idrv)->secondaries     = NULL;

    return MMSYSERR_NOERROR;
}

DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
    TRACE("(%d,%p)\n",wDevID,desc);
    memcpy(desc, &(WOutDev[wDevID].ossdev->ds_desc), sizeof(DSDRIVERDESC));
    return MMSYSERR_NOERROR;
}

#endif /* HAVE_OSS */
