/*
 * Alsa MIXER Wine Driver for Linux
 * Very loosely based on wineoss mixer driver
 *
 * Copyright 2007 Maarten Lankhorst
 *
 * 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
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif

#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "mmddk.h"
#include "mmreg.h"
#include "dsound.h"
#include "dsdriver.h"
#include "mmsystem.h"
#include "alsa.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(mixer);

#define	WINE_MIXER_MANUF_ID      0xAA
#define	WINE_MIXER_PRODUCT_ID    0x55
#define	WINE_MIXER_VERSION       0x0100

/* Generic notes:
 * In windows it seems to be required for all controls to have a volume switch
 * In alsa that's optional
 *
 * I assume for playback controls, that there is always a playback volume switch available
 * Mute is optional
 *
 * For capture controls, it is needed that there is a capture switch and a volume switch,
 * It doesn't matter whether it is a playback volume switch or a capture volume switch.
 * The code will first try to get/adjust capture volume, if that fails it tries playback volume
 * It is not pretty, but under my 3 test cards it seems that there is no other choice:
 * Most capture controls don't have a capture volume setting
 *
 * MUX means that only capture source can be exclusively selected,
 * MIXER means that multiple sources can be selected simultaneously.
 */

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);
    default: break;
    }
#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);
}

/* A simple declaration of a line control
 * These are each of the channels that show up
 */
typedef struct line {
    /* Name we present to outside world */
    WCHAR name[MAXPNAMELEN];

    DWORD component;
    DWORD dst;
    DWORD capt;
    DWORD chans;
    snd_mixer_elem_t *elem;
} line;

/* A control structure, with toggle enabled switch
 * Control structures control volume, muted, which capture source
 */
typedef struct control {
    BOOL enabled;
    MIXERCONTROLW c;
} control;

/* Mixer device */
typedef struct mixer
{
    snd_mixer_t *mix;
    WCHAR mixername[MAXPNAMELEN];

    int chans, dests;
    LPDRVCALLBACK callback;
    DWORD_PTR callbackpriv;
    HDRVR hmx;

    line *lines;
    control *controls;
} mixer;

#define MAX_MIXERS 32
#define CONTROLSPERLINE 3
#define OFS_MUTE 2
#define OFS_MUX 1

static int cards = 0;
static mixer mixdev[MAX_MIXERS];
static HANDLE thread;
static int elem_callback(snd_mixer_elem_t *elem, unsigned int mask);
static DWORD WINAPI ALSA_MixerPollThread(LPVOID lParam);
static CRITICAL_SECTION elem_crst;
static int msg_pipe[2];
static LONG refcnt;

/* found channel names in alsa lib, alsa api doesn't have another way for this
 * map name -> componenttype, worst case we get a wrong componenttype which is
 * mostly harmless
 */

static const struct mixerlinetype {
    const char *name;  DWORD cmpt;
} converttable[] = {
    { "Master",     MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,    },
    { "Capture",    MIXERLINE_COMPONENTTYPE_DST_WAVEIN,      },
    { "PCM",        MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT,     },
    { "PC Speaker", MIXERLINE_COMPONENTTYPE_SRC_PCSPEAKER,   },
    { "Synth",      MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER, },
    { "Headphone",  MIXERLINE_COMPONENTTYPE_DST_HEADPHONES,  },
    { "Mic",        MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,  },
    { "Aux",        MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED,   },
    { "CD",         MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC, },
    { "Line",       MIXERLINE_COMPONENTTYPE_SRC_LINE,        },
    { "Phone",      MIXERLINE_COMPONENTTYPE_SRC_TELEPHONE,   },
    { "Digital",    MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,  },
    { "Front Mic",  MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE,  },
};

/* Map name to MIXERLINE_COMPONENTTYPE_XXX */
static int getcomponenttype(const char *name)
{
    int x;
    for (x=0; x< sizeof(converttable)/sizeof(converttable[0]); ++x)
        if (!strcasecmp(name, converttable[x].name))
        {
            TRACE("%d -> %s\n", x, name);
            return converttable[x].cmpt;
        }
    WARN("Unknown mixer name %s, probably harmless\n", name);
    return MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED;
}

/* Is this control suited for showing up? */
static int blacklisted(snd_mixer_elem_t *elem)
{
    const char *name = snd_mixer_selem_get_name(elem);
    BOOL blisted = 0;

    if (!snd_mixer_selem_has_playback_volume(elem) &&
        !snd_mixer_selem_has_capture_volume(elem))
        blisted = 1;

    TRACE("%s: %x\n", name, blisted);
    return blisted;
}

static void fillcontrols(mixer *mmixer)
{
    int id;
    for (id = 0; id < mmixer->chans; ++id)
    {
        line *mline = &mmixer->lines[id];
        int ofs = CONTROLSPERLINE * id;
        int x;
        long min, max;

        TRACE("Filling control %d\n", id);
        if (!mline->elem)
            break;
        if (id == 1 && !mline->elem)
            continue;

        if (mline->capt && snd_mixer_selem_has_capture_volume(mline->elem))
            snd_mixer_selem_get_capture_volume_range(mline->elem, &min, &max);
        else
            snd_mixer_selem_get_playback_volume_range(mline->elem, &min, &max);

        /* (!snd_mixer_selem_has_playback_volume(elem) || snd_mixer_selem_has_capture_volume(elem)) */
        /* Volume, always enabled by definition of blacklisted channels */
        mmixer->controls[ofs].enabled = 1;
        mmixer->controls[ofs].c.cbStruct = sizeof(mmixer->controls[ofs].c);
        mmixer->controls[ofs].c.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
        mmixer->controls[ofs].c.dwControlID = ofs;
        mmixer->controls[ofs].c.Bounds.s1.dwMinimum = 0;
        mmixer->controls[ofs].c.Bounds.s1.dwMaximum = 65535;
        mmixer->controls[ofs].c.Metrics.cSteps = 65536/(max-min);

        if ((id == 1 && snd_mixer_selem_has_capture_switch(mline->elem)) ||
            (!mline->capt && snd_mixer_selem_has_playback_switch(mline->elem)))
        { /* MUTE button optional, main capture channel should have one too */
            mmixer->controls[ofs+OFS_MUTE].enabled = 1;
            mmixer->controls[ofs+OFS_MUTE].c.cbStruct = sizeof(mmixer->controls[ofs].c);
            mmixer->controls[ofs+OFS_MUTE].c.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
            mmixer->controls[ofs+OFS_MUTE].c.dwControlID = ofs+OFS_MUTE;
            mmixer->controls[ofs+OFS_MUTE].c.Bounds.s1.dwMaximum = 1;
        }

        if (mline->capt && snd_mixer_selem_has_capture_switch_exclusive(mline->elem))
            mmixer->controls[CONTROLSPERLINE+OFS_MUX].c.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX;

        if (id == 1)
        { /* Capture select, in case cMultipleItems is 0, it means capture is disabled anyway */
            mmixer->controls[ofs+OFS_MUX].enabled = 1;
            mmixer->controls[ofs+OFS_MUX].c.cbStruct = sizeof(mmixer->controls[ofs].c);
            mmixer->controls[ofs+OFS_MUX].c.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER;
            mmixer->controls[ofs+OFS_MUX].c.dwControlID = ofs+OFS_MUX;
            mmixer->controls[ofs+OFS_MUX].c.fdwControl = MIXERCONTROL_CONTROLF_MULTIPLE;

            for (x = 0; x<mmixer->chans; ++x)
                if (x != id && mmixer->lines[x].dst == id)
                    ++(mmixer->controls[ofs+OFS_MUX].c.cMultipleItems);
            if (!mmixer->controls[ofs+OFS_MUX].c.cMultipleItems)
                mmixer->controls[ofs+OFS_MUX].enabled = 0;

            mmixer->controls[ofs+OFS_MUX].c.Bounds.s1.dwMaximum = mmixer->controls[ofs+OFS_MUX].c.cMultipleItems - 1;
            mmixer->controls[ofs+OFS_MUX].c.Metrics.cSteps = mmixer->controls[ofs+OFS_MUX].c.cMultipleItems;
        }
        for (x=0; x<CONTROLSPERLINE; ++x)
        {
            lstrcpynW(mmixer->controls[ofs+x].c.szShortName, mline->name, sizeof(mmixer->controls[ofs+x].c.szShortName)/sizeof(WCHAR));
            lstrcpynW(mmixer->controls[ofs+x].c.szName, mline->name, sizeof(mmixer->controls[ofs+x].c.szName)/sizeof(WCHAR));
        }
    }
}

