/*
 * Sample MIXER Wine Driver for Mac OS X (based on OSS mixer)
 *
 * Copyright 	1997 Marcus Meissner
 * 		1999,2001 Eric Pouech
 *              2006,2007 Emmanuel Maillard
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "mmddk.h"
#include "coreaudio.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(mixer);

#if defined(HAVE_COREAUDIO_COREAUDIO_H)
#include <CoreAudio/CoreAudio.h>
#include <CoreFoundation/CoreFoundation.h>

#define	WINE_MIXER_NAME "CoreAudio Mixer"

#define InputDevice (1 << 0)
#define OutputDevice (1 << 1)

#define IsInput(dir) ((dir) & InputDevice)
#define IsOutput(dir) ((dir) & OutputDevice)

#define ControlsPerLine 2 /* number of control per line : volume & (mute | onoff) */

#define IDControlVolume 0
#define IDControlMute 1

typedef struct tagMixerLine
{
    char *name;
    int direction;
    int numChannels;
    int componentType;
    AudioDeviceID deviceID;
} MixerLine;

typedef struct tagMixerCtrl
{
    DWORD dwLineID;
    MIXERCONTROLW ctrl;
} MixerCtrl;

typedef struct tagCoreAudio_Mixer
{
    MIXERCAPSW caps;

    MixerCtrl *mixerCtrls;
    MixerLine *lines;
    DWORD numCtrl;
} CoreAudio_Mixer;

static CoreAudio_Mixer mixer;
static int numMixers = 1;

/**************************************************************************
*/

static const char * getMessage(UINT uMsg)
{
#define MSG_TO_STR(x) case x: return #x;
    switch (uMsg) {
        MSG_TO_STR(DRVM_INIT);
        MSG_TO_STR(DRVM_EXIT);
        MSG_TO_STR(DRVM_ENABLE);
        MSG_TO_STR(DRVM_DISABLE);
        MSG_TO_STR(MXDM_GETDEVCAPS);
        MSG_TO_STR(MXDM_GETLINEINFO);
        MSG_TO_STR(MXDM_GETNUMDEVS);
        MSG_TO_STR(MXDM_OPEN);
        MSG_TO_STR(MXDM_CLOSE);
        MSG_TO_STR(MXDM_GETLINECONTROLS);
        MSG_TO_STR(MXDM_GETCONTROLDETAILS);
        MSG_TO_STR(MXDM_SETCONTROLDETAILS);
    }
#undef MSG_TO_STR
    return wine_dbg_sprintf("UNKNOWN(%08x)", uMsg);
}

static const char * getControlType(DWORD dwControlType)
{
#define TYPE_TO_STR(x) case x: return #x;
    switch (dwControlType) {
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_CUSTOM);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEANMETER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNEDMETER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PEAKMETER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNEDMETER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BOOLEAN);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_ONOFF);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUTE);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MONO);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_LOUDNESS);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_STEREOENH);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS_BOOST);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BUTTON);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_DECIBELS);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SIGNED);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_UNSIGNED);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PERCENT);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SLIDER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_PAN);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_QSOUNDPAN);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_FADER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_VOLUME);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_BASS);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_TREBLE);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_EQUALIZER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_SINGLESELECT);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MUX);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MIXER);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MICROTIME);
        TYPE_TO_STR(MIXERCONTROL_CONTROLTYPE_MILLITIME);
    }
#undef TYPE_TO_STR
    return wine_dbg_sprintf("UNKNOWN(%08x)", dwControlType);
}

static const char * getComponentType(DWORD dwComponentType)
{
#define TYPE_TO_STR(x) case x: return #x;
    switch (dwComponentType) {
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_UNDEFINED);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_DIGITAL);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_LINE);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_MONITOR);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_HEADPHONES);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_TELEPHONE);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_WAVEIN);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_DST_VOICEIN);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_DIGITAL);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_LINE);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY);
        TYPE_TO_STR(MIXERLINE_COMPONENTTYPE_SRC_ANALOG);
    }
#undef TYPE_TO_STR
    return wine_dbg_sprintf("UNKNOWN(%08x)", dwComponentType);
}

static const char * getTargetType(DWORD dwType)
{
#define TYPE_TO_STR(x) case x: return #x;
    switch (dwType) {
        TYPE_TO_STR(MIXERLINE_TARGETTYPE_UNDEFINED);
        TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEOUT);
        TYPE_TO_STR(MIXERLINE_TARGETTYPE_WAVEIN);
        TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIOUT);
        TYPE_TO_STR(MIXERLINE_TARGETTYPE_MIDIIN);
        TYPE_TO_STR(MIXERLINE_TARGETTYPE_AUX);
    }
#undef TYPE_TO_STR
    return wine_dbg_sprintf("UNKNOWN(%08x)", dwType);
}

