/*
 * 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 "mmsystem.h"
#include "alsa.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(mixer);

#ifdef HAVE_ALSA

#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, 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, *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;
                    ++(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 (!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;
}

#endif /*HAVE_ALSA*/

/**************************************************************************
 *                        mxdMessage (WINEALSA.3)
 */
DWORD WINAPI ALSA_mxdMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser,
                             DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
#ifdef HAVE_ALSA
    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;
#else /*HAVE_ALSA*/
    TRACE("(%04X, %04X, %08lX, %08lX, %08lX);\n", wDevID, wMsg, dwUser, dwParam1, dwParam2);

    return MMSYSERR_NOTENABLED;
#endif /*HAVE_ALSA*/
}