/* get amount of channels for elem */
/* Officially we should keep capture/playback separated,
 * but that's not going to work in the alsa api */
static int chans(mixer *mmixer, snd_mixer_elem_t * elem, DWORD capt)
{
    int ret=0, chn;

    if (capt && snd_mixer_selem_has_capture_volume(elem)) {
        for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
            if (snd_mixer_selem_has_capture_channel(elem, chn))
                ++ret;
    } else {
        for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
            if (snd_mixer_selem_has_playback_channel(elem, chn))
                ++ret;
    }
    if (!ret)
        FIXME("Mixer channel %s was found for %s, but no channels were found? Wrong selection!\n", snd_mixer_selem_get_name(elem), (snd_mixer_selem_has_playback_volume(elem) ? "playback" : "capture"));
    return ret;
}

static void filllines(mixer *mmixer, snd_mixer_elem_t *mastelem, snd_mixer_elem_t *captelem, int capt)
{
    snd_mixer_elem_t *elem;
    line *mline = mmixer->lines;

    if (mastelem) {
        /* Master control */
        MultiByteToWideChar(CP_UNIXCP, 0, snd_mixer_selem_get_name(mastelem), -1, mline->name, sizeof(mline->name)/sizeof(WCHAR));
        mline->component = getcomponenttype(snd_mixer_selem_get_name(mastelem));
        mline->dst = 0;
        mline->capt = 0;
        mline->elem = mastelem;
        mline->chans = chans(mmixer, mastelem, 0);

        snd_mixer_elem_set_callback(mastelem, &elem_callback);
        snd_mixer_elem_set_callback_private(mastelem, mmixer);
    } else {
        MultiByteToWideChar(CP_UNIXCP, 0, "Empty Master Element", -1, mline->name, sizeof(mline->name)/sizeof(WCHAR));
    }

    /* Capture control
     * Note: since mmixer->dests = 1, it means only playback control is visible
     * This makes sense, because if there are no capture sources capture control
     * can't do anything and should be invisible */

    /* Control 1 is reserved for capture even when not enabled */
    ++mline;
    if (capt)
    {
        MultiByteToWideChar(CP_UNIXCP, 0, snd_mixer_selem_get_name(captelem), -1, mline->name, sizeof(mline->name)/sizeof(WCHAR));
        mline->component = getcomponenttype(snd_mixer_selem_get_name(captelem));
        mline->dst = 1;
        mline->capt = 1;
        mline->elem = captelem;
        mline->chans = chans(mmixer, captelem, 1);

        snd_mixer_elem_set_callback(captelem, &elem_callback);
        snd_mixer_elem_set_callback_private(captelem, mmixer);
    }

    for (elem = snd_mixer_first_elem(mmixer->mix); elem; elem = snd_mixer_elem_next(elem))
        if (elem != mastelem && elem != captelem && !blacklisted(elem))
        {
            const char * name = snd_mixer_selem_get_name(elem);
            DWORD comp = getcomponenttype(name);

            if (snd_mixer_selem_has_playback_volume(elem) &&
               (snd_mixer_selem_has_capture_volume(elem) || comp != MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE))
            {
                (++mline)->component = comp;
                MultiByteToWideChar(CP_UNIXCP, 0, name, -1, mline->name, MAXPNAMELEN);
                mline->capt = mline->dst = 0;
                mline->elem = elem;
                mline->chans = chans(mmixer, elem, 0);
            }
            else if (!capt)
                continue;

            if (capt && (snd_mixer_selem_has_capture_volume(elem) || comp == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE))
            {
                (++mline)->component = comp;
                MultiByteToWideChar(CP_UNIXCP, 0, name, -1, mline->name, MAXPNAMELEN);
                mline->capt = mline->dst = 1;
                mline->elem = elem;
                mline->chans = chans(mmixer, elem, 1);
            }

            snd_mixer_elem_set_callback(elem, &elem_callback);
            snd_mixer_elem_set_callback_private(elem, mmixer);
        }
}

static void filllines_no_master(mixer *mmixer, snd_mixer_elem_t *captelem, int capt)
{
    line *mline = mmixer->lines;

    MultiByteToWideChar(CP_UNIXCP, 0, snd_mixer_selem_get_name(captelem), -1, mline->name, sizeof(mline->name)/sizeof(WCHAR));
    mline->component = getcomponenttype(snd_mixer_selem_get_name(captelem));
    mline->dst = 0;
    mline->capt = 1;
    mline->elem = captelem;
    mline->chans = chans(mmixer, captelem, 1);

    snd_mixer_elem_set_callback(captelem, &elem_callback);
    snd_mixer_elem_set_callback_private(captelem, mmixer);
}

/* Windows api wants to have a 'master' device to which all slaves are attached
 * There are 2 ones in this code:
 * - 'Master', fall back to 'Headphone' if unavailable, and if that's not available 'PCM'
 * - 'Capture'
 * Capture might not always be available, so should be prepared to be without if needed
 */