/* FIXME is there a better way ? */
static DWORD DeviceComponentType(char *name)
{
    if (strcmp(name, "Built-in Microphone") == 0)
        return MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;

    if (strcmp(name, "Built-in Line Input") == 0)
        return MIXERLINE_COMPONENTTYPE_SRC_LINE;

    if (strcmp(name, "Built-in Output") == 0)
        return MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;

    return MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED;
}

static BOOL DeviceHasMute(AudioDeviceID deviceID, Boolean isInput)
{
    Boolean writable = false;
    OSStatus err = noErr;
    err = AudioDeviceGetPropertyInfo(deviceID, 0, isInput, kAudioDevicePropertyMute, NULL, NULL);
    if (err == noErr)
    {
        /* check if we can set it */
        err = AudioDeviceGetPropertyInfo(deviceID, 0, isInput, kAudioDevicePropertyMute, NULL, &writable);
        if (err == noErr)
            return writable;
    }
    return FALSE;
}

/*
 * Getters
 */
static BOOL MIX_LineGetVolume(DWORD lineID, DWORD channels, Float32 *left, Float32 *right)
{
    MixerLine *line = &mixer.lines[lineID];
    UInt32 size = sizeof(Float32);
    OSStatus err = noErr;
    *left = *right = 0.0;

    err = AudioDeviceGetProperty(line->deviceID, 1, IsInput(line->direction), kAudioDevicePropertyVolumeScalar, &size, left);
    if (err != noErr)
        return FALSE;

    if (channels == 2)
    {
        size = sizeof(Float32);
        err = AudioDeviceGetProperty(line->deviceID, 2, IsInput(line->direction), kAudioDevicePropertyVolumeScalar, &size, right);
        if (err != noErr)
            return FALSE;
    }

    TRACE("lineID %d channels %d return left %f right %f\n", lineID, channels, *left, *right);
    return (err == noErr);
}

static BOOL MIX_LineGetMute(DWORD lineID, BOOL *muted)
{
    MixerLine *line = &mixer.lines[lineID];
    UInt32 size = sizeof(UInt32);
    UInt32 val = 0;
    OSStatus err = noErr;
    err = AudioDeviceGetProperty(line->deviceID, 0, IsInput(line->direction), kAudioDevicePropertyMute, &size, &val);
    *muted = val;

    return (err == noErr);
}

/*
 * Setters
 */
static BOOL MIX_LineSetVolume(DWORD lineID, DWORD channels, Float32 left, Float32 right)
{
    MixerLine *line = &mixer.lines[lineID];
    UInt32 size = sizeof(Float32);
    OSStatus err = noErr;
    TRACE("lineID %d channels %d left %f right %f\n", lineID, channels, left, right);

    if (channels == 2)
    {
        err = AudioDeviceSetProperty(line->deviceID, NULL, 1, IsInput(line->direction), kAudioDevicePropertyVolumeScalar, size, &left);
        if (err != noErr)
            return FALSE;

        err = AudioDeviceSetProperty(line->deviceID, NULL, 2, IsInput(line->direction), kAudioDevicePropertyVolumeScalar, size, &right);
    }
    else
    {
        /*
            FIXME Using master channel failed ?? return kAudioHardwareUnknownPropertyError
            err = AudioDeviceSetProperty(line->deviceID, NULL, 0, IsInput(line->direction), kAudioDevicePropertyVolumeScalar, size, &left);
        */
        right = left;
        err = AudioDeviceSetProperty(line->deviceID, NULL, 1, IsInput(line->direction), kAudioDevicePropertyVolumeScalar, size, &left);
        if (err != noErr)
            return FALSE;
        err = AudioDeviceSetProperty(line->deviceID, NULL, 2, IsInput(line->direction), kAudioDevicePropertyVolumeScalar, size, &right);
    }
    return (err == noErr);
}

static BOOL MIX_LineSetMute(DWORD lineID, BOOL mute)
{
    MixerLine *line = &mixer.lines[lineID];
    UInt32 val = mute;
    UInt32 size = sizeof(UInt32);
    OSStatus err = noErr;

    err = AudioDeviceSetProperty(line->deviceID, 0, 0, IsInput(line->direction), kAudioDevicePropertyMute, size, &val);
    return (err == noErr);
}

