/*
 * Sample Wine Driver for Advanced Linux Sound System (ALSA)
 *      Based on version <final> of the ALSA API
 *
 * This file performs the initialisation and scanning of the sound subsystem.
 *
 * Copyright    2002 Eric Pouech
 *              2002 Marco Pietrobono
 *              2003 Christian Costa : WaveIn support
 *              2006-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 <errno.h>
#include <limits.h>
#include <fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winerror.h"
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "mmddk.h"

/* ksmedia.h defines KSDATAFORMAT_SUBTYPE_PCM and KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
 * However either all files that use it will define it, or no files will
 * The only way to solve this is by adding initguid.h here, and include the guid that way
 */
#include "initguid.h"
#include "alsa.h"

#include "wine/library.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wave);

#ifdef HAVE_ALSA

/*----------------------------------------------------------------------------
**  ALSA_TestDeviceForWine
**
**      Test to see if a given device is sufficient for Wine.
*/
static int ALSA_TestDeviceForWine(int card, int device,  snd_pcm_stream_t streamtype)
{
    snd_pcm_t *pcm = NULL;
    char pcmname[256];
    int retcode;
    snd_pcm_hw_params_t *hwparams;
    const char *reason = NULL;
    unsigned int rrate;

    /* Note that the plug: device masks out a lot of info, we want to avoid that */
    sprintf(pcmname, "hw:%d,%d", card, device);
    retcode = snd_pcm_open(&pcm, pcmname, streamtype, SND_PCM_NONBLOCK);
    if (retcode < 0)
    {
        /* Note that a busy device isn't automatically disqualified */
        if (retcode == (-1 * EBUSY))
            retcode = 0;
        goto exit;
    }

    snd_pcm_hw_params_alloca(&hwparams);

    retcode = snd_pcm_hw_params_any(pcm, hwparams);
    if (retcode < 0)
    {
        reason = "Could not retrieve hw_params";
        goto exit;
    }

    /* set the count of channels */
    retcode = snd_pcm_hw_params_set_channels(pcm, hwparams, 2);
    if (retcode < 0)
    {
        reason = "Could not set channels";
        goto exit;
    }

    rrate = 44100;
    retcode = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rrate, 0);
    if (retcode < 0)
    {
        reason = "Could not set rate";
        goto exit;
    }

    if (rrate == 0)
    {
        reason = "Rate came back as 0";
        goto exit;
    }

    /* write the parameters to device */
    retcode = snd_pcm_hw_params(pcm, hwparams);
    if (retcode < 0)
    {
        reason = "Could not set hwparams";
        goto exit;
    }

    retcode = 0;

exit:
    if (pcm)
        snd_pcm_close(pcm);

    if (retcode != 0 && retcode != (-1 * ENOENT))
        TRACE("Discarding card %d/device %d:  %s [%d(%s)]\n", card, device, reason, retcode, snd_strerror(retcode));

    return retcode;
}

/*----------------------------------------------------------------------------
** ALSA_RegGetString
**  Retrieve a string from a registry key
*/
static int ALSA_RegGetString(HKEY key, const char *value, char **bufp)
{
    DWORD rc;
    DWORD type;
    DWORD bufsize;

    *bufp = NULL;
    rc = RegQueryValueExA(key, value, NULL, &type, NULL, &bufsize);
    if (rc != ERROR_SUCCESS)
        return(rc);

    if (type != REG_SZ)
        return 1;

    *bufp = HeapAlloc(GetProcessHeap(), 0, bufsize);
    if (! *bufp)
        return 1;

    rc = RegQueryValueExA(key, value, NULL, NULL, (LPBYTE)*bufp, &bufsize);
    return rc;
}

/*----------------------------------------------------------------------------
** ALSA_RegGetBoolean
**  Get a string and interpret it as a boolean
*/

/* Possible truths:
   Y(es), T(rue), 1, E(nabled) */

#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1' || (ch) == 'e' || (ch) == 'E')
static int ALSA_RegGetBoolean(HKEY key, const char *value, BOOL *answer)
{
    DWORD rc;
    char *buf = NULL;

    rc = ALSA_RegGetString(key, value, &buf);
    if (buf)
    {
        *answer = FALSE;
        if (IS_OPTION_TRUE(*buf))
            *answer = TRUE;

        HeapFree(GetProcessHeap(), 0, buf);
    }

    return rc;
}