static void ALSA_MixerInit(void)
{
    int x, mixnum = 0;
    snd_ctl_card_info_t *info;

    info = HeapAlloc( GetProcessHeap(), 0, snd_ctl_card_info_sizeof());
    for (x = 0; x < MAX_MIXERS; ++x)
    {
        int card, err, capcontrols = 0, total_elems = 0;
        char cardind[6], cardname[10];

        snd_ctl_t *ctl;
        snd_mixer_elem_t *elem, *mastelem = NULL, *headelem = NULL, *captelem = NULL, *pcmelem = NULL, *lineelem = NULL, *micelem = NULL;

        memset(info, 0, snd_ctl_card_info_sizeof());
        memset(&mixdev[mixnum], 0, sizeof(*mixdev));
        snprintf(cardind, sizeof(cardind), "%d", x);
        card = snd_card_get_index(cardind);
        if (card < 0)
            continue;

        snprintf(cardname, sizeof(cardname), "hw:%d", card);

        err = snd_ctl_open(&ctl, cardname, 0);
        if (err < 0)
        {
            WARN("Cannot open card: %s\n", snd_strerror(err));
            continue;
        }

        err = snd_ctl_card_info(ctl, info);
        if (err < 0)
        {
            WARN("Cannot get card info: %s\n", snd_strerror(err));
            snd_ctl_close(ctl);
            continue;
        }

        MultiByteToWideChar(CP_UNIXCP, 0, snd_ctl_card_info_get_name(info), -1, mixdev[mixnum].mixername, sizeof(mixdev[mixnum].mixername)/sizeof(WCHAR));
        snd_ctl_close(ctl);

        err = snd_mixer_open(&mixdev[mixnum].mix, 0);
        if (err < 0)
        {
            WARN("Error occurred opening mixer: %s\n", snd_strerror(err));
            continue;
        }

        err = snd_mixer_attach(mixdev[mixnum].mix, cardname);
        if (err < 0)
            goto eclose;

        err = snd_mixer_selem_register(mixdev[mixnum].mix, NULL, NULL);
        if (err < 0)
            goto eclose;

        err = snd_mixer_load(mixdev[mixnum].mix);
        if (err < 0)
            goto eclose;

        /* First, lets see what's available..
         * If there are multiple Master or Captures, all except 1 will be added as slaves
         */
        total_elems = snd_mixer_get_count(mixdev[mixnum].mix);
        TRACE("Total elems: %d\n", total_elems);

        for (elem = snd_mixer_first_elem(mixdev[mixnum].mix); elem; elem = snd_mixer_elem_next(elem))
            if (!strcasecmp(snd_mixer_selem_get_name(elem), "Master") && !mastelem)
            {
                mastelem = elem;
                ++(mixdev[mixnum].chans);
            }
            else if (!strcasecmp(snd_mixer_selem_get_name(elem), "Capture") && !captelem)
                captelem = elem;
            else if (!strcasecmp(snd_mixer_selem_get_name(elem), "Mic") && !micelem && !mastelem && total_elems == 1)
                /* this is what snd-usb-audio mics look like; just a Mic control and that's it.*/
                micelem = elem;
            else if (!blacklisted(elem))
            {
                DWORD comp = getcomponenttype(snd_mixer_selem_get_name(elem));
                DWORD skip = 0;

                /* Work around buggy drivers: Make this a capture control if the name is recognised as a microphone */
                if (snd_mixer_selem_has_capture_volume(elem))
                    ++capcontrols;
                else if (comp == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
                {
                    ++capcontrols;
                    skip = 1;
                }

                if (!skip && snd_mixer_selem_has_playback_volume(elem))
                {
                    if (!strcasecmp(snd_mixer_selem_get_name(elem), "Headphone") && !headelem)
                        headelem = elem;
                    else if (!strcasecmp(snd_mixer_selem_get_name(elem), "PCM") && !pcmelem)
                        pcmelem = elem;
                    else if (!strcasecmp(snd_mixer_selem_get_name(elem), "Line") && !lineelem)
                        lineelem = elem;
                    ++(mixdev[mixnum].chans);
                }
            }

        /* Add dummy capture channel, wanted by Windows  */
        mixdev[mixnum].chans += 1;

        /* If there is only 'Capture' and 'Master', this device is not worth it */
        if (mixdev[mixnum].chans == 2)
        {
            WARN("No channels found, skipping device!\n");
            goto close;
        }

        /* Master element can't have a capture control in this code, so
         * if Headphone or PCM is promoted to master, unset its capture control */
        if (headelem && !mastelem)
        {
            /* Using 'Headphone' as master device */
            mastelem = headelem;
            capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
        }
        else if (pcmelem && !mastelem)
        {
            /* Use 'PCM' as master device */
            mastelem = pcmelem;
            capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
        }
        else if (lineelem && !mastelem)
        {
            /* Use 'Line' as master device */
            mastelem = lineelem;
            capcontrols -= !!snd_mixer_selem_has_capture_switch(mastelem);
        }
        else if (!mastelem && !captelem && !micelem)
        {
            /* If there is nothing sensible that can act as 'Master' control, something is wrong */
            FIXME("No master control found on %s, disabling mixer\n", snd_ctl_card_info_get_name(info));
            goto close;
        }

        if (!captelem || !capcontrols)
        {
            /* Can't enable capture, so disabling it
             * Note: capture control will still exist because
             * dwLineID 0 and 1 are reserved for Master and Capture
             */
            WARN("No use enabling capture part of mixer, capture control found: %s, amount of capture controls: %d\n",
                 (!captelem ? "no" : "yes"), capcontrols);
            capcontrols = 0;
            mixdev[mixnum].dests = 1;
        }
        else
        {
            mixdev[mixnum].chans += capcontrols;
            mixdev[mixnum].dests = 2;
        }

        mixdev[mixnum].lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(line) * mixdev[mixnum].chans);
        mixdev[mixnum].controls = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(control) * CONTROLSPERLINE*mixdev[mixnum].chans);
        err = -ENOMEM;
        if (!mixdev[mixnum].lines || !mixdev[mixnum].controls)
            goto close;

        if (mastelem)
            filllines(&mixdev[mixnum], mastelem, captelem, capcontrols);
        else if (micelem)
            filllines_no_master(&mixdev[mixnum], micelem, 1);
        fillcontrols(&mixdev[mixnum]);

        TRACE("%s: Amount of controls: %i/%i, name: %s\n", cardname, mixdev[mixnum].dests, mixdev[mixnum].chans, debugstr_w(mixdev[mixnum].mixername));
        mixnum++;
        continue;

        eclose:
        WARN("Error occurred initialising mixer: %s\n", snd_strerror(err));
        close:
        HeapFree(GetProcessHeap(), 0, mixdev[mixnum].lines);
        HeapFree(GetProcessHeap(), 0, mixdev[mixnum].controls);
        snd_mixer_close(mixdev[mixnum].mix);
    }
    cards = mixnum;
    HeapFree( GetProcessHeap(), 0, info );

    /* There is no trouble with already assigning callbacks without initialising critsect:
     * Callbacks only occur when snd_mixer_handle_events is called (only happens in thread)
     */
    InitializeCriticalSection(&elem_crst);
    elem_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ALSA_MIXER.elem_crst");
    TRACE("\n");
}

