/*
 * 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)
{
    static char str[64];
#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
        sprintf(str, "UNKNOWN(%08x)", uMsg);
    return str;
}

static const char * getControlType(DWORD dwControlType)
{
    static char str[64];
#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
        sprintf(str, "UNKNOWN(%08x)", dwControlType);
    return str;
}

static const char * getComponentType(DWORD dwComponentType)
{
    static char str[64];
#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
        sprintf(str, "UNKNOWN(%08x)", dwComponentType);
    return str;
}

static const char * getTargetType(DWORD dwType)
{
    static char str[64];
#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
        sprintf(str, "UNKNOWN(%08x)", dwType);
    return str;
}

/* 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 */