/*----------------------------------------------------------------------------
** ALSA_RegGetBoolean
**  Get a string and interpret it as a DWORD
*/
static int ALSA_RegGetInt(HKEY key, const char *value, DWORD *answer)
{
    DWORD rc;
    char *buf = NULL;

    rc = ALSA_RegGetString(key, value, &buf);
    if (buf)
    {
        *answer = atoi(buf);
        HeapFree(GetProcessHeap(), 0, buf);
    }

    return rc;
}

/* return a string duplicated on the win32 process heap, free with HeapFree */
static char* ALSA_strdup(const char *s) {
    char *result = HeapAlloc(GetProcessHeap(), 0, strlen(s)+1);
    if (!result)
        return NULL;
    strcpy(result, s);
    return result;
}

#define ALSA_RETURN_ONFAIL(mycall)                                      \
{                                                                       \
    int rc;                                                             \
    {rc = mycall;}                                                      \
    if ((rc) < 0)                                                       \
    {                                                                   \
        ERR("%s failed:  %s(%d)\n", #mycall, snd_strerror(rc), rc);     \
        return(rc);                                                     \
    }                                                                   \
}

/*----------------------------------------------------------------------------
**  ALSA_ComputeCaps
**
**      Given an ALSA PCM, figure out our HW CAPS structure info.
**  ctl can be null, pcm is required, as is all output parms.
**
*/
static int ALSA_ComputeCaps(snd_ctl_t *ctl, snd_pcm_t *pcm,
        WORD *channels, DWORD *flags, DWORD *formats, DWORD *supports)
{
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_format_mask_t *fmask;
    snd_pcm_access_mask_t *acmask;
    unsigned int ratemin = 0;
    unsigned int ratemax = 0;
    unsigned int chmin = 0;
    unsigned int chmax = 0;
    int dir = 0;

    snd_pcm_hw_params_alloca(&hw_params);
    ALSA_RETURN_ONFAIL(snd_pcm_hw_params_any(pcm, hw_params));

    snd_pcm_format_mask_alloca(&fmask);
    snd_pcm_hw_params_get_format_mask(hw_params, fmask);

    snd_pcm_access_mask_alloca(&acmask);
    ALSA_RETURN_ONFAIL(snd_pcm_hw_params_get_access_mask(hw_params, acmask));

    ALSA_RETURN_ONFAIL(snd_pcm_hw_params_get_rate_min(hw_params, &ratemin, &dir));
    ALSA_RETURN_ONFAIL(snd_pcm_hw_params_get_rate_max(hw_params, &ratemax, &dir));
    ALSA_RETURN_ONFAIL(snd_pcm_hw_params_get_channels_min(hw_params, &chmin));
    ALSA_RETURN_ONFAIL(snd_pcm_hw_params_get_channels_max(hw_params, &chmax));

#define X(r,v) \
    if ( (r) >= ratemin && ( (r) <= ratemax || ratemax == -1) ) \
    { \
       if (snd_pcm_format_mask_test( fmask, SND_PCM_FORMAT_U8)) \
       { \
          if (chmin <= 1 && 1 <= chmax) \
              *formats |= WAVE_FORMAT_##v##M08; \
          if (chmin <= 2 && 2 <= chmax) \
              *formats |= WAVE_FORMAT_##v##S08; \
       } \
       if (snd_pcm_format_mask_test( fmask, SND_PCM_FORMAT_S16_LE)) \
       { \
          if (chmin <= 1 && 1 <= chmax) \
              *formats |= WAVE_FORMAT_##v##M16; \
          if (chmin <= 2 && 2 <= chmax) \
              *formats |= WAVE_FORMAT_##v##S16; \
       } \
    }
    X(11025,1);
    X(22050,2);
    X(44100,4);
    X(48000,48);
    X(96000,96);
#undef X

    if (chmin > 1)
        FIXME("Device has a minimum of %d channels\n", chmin);
    *channels = chmax;

    /* FIXME: is sample accurate always true ?
    ** Can we do WAVECAPS_PITCH, WAVECAPS_SYNC, or WAVECAPS_PLAYBACKRATE? */
    *supports |= WAVECAPS_SAMPLEACCURATE;

    /* FIXME: NONITERLEAVED and COMPLEX are not supported right now */
    if ( snd_pcm_access_mask_test( acmask, SND_PCM_ACCESS_MMAP_INTERLEAVED ) )
        *supports |= WAVECAPS_DIRECTSOUND;

    /* check for volume control support */
    if (ctl) {
        *supports |= WAVECAPS_VOLUME;

        if (chmin <= 2 && 2 <= chmax)
            *supports |= WAVECAPS_LRVOLUME;
    }

    if (*formats & (WAVE_FORMAT_1M08  | WAVE_FORMAT_2M08  |
                               WAVE_FORMAT_4M08  | WAVE_FORMAT_48M08 |
                               WAVE_FORMAT_96M08 | WAVE_FORMAT_1M16  |
                               WAVE_FORMAT_2M16  | WAVE_FORMAT_4M16  |
                               WAVE_FORMAT_48M16 | WAVE_FORMAT_96M16) )
        *flags |= DSCAPS_PRIMARYMONO;

    if (*formats & (WAVE_FORMAT_1S08  | WAVE_FORMAT_2S08  |
                               WAVE_FORMAT_4S08  | WAVE_FORMAT_48S08 |
                               WAVE_FORMAT_96S08 | WAVE_FORMAT_1S16  |
                               WAVE_FORMAT_2S16  | WAVE_FORMAT_4S16  |
                               WAVE_FORMAT_48S16 | WAVE_FORMAT_96S16) )
        *flags |= DSCAPS_PRIMARYSTEREO;

    if (*formats & (WAVE_FORMAT_1M08  | WAVE_FORMAT_2M08  |
                               WAVE_FORMAT_4M08  | WAVE_FORMAT_48M08 |
                               WAVE_FORMAT_96M08 | WAVE_FORMAT_1S08  |
                               WAVE_FORMAT_2S08  | WAVE_FORMAT_4S08  |
                               WAVE_FORMAT_48S08 | WAVE_FORMAT_96S08) )
        *flags |= DSCAPS_PRIMARY8BIT;

    if (*formats & (WAVE_FORMAT_1M16  | WAVE_FORMAT_2M16  |
                               WAVE_FORMAT_4M16  | WAVE_FORMAT_48M16 |
                               WAVE_FORMAT_96M16 | WAVE_FORMAT_1S16  |
                               WAVE_FORMAT_2S16  | WAVE_FORMAT_4S16  |
                               WAVE_FORMAT_48S16 | WAVE_FORMAT_96S16) )
        *flags |= DSCAPS_PRIMARY16BIT;

    return(0);
}

/*----------------------------------------------------------------------------
**  ALSA_AddCommonDevice
**
**      Perform Alsa initialization common to both capture and playback
**
**  Side Effect:  ww->pcname and ww->ctlname may need to be freed.
**
**  Note:  this was originally coded by using snd_pcm_name(pcm), until
**         I discovered that with at least one version of alsa lib,
**         the use of a pcm named default:0 would cause snd_pcm_name() to fail.
**         So passing the name in is logically extraneous.  Sigh.
*/
static int ALSA_AddCommonDevice(snd_ctl_t *ctl, snd_pcm_t *pcm, const char *pcmname, WINE_WAVEDEV *ww)
{
    snd_pcm_info_t *infop;

    snd_pcm_info_alloca(&infop);
    ALSA_RETURN_ONFAIL(snd_pcm_info(pcm, infop));

    if (pcm && pcmname)
        ww->pcmname = ALSA_strdup(pcmname);
    else
        return -1;

    if (ctl && snd_ctl_name(ctl))
        ww->ctlname = ALSA_strdup(snd_ctl_name(ctl));

    strcpy(ww->interface_name, "winealsa: ");
    memcpy(ww->interface_name + strlen(ww->interface_name),
            ww->pcmname,
            min(strlen(ww->pcmname), sizeof(ww->interface_name) - strlen("winealsa:   ")));

    strcpy(ww->ds_desc.szDrvname, "winealsa.drv");

    memcpy(ww->ds_desc.szDesc, snd_pcm_info_get_name(infop),
            min( (sizeof(ww->ds_desc.szDesc) - 1), strlen(snd_pcm_info_get_name(infop))) );

    ww->ds_caps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
    ww->ds_caps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
    ww->ds_caps.dwPrimaryBuffers = 1;

    return 0;
}

/*----------------------------------------------------------------------------
** ALSA_FreeDevice
*/
static void ALSA_FreeDevice(WINE_WAVEDEV *ww)
{
    HeapFree(GetProcessHeap(), 0, ww->pcmname);
    ww->pcmname = NULL;

    HeapFree(GetProcessHeap(), 0, ww->ctlname);
    ww->ctlname = NULL;
}

/*----------------------------------------------------------------------------
**  ALSA_AddDeviceToArray
**
**      Dynamically size one of the wavein or waveout arrays of devices,
**  and add a fully configured device node to the array.
**
*/
static int ALSA_AddDeviceToArray(WINE_WAVEDEV *ww, WINE_WAVEDEV **array,
        DWORD *count, DWORD *alloced, int isdefault)
{
    int i = *count;

    if (*count >= *alloced)
    {
        (*alloced) += WAVEDEV_ALLOC_EXTENT_SIZE;
        if (! (*array))
            *array = HeapAlloc(GetProcessHeap(), 0, sizeof(*ww) * (*alloced));
        else
            *array = HeapReAlloc(GetProcessHeap(), 0, *array, sizeof(*ww) * (*alloced));

        if (!*array)
        {
            return -1;
        }
    }

    /* If this is the default, arrange for it to be the first element */
    if (isdefault && i > 0)
    {
        (*array)[*count] = (*array)[0];
        i = 0;
    }

    (*array)[i] = *ww;

    (*count)++;
    return 0;
}

/*----------------------------------------------------------------------------
**  ALSA_AddPlaybackDevice
**
**      Add a given Alsa device to Wine's internal list of Playback
**  devices.
*/
static int ALSA_AddPlaybackDevice(snd_ctl_t *ctl, snd_pcm_t *pcm, const char *pcmname, int isdefault)
{
    WINE_WAVEDEV    wwo;
    int rc;

    memset(&wwo, '\0', sizeof(wwo));

    rc = ALSA_AddCommonDevice(ctl, pcm, pcmname, &wwo);
    if (rc)
        return(rc);

    MultiByteToWideChar(CP_ACP, 0, wwo.ds_desc.szDesc, -1,
                        wwo.outcaps.szPname, sizeof(wwo.outcaps.szPname)/sizeof(WCHAR));
    wwo.outcaps.szPname[sizeof(wwo.outcaps.szPname)/sizeof(WCHAR) - 1] = '\0';

    wwo.outcaps.wMid = MM_CREATIVE;
    wwo.outcaps.wPid = MM_CREATIVE_SBP16_WAVEOUT;
    wwo.outcaps.vDriverVersion = 0x0100;

    rc = ALSA_ComputeCaps(ctl, pcm, &wwo.outcaps.wChannels, &wwo.ds_caps.dwFlags,
            &wwo.outcaps.dwFormats, &wwo.outcaps.dwSupport);
    if (rc)
    {
        WARN("Error calculating device caps for pcm [%s]\n", wwo.pcmname);
        ALSA_FreeDevice(&wwo);
        return(rc);
    }

    rc = ALSA_AddDeviceToArray(&wwo, &WOutDev, &ALSA_WodNumDevs, &ALSA_WodNumMallocedDevs, isdefault);
    if (rc)
        ALSA_FreeDevice(&wwo);
    return (rc);
}

/*----------------------------------------------------------------------------
**  ALSA_AddCaptureDevice
**
**      Add a given Alsa device to Wine's internal list of Capture
**  devices.
*/
static int ALSA_AddCaptureDevice(snd_ctl_t *ctl, snd_pcm_t *pcm, const char *pcmname, int isdefault)
{
    WINE_WAVEDEV    wwi;
    int rc;

    memset(&wwi, '\0', sizeof(wwi));

    rc = ALSA_AddCommonDevice(ctl, pcm, pcmname, &wwi);
    if (rc)
        return(rc);

    MultiByteToWideChar(CP_ACP, 0, wwi.ds_desc.szDesc, -1,
                        wwi.incaps.szPname, sizeof(wwi.incaps.szPname) / sizeof(WCHAR));
    wwi.incaps.szPname[sizeof(wwi.incaps.szPname)/sizeof(WCHAR) - 1] = '\0';

    wwi.incaps.wMid = MM_CREATIVE;
    wwi.incaps.wPid = MM_CREATIVE_SBP16_WAVEOUT;
    wwi.incaps.vDriverVersion = 0x0100;

    rc = ALSA_ComputeCaps(ctl, pcm, &wwi.incaps.wChannels, &wwi.ds_caps.dwFlags,
            &wwi.incaps.dwFormats, &wwi.dwSupport);
    if (rc)
    {
        WARN("Error calculating device caps for pcm [%s]\n", wwi.pcmname);
        ALSA_FreeDevice(&wwi);
        return(rc);
    }

    if (wwi.dwSupport & WAVECAPS_DIRECTSOUND)
    {
        FIXME("Add support for DSCapture\n");
        wwi.dwSupport &= ~WAVECAPS_DIRECTSOUND;
    }

    rc = ALSA_AddDeviceToArray(&wwi, &WInDev, &ALSA_WidNumDevs, &ALSA_WidNumMallocedDevs, isdefault);
    if (rc)
        ALSA_FreeDevice(&wwi);
    return(rc);
}

/*----------------------------------------------------------------------------
**  ALSA_CheckEnvironment
**
**      Given an Alsa style configuration node, scan its subitems
**  for environment variable names, and use them to find an override,
**  if appropriate.
**      This is essentially a long and convolunted way of doing:
**          getenv("ALSA_CARD")
**          getenv("ALSA_CTL_CARD")
**          getenv("ALSA_PCM_CARD")
**          getenv("ALSA_PCM_DEVICE")
**
**  The output value is set with the atoi() of the first environment
**  variable found to be set, if any; otherwise, it is left alone
*/
static void ALSA_CheckEnvironment(snd_config_t *node, int *outvalue)
{
    snd_config_iterator_t iter;

    for (iter = snd_config_iterator_first(node);
         iter != snd_config_iterator_end(node);
         iter = snd_config_iterator_next(iter))
    {
        snd_config_t *leaf = snd_config_iterator_entry(iter);
        if (snd_config_get_type(leaf) == SND_CONFIG_TYPE_STRING)
        {
            const char *value;
            if (snd_config_get_string(leaf, &value) >= 0)
            {
                char *p = getenv(value);
                if (p)
                {
                    *outvalue = atoi(p);
                    return;
                }
            }
        }
    }
}

/*----------------------------------------------------------------------------
**  ALSA_DefaultDevices
**
**      Jump through Alsa style hoops to (hopefully) properly determine
**  Alsa defaults for CTL Card #, as well as for PCM Card + Device #.
**  We'll also find out if the user has set any of the environment
**  variables that specify we're to use a specific card or device.
**
**  Parameters:
**      directhw        Whether to use a direct hardware device or not;
**                      essentially switches the pcm device name from
**                      one of 'default:X' or 'plughw:X' to "hw:X"
**      defctlcard      If !NULL, will hold the ctl card number given
**                      by the ALSA config as the default
**      defpcmcard      If !NULL, default pcm card #
**      defpcmdev       If !NULL, default pcm device #
**      fixedctlcard    If !NULL, and the user set the appropriate
**                          environment variable, we'll set to the
**                          card the user specified.
**      fixedpcmcard    If !NULL, and the user set the appropriate
**                          environment variable, we'll set to the
**                          card the user specified.
**      fixedpcmdev     If !NULL, and the user set the appropriate
**                          environment variable, we'll set to the
**                          device the user specified.
**
**  Returns:  0 on success, < 0 on failiure
*/
static int ALSA_DefaultDevices(int directhw,
            long *defctlcard,
            long *defpcmcard, long *defpcmdev,
            int *fixedctlcard,
            int *fixedpcmcard, int *fixedpcmdev)
{
    snd_config_t   *configp;
    char pcmsearch[256];

    ALSA_RETURN_ONFAIL(snd_config_update());

    if (defctlcard)
        if (snd_config_search(snd_config, "defaults.ctl.card", &configp) >= 0)
            snd_config_get_integer(configp, defctlcard);

    if (defpcmcard)
        if (snd_config_search(snd_config, "defaults.pcm.card", &configp) >= 0)
            snd_config_get_integer(configp, defpcmcard);

    if (defpcmdev)
        if (snd_config_search(snd_config, "defaults.pcm.device", &configp) >= 0)
            snd_config_get_integer(configp, defpcmdev);


    if (fixedctlcard)
    {
        if (snd_config_search(snd_config, "ctl.hw.@args.CARD.default.vars", &configp) >= 0)
            ALSA_CheckEnvironment(configp, fixedctlcard);
    }

    if (fixedpcmcard)
    {
        sprintf(pcmsearch, "pcm.%s.@args.CARD.default.vars", directhw ? "hw" : "plughw");
        if (snd_config_search(snd_config, pcmsearch, &configp) >= 0)
            ALSA_CheckEnvironment(configp, fixedpcmcard);
    }

    if (fixedpcmdev)
    {
        sprintf(pcmsearch, "pcm.%s.@args.DEV.default.vars", directhw ? "hw" : "plughw");
        if (snd_config_search(snd_config, pcmsearch, &configp) >= 0)
            ALSA_CheckEnvironment(configp, fixedpcmdev);
    }

    return 0;
}


/*----------------------------------------------------------------------------
**  ALSA_ScanDevices
**
**      Iterate through all discoverable ALSA cards, searching
**  for usable PCM devices.
**
**  Parameters:
**      directhw        Whether to use a direct hardware device or not;
**                      essentially switches the pcm device name from
**                      one of 'default:X' or 'plughw:X' to "hw:X"
**      defctlcard      Alsa's notion of the default ctl card.
**      defpcmcard         . pcm card
**      defpcmdev          . pcm device
**      fixedctlcard    If not -1, then gives the value of ALSA_CTL_CARD
**                          or equivalent environment variable
**      fixedpcmcard    If not -1, then gives the value of ALSA_PCM_CARD
**                          or equivalent environment variable
**      fixedpcmdev     If not -1, then gives the value of ALSA_PCM_DEVICE
**                          or equivalent environment variable
**
**  Returns:  0 on success, < 0 on failiure
*/
static int ALSA_ScanDevices(int directhw,
        long defctlcard, long defpcmcard, long defpcmdev,
        int fixedctlcard, int fixedpcmcard, int fixedpcmdev)
{
    int card = fixedpcmcard;
    int scan_devices = (fixedpcmdev == -1);

    /*------------------------------------------------------------------------
    ** Loop through all available cards
    **----------------------------------------------------------------------*/
    if (card == -1)
        snd_card_next(&card);

    for (; card != -1; snd_card_next(&card))
    {
        char ctlname[256];
        snd_ctl_t *ctl;
        int rc;
        int device;

        /*--------------------------------------------------------------------
        ** Try to open a ctl handle; Wine doesn't absolutely require one,
        **  but it does allow for volume control and for device scanning
        **------------------------------------------------------------------*/
        sprintf(ctlname, "default:%d", fixedctlcard == -1 ? card : fixedctlcard);
        rc = snd_ctl_open(&ctl, ctlname, SND_CTL_NONBLOCK);
        if (rc < 0)
        {
            sprintf(ctlname, "hw:%d", fixedctlcard == -1 ? card : fixedctlcard);
            rc = snd_ctl_open(&ctl, ctlname, SND_CTL_NONBLOCK);
        }
        if (rc < 0)
        {
            ctl = NULL;
            WARN("Unable to open an alsa ctl for [%s] (pcm card %d): %s; not scanning devices\n",
                    ctlname, card, snd_strerror(rc));
            if (fixedpcmdev == -1)
                fixedpcmdev = 0;
        }

        /*--------------------------------------------------------------------
        ** Loop through all available devices on this card
        **------------------------------------------------------------------*/
        device = fixedpcmdev;
        if (device == -1)
            snd_ctl_pcm_next_device(ctl, &device);

        for (; device != -1; snd_ctl_pcm_next_device(ctl, &device))
        {
            char defaultpcmname[256];
            char plugpcmname[256];
            char hwpcmname[256];
            char *pcmname = NULL;
            snd_pcm_t *pcm;

            sprintf(defaultpcmname, "default:%d", card);
            sprintf(plugpcmname,    "plughw:%d,%d", card, device);
            sprintf(hwpcmname,      "hw:%d,%d", card, device);

            /*----------------------------------------------------------------
            ** See if it's a valid playback device
            **--------------------------------------------------------------*/
            if (ALSA_TestDeviceForWine(card, device, SND_PCM_STREAM_PLAYBACK) == 0)
            {
                /* If we can, try the default:X device name first */
                if (! scan_devices && ! directhw)
                {
                    pcmname = defaultpcmname;
                    rc = snd_pcm_open(&pcm, pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
                }
                else
                    rc = -1;

                if (rc < 0)
                {
                    pcmname = directhw ? hwpcmname : plugpcmname;
                    rc = snd_pcm_open(&pcm, pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
                }

                if (rc >= 0)
                {
                    if (defctlcard == card && defpcmcard == card && defpcmdev == device)
                        ALSA_AddPlaybackDevice(ctl, pcm, pcmname, TRUE);
                    else
                        ALSA_AddPlaybackDevice(ctl, pcm, pcmname, FALSE);
                    snd_pcm_close(pcm);
                }
                else
                {
                    TRACE("Device [%s/%s] failed to open for playback: %s\n",
                        directhw || scan_devices ? "(N/A)" : defaultpcmname,
                        directhw ? hwpcmname : plugpcmname,
                        snd_strerror(rc));
                }
            }

            /*----------------------------------------------------------------
            ** See if it's a valid capture device
            **--------------------------------------------------------------*/
            if (ALSA_TestDeviceForWine(card, device, SND_PCM_STREAM_CAPTURE) == 0)
            {
                /* If we can, try the default:X device name first */
                if (! scan_devices && ! directhw)
                {
                    pcmname = defaultpcmname;
                    rc = snd_pcm_open(&pcm, pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
                }
                else
                    rc = -1;

                if (rc < 0)
                {
                    pcmname = directhw ? hwpcmname : plugpcmname;
                    rc = snd_pcm_open(&pcm, pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
                }

                if (rc >= 0)
                {
                    if (defctlcard == card && defpcmcard == card && defpcmdev == device)
                        ALSA_AddCaptureDevice(ctl, pcm, pcmname, TRUE);
                    else
                        ALSA_AddCaptureDevice(ctl, pcm, pcmname, FALSE);

                    snd_pcm_close(pcm);
                }
                else
                {
                    TRACE("Device [%s/%s] failed to open for capture: %s\n",
                        directhw || scan_devices ? "(N/A)" : defaultpcmname,
                        directhw ? hwpcmname : plugpcmname,
                        snd_strerror(rc));
                }
            }

            if (! scan_devices)
                break;
        }

        if (ctl)
            snd_ctl_close(ctl);

        /*--------------------------------------------------------------------
        ** If the user has set env variables such that we're pegged to
        **  a specific card, then break after we've examined it
        **------------------------------------------------------------------*/
        if (fixedpcmcard != -1)
            break;
    }

    return 0;

}

/*----------------------------------------------------------------------------
** ALSA_PerformDefaultScan
**  Perform the basic default scanning for devices within ALSA.
**  The hope is that this routine implements a 'correct'
**  scanning algorithm from the Alsalib point of view.
**
**      Note that Wine, overall, has other mechanisms to
**  override and specify exact CTL and PCM device names,
**  but this routine is imagined as the default that
**  99% of users will use.
**
**      The basic algorithm is simple:
**  Use snd_card_next to iterate cards; within cards, use
**  snd_ctl_pcm_next_device to iterate through devices.
**
**      We add a little complexity by taking into consideration
**  environment variables such as ALSA_CARD (et all), and by
**  detecting when a given device matches the default specified
**  by Alsa.
**
**  Parameters:
**      directhw        If !0, indicates we should use the hw:X
**                      PCM interface, rather than first try
**                      the 'default' device followed by the plughw
**                      device.  (default and plughw do fancy mixing
**                      and audio scaling, if they are available).
**      devscan         If TRUE, we should scan all devices, not
**                      juse use device 0 on each card
**
**  Returns:
**      0   on success
**
**  Effects:
**      Invokes the ALSA_AddXXXDevice functions on valid
**  looking devices
*/
static int ALSA_PerformDefaultScan(int directhw, BOOL devscan)
{
    long defctlcard = -1, defpcmcard = -1, defpcmdev = -1;
    int fixedctlcard = -1, fixedpcmcard = -1, fixedpcmdev = -1;
    int rc;

    /* FIXME:  We should dlsym the new snd_names_list/snd_names_list_free 1.0.9 apis,
    **          and use them instead of this scan mechanism if they are present         */

    rc = ALSA_DefaultDevices(directhw, &defctlcard, &defpcmcard, &defpcmdev,
            &fixedctlcard, &fixedpcmcard, &fixedpcmdev);
    if (rc)
        return(rc);

    if (fixedpcmdev == -1 && ! devscan)
        fixedpcmdev = 0;

    return(ALSA_ScanDevices(directhw, defctlcard, defpcmcard, defpcmdev, fixedctlcard, fixedpcmcard, fixedpcmdev));
}


/*----------------------------------------------------------------------------
** ALSA_AddUserSpecifiedDevice
**  Add a device given from the registry
*/
static int ALSA_AddUserSpecifiedDevice(const char *ctlname, const char *pcmname)
{
    int rc;
    int okay = 0;
    snd_ctl_t *ctl = NULL;
    snd_pcm_t *pcm = NULL;

    if (ctlname)
    {
        rc = snd_ctl_open(&ctl, ctlname, SND_CTL_NONBLOCK);
        if (rc < 0)
            ctl = NULL;
    }

    rc = snd_pcm_open(&pcm, pcmname, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
    if (rc >= 0)
    {
        ALSA_AddPlaybackDevice(ctl, pcm, pcmname, FALSE);
        okay++;
        snd_pcm_close(pcm);
    }

    rc = snd_pcm_open(&pcm, pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
    if (rc >= 0)
    {
        ALSA_AddCaptureDevice(ctl, pcm, pcmname, FALSE);
        okay++;
        snd_pcm_close(pcm);
    }

    if (ctl)
        snd_ctl_close(ctl);

    return (okay == 0);
}


/*----------------------------------------------------------------------------
** ALSA_WaveInit
**  Initialize the Wine Alsa sub system.
** The main task is to probe for and store a list of all appropriate playback
** and capture devices.
**  Key control points are from the registry key:
**  [Software\Wine\Alsa Driver]
**  AutoScanCards           Whether or not to scan all known sound cards
**                          and add them to Wine's list (default yes)
**  AutoScanDevices         Whether or not to scan all known PCM devices
**                          on each card (default no)
**  UseDirectHW             Whether or not to use the hw:X device,
**                          instead of the fancy default:X or plughw:X device.
**                          The hw:X device goes straight to the hardware
**                          without any fancy mixing or audio scaling in between.
**  DeviceCount             If present, specifies the number of hard coded
**                          Alsa devices to add to Wine's list; default 0
**  DevicePCMn              Specifies the Alsa PCM devices to open for
**                          Device n (where n goes from 1 to DeviceCount)
**  DeviceCTLn              Specifies the Alsa control devices to open for
**                          Device n (where n goes from 1 to DeviceCount)
**
**                          Using AutoScanCards no, and then Devicexxx info
**                          is a way to exactly specify the devices used by Wine.
**
*/
LONG ALSA_WaveInit(void)
{
    DWORD rc;
    BOOL  AutoScanCards = TRUE;
    BOOL  AutoScanDevices = FALSE;
    BOOL  UseDirectHW = FALSE;
    DWORD DeviceCount = 0;
    HKEY  key = 0;
    int   i;

    if (!wine_dlopen("libasound.so.2", RTLD_LAZY|RTLD_GLOBAL, NULL, 0))
    {
        ERR("Error: ALSA lib needs to be loaded with flags RTLD_LAZY and RTLD_GLOBAL.\n");
        return -1;
    }

    /* @@ Wine registry key: HKCU\Software\Wine\Alsa Driver */
    rc = RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\Alsa Driver", 0, KEY_QUERY_VALUE, &key);
    if (rc == ERROR_SUCCESS)
    {
        ALSA_RegGetBoolean(key, "AutoScanCards", &AutoScanCards);
        ALSA_RegGetBoolean(key, "AutoScanDevices", &AutoScanDevices);
        ALSA_RegGetBoolean(key, "UseDirectHW", &UseDirectHW);
        ALSA_RegGetInt(key, "DeviceCount", &DeviceCount);
    }

    if (AutoScanCards)
        rc = ALSA_PerformDefaultScan(UseDirectHW, AutoScanDevices);

    for (i = 0; i < DeviceCount; i++)
    {
        char *ctl_name = NULL;
        char *pcm_name = NULL;
        char value[30];

        sprintf(value, "DevicePCM%d", i + 1);
        if (ALSA_RegGetString(key, value, &pcm_name) == ERROR_SUCCESS)
        {
            sprintf(value, "DeviceCTL%d", i + 1);
            ALSA_RegGetString(key, value, &ctl_name);
            ALSA_AddUserSpecifiedDevice(ctl_name, pcm_name);
        }

        HeapFree(GetProcessHeap(), 0, ctl_name);
        HeapFree(GetProcessHeap(), 0, pcm_name);
    }

    if (key)
        RegCloseKey(key);

    return (rc);
}

#endif /* HAVE_ALSA */