static void ALSA_MixerExit(void)
{
    int x;

    if (refcnt)
    {
        WARN("Callback thread still alive, terminating uncleanly, refcnt: %d\n", refcnt);
        /* Least we can do is making sure we're not in 'foreign' code */
        EnterCriticalSection(&elem_crst);
        TerminateThread(thread, 1);
        refcnt = 0;
        LeaveCriticalSection(&elem_crst);
    }

    TRACE("Cleaning up\n");

    elem_crst.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&elem_crst);
    for (x = 0; x < cards; ++x)
    {
        snd_mixer_close(mixdev[x].mix);
        HeapFree(GetProcessHeap(), 0, mixdev[x].lines);
        HeapFree(GetProcessHeap(), 0, mixdev[x].controls);
    }
    cards = 0;
}

static mixer* MIX_GetMix(UINT wDevID)
{
    mixer *mmixer;

    if (wDevID >= cards)
    {
        WARN("Invalid mixer id: %d\n", wDevID);
        return NULL;
    }

    mmixer = &mixdev[wDevID];
    return mmixer;
}

/* Since alsa doesn't tell what exactly changed, just assume all affected controls changed */
static int elem_callback(snd_mixer_elem_t *elem, unsigned int type)
{
    mixer *mmixer = snd_mixer_elem_get_callback_private(elem);
    int x;
    BOOL captchanged = 0;

    if (type != SND_CTL_EVENT_MASK_VALUE)
        return 0;

    assert(mmixer);

    EnterCriticalSection(&elem_crst);

    if (!mmixer->callback)
        goto out;

    for (x=0; x<mmixer->chans; ++x)
    {
        const int ofs = CONTROLSPERLINE*x;
        if (elem != mmixer->lines[x].elem)
            continue;

        if (mmixer->lines[x].capt)
            ++captchanged;

        TRACE("Found changed control %s\n", debugstr_w(mmixer->lines[x].name));
        mmixer->callback(mmixer->hmx, MM_MIXM_LINE_CHANGE, mmixer->callbackpriv, x, 0);
        mmixer->callback(mmixer->hmx, MM_MIXM_CONTROL_CHANGE, mmixer->callbackpriv, ofs, 0);

        if (mmixer->controls[ofs+OFS_MUTE].enabled)
            mmixer->callback(mmixer->hmx, MM_MIXM_CONTROL_CHANGE, mmixer->callbackpriv, ofs+OFS_MUTE, 0);
    }
    if (captchanged)
        mmixer->callback(mmixer->hmx, MM_MIXM_CONTROL_CHANGE, mmixer->callbackpriv, CONTROLSPERLINE+OFS_MUX, 0);

    out:
    LeaveCriticalSection(&elem_crst);

    return 0;
}

static DWORD WINAPI ALSA_MixerPollThread(LPVOID lParam)
{
    struct pollfd *pfds = NULL;
    int x, y, err, mcnt, count = 1;

    TRACE("%p\n", lParam);

    for (x = 0; x < cards; ++x)
        count += snd_mixer_poll_descriptors_count(mixdev[x].mix);

    TRACE("Counted %d descriptors\n", count);
    pfds = HeapAlloc(GetProcessHeap(), 0, count * sizeof(struct pollfd));

    if (!pfds)
    {
        WARN("Out of memory\n");
        goto die;
    }

    pfds[0].fd = msg_pipe[0];
    pfds[0].events = POLLIN;

    y = 1;
    for (x = 0; x < cards; ++x)
        y += snd_mixer_poll_descriptors(mixdev[x].mix, &pfds[y], count - y);

    while ((err = poll(pfds, (unsigned int) count, -1)) >= 0 || errno == EINTR || errno == EAGAIN)
    {
        if (pfds[0].revents & POLLIN)
            break;

        mcnt = 1;
        for (x = y = 0; x < cards; ++x)
        {
            int j, max = snd_mixer_poll_descriptors_count(mixdev[x].mix);
            for (j = 0; j < max; ++j)
                if (pfds[mcnt+j].revents)
                {
                    y += snd_mixer_handle_events(mixdev[x].mix);
                    break;
                }
            mcnt += max;
        }
        if (y)
            TRACE("Handled %d events\n", y);
    }

    die:
    TRACE("Shutting down\n");
    HeapFree(GetProcessHeap(), 0, pfds);

    y = read(msg_pipe[0], &x, sizeof(x));
    close(msg_pipe[1]);
    close(msg_pipe[0]);
    return 0;
}

static DWORD MIX_Open(UINT wDevID, LPMIXEROPENDESC desc, DWORD_PTR flags)
{
    mixer *mmixer = MIX_GetMix(wDevID);
    if (!mmixer)
        return MMSYSERR_BADDEVICEID;

    flags &= CALLBACK_TYPEMASK;
    switch (flags)
    {
    case CALLBACK_NULL:
        goto done;

    case CALLBACK_FUNCTION:
        break;

    default:
        FIXME("Unhandled callback type: %08lx\n", flags & CALLBACK_TYPEMASK);
        return MIXERR_INVALVALUE;
    }

    mmixer->callback = (LPDRVCALLBACK)desc->dwCallback;
    mmixer->callbackpriv = desc->dwInstance;
    mmixer->hmx = (HDRVR)desc->hmx;

    done:
    if (InterlockedIncrement(&refcnt) == 1)
    {
        if (pipe(msg_pipe) >= 0)
        {
            thread = CreateThread(NULL, 0, ALSA_MixerPollThread, NULL, 0, NULL);
            if (!thread)
            {
                close(msg_pipe[0]);
                close(msg_pipe[1]);
                msg_pipe[0] = msg_pipe[1] = -1;
            }
        }
        else
            msg_pipe[0] = msg_pipe[1] = -1;
    }

    return MMSYSERR_NOERROR;
}

static DWORD MIX_Close(UINT wDevID)
{
    int x = 0;
    mixer *mmixer = MIX_GetMix(wDevID);
    if (!mmixer)
        return MMSYSERR_BADDEVICEID;

    EnterCriticalSection(&elem_crst);
    mmixer->callback = 0;
    LeaveCriticalSection(&elem_crst);

    if (!InterlockedDecrement(&refcnt))
    {
        if (write(msg_pipe[1], &x, sizeof(x)) > 0)
        {
            TRACE("Shutting down thread...\n");
            WaitForSingleObject(thread, INFINITE);
            TRACE("Done\n");
        }
    }

    return MMSYSERR_NOERROR;
}

static DWORD MIX_GetDevCaps(UINT wDevID, LPMIXERCAPS2W caps, DWORD_PTR parm2)
{
    mixer *mmixer = MIX_GetMix(wDevID);
    MIXERCAPS2W capsW;

    if (!caps)
        return MMSYSERR_INVALPARAM;

    if (!mmixer)
        return MMSYSERR_BADDEVICEID;

    memset(&capsW, 0, sizeof(MIXERCAPS2W));

    capsW.wMid = WINE_MIXER_MANUF_ID;
    capsW.wPid = WINE_MIXER_PRODUCT_ID;
    capsW.vDriverVersion = WINE_MIXER_VERSION;

    lstrcpynW(capsW.szPname, mmixer->mixername, sizeof(capsW.szPname)/sizeof(WCHAR));
    capsW.cDestinations = mmixer->dests;
    memcpy(caps, &capsW, min(parm2, sizeof(capsW)));
    return MMSYSERR_NOERROR;
}