static void MIX_FillControls(void)
{
    int i;
    int ctrl = 0;
    MixerLine *line;
    for (i = 0; i < mixer.caps.cDestinations; i++)
    {
        line = &mixer.lines[i];
        mixer.mixerCtrls[ctrl].dwLineID = i;
        mixer.mixerCtrls[ctrl].ctrl.cbStruct = sizeof(MIXERCONTROLW);
        mixer.mixerCtrls[ctrl].ctrl.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
        mixer.mixerCtrls[ctrl].ctrl.dwControlID = ctrl;
        mixer.mixerCtrls[ctrl].ctrl.Bounds.s1.dwMinimum = 0;
        mixer.mixerCtrls[ctrl].ctrl.Bounds.s1.dwMaximum = 65535;
        mixer.mixerCtrls[ctrl].ctrl.Metrics.cSteps = 656;
        ctrl++;

        mixer.mixerCtrls[ctrl].dwLineID = i;
        if ( !DeviceHasMute(line->deviceID, IsInput(line->direction)) )
            mixer.mixerCtrls[ctrl].ctrl.fdwControl |= MIXERCONTROL_CONTROLF_DISABLED;

        mixer.mixerCtrls[ctrl].ctrl.cbStruct = sizeof(MIXERCONTROLW);
        mixer.mixerCtrls[ctrl].ctrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
        mixer.mixerCtrls[ctrl].ctrl.dwControlID = ctrl;
        mixer.mixerCtrls[ctrl].ctrl.Bounds.s1.dwMinimum = 0;
        mixer.mixerCtrls[ctrl].ctrl.Bounds.s1.dwMaximum = 1;
        ctrl++;
    }
    assert(ctrl == mixer.numCtrl);
}

/**************************************************************************
* 				CoreAudio_MixerInit
*/
LONG CoreAudio_MixerInit(void)
{
    OSStatus status;
    UInt32 propertySize;
    AudioDeviceID *deviceArray = NULL;
    char name[MAXPNAMELEN];
    int i;
    int numLines;

    AudioStreamBasicDescription streamDescription;

    /* Find number of lines */
    status = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propertySize, NULL);
    if (status)
    {
        ERR("AudioHardwareGetPropertyInfo for kAudioHardwarePropertyDevices return %s\n", wine_dbgstr_fourcc(status));
        return DRV_FAILURE;
    }

    numLines = propertySize / sizeof(AudioDeviceID);

    mixer.mixerCtrls = NULL;
    mixer.lines = NULL;
    mixer.numCtrl = 0;

    mixer.caps.cDestinations = numLines;
    mixer.caps.wMid = 0xAA;
    mixer.caps.wPid = 0x55;
    mixer.caps.vDriverVersion = 0x0100;

    MultiByteToWideChar(CP_ACP, 0, WINE_MIXER_NAME, -1, mixer.caps.szPname, sizeof(mixer.caps.szPname) / sizeof(WCHAR));

    mixer.caps.fdwSupport = 0; /* No bits defined yet */

    mixer.lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MixerLine) * numLines);
    if (!mixer.lines)
        goto error;

    deviceArray = HeapAlloc(GetProcessHeap(), 0, sizeof(AudioDeviceID) * numLines);

    propertySize = sizeof(AudioDeviceID) * numLines;
    status = AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propertySize, deviceArray);
    if (status)
    {
        ERR("AudioHardwareGetProperty for kAudioHardwarePropertyDevices return %s\n", wine_dbgstr_fourcc(status));
        goto error;
    }

    for (i = 0; i < numLines; i++)
    {
        Boolean write;
        MixerLine *line = &mixer.lines[i];

        line->deviceID = deviceArray[i];

        propertySize = MAXPNAMELEN;
        status = AudioDeviceGetProperty(line->deviceID, 0 , FALSE, kAudioDevicePropertyDeviceName, &propertySize, name);
        if (status) {
            ERR("AudioHardwareGetProperty for kAudioDevicePropertyDeviceName return %s\n", wine_dbgstr_fourcc(status));
            goto error;
        }

        line->name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(name) + 1);
        if (!line->name)
            goto error;

        memcpy(line->name, name, strlen(name));

        line->componentType = DeviceComponentType(line->name);

        /* check for directions */
        /* Output ? */
        propertySize = sizeof(UInt32);
	status = AudioDeviceGetPropertyInfo(line->deviceID, 0, FALSE, kAudioDevicePropertyStreams, &propertySize, &write );
        if (status) {
            ERR("AudioDeviceGetPropertyInfo for kAudioDevicePropertyDataSource return %s\n", wine_dbgstr_fourcc(status));
            goto error;
        }

        if ( (propertySize / sizeof(AudioStreamID)) != 0)
        {
            line->direction |= OutputDevice;

            /* Check the number of channel for the stream */
            propertySize = sizeof(streamDescription);
            status = AudioDeviceGetProperty(line->deviceID, 0, FALSE , kAudioDevicePropertyStreamFormat, &propertySize, &streamDescription);
            if (status != noErr) {
                ERR("AudioHardwareGetProperty for kAudioDevicePropertyStreamFormat return %s\n", wine_dbgstr_fourcc(status));
                goto error;
            }
            line->numChannels = streamDescription.mChannelsPerFrame;
        }
        else
        {
            /* Input ? */
            propertySize = sizeof(UInt32);
            status = AudioDeviceGetPropertyInfo(line->deviceID, 0, TRUE, kAudioDevicePropertyStreams, &propertySize, &write );
            if (status) {
                ERR("AudioDeviceGetPropertyInfo for kAudioDevicePropertyStreams return %s\n", wine_dbgstr_fourcc(status));
                goto error;
            }
            if ( (propertySize / sizeof(AudioStreamID)) != 0)
            {
                line->direction |= InputDevice;

                /* Check the number of channel for the stream */
                propertySize = sizeof(streamDescription);
                status = AudioDeviceGetProperty(line->deviceID, 0, TRUE, kAudioDevicePropertyStreamFormat, &propertySize, &streamDescription);
                if (status != noErr) {
                    ERR("AudioHardwareGetProperty for kAudioDevicePropertyStreamFormat return %s\n", wine_dbgstr_fourcc(status));
                    goto error;
                }
                line->numChannels = streamDescription.mChannelsPerFrame;
            }
        }

        mixer.numCtrl += ControlsPerLine; /* volume & (mute | onoff) */
    }
    mixer.mixerCtrls = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MixerCtrl) * mixer.numCtrl);
    if (!mixer.mixerCtrls)
        goto error;

    MIX_FillControls();

    HeapFree(GetProcessHeap(), 0, deviceArray);
    return DRV_SUCCESS;