/* convert win32 volume to alsa volume, and vice versa */
static INT normalized(INT value, INT prevmax, INT nextmax)
{
    int ret = MulDiv(value, nextmax, prevmax);

    /* Have to stay in range */
    TRACE("%d/%d -> %d/%d\n", value, prevmax, ret, nextmax);
    if (ret > nextmax)
        ret = nextmax;
    else if (ret < 0)
        ret = 0;

    return ret;
}

/* get amount of sources for dest */
static int getsrccntfromchan(mixer *mmixer, int dad)
{
    int i, j=0;

    for (i=0; i<mmixer->chans; ++i)
        if (i != dad && mmixer->lines[i].dst == dad)
        {
            ++j;
        }
    if (!j)
        FIXME("No src found for %i (%s)?\n", dad, debugstr_w(mmixer->lines[dad].name));
    return j;
}

/* find lineid for source 'num' with dest 'dad' */
static int getsrclinefromchan(mixer *mmixer, int dad, int num)
{
    int i, j=0;
    for (i=0; i<mmixer->chans; ++i)
        if (i != dad && mmixer->lines[i].dst == dad)
        {
            if (num == j)
                return i;
            ++j;
        }
    WARN("No src found for src %i from dest %i\n", num, dad);
    return 0;
}

/* get the source number belonging to line */
static int getsrcfromline(mixer *mmixer, int line)
{
    int i, j=0, dad = mmixer->lines[line].dst;

    for (i=0; i<mmixer->chans; ++i)
        if (i != dad && mmixer->lines[i].dst == dad)
        {
            if (line == i)
                return j;
            ++j;
        }
    WARN("No src found for line %i with dad %i\n", line, dad);
    return 0;
}

/* Get volume/muted/capture channel */
static DWORD MIX_GetControlDetails(UINT wDevID, LPMIXERCONTROLDETAILS mctrld, DWORD_PTR flags)
{
    mixer *mmixer = MIX_GetMix(wDevID);
    DWORD ctrl;
    DWORD line;
    control *ct;

    if (!mctrld)
        return MMSYSERR_INVALPARAM;

    ctrl = mctrld->dwControlID;
    line = ctrl/CONTROLSPERLINE;

    if (mctrld->cbStruct != sizeof(*mctrld))
        return MMSYSERR_INVALPARAM;

    if (!mmixer)
        return MMSYSERR_BADDEVICEID;

    if (line >= mmixer->chans || !mmixer->controls[ctrl].enabled)
        return MIXERR_INVALCONTROL;

    ct = &mmixer->controls[ctrl];

    flags &= MIXER_GETCONTROLDETAILSF_QUERYMASK;

    switch (flags) {
    case MIXER_GETCONTROLDETAILSF_VALUE:
        TRACE("MIXER_GETCONTROLDETAILSF_VALUE (%d/%d)\n", ctrl, line);
        switch (ct->c.dwControlType)
        {
        case MIXERCONTROL_CONTROLTYPE_VOLUME:
        {
            long min = 0, max = 0, vol = 0;
            int chn;
            LPMIXERCONTROLDETAILS_UNSIGNED mcdu;
            snd_mixer_elem_t * elem = mmixer->lines[line].elem;

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

            TRACE("%s MIXERCONTROLDETAILS_UNSIGNED[%u]\n", getControlType(ct->c.dwControlType), mctrld->cChannels);

            mcdu = mctrld->paDetails;

            if (mctrld->cChannels != 1 && mmixer->lines[line].chans != mctrld->cChannels)
            {
                WARN("Unsupported cChannels (%d instead of %d)\n", mctrld->cChannels, mmixer->lines[line].chans);
                return MMSYSERR_INVALPARAM;
            }

            if (mmixer->lines[line].capt && snd_mixer_selem_has_capture_volume(elem)) {
                snd_mixer_selem_get_capture_volume_range(elem, &min, &max);
                for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                    if (snd_mixer_selem_has_capture_channel(elem, chn))
                    {
                        snd_mixer_selem_get_capture_volume(elem, chn, &vol);
                        mcdu->dwValue = normalized(vol - min, max, 65535);
                        if (mctrld->cChannels == 1)
                            break;
                        ++mcdu;
                    }
            } else {
                snd_mixer_selem_get_playback_volume_range(elem, &min, &max);

                for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                    if (snd_mixer_selem_has_playback_channel(elem, chn))
                    {
                        snd_mixer_selem_get_playback_volume(elem, chn, &vol);
                        mcdu->dwValue = normalized(vol - min, max, 65535);
                        if (mctrld->cChannels == 1)
                            break;
                        ++mcdu;
                    }
            }

            return MMSYSERR_NOERROR;
        }

        case MIXERCONTROL_CONTROLTYPE_ONOFF:
        case MIXERCONTROL_CONTROLTYPE_MUTE:
        {
            LPMIXERCONTROLDETAILS_BOOLEAN mcdb;
            int chn, ival;
            snd_mixer_elem_t * elem = mmixer->lines[line].elem;

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

            TRACE("%s MIXERCONTROLDETAILS_BOOLEAN[%u]\n", getControlType(ct->c.dwControlType), mctrld->cChannels);

            mcdb = mctrld->paDetails;

            if (line == 1)
                for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                {
                    if (!snd_mixer_selem_has_capture_channel(elem, chn))
                        continue;
                    snd_mixer_selem_get_capture_switch(elem, chn, &ival);
                    break;
                }
            else
                for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                {
                    if (!snd_mixer_selem_has_playback_channel(elem, chn))
                        continue;
                    snd_mixer_selem_get_playback_switch(elem, chn, &ival);
                    break;
                }

	    if (chn > SND_MIXER_SCHN_LAST)
	    {
		TRACE("can't find active channel\n");
		return MMSYSERR_INVALPARAM;  /* fixme: what's right error? */
	    }

            mcdb->fValue = !ival;
            TRACE("=> %s\n", mcdb->fValue ? "on" : "off");
            return MMSYSERR_NOERROR;
        }
        case MIXERCONTROL_CONTROLTYPE_MIXER:
        case MIXERCONTROL_CONTROLTYPE_MUX:
        {
            LPMIXERCONTROLDETAILS_BOOLEAN mcdb;
            int x, i=0, ival = 0, chn;

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

            TRACE("%s MIXERCONTROLDETAILS_BOOLEAN[%u]\n", getControlType(ct->c.dwControlType), mctrld->cChannels);

            mcdb = mctrld->paDetails;

            for (x = 0; x<mmixer->chans; ++x)
                if (line != x && mmixer->lines[x].dst == line)
                {
                    ival = 0;
                    for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                    {
                        if (!snd_mixer_selem_has_capture_channel(mmixer->lines[x].elem, chn))
                            continue;
                        snd_mixer_selem_get_capture_switch(mmixer->lines[x].elem, chn, &ival);
                        if (ival)
                            break;
                    }
                    if (i >= mctrld->u.cMultipleItems)
                    {
                        TRACE("overflow\n");
                        return MMSYSERR_INVALPARAM;
                    }
                    TRACE("fVal[%i] = %sselected\n", i, (!ival ? "un" : ""));
                    mcdb[i++].fValue = ival;
                }
            break;
        }
        default:

            FIXME("Unhandled controltype %s\n", getControlType(ct->c.dwControlType));
            return MMSYSERR_INVALPARAM;
        }
        return MMSYSERR_NOERROR;

    case MIXER_GETCONTROLDETAILSF_LISTTEXT:
        TRACE("MIXER_GETCONTROLDETAILSF_LISTTEXT (%d)\n", ctrl);

        if (ct->c.dwControlType == MIXERCONTROL_CONTROLTYPE_MUX || ct->c.dwControlType == MIXERCONTROL_CONTROLTYPE_MIXER)
        {
            LPMIXERCONTROLDETAILS_LISTTEXTW mcdlt = mctrld->paDetails;
            int i, j;

            for (i = j = 0; j < mmixer->chans; ++j)
                if (j != line && mmixer->lines[j].dst == line)
                {
                    if (i > mctrld->u.cMultipleItems)
                        return MMSYSERR_INVALPARAM;
                    mcdlt->dwParam1 = j;
                    mcdlt->dwParam2 = mmixer->lines[j].component;
                    lstrcpynW(mcdlt->szName, mmixer->lines[j].name, sizeof(mcdlt->szName) / sizeof(WCHAR));
                    TRACE("Adding %i as %s\n", j, debugstr_w(mcdlt->szName));
                    ++i; ++mcdlt;
                }
            if (i < mctrld->u.cMultipleItems)
                return MMSYSERR_INVALPARAM;
            return MMSYSERR_NOERROR;
        }
        FIXME ("Imagine this code being horribly broken and incomplete, introducing: reality\n");
        return MMSYSERR_INVALPARAM;

    default:
        WARN("Unknown flag (%08lx)\n", flags);
        return MMSYSERR_INVALPARAM;
    }
}

/* Set volume/capture channel/muted for control */
static DWORD MIX_SetControlDetails(UINT wDevID, LPMIXERCONTROLDETAILS mctrld, DWORD_PTR flags)
{
    mixer *mmixer = MIX_GetMix(wDevID);
    DWORD ctrl, line, i;
    control *ct;
    snd_mixer_elem_t * elem;

    if (!mctrld)
        return MMSYSERR_INVALPARAM;

    ctrl = mctrld->dwControlID;
    line = ctrl/CONTROLSPERLINE;

    if (mctrld->cbStruct != sizeof(*mctrld))
    {
        WARN("Invalid size of mctrld %d\n", mctrld->cbStruct);
        return MMSYSERR_INVALPARAM;
    }

    if (!mmixer)
        return MMSYSERR_BADDEVICEID;

    if (line >= mmixer->chans)
    {
        WARN("Invalid line id: %d not in range of 0-%d\n", line, mmixer->chans-1);
        return MMSYSERR_INVALPARAM;
    }

    if (!mmixer->controls[ctrl].enabled)
    {
        WARN("Control %d not enabled\n", ctrl);
        return MIXERR_INVALCONTROL;
    }

    ct = &mmixer->controls[ctrl];
    elem = mmixer->lines[line].elem;
    flags &= MIXER_SETCONTROLDETAILSF_QUERYMASK;

    switch (flags) {
    case MIXER_SETCONTROLDETAILSF_VALUE:
        TRACE("MIXER_SETCONTROLDETAILSF_VALUE (%d)\n", ctrl);
        break;

    default:
        WARN("Unknown flag (%08lx)\n", flags);
        return MMSYSERR_INVALPARAM;
    }

    switch (ct->c.dwControlType)
    {
    case MIXERCONTROL_CONTROLTYPE_VOLUME:
    {
        long min = 0, max = 0;
        int chn;
        LPMIXERCONTROLDETAILS_UNSIGNED mcdu;
        snd_mixer_elem_t * elem = mmixer->lines[line].elem;

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

        if (mctrld->cChannels != 1 && mmixer->lines[line].chans != mctrld->cChannels)
        {
            WARN("Unsupported cChannels (%d instead of %d)\n", mctrld->cChannels, mmixer->lines[line].chans);
            return MMSYSERR_INVALPARAM;
        }

        TRACE("%s MIXERCONTROLDETAILS_UNSIGNED[%u]\n", getControlType(ct->c.dwControlType), mctrld->cChannels);
        mcdu = mctrld->paDetails;

        for (chn=0; chn<mctrld->cChannels;++chn)
        {
            TRACE("Chan %d value %d\n", chn, mcdu[chn].dwValue);
        }

        /* There isn't always a capture volume, so in that case change playback volume */
        if (mmixer->lines[line].capt && snd_mixer_selem_has_capture_volume(elem))
        {
            snd_mixer_selem_get_capture_volume_range(elem, &min, &max);

            for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                if (snd_mixer_selem_has_capture_channel(elem, chn))
                {
                    snd_mixer_selem_set_capture_volume(elem, chn, min + normalized(mcdu->dwValue, 65535, max));
                    if (mctrld->cChannels != 1)
                        mcdu++;
                }
        }
        else
        {
            snd_mixer_selem_get_playback_volume_range(elem, &min, &max);

            for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                if (snd_mixer_selem_has_playback_channel(elem, chn))
                {
                    snd_mixer_selem_set_playback_volume(elem, chn, min + normalized(mcdu->dwValue, 65535, max));
                    if (mctrld->cChannels != 1)
                        mcdu++;
                }
        }

        break;
    }
    case MIXERCONTROL_CONTROLTYPE_MUTE:
    case MIXERCONTROL_CONTROLTYPE_ONOFF:
    {
        LPMIXERCONTROLDETAILS_BOOLEAN	mcdb;

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

        TRACE("%s MIXERCONTROLDETAILS_BOOLEAN[%u]\n", getControlType(ct->c.dwControlType), mctrld->cChannels);

        mcdb = mctrld->paDetails;
        if (line == 1) /* Mute/unmute capturing */
            for (i = 0; i <= SND_MIXER_SCHN_LAST; ++i)
            {
                if (snd_mixer_selem_has_capture_channel(elem, i))
                    snd_mixer_selem_set_capture_switch(elem, i, !mcdb->fValue);
            }
        else
            for (i = 0; i <= SND_MIXER_SCHN_LAST; ++i)
                if (snd_mixer_selem_has_playback_channel(elem, i))
                    snd_mixer_selem_set_playback_switch(elem, i, !mcdb->fValue);
        break;
    }

    case MIXERCONTROL_CONTROLTYPE_MIXER:
    case MIXERCONTROL_CONTROLTYPE_MUX:
    {
        LPMIXERCONTROLDETAILS_BOOLEAN mcdb;
        int x, i=0, chn;
        int didone = 0, canone = (ct->c.dwControlType == MIXERCONTROL_CONTROLTYPE_MUX);

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

        TRACE("%s MIXERCONTROLDETAILS_BOOLEAN[%u]\n", getControlType(ct->c.dwControlType), mctrld->cChannels);
        mcdb = mctrld->paDetails;

        for (x=i=0; x < mmixer->chans; ++x)
            if (line != x && mmixer->lines[x].dst == line)
            {
                TRACE("fVal[%i] (%s) = %i\n", i, debugstr_w(mmixer->lines[x].name), mcdb[i].fValue);
                if (i >= mctrld->u.cMultipleItems)
                {
                    TRACE("Too many items to fit, overflowing\n");
                    return MIXERR_INVALVALUE;
                }
                if (mcdb[i].fValue && canone && didone)
                {
                    TRACE("Nice try, but it's not going to work\n");
                    elem_callback(mmixer->lines[1].elem, SND_CTL_EVENT_MASK_VALUE);
                    return MIXERR_INVALVALUE;
                }
                if (mcdb[i].fValue)
                    didone = 1;
                ++i;
            }

        if (canone && !didone)
        {
            TRACE("Nice try, this is not going to work either\n");
            elem_callback(mmixer->lines[1].elem, SND_CTL_EVENT_MASK_VALUE);
            return MIXERR_INVALVALUE;
        }

        for (x = i = 0; x<mmixer->chans; ++x)
            if (line != x && mmixer->lines[x].dst == line)
            {
                if (mcdb[i].fValue)
                    for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                    {
                        if (!snd_mixer_selem_has_capture_channel(mmixer->lines[x].elem, chn))
                            continue;
                        snd_mixer_selem_set_capture_switch(mmixer->lines[x].elem, chn, mcdb[i].fValue);
                    }
                ++i;
            }

        /* If it's a MUX, it means that only 1 channel can be selected
         * and the other channels are unselected
         *
         * For MIXER multiple sources are allowed, so unselect here
         */
        if (canone)
            break;

        for (x = i = 0; x<mmixer->chans; ++x)
            if (line != x && mmixer->lines[x].dst == line)
            {
                if (!mcdb[i].fValue)
                    for (chn = 0; chn <= SND_MIXER_SCHN_LAST; ++chn)
                    {
                        if (!snd_mixer_selem_has_capture_channel(mmixer->lines[x].elem, chn))
                            continue;
                        snd_mixer_selem_set_capture_switch(mmixer->lines[x].elem, chn, mcdb[i].fValue);
                    }
                ++i;
            }
        break;
    }
    default:
        FIXME("Unhandled type %s\n", getControlType(ct->c.dwControlType));
        return MMSYSERR_INVALPARAM;
    }
    return MMSYSERR_NOERROR;
}