error:
    if (mixer.lines)
    {
        int i;
        for (i = 0; i < mixer.caps.cDestinations; i++)
        {
            HeapFree(GetProcessHeap(), 0, mixer.lines[i].name);
        }
        HeapFree(GetProcessHeap(), 0, mixer.lines);
    }
    HeapFree(GetProcessHeap(), 0, deviceArray);
    if (mixer.mixerCtrls)
        HeapFree(GetProcessHeap(), 0, mixer.mixerCtrls);
    return DRV_FAILURE;
}

/**************************************************************************
* 				CoreAudio_MixerRelease
*/
void CoreAudio_MixerRelease(void)
{
    TRACE("()\n");

    if (mixer.lines)
    {
        int i;
        for (i = 0; i < mixer.caps.cDestinations; i++)
        {
            HeapFree(GetProcessHeap(), 0, mixer.lines[i].name);
        }
        HeapFree(GetProcessHeap(), 0, mixer.lines);
    }
    if (mixer.mixerCtrls)
        HeapFree(GetProcessHeap(), 0, mixer.mixerCtrls);
}

/**************************************************************************
* 				MIX_Open			[internal]
*/
static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpMod, DWORD_PTR flags)
{
    TRACE("wDevID=%d lpMod=%p dwSize=%08lx\n", wDevID, lpMod, flags);
    if (lpMod == NULL) {
        WARN("invalid parameter: lpMod == NULL\n");
        return MMSYSERR_INVALPARAM;
    }

    if (wDevID >= numMixers) {
        WARN("bad device ID: %04X\n", wDevID);
        return MMSYSERR_BADDEVICEID;
    }
    return MMSYSERR_NOERROR;
}

/**************************************************************************
* 				MIX_GetNumDevs			[internal]
*/
static DWORD MIX_GetNumDevs(void)
{
    TRACE("()\n");
    return numMixers;
}

static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPSW lpCaps, DWORD_PTR dwSize)
{
    TRACE("wDevID=%d lpCaps=%p\n", wDevID, lpCaps);

    if (lpCaps == NULL) {
	WARN("Invalid Parameter\n");
	return MMSYSERR_INVALPARAM;
    }

    if (wDevID >= numMixers) {
        WARN("bad device ID : %d\n", wDevID);
	return MMSYSERR_BADDEVICEID;
    }
    memcpy(lpCaps, &mixer.caps, min(dwSize, sizeof(*lpCaps)));
    return MMSYSERR_NOERROR;
}