/* Here we give info over the source/dest line given by dwSource+dwDest or dwDest, respectively
 * It is also possible that a line is found by componenttype or target type, latter is not implemented yet
 * Most important values returned in struct:
 * dwLineID
 * sz(Short)Name
 * line control count
 * amount of channels
 */
static DWORD MIX_GetLineInfo(UINT wDevID, LPMIXERLINEW Ml, DWORD_PTR flags)
{
    DWORD_PTR qf = flags & MIXER_GETLINEINFOF_QUERYMASK;
    mixer *mmixer = MIX_GetMix(wDevID);
    line *mline;
    int idx, i;

    if (!Ml)
    {
        WARN("No Ml\n");
        return MMSYSERR_INVALPARAM;
    }

    if (!mmixer)
    {
        WARN("Device %u not found\n", wDevID);
        return MMSYSERR_BADDEVICEID;
    }

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

    Ml->dwUser  = 0;
    Ml->fdwLine = MIXERLINE_LINEF_DISCONNECTED;
    switch (qf)
    {
    case MIXER_GETLINEINFOF_COMPONENTTYPE:
    {
        Ml->dwLineID = 0xFFFF;
        TRACE("Looking for componenttype %d/%x\n", Ml->dwComponentType, Ml->dwComponentType);
        for (idx = 0; idx < mmixer->chans; ++idx)
            if (mmixer->lines[idx].component == Ml->dwComponentType)
            {
                Ml->dwLineID = idx;
                break;
            }
        if (Ml->dwLineID == 0xFFFF)
            return MMSYSERR_KEYNOTFOUND;
        /* Now that we have lineid, fallback to lineid*/
    }

    case MIXER_GETLINEINFOF_LINEID:
        if (Ml->dwLineID >= mmixer->chans)
            return MIXERR_INVALLINE;

        TRACE("MIXER_GETLINEINFOF_LINEID %d\n", Ml->dwLineID);
        Ml->dwDestination = mmixer->lines[Ml->dwLineID].dst;

        if (Ml->dwDestination != Ml->dwLineID)
        {
            Ml->dwSource = getsrcfromline(mmixer, Ml->dwLineID);
            Ml->cConnections = 1;
        }
        else
        {
            Ml->cConnections = getsrccntfromchan(mmixer, Ml->dwLineID);
            Ml->dwSource = 0xFFFFFFFF;
        }
        TRACE("Connections %d, source %d\n", Ml->cConnections, Ml->dwSource);
        break;

    case MIXER_GETLINEINFOF_DESTINATION:
        if (Ml->dwDestination >= mmixer->dests)
        {
            WARN("dest %d out of bounds\n", Ml->dwDestination);
            return MIXERR_INVALLINE;
        }

        Ml->dwLineID = Ml->dwDestination;
        Ml->cConnections = getsrccntfromchan(mmixer, Ml->dwLineID);
        Ml->dwSource = 0xFFFFFFFF;
        break;

    case MIXER_GETLINEINFOF_SOURCE:
        if (Ml->dwDestination >= mmixer->dests)
        {
            WARN("dest %d for source out of bounds\n", Ml->dwDestination);
            return MIXERR_INVALLINE;
        }

        if (Ml->dwSource >= getsrccntfromchan(mmixer, Ml->dwDestination))
        {
            WARN("src %d out of bounds\n", Ml->dwSource);
            return MIXERR_INVALLINE;
        }

        Ml->dwLineID = getsrclinefromchan(mmixer, Ml->dwDestination, Ml->dwSource);
        Ml->cConnections = 1;
        break;

    case MIXER_GETLINEINFOF_TARGETTYPE:
        FIXME("TODO: TARGETTYPE, stub\n");
        return MMSYSERR_INVALPARAM;

    default:
        FIXME("Unknown query flag: %08lx\n", qf);
        return MMSYSERR_INVALPARAM;
    }

    Ml->fdwLine &= ~MIXERLINE_LINEF_DISCONNECTED;
    Ml->fdwLine |= MIXERLINE_LINEF_ACTIVE;
    if (Ml->dwLineID >= mmixer->dests)
        Ml->fdwLine |= MIXERLINE_LINEF_SOURCE;

    mline = &mmixer->lines[Ml->dwLineID];
    Ml->dwComponentType = mline->component;
    Ml->cChannels = mmixer->lines[Ml->dwLineID].chans;
    Ml->cControls = 0;

    for (i=CONTROLSPERLINE*Ml->dwLineID;i<CONTROLSPERLINE*(Ml->dwLineID+1); ++i)
        if (mmixer->controls[i].enabled)
            ++(Ml->cControls);

    lstrcpynW(Ml->szShortName, mmixer->lines[Ml->dwLineID].name, sizeof(Ml->szShortName)/sizeof(WCHAR));
    lstrcpynW(Ml->szName, mmixer->lines[Ml->dwLineID].name, sizeof(Ml->szName)/sizeof(WCHAR));
    if (mline->capt)
        Ml->Target.dwType = MIXERLINE_TARGETTYPE_WAVEIN;
    else
        Ml->Target.dwType = MIXERLINE_TARGETTYPE_WAVEOUT;
    Ml->Target.dwDeviceID = 0xFFFFFFFF;
    Ml->Target.wMid = WINE_MIXER_MANUF_ID;
    Ml->Target.wPid = WINE_MIXER_PRODUCT_ID;
    Ml->Target.vDriverVersion = WINE_MIXER_VERSION;
    lstrcpynW(Ml->Target.szPname, mmixer->mixername, sizeof(Ml->Target.szPname)/sizeof(WCHAR));
    return MMSYSERR_NOERROR;
}

/* Get the controls that belong to a certain line, either all or 1 */
static DWORD MIX_GetLineControls(UINT wDevID, LPMIXERLINECONTROLSW mlc, DWORD_PTR flags)
{
    mixer *mmixer = MIX_GetMix(wDevID);
    int i,j = 0;
    DWORD ct;

    if (!mlc || mlc->cbStruct != sizeof(*mlc))
    {
        WARN("Invalid mlc %p, cbStruct: %d\n", mlc, (!mlc ? -1 : mlc->cbStruct));
        return MMSYSERR_INVALPARAM;
    }

    if (mlc->cbmxctrl != sizeof(MIXERCONTROLW))
    {
        WARN("cbmxctrl %d\n", mlc->cbmxctrl);
        return MMSYSERR_INVALPARAM;
    }

    if (!mmixer)
        return MMSYSERR_BADDEVICEID;

    flags &= MIXER_GETLINECONTROLSF_QUERYMASK;

    if (flags == MIXER_GETLINECONTROLSF_ONEBYID)
        mlc->dwLineID = mlc->u.dwControlID / CONTROLSPERLINE;

    if (mlc->dwLineID >= mmixer->chans)
    {
        TRACE("Invalid dwLineID %d\n", mlc->dwLineID);
        return MIXERR_INVALLINE;
    }

    switch (flags)
    {
    case MIXER_GETLINECONTROLSF_ALL:
       TRACE("line=%08x MIXER_GETLINECONTROLSF_ALL (%d)\n", mlc->dwLineID, mlc->cControls);
       for (i = 0; i < CONTROLSPERLINE; ++i)
           if (mmixer->controls[i+mlc->dwLineID * CONTROLSPERLINE].enabled)
           {
               memcpy(&mlc->pamxctrl[j], &mmixer->controls[i+mlc->dwLineID * CONTROLSPERLINE].c, sizeof(MIXERCONTROLW));
               TRACE("Added %s (%s)\n", debugstr_w(mlc->pamxctrl[j].szShortName), debugstr_w(mlc->pamxctrl[j].szName));
               ++j;
               if (j > mlc->cControls)
               {
                   WARN("invalid parameter\n");
                   return MMSYSERR_INVALPARAM;
               }
           }

        if (!j || mlc->cControls > j)
        {
            WARN("invalid parameter\n");
            return MMSYSERR_INVALPARAM;
        }
        break;
    case MIXER_GETLINECONTROLSF_ONEBYID:
        TRACE("line=%08x MIXER_GETLINECONTROLSF_ONEBYID (%x)\n", mlc->dwLineID, mlc->u.dwControlID);

        if (!mmixer->controls[mlc->u.dwControlID].enabled)
           return MIXERR_INVALCONTROL;

        mlc->pamxctrl[0] = mmixer->controls[mlc->u.dwControlID].c;
        break;
    case MIXER_GETLINECONTROLSF_ONEBYTYPE:
        TRACE("line=%08x MIXER_GETLINECONTROLSF_ONEBYTYPE (%s)\n", mlc->dwLineID, getControlType(mlc->u.dwControlType));

        ct = mlc->u.dwControlType & MIXERCONTROL_CT_CLASS_MASK;
        for (i = 0; i <= CONTROLSPERLINE; ++i)
        {
            const int ofs = i+mlc->dwLineID*CONTROLSPERLINE;
            if (i == CONTROLSPERLINE)
            {
                WARN("invalid parameter: control %s not found\n", getControlType(mlc->u.dwControlType));
                return MIXERR_INVALCONTROL;
            }
            if (mmixer->controls[ofs].enabled && (mmixer->controls[ofs].c.dwControlType & MIXERCONTROL_CT_CLASS_MASK) == ct)
            {
                mlc->pamxctrl[0] = mmixer->controls[ofs].c;
                break;
            }
        }
    break;
    default:
        FIXME("Unknown flag %08lx\n", flags & MIXER_GETLINECONTROLSF_QUERYMASK);
        return MMSYSERR_INVALPARAM;
    }

    return MMSYSERR_NOERROR;
}

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

    switch (wMsg)
    {
    case DRVM_INIT: ALSA_MixerInit(); ret = MMSYSERR_NOERROR; break;
    case DRVM_EXIT: ALSA_MixerExit(); ret = MMSYSERR_NOERROR; break;
    /* All taken care of by driver initialisation */
    /* Unimplemented, and not needed */
    case DRVM_ENABLE:
    case DRVM_DISABLE:
        ret = MMSYSERR_NOERROR; break;

    case MXDM_OPEN:
        ret = MIX_Open(wDevID, (LPMIXEROPENDESC) dwParam1, dwParam2); break;

    case MXDM_CLOSE:
        ret = MIX_Close(wDevID); break;

    case MXDM_GETDEVCAPS:
        ret = MIX_GetDevCaps(wDevID, (LPMIXERCAPS2W)dwParam1, dwParam2); break;

    case MXDM_GETLINEINFO:
        ret = MIX_GetLineInfo(wDevID, (LPMIXERLINEW)dwParam1, dwParam2); break;

    case MXDM_GETLINECONTROLS:
        ret = MIX_GetLineControls(wDevID, (LPMIXERLINECONTROLSW)dwParam1, dwParam2); break;

    case MXDM_GETCONTROLDETAILS:
        ret = MIX_GetControlDetails(wDevID, (LPMIXERCONTROLDETAILS)dwParam1, dwParam2); break;

    case MXDM_SETCONTROLDETAILS:
        ret = MIX_SetControlDetails(wDevID, (LPMIXERCONTROLDETAILS)dwParam1, dwParam2); break;

    case MXDM_GETNUMDEVS:
        ret = cards; break;

    default:
        WARN("unknown message %s!\n", getMessage(wMsg));
        return MMSYSERR_NOTSUPPORTED;
    }

    TRACE("Returning %08X\n", ret);
    return ret;
}