/**************************************************************************
* 				MIX_GetLineInfo			[internal]
*/
static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINEW lpMl, DWORD_PTR fdwInfo)
{
    int i;
    DWORD ret = MMSYSERR_ERROR;
    MixerLine *line = NULL;

    TRACE("%04X, %p, %08lx\n", wDevID, lpMl, fdwInfo);

    if (lpMl == NULL) {
        WARN("invalid parameter: lpMl = NULL\n");
	return MMSYSERR_INVALPARAM;
    }

    if (lpMl->cbStruct != sizeof(*lpMl)) {
        WARN("invalid parameter: lpMl->cbStruct\n");
	return MMSYSERR_INVALPARAM;
    }

    if (wDevID >= numMixers) {
        WARN("bad device ID: %04X\n", wDevID);
        return MMSYSERR_BADDEVICEID;
    }

    /* FIXME: set all the variables correctly... the lines below
        * are very wrong...
        */
    lpMl->dwUser = 0;

    switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK)
    {
        case MIXER_GETLINEINFOF_DESTINATION:
            TRACE("MIXER_GETLINEINFOF_DESTINATION %d\n", lpMl->dwDestination);
            if ( (lpMl->dwDestination >= 0) && (lpMl->dwDestination < mixer.caps.cDestinations) )
            {
                lpMl->dwLineID = lpMl->dwDestination;
                line = &mixer.lines[lpMl->dwDestination];
            }
            else ret = MIXERR_INVALLINE;
            break;
        case MIXER_GETLINEINFOF_COMPONENTTYPE:
            TRACE("MIXER_GETLINEINFOF_COMPONENTTYPE %s\n", getComponentType(lpMl->dwComponentType));
            for (i = 0; i < mixer.caps.cDestinations; i++)
            {
                if (mixer.lines[i].componentType == lpMl->dwComponentType)
                {
                    lpMl->dwDestination = lpMl->dwLineID = i;
                    line = &mixer.lines[i];
                    break;
                }
            }
            if (line == NULL)
            {
                WARN("can't find component type %s\n", getComponentType(lpMl->dwComponentType));
                ret = MIXERR_INVALVALUE;
            }
            break;
        case MIXER_GETLINEINFOF_SOURCE:
            FIXME("MIXER_GETLINEINFOF_SOURCE %d dst=%d\n", lpMl->dwSource, lpMl->dwDestination);
            break;
        case MIXER_GETLINEINFOF_LINEID:
            TRACE("MIXER_GETLINEINFOF_LINEID %d\n", lpMl->dwLineID);
            if ( (lpMl->dwLineID >= 0) && (lpMl->dwLineID < mixer.caps.cDestinations) )
            {
                lpMl->dwDestination = lpMl->dwLineID;
                line = &mixer.lines[lpMl->dwLineID];
            }
            else ret = MIXERR_INVALLINE;
            break;
        case MIXER_GETLINEINFOF_TARGETTYPE:
            FIXME("MIXER_GETLINEINFOF_TARGETTYPE (%s)\n", getTargetType(lpMl->Target.dwType));
            switch (lpMl->Target.dwType) {
                case MIXERLINE_TARGETTYPE_UNDEFINED:
                case MIXERLINE_TARGETTYPE_WAVEOUT:
                case MIXERLINE_TARGETTYPE_WAVEIN:
                case MIXERLINE_TARGETTYPE_MIDIOUT:
                case MIXERLINE_TARGETTYPE_MIDIIN:
                case MIXERLINE_TARGETTYPE_AUX:
                default:
                    FIXME("Unhandled target type (%s)\n",
                          getTargetType(lpMl->Target.dwType));
                    return MMSYSERR_INVALPARAM;
            }
                break;
        default:
            WARN("Unknown flag (%08lx)\n", fdwInfo & MIXER_GETLINEINFOF_QUERYMASK);
            break;
    }

    if (line)
    {
        lpMl->dwComponentType = line->componentType;
        lpMl->cChannels = line->numChannels;
        lpMl->cControls = ControlsPerLine;

        /* FIXME check there with CoreAudio */
        lpMl->cConnections = 1;
        lpMl->fdwLine = MIXERLINE_LINEF_ACTIVE;

        MultiByteToWideChar(CP_ACP, 0, line->name, -1, lpMl->szShortName, sizeof(lpMl->szShortName) / sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, line->name, -1, lpMl->szName, sizeof(lpMl->szName) / sizeof(WCHAR));

        if ( IsInput(line->direction) )
            lpMl->Target.dwType = MIXERLINE_TARGETTYPE_WAVEIN;
        else
            lpMl->Target.dwType = MIXERLINE_TARGETTYPE_WAVEOUT;

        lpMl->Target.dwDeviceID = line->deviceID;
        lpMl->Target.wMid = mixer.caps.wMid;
        lpMl->Target.wPid = mixer.caps.wPid;
        lpMl->Target.vDriverVersion = mixer.caps.vDriverVersion;

        MultiByteToWideChar(CP_ACP, 0, WINE_MIXER_NAME, -1, lpMl->Target.szPname, sizeof(lpMl->Target.szPname) / sizeof(WCHAR));
        ret = MMSYSERR_NOERROR;
    }
    return ret;
}

/**************************************************************************
* 				MIX_GetLineControls		[internal]
*/
static DWORD MIX_GetLineControls(WORD wDevID, LPMIXERLINECONTROLSW lpMlc, DWORD_PTR flags)
{
    DWORD ret = MMSYSERR_NOTENABLED;
    int ctrl = 0;
    TRACE("%04X, %p, %08lX\n", wDevID, lpMlc, flags);

    if (lpMlc == NULL) {
        WARN("invalid parameter: lpMlc == NULL\n");
        return MMSYSERR_INVALPARAM;
    }

    if (lpMlc->cbStruct < sizeof(*lpMlc)) {
        WARN("invalid parameter: lpMlc->cbStruct = %d\n", lpMlc->cbStruct);
	return MMSYSERR_INVALPARAM;
    }

    if (lpMlc->cbmxctrl < sizeof(MIXERCONTROLW)) {
        WARN("invalid parameter: lpMlc->cbmxctrl = %d\n", lpMlc->cbmxctrl);
	return MMSYSERR_INVALPARAM;
    }

    if (wDevID >= numMixers) {
        WARN("bad device ID: %04X\n", wDevID);
        return MMSYSERR_BADDEVICEID;
    }

    switch (flags & MIXER_GETLINECONTROLSF_QUERYMASK)
    {
        case MIXER_GETLINECONTROLSF_ALL:
            FIXME("dwLineID=%d MIXER_GETLINECONTROLSF_ALL (%d)\n", lpMlc->dwLineID, lpMlc->cControls);
            if (lpMlc->cControls != ControlsPerLine)
            {
                WARN("invalid parameter lpMlc->cControls %d\n", lpMlc->cControls);
                ret = MMSYSERR_INVALPARAM;
	    }
            else
            {
                if ( (lpMlc->dwLineID >= 0) && (lpMlc->dwLineID < mixer.caps.cDestinations) )
                {
                    int i;
                    for (i = 0; i < lpMlc->cControls; i++)
                    {
                        lpMlc->pamxctrl[i] = mixer.mixerCtrls[lpMlc->dwLineID * i].ctrl;
                    }
                    ret = MMSYSERR_NOERROR;
                }
                else ret = MIXERR_INVALLINE;
            }
            break;
        case MIXER_GETLINECONTROLSF_ONEBYID:
            TRACE("dwLineID=%d MIXER_GETLINECONTROLSF_ONEBYID (%d)\n", lpMlc->dwLineID, lpMlc->u.dwControlID);
            if ( lpMlc->u.dwControlID >= 0 && lpMlc->u.dwControlID < mixer.numCtrl )
            {
                lpMlc->pamxctrl[0] = mixer.mixerCtrls[lpMlc->u.dwControlID].ctrl;
                ret = MMSYSERR_NOERROR;
            }
            else ret = MIXERR_INVALVALUE;
            break;
        case MIXER_GETLINECONTROLSF_ONEBYTYPE:
            TRACE("dwLineID=%d MIXER_GETLINECONTROLSF_ONEBYTYPE (%s)\n", lpMlc->dwLineID, getControlType(lpMlc->u.dwControlType));
            if ( (lpMlc->dwLineID < 0) || (lpMlc->dwLineID >= mixer.caps.cDestinations) )
            {
                ret = MIXERR_INVALLINE;
                break;
            }
            if (lpMlc->u.dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
            {
                ctrl = (lpMlc->dwLineID * ControlsPerLine) + IDControlVolume;
                lpMlc->pamxctrl[0] = mixer.mixerCtrls[ctrl].ctrl;
                ret = MMSYSERR_NOERROR;
            }
            else
                if (lpMlc->u.dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
                {
                    ctrl = (lpMlc->dwLineID * ControlsPerLine) + IDControlMute;
                    lpMlc->pamxctrl[0] = mixer.mixerCtrls[ctrl].ctrl;
                    ret = MMSYSERR_NOERROR;
                }
                break;
        default:
            ERR("Unknown flag %08lx\n", flags & MIXER_GETLINECONTROLSF_QUERYMASK);
            ret = MMSYSERR_INVALPARAM;
    }

    return ret;
}

/**************************************************************************
 * 				MIX_GetControlDetails		[internal]
 */
static DWORD MIX_GetControlDetails(WORD wDevID, LPMIXERCONTROLDETAILS lpmcd, DWORD_PTR fdwDetails)
{
    DWORD ret = MMSYSERR_NOTSUPPORTED;
    DWORD dwControlType;

    TRACE("%04X, %p, %08lx\n", wDevID, lpmcd, fdwDetails);

    if (lpmcd == NULL) {
        TRACE("invalid parameter: lpmcd == NULL\n");
        return MMSYSERR_INVALPARAM;
    }

    if (wDevID >= numMixers) {
        WARN("bad device ID: %04X\n", wDevID);
        return MMSYSERR_BADDEVICEID;
    }

    if ( (fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK) != MIXER_GETCONTROLDETAILSF_VALUE )
    {
        WARN("Unknown/unimplement GetControlDetails flag (%08lx)\n", fdwDetails & MIXER_GETCONTROLDETAILSF_QUERYMASK);
        return MMSYSERR_NOTSUPPORTED;
    }

    if ( lpmcd->dwControlID < 0 || lpmcd->dwControlID >= mixer.numCtrl )
    {
        WARN("bad control ID: %d\n", lpmcd->dwControlID);
        return MIXERR_INVALVALUE;
    }

    TRACE("MIXER_GETCONTROLDETAILSF_VALUE %d\n", lpmcd->dwControlID);

    dwControlType = mixer.mixerCtrls[lpmcd->dwControlID].ctrl.dwControlType;
    switch (dwControlType)
    {
        case MIXERCONTROL_CONTROLTYPE_VOLUME:
            FIXME("controlType : %s channels %d\n", getControlType(dwControlType), lpmcd->cChannels);
            {
                LPMIXERCONTROLDETAILS_UNSIGNED mcdu;
                Float32 left, right;

                if (lpmcd->cbDetails != sizeof(MIXERCONTROLDETAILS_UNSIGNED)) {
                    WARN("invalid parameter: lpmcd->cbDetails == %d\n", lpmcd->cbDetails);
                    return MMSYSERR_INVALPARAM;
                }

                if ( MIX_LineGetVolume(mixer.mixerCtrls[lpmcd->dwControlID].dwLineID, lpmcd->cChannels, &left, &right) )
                {
                    mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)lpmcd->paDetails;

		    switch (lpmcd->cChannels)
		    {
                        case 1:
                            /* mono... so R = L */
                            mcdu->dwValue = left * 65535;
                            TRACE("Reading RL = %d\n", mcdu->dwValue);
                            break;
                        case 2:
                            /* stereo, left is paDetails[0] */
                            mcdu->dwValue = left * 65535;
                            TRACE("Reading L = %d\n", mcdu->dwValue);
                            mcdu++;
                            mcdu->dwValue = right * 65535;
                            TRACE("Reading R = %d\n", mcdu->dwValue);
                            break;
                        default:
                            WARN("Unsupported cChannels (%d)\n", lpmcd->cChannels);
                            return MMSYSERR_INVALPARAM;
		    }
                    TRACE("=> %08x\n", mcdu->dwValue);
                    ret = MMSYSERR_NOERROR;
                }
            }
            break;
        case MIXERCONTROL_CONTROLTYPE_MUTE:
        case MIXERCONTROL_CONTROLTYPE_ONOFF:
            FIXME("%s MIXERCONTROLDETAILS_BOOLEAN[%u]\n", getControlType(dwControlType), lpmcd->cChannels);
            {
                LPMIXERCONTROLDETAILS_BOOLEAN mcdb;
                BOOL muted;
                if (lpmcd->cbDetails != sizeof(MIXERCONTROLDETAILS_BOOLEAN)) {
                    WARN("invalid parameter: lpmcd->cbDetails = %d\n", lpmcd->cbDetails);
                    return MMSYSERR_INVALPARAM;
                }
                mcdb = (LPMIXERCONTROLDETAILS_BOOLEAN)lpmcd->paDetails;

                if ( MIX_LineGetMute(mixer.mixerCtrls[lpmcd->dwControlID].dwLineID, &muted) )
                {
                    mcdb->fValue = muted;
		    TRACE("=> %s\n", mcdb->fValue ? "on" : "off");
                    ret = MMSYSERR_NOERROR;
                }
            }
            break;
        case MIXERCONTROL_CONTROLTYPE_MIXER:
        case MIXERCONTROL_CONTROLTYPE_MUX:
        default:
            FIXME("controlType : %s\n", getControlType(dwControlType));
            break;
    }
    return ret;
}

/**************************************************************************
* 				MIX_SetControlDetails		[internal]
*/
static DWORD MIX_SetControlDetails(WORD wDevID, LPMIXERCONTROLDETAILS lpmcd, DWORD_PTR fdwDetails)
{
    DWORD ret = MMSYSERR_NOTSUPPORTED;
    DWORD dwControlType;

    TRACE("%04X, %p, %08lx\n", wDevID, lpmcd, fdwDetails);

    if (lpmcd == NULL) {
        TRACE("invalid parameter: lpmcd == NULL\n");
        return MMSYSERR_INVALPARAM;
    }

    if (wDevID >= numMixers) {
        WARN("bad device ID: %04X\n", wDevID);
        return MMSYSERR_BADDEVICEID;
    }

    if ( (fdwDetails & MIXER_SETCONTROLDETAILSF_QUERYMASK) != MIXER_GETCONTROLDETAILSF_VALUE )
    {
        WARN("Unknown SetControlDetails flag (%08lx)\n", fdwDetails & MIXER_SETCONTROLDETAILSF_QUERYMASK);
        return MMSYSERR_NOTSUPPORTED;
    }

    TRACE("MIXER_SETCONTROLDETAILSF_VALUE dwControlID=%d\n", lpmcd->dwControlID);
    dwControlType = mixer.mixerCtrls[lpmcd->dwControlID].ctrl.dwControlType;
    switch (dwControlType)
    {
        case MIXERCONTROL_CONTROLTYPE_VOLUME:
            FIXME("controlType : %s\n", getControlType(dwControlType));
            {
                LPMIXERCONTROLDETAILS_UNSIGNED mcdu;
                Float32 left, right = 0;

                if (lpmcd->cbDetails != sizeof(MIXERCONTROLDETAILS_UNSIGNED)) {
                    WARN("invalid parameter: lpmcd->cbDetails == %d\n", lpmcd->cbDetails);
                    return MMSYSERR_INVALPARAM;
                }

                mcdu = (LPMIXERCONTROLDETAILS_UNSIGNED)lpmcd->paDetails;

                switch (lpmcd->cChannels)
                {
                    case 1:
                        /* mono... so R = L */
                        TRACE("Setting RL to %d\n", mcdu->dwValue);
                        left = (Float32) mcdu->dwValue / 65535.0;
                        break;
                    case 2:
                        /* stereo, left is paDetails[0] */
			TRACE("Setting L to %d\n", mcdu->dwValue);
			left = (Float32) mcdu->dwValue / 65535.0;
                        mcdu++;
			TRACE("Setting R to %d\n", mcdu->dwValue);
			right = (Float32) mcdu->dwValue / 65535.0;
			break;
                    default:
                        WARN("Unsupported cChannels (%d)\n", lpmcd->cChannels);
                        return MMSYSERR_INVALPARAM;
                }
                if ( MIX_LineSetVolume(mixer.mixerCtrls[lpmcd->dwControlID].dwLineID, lpmcd->cChannels, left, right) )
                    ret = MMSYSERR_NOERROR;
            }
            break;
        case MIXERCONTROL_CONTROLTYPE_MUTE:
        case MIXERCONTROL_CONTROLTYPE_ONOFF:
            TRACE("%s MIXERCONTROLDETAILS_BOOLEAN[%u]\n", getControlType(dwControlType), lpmcd->cChannels);
            {
                LPMIXERCONTROLDETAILS_BOOLEAN	mcdb;

                if (lpmcd->cbDetails != sizeof(MIXERCONTROLDETAILS_BOOLEAN)) {
                    WARN("invalid parameter: cbDetails\n");
                    return MMSYSERR_INVALPARAM;
                }
                mcdb = (LPMIXERCONTROLDETAILS_BOOLEAN)lpmcd->paDetails;
                if ( MIX_LineSetMute(mixer.mixerCtrls[lpmcd->dwControlID].dwLineID, mcdb->fValue) )
                    ret = MMSYSERR_NOERROR;
            }
            break;
        case MIXERCONTROL_CONTROLTYPE_MIXER:
        case MIXERCONTROL_CONTROLTYPE_MUX:
        default:
            FIXME("controlType : %s\n", getControlType(dwControlType));
            ret = MMSYSERR_NOTSUPPORTED;
            break;
    }
    return ret;
}

/**************************************************************************
* 				mxdMessage
*/
DWORD WINAPI CoreAudio_mxdMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
                                  DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    TRACE("(%04X, %s, %08lX, %08lX, %08lX);\n", wDevID, getMessage(wMsg),
          dwUser, dwParam1, dwParam2);

    switch (wMsg)
    {
        case DRVM_INIT:
        case DRVM_EXIT:
        case DRVM_ENABLE:
        case DRVM_DISABLE:
            /* FIXME: Pretend this is supported */
            return 0;
        case MXDM_OPEN:
            return MIX_Open(wDevID, (LPMIXEROPENDESC)dwParam1, dwParam2);
        case MXDM_CLOSE:
            return MMSYSERR_NOERROR;
        case MXDM_GETNUMDEVS:
            return MIX_GetNumDevs();
        case MXDM_GETDEVCAPS:
            return MIX_GetDevCaps(wDevID, (LPMIXERCAPSW)dwParam1, dwParam2);
        case MXDM_GETLINEINFO:
            return MIX_GetLineInfo(wDevID, (LPMIXERLINEW)dwParam1, dwParam2);
        case MXDM_GETLINECONTROLS:
            return MIX_GetLineControls(wDevID, (LPMIXERLINECONTROLSW)dwParam1, dwParam2);
        case MXDM_GETCONTROLDETAILS:
            return MIX_GetControlDetails(wDevID, (LPMIXERCONTROLDETAILS)dwParam1, dwParam2);
        case MXDM_SETCONTROLDETAILS:
            return MIX_SetControlDetails(wDevID, (LPMIXERCONTROLDETAILS)dwParam1, dwParam2);
        default:
            WARN("unknown message %d!\n", wMsg);
            return MMSYSERR_NOTSUPPORTED;
    }
}

#else

DWORD WINAPI CoreAudio_mxdMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
                                  DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
    TRACE("(%04X, %04x, %08lX, %08lX, %08lX);\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);
    return MMSYSERR_NOTENABLED;
}
#endif /* HAVE_COREAUDIO_COREAUDIO_H */
