/*
 * Test mixer
 *
 * Copyright (c) 2004 Robert Reif
 *
 * 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
 */

/*
 * To Do:
 * add interactive tests
 */

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "wine/test.h"
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "mmsystem.h"

#include "winmm_test.h"

static const char * line_flags(DWORD fdwLine)
{
    static char flags[100];
    BOOL first=TRUE;
    flags[0]=0;
    if (fdwLine&MIXERLINE_LINEF_ACTIVE) {
        strcat(flags,"MIXERLINE_LINEF_ACTIVE");
        first=FALSE;
    }
    if (fdwLine&MIXERLINE_LINEF_DISCONNECTED) {
        if (!first)
            strcat(flags, "|");

        strcat(flags,"MIXERLINE_LINEF_DISCONNECTED");
        first=FALSE;
    }

    if (fdwLine&MIXERLINE_LINEF_SOURCE) {
        if (!first)
            strcat(flags, "|");

        strcat(flags,"MIXERLINE_LINEF_SOURCE");
    }

    return flags;
}

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

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

static const char * control_type(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 "UNKNOWN";
}

static const char * control_flags(DWORD fdwControl)
{
    static char flags[100];
    BOOL first=TRUE;
    flags[0]=0;
    if (fdwControl&MIXERCONTROL_CONTROLF_UNIFORM) {
        strcat(flags,"MIXERCONTROL_CONTROLF_UNIFORM");
        first=FALSE;
    }
    if (fdwControl&MIXERCONTROL_CONTROLF_MULTIPLE) {
        if (!first)
            strcat(flags, "|");

        strcat(flags,"MIXERCONTROL_CONTROLF_MULTIPLE");
        first=FALSE;
    }

    if (fdwControl&MIXERCONTROL_CONTROLF_DISABLED) {
        if (!first)
            strcat(flags, "|");

        strcat(flags,"MIXERCONTROL_CONTROLF_DISABLED");
    }

    return flags;
}

static void test_mixerClose(HMIXER mix)
{
    MMRESULT rc;

    rc = mixerClose(mix);
    ok(rc == MMSYSERR_NOERROR || rc == MMSYSERR_INVALHANDLE,
       "mixerClose: MMSYSERR_NOERROR or MMSYSERR_INVALHANDLE expected, got %s\n",
       mmsys_error(rc));
}

static void mixer_test_controlA(HMIXEROBJ mix, MIXERCONTROLA *control)
{
    MMRESULT rc;

    if ((control->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_UNSIGNED)) {
        MIXERCONTROLDETAILS details;
        MIXERCONTROLDETAILS_UNSIGNED value;

        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
        details.dwControlID = control->dwControlID;
        details.cChannels = 1;
        U(details).cMultipleItems = 0;
        details.cbDetails = sizeof(value);

        /* test NULL paDetails */
        details.paDetails = NULL;
        rc = mixerGetControlDetailsA(mix, &details, MIXER_GETCONTROLDETAILSF_VALUE);
        ok(rc==MMSYSERR_INVALPARAM,
           "mixerGetDevCapsA: MMSYSERR_INVALPARAM expected, got %s\n",
           mmsys_error(rc));

        /* read the current control value */
        details.paDetails = &value;
        rc = mixerGetControlDetailsA(mix, &details, MIXER_GETCONTROLDETAILSF_VALUE);
        ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
           "MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc==MMSYSERR_NOERROR && winetest_interactive) {
            MIXERCONTROLDETAILS new_details;
            MIXERCONTROLDETAILS_UNSIGNED new_value;

            trace("            Value=%d\n",value.dwValue);

            if (value.dwValue + control->Metrics.cSteps < S1(control->Bounds).dwMaximum)
                new_value.dwValue = value.dwValue + control->Metrics.cSteps;
            else
                new_value.dwValue = value.dwValue - control->Metrics.cSteps;

            new_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
            new_details.dwControlID = control->dwControlID;
            new_details.cChannels = 1;
            U(new_details).cMultipleItems = 0;
            new_details.paDetails = &new_value;
            new_details.cbDetails = sizeof(new_value);

            /* change the control value by one step */
            rc = mixerSetControlDetails(mix, &new_details, MIXER_SETCONTROLDETAILSF_VALUE);
            ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            if (rc==MMSYSERR_NOERROR) {
                MIXERCONTROLDETAILS ret_details;
                MIXERCONTROLDETAILS_UNSIGNED ret_value;

                ret_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                ret_details.dwControlID = control->dwControlID;
                ret_details.cChannels = 1;
                U(ret_details).cMultipleItems = 0;
                ret_details.paDetails = &ret_value;
                ret_details.cbDetails = sizeof(ret_value);

                /* read back the new control value */
                rc = mixerGetControlDetailsA(mix, &ret_details, MIXER_GETCONTROLDETAILSF_VALUE);
                ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NOERROR) {
                    /* result may not match exactly because of rounding */
                    ok(abs(ret_value.dwValue-new_value.dwValue)<=1,
                       "Couldn't change value from %d to %d, returned %d\n",
                       value.dwValue,new_value.dwValue,ret_value.dwValue);

                    if (abs(ret_value.dwValue-new_value.dwValue)<=1) {
                        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                        details.dwControlID = control->dwControlID;
                        details.cChannels = 1;
                        U(details).cMultipleItems = 0;
                        details.paDetails = &value;
                        details.cbDetails = sizeof(value);

                        /* restore original value */
                        rc = mixerSetControlDetails(mix, &details, MIXER_SETCONTROLDETAILSF_VALUE);
                        ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
                           "MMSYSERR_NOERROR expected, got %s\n",
                           mmsys_error(rc));
                    }
                }
            }
        }
    } else if ((control->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_BOOLEAN) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_BUTTON)) {
        MIXERCONTROLDETAILS details;
        MIXERCONTROLDETAILS_BOOLEAN value;

        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
        details.dwControlID = control->dwControlID;
        details.cChannels = 1;
        U(details).cMultipleItems = 0;
        details.paDetails = &value;
        details.cbDetails = sizeof(value);

        rc = mixerGetControlDetailsA(mix, &details, MIXER_GETCONTROLDETAILSF_VALUE);
        ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
           "MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc==MMSYSERR_NOERROR && winetest_interactive) {
            MIXERCONTROLDETAILS new_details;
            MIXERCONTROLDETAILS_BOOLEAN new_value;

            trace("            Value=%d\n",value.fValue);

            if (value.fValue == FALSE)
                new_value.fValue = TRUE;
            else
                new_value.fValue = FALSE;

            new_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
            new_details.dwControlID = control->dwControlID;
            new_details.cChannels = 1;
            U(new_details).cMultipleItems = 0;
            new_details.paDetails = &new_value;
            new_details.cbDetails = sizeof(new_value);

            /* change the control value by one step */
            rc = mixerSetControlDetails(mix, &new_details, MIXER_SETCONTROLDETAILSF_VALUE);
            ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            if (rc==MMSYSERR_NOERROR) {
                MIXERCONTROLDETAILS ret_details;
                MIXERCONTROLDETAILS_BOOLEAN ret_value;

                ret_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                ret_details.dwControlID = control->dwControlID;
                ret_details.cChannels = 1;
                U(ret_details).cMultipleItems = 0;
                ret_details.paDetails = &ret_value;
                ret_details.cbDetails = sizeof(ret_value);

                /* read back the new control value */
                rc = mixerGetControlDetailsA(mix, &ret_details, MIXER_GETCONTROLDETAILSF_VALUE);
                ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NOERROR) {
                    /* result may not match exactly because of rounding */
                    ok(ret_value.fValue==new_value.fValue,
                       "Couldn't change value from %d to %d, returned %d\n",
                       value.fValue,new_value.fValue,ret_value.fValue);

                    if (ret_value.fValue==new_value.fValue) {
                        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                        details.dwControlID = control->dwControlID;
                        details.cChannels = 1;
                        U(details).cMultipleItems = 0;
                        details.paDetails = &value;
                        details.cbDetails = sizeof(value);

                        /* restore original value */
                        rc = mixerSetControlDetails(mix, &details, MIXER_SETCONTROLDETAILSF_VALUE);
                        ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
                           "MMSYSERR_NOERROR expected, got %s\n",
                           mmsys_error(rc));
                    }
                }
            }
        }
    } else {
        /* FIXME */
    }
}

static void mixer_test_deviceA(int device)
{
    MIXERCAPSA capsA;
    HMIXEROBJ mix;
    MMRESULT rc;
    DWORD d,s,ns,nc;

    rc=mixerGetDevCapsA(device,0,sizeof(capsA));
    ok(rc==MMSYSERR_INVALPARAM,
       "mixerGetDevCapsA: MMSYSERR_INVALPARAM expected, got %s\n",
       mmsys_error(rc));

    rc=mixerGetDevCapsA(device,&capsA,4);
    ok(rc==MMSYSERR_NOERROR,
       "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
       mmsys_error(rc));

    rc=mixerGetDevCapsA(device,&capsA,sizeof(capsA));
    ok(rc==MMSYSERR_NOERROR,
       "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
       mmsys_error(rc));

    if (winetest_interactive) {
        trace("  %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device,
              capsA.szPname, capsA.vDriverVersion >> 8,
              capsA.vDriverVersion & 0xff,capsA.wMid,capsA.wPid,
              capsA.cDestinations);
    } else {
        trace("  %d: \"%s\" %d.%d (%d:%d)\n", device,
              capsA.szPname, capsA.vDriverVersion >> 8,
              capsA.vDriverVersion & 0xff,capsA.wMid,capsA.wPid);
    }

    rc = mixerOpen((HMIXER*)&mix, device, 0, 0, 0);
    ok(rc==MMSYSERR_NOERROR,
       "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",mmsys_error(rc));
    if (rc==MMSYSERR_NOERROR) {
        MIXERCAPSA capsA2;

        rc=mixerGetDevCapsA((UINT_PTR)mix,&capsA2,sizeof(capsA2));
        ok(rc==MMSYSERR_NOERROR,
           "mixerGetDevCapsA: MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        ok(!strcmp(capsA2.szPname, capsA.szPname), "Got wrong device caps\n");

        for (d=0;d<capsA.cDestinations;d++) {
            MIXERLINEA mixerlineA;
            mixerlineA.cbStruct = 0;
            mixerlineA.dwDestination=d;
            rc = mixerGetLineInfoA(mix, &mixerlineA, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_INVALPARAM,
               "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_INVALPARAM expected, got %s\n",
               mmsys_error(rc));

            mixerlineA.cbStruct = sizeof(mixerlineA);
            mixerlineA.dwDestination=capsA.cDestinations;
            rc = mixerGetLineInfoA(mix, &mixerlineA, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_INVALPARAM||rc==MIXERR_INVALLINE,
               "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
               mmsys_error(rc));

            mixerlineA.cbStruct = sizeof(mixerlineA);
            mixerlineA.dwDestination=d;
            rc = mixerGetLineInfoA(mix, 0, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_INVALPARAM,
               "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_INVALPARAM expected, got %s\n",
               mmsys_error(rc));

            mixerlineA.cbStruct = sizeof(mixerlineA);
            mixerlineA.dwDestination=d;
            rc = mixerGetLineInfoA(mix, &mixerlineA, -1);
            ok(rc==MMSYSERR_INVALFLAG,
               "mixerGetLineInfoA(-1): MMSYSERR_INVALFLAG expected, got %s\n",
               mmsys_error(rc));

            mixerlineA.cbStruct = sizeof(mixerlineA);
            mixerlineA.dwDestination=d;
            mixerlineA.dwUser = (ULONG_PTR)0xdeadbeef;
            rc = mixerGetLineInfoA(mix, &mixerlineA, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_NOERROR||rc==MMSYSERR_NODRIVER,
               "mixerGetLineInfoA(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            ok(mixerlineA.dwUser == 0, "dwUser was not reset\n");
            if (rc==MMSYSERR_NODRIVER)
                trace("  No Driver\n");
            else if (rc==MMSYSERR_NOERROR) {
	      if (winetest_interactive) {
                trace("    %d: \"%s\" (%s) Destination=%d Source=%d\n",
                      d,mixerlineA.szShortName, mixerlineA.szName,
                      mixerlineA.dwDestination,mixerlineA.dwSource);
                trace("        LineID=%08x Channels=%d "
                      "Connections=%d Controls=%d\n",
                      mixerlineA.dwLineID,mixerlineA.cChannels,
                      mixerlineA.cConnections,mixerlineA.cControls);
                trace("        State=0x%08x(%s)\n",
                      mixerlineA.fdwLine,line_flags(mixerlineA.fdwLine));
                trace("        ComponentType=%s\n",
                      component_type(mixerlineA.dwComponentType));
                trace("        Type=%s\n",
                      target_type(mixerlineA.Target.dwType));
                trace("        Device=%d (%s) %d.%d (%d:%d)\n",
                      mixerlineA.Target.dwDeviceID,
                      mixerlineA.Target.szPname,
                      mixerlineA.Target.vDriverVersion >> 8,
                      mixerlineA.Target.vDriverVersion & 0xff,
                      mixerlineA.Target.wMid, mixerlineA.Target.wPid);
	      }
              ns=mixerlineA.cConnections;
              for(s=0;s<ns;s++) {
                mixerlineA.cbStruct = sizeof(mixerlineA);
                mixerlineA.dwDestination=d;
                mixerlineA.dwSource=s;
                rc = mixerGetLineInfoA(mix, &mixerlineA, MIXER_GETLINEINFOF_SOURCE);
                ok(rc==MMSYSERR_NOERROR||rc==MMSYSERR_NODRIVER,
                   "mixerGetLineInfoA(MIXER_GETLINEINFOF_SOURCE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NODRIVER)
                    trace("  No Driver\n");
                else if (rc==MMSYSERR_NOERROR) {
                    LPMIXERCONTROLA    array;
                    MIXERLINECONTROLSA controls;
                    if (winetest_interactive) {
                        trace("      %d: \"%s\" (%s) Destination=%d Source=%d\n",
                              s,mixerlineA.szShortName, mixerlineA.szName,
                              mixerlineA.dwDestination,mixerlineA.dwSource);
                        trace("          LineID=%08x Channels=%d "
                              "Connections=%d Controls=%d\n",
                              mixerlineA.dwLineID,mixerlineA.cChannels,
                              mixerlineA.cConnections,mixerlineA.cControls);
                        trace("          State=0x%08x(%s)\n",
                              mixerlineA.fdwLine,line_flags(mixerlineA.fdwLine));
                        trace("          ComponentType=%s\n",
                              component_type(mixerlineA.dwComponentType));
                        trace("          Type=%s\n",
                              target_type(mixerlineA.Target.dwType));
                        trace("          Device=%d (%s) %d.%d (%d:%d)\n",
                              mixerlineA.Target.dwDeviceID,
                              mixerlineA.Target.szPname,
                              mixerlineA.Target.vDriverVersion >> 8,
                              mixerlineA.Target.vDriverVersion & 0xff,
                              mixerlineA.Target.wMid, mixerlineA.Target.wPid);
                    }
                    if (mixerlineA.cControls) {
                        array=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
                            mixerlineA.cControls*sizeof(MIXERCONTROLA));
                        if (array) {
                            memset(&controls, 0, sizeof(controls));

                            rc = mixerGetLineControlsA(mix, 0, MIXER_GETLINECONTROLSF_ALL);
                            ok(rc==MMSYSERR_INVALPARAM,
                               "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
                               "MMSYSERR_INVALPARAM expected, got %s\n",
                               mmsys_error(rc));

                            rc = mixerGetLineControlsA(mix, &controls, -1);
                            ok(rc==MMSYSERR_INVALFLAG||rc==MMSYSERR_INVALPARAM,
                               "mixerGetLineControlsA(-1): "
                               "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
                               mmsys_error(rc));

                            controls.cbStruct = sizeof(MIXERLINECONTROLSA);
                            controls.cControls = mixerlineA.cControls;
                            controls.dwLineID = mixerlineA.dwLineID;
                            controls.pamxctrl = array;
                            controls.cbmxctrl = sizeof(MIXERCONTROLA);

                            /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
                             * and MIXER_GETLINECONTROLSF_ONEBYTYPE
                             */
                            rc = mixerGetLineControlsA(mix, &controls, MIXER_GETLINECONTROLSF_ALL);
                            ok(rc==MMSYSERR_NOERROR,
                               "mixerGetLineControlsA(MIXER_GETLINECONTROLSF_ALL): "
                               "MMSYSERR_NOERROR expected, got %s\n",
                               mmsys_error(rc));
                            if (rc==MMSYSERR_NOERROR) {
                                for(nc=0;nc<mixerlineA.cControls;nc++) {
                                    if (winetest_interactive) {
                                        trace("        %d: \"%s\" (%s) ControlID=%d\n", nc,
                                              array[nc].szShortName,
                                              array[nc].szName, array[nc].dwControlID);
                                        trace("            ControlType=%s\n",
                                               control_type(array[nc].dwControlType));
                                        trace("            Control=0x%08x(%s)\n",
                                              array[nc].fdwControl,
                                              control_flags(array[nc].fdwControl));
                                        trace("            Items=%d Min=%d Max=%d Step=%d\n",
                                              array[nc].cMultipleItems,
                                              S1(array[nc].Bounds).dwMinimum,
                                              S1(array[nc].Bounds).dwMaximum,
                                              array[nc].Metrics.cSteps);
                                    }

                                    mixer_test_controlA(mix, &array[nc]);
                                }
                            }

                            HeapFree(GetProcessHeap(),0,array);
                        }
                    }
                }
              }
            }
        }
        test_mixerClose((HMIXER)mix);
    }
}

static void mixer_test_controlW(HMIXEROBJ mix, MIXERCONTROLW *control)
{
    MMRESULT rc;

    if ((control->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_UNSIGNED)) {
        MIXERCONTROLDETAILS details;
        MIXERCONTROLDETAILS_UNSIGNED value;

        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
        details.dwControlID = control->dwControlID;
        details.cChannels = 1;
        U(details).cMultipleItems = 0;
        details.paDetails = &value;
        details.cbDetails = sizeof(value);

        /* read the current control value */
        rc = mixerGetControlDetailsW(mix, &details, MIXER_GETCONTROLDETAILSF_VALUE);
        ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
           "MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc==MMSYSERR_NOERROR && winetest_interactive) {
            MIXERCONTROLDETAILS new_details;
            MIXERCONTROLDETAILS_UNSIGNED new_value;

            trace("            Value=%d\n",value.dwValue);

            if (value.dwValue + control->Metrics.cSteps < S1(control->Bounds).dwMaximum)
                new_value.dwValue = value.dwValue + control->Metrics.cSteps;
            else
                new_value.dwValue = value.dwValue - control->Metrics.cSteps;

            new_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
            new_details.dwControlID = control->dwControlID;
            new_details.cChannels = 1;
            U(new_details).cMultipleItems = 0;
            new_details.paDetails = &new_value;
            new_details.cbDetails = sizeof(new_value);

            /* change the control value by one step */
            rc = mixerSetControlDetails(mix, &new_details, MIXER_SETCONTROLDETAILSF_VALUE);
            ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            if (rc==MMSYSERR_NOERROR) {
                MIXERCONTROLDETAILS ret_details;
                MIXERCONTROLDETAILS_UNSIGNED ret_value;

                ret_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                ret_details.dwControlID = control->dwControlID;
                ret_details.cChannels = 1;
                U(ret_details).cMultipleItems = 0;
                ret_details.paDetails = &ret_value;
                ret_details.cbDetails = sizeof(ret_value);

                /* read back the new control value */
                rc = mixerGetControlDetailsW(mix, &ret_details, MIXER_GETCONTROLDETAILSF_VALUE);
                ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NOERROR) {
                    /* result may not match exactly because of rounding */
                    ok(abs(ret_value.dwValue-new_value.dwValue)<=1,
                       "Couldn't change value from %d to %d, returned %d\n",
                       value.dwValue,new_value.dwValue,ret_value.dwValue);

                    if (abs(ret_value.dwValue-new_value.dwValue)<=1) {
                        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                        details.dwControlID = control->dwControlID;
                        details.cChannels = 1;
                        U(details).cMultipleItems = 0;
                        details.paDetails = &value;
                        details.cbDetails = sizeof(value);

                        /* restore original value */
                        rc = mixerSetControlDetails(mix, &details, MIXER_SETCONTROLDETAILSF_VALUE);
                        ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
                           "MMSYSERR_NOERROR expected, got %s\n",
                           mmsys_error(rc));
                    }
                }
            }
        }
    } else if ((control->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_BOOLEAN) ||
        (control->dwControlType == MIXERCONTROL_CONTROLTYPE_BUTTON)) {
        MIXERCONTROLDETAILS details;
        MIXERCONTROLDETAILS_BOOLEAN value;

        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
        details.dwControlID = control->dwControlID;
        details.cChannels = 1;
        U(details).cMultipleItems = 0;
        details.paDetails = &value;
        details.cbDetails = sizeof(value);

        rc = mixerGetControlDetailsW(mix, &details, MIXER_GETCONTROLDETAILSF_VALUE);
        ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
           "MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc==MMSYSERR_NOERROR && winetest_interactive) {
            MIXERCONTROLDETAILS new_details;
            MIXERCONTROLDETAILS_BOOLEAN new_value;

            trace("            Value=%d\n",value.fValue);

            if (value.fValue == FALSE)
                new_value.fValue = TRUE;
            else
                new_value.fValue = FALSE;

            new_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
            new_details.dwControlID = control->dwControlID;
            new_details.cChannels = 1;
            U(new_details).cMultipleItems = 0;
            new_details.paDetails = &new_value;
            new_details.cbDetails = sizeof(new_value);

            /* change the control value by one step */
            rc = mixerSetControlDetails(mix, &new_details, MIXER_SETCONTROLDETAILSF_VALUE);
            ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            if (rc==MMSYSERR_NOERROR) {
                MIXERCONTROLDETAILS ret_details;
                MIXERCONTROLDETAILS_BOOLEAN ret_value;

                ret_details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                ret_details.dwControlID = control->dwControlID;
                ret_details.cChannels = 1;
                U(ret_details).cMultipleItems = 0;
                ret_details.paDetails = &ret_value;
                ret_details.cbDetails = sizeof(ret_value);

                /* read back the new control value */
                rc = mixerGetControlDetailsW(mix, &ret_details, MIXER_GETCONTROLDETAILSF_VALUE);
                ok(rc==MMSYSERR_NOERROR,"mixerGetControlDetails(MIXER_GETCONTROLDETAILSF_VALUE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NOERROR) {
                    /* result may not match exactly because of rounding */
                    ok(ret_value.fValue==new_value.fValue,
                       "Couldn't change value from %d to %d, returned %d\n",
                       value.fValue,new_value.fValue,ret_value.fValue);

                    if (ret_value.fValue==new_value.fValue) {
                        details.cbStruct = sizeof(MIXERCONTROLDETAILS);
                        details.dwControlID = control->dwControlID;
                        details.cChannels = 1;
                        U(details).cMultipleItems = 0;
                        details.paDetails = &value;
                        details.cbDetails = sizeof(value);

                        /* restore original value */
                        rc = mixerSetControlDetails(mix, &details, MIXER_SETCONTROLDETAILSF_VALUE);
                        ok(rc==MMSYSERR_NOERROR,"mixerSetControlDetails(MIXER_SETCONTROLDETAILSF_VALUE): "
                           "MMSYSERR_NOERROR expected, got %s\n",
                           mmsys_error(rc));
                    }
                }
            }
        }
    } else {
        /* FIXME */
    }
}

static void mixer_test_deviceW(int device)
{
    MIXERCAPSW capsW;
    HMIXEROBJ mix;
    MMRESULT rc;
    DWORD d,s,ns,nc;
    char szShortName[MIXER_SHORT_NAME_CHARS];
    char szName[MIXER_LONG_NAME_CHARS];
    char szPname[MAXPNAMELEN];

    rc=mixerGetDevCapsW(device,0,sizeof(capsW));
    ok(rc==MMSYSERR_INVALPARAM,
       "mixerGetDevCapsW: MMSYSERR_INVALPARAM expected, got %s\n",
       mmsys_error(rc));

    rc=mixerGetDevCapsW(device,&capsW,4);
    ok(rc==MMSYSERR_NOERROR ||
       rc==MMSYSERR_INVALPARAM, /* Vista and W2K8 */
       "mixerGetDevCapsW: MMSYSERR_NOERROR or MMSYSERR_INVALPARAM expected, got %s\n",
       mmsys_error(rc));

    rc=mixerGetDevCapsW(device,&capsW,sizeof(capsW));
    ok(rc==MMSYSERR_NOERROR,
       "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
       mmsys_error(rc));

    WideCharToMultiByte(CP_ACP,0,capsW.szPname, MAXPNAMELEN,szPname,
                        MAXPNAMELEN,NULL,NULL);
    if (winetest_interactive) {
        trace("  %d: \"%s\" %d.%d (%d:%d) destinations=%d\n", device,
              szPname, capsW.vDriverVersion >> 8,
              capsW.vDriverVersion & 0xff,capsW.wMid,capsW.wPid,
              capsW.cDestinations);
    } else {
        trace("  %d: \"%s\" %d.%d (%d:%d)\n", device,
              szPname, capsW.vDriverVersion >> 8,
              capsW.vDriverVersion & 0xff,capsW.wMid,capsW.wPid);
    }


    rc = mixerOpen((HMIXER*)&mix, device, 0, 0, 0);
    ok(rc==MMSYSERR_NOERROR,
       "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",mmsys_error(rc));
    if (rc==MMSYSERR_NOERROR) {
        MIXERCAPSW capsW2;

        rc=mixerGetDevCapsW((UINT_PTR)mix,&capsW2,sizeof(capsW2));
        ok(rc==MMSYSERR_NOERROR,
           "mixerGetDevCapsW: MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        ok(!lstrcmpW(capsW2.szPname, capsW.szPname), "Got wrong device caps\n");

        for (d=0;d<capsW.cDestinations;d++) {
            MIXERLINEW mixerlineW;
            mixerlineW.cbStruct = 0;
            mixerlineW.dwDestination=d;
            rc = mixerGetLineInfoW(mix, &mixerlineW, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_INVALPARAM,
               "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_INVALPARAM expected, got %s\n",
               mmsys_error(rc));

            mixerlineW.cbStruct = sizeof(mixerlineW);
            mixerlineW.dwDestination=capsW.cDestinations;
            rc = mixerGetLineInfoW(mix, &mixerlineW, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_INVALPARAM||rc==MIXERR_INVALLINE,
               "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_INVALPARAM or MIXERR_INVALLINE expected, got %s\n",
               mmsys_error(rc));

            mixerlineW.cbStruct = sizeof(mixerlineW);
            mixerlineW.dwDestination=d;
            rc = mixerGetLineInfoW(mix, 0, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_INVALPARAM,
               "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_INVALPARAM expected, got %s\n",
               mmsys_error(rc));

            mixerlineW.cbStruct = sizeof(mixerlineW);
            mixerlineW.dwDestination=d;
            rc = mixerGetLineInfoW(mix, &mixerlineW, -1);
            ok(rc==MMSYSERR_INVALFLAG,
               "mixerGetLineInfoW(-1): MMSYSERR_INVALFLAG expected, got %s\n",
               mmsys_error(rc));

            mixerlineW.cbStruct = sizeof(mixerlineW);
            mixerlineW.dwDestination=d;
            mixerlineW.dwUser = (ULONG_PTR)0xdeadbeef;
            rc = mixerGetLineInfoW(mix, &mixerlineW, MIXER_GETLINEINFOF_DESTINATION);
            ok(rc==MMSYSERR_NOERROR||rc==MMSYSERR_NODRIVER,
               "mixerGetLineInfoW(MIXER_GETLINEINFOF_DESTINATION): "
               "MMSYSERR_NOERROR expected, got %s\n",
               mmsys_error(rc));
            ok(mixerlineW.dwUser == 0, "dwUser was not reset\n");
            if (rc==MMSYSERR_NODRIVER)
                trace("  No Driver\n");
            else if (rc==MMSYSERR_NOERROR && winetest_interactive) {
                WideCharToMultiByte(CP_ACP,0,mixerlineW.szShortName,
                    MIXER_SHORT_NAME_CHARS,szShortName,
                    MIXER_SHORT_NAME_CHARS,NULL,NULL);
                WideCharToMultiByte(CP_ACP,0,mixerlineW.szName,
                    MIXER_LONG_NAME_CHARS,szName,
                    MIXER_LONG_NAME_CHARS,NULL,NULL);
                WideCharToMultiByte(CP_ACP,0,mixerlineW.Target.szPname,
                    MAXPNAMELEN,szPname,
                    MAXPNAMELEN,NULL, NULL);
                trace("    %d: \"%s\" (%s) Destination=%d Source=%d\n",
                      d,szShortName,szName,
                      mixerlineW.dwDestination,mixerlineW.dwSource);
                trace("        LineID=%08x Channels=%d "
                      "Connections=%d Controls=%d\n",
                      mixerlineW.dwLineID,mixerlineW.cChannels,
                      mixerlineW.cConnections,mixerlineW.cControls);
                trace("        State=0x%08x(%s)\n",
                      mixerlineW.fdwLine,line_flags(mixerlineW.fdwLine));
                trace("        ComponentType=%s\n",
                      component_type(mixerlineW.dwComponentType));
                trace("        Type=%s\n",
                      target_type(mixerlineW.Target.dwType));
                trace("        Device=%d (%s) %d.%d (%d:%d)\n",
                      mixerlineW.Target.dwDeviceID,szPname,
                      mixerlineW.Target.vDriverVersion >> 8,
                      mixerlineW.Target.vDriverVersion & 0xff,
                      mixerlineW.Target.wMid, mixerlineW.Target.wPid);
            }
            ns=mixerlineW.cConnections;
            for(s=0;s<ns;s++) {
                mixerlineW.cbStruct = sizeof(mixerlineW);
                mixerlineW.dwDestination=d;
                mixerlineW.dwSource=s;
                rc = mixerGetLineInfoW(mix, &mixerlineW, MIXER_GETLINEINFOF_SOURCE);
                ok(rc==MMSYSERR_NOERROR||rc==MMSYSERR_NODRIVER,
                   "mixerGetLineInfoW(MIXER_GETLINEINFOF_SOURCE): "
                   "MMSYSERR_NOERROR expected, got %s\n",
                   mmsys_error(rc));
                if (rc==MMSYSERR_NODRIVER)
                    trace("  No Driver\n");
                else if (rc==MMSYSERR_NOERROR) {
                    LPMIXERCONTROLW    array;
                    MIXERLINECONTROLSW controls;
                    if (winetest_interactive) {
                        WideCharToMultiByte(CP_ACP,0,mixerlineW.szShortName,
                            MIXER_SHORT_NAME_CHARS,szShortName,
                            MIXER_SHORT_NAME_CHARS,NULL,NULL);
                        WideCharToMultiByte(CP_ACP,0,mixerlineW.szName,
                            MIXER_LONG_NAME_CHARS,szName,
                            MIXER_LONG_NAME_CHARS,NULL,NULL);
                        WideCharToMultiByte(CP_ACP,0,mixerlineW.Target.szPname,
                            MAXPNAMELEN,szPname,
                            MAXPNAMELEN,NULL, NULL);
                        trace("      %d: \"%s\" (%s) Destination=%d Source=%d\n",
                              s,szShortName,szName,
                              mixerlineW.dwDestination,mixerlineW.dwSource);
                        trace("          LineID=%08x Channels=%d "
                              "Connections=%d Controls=%d\n",
                              mixerlineW.dwLineID,mixerlineW.cChannels,
                              mixerlineW.cConnections,mixerlineW.cControls);
                        trace("          State=0x%08x(%s)\n",
                              mixerlineW.fdwLine,line_flags(mixerlineW.fdwLine));
                        trace("          ComponentType=%s\n",
                              component_type(mixerlineW.dwComponentType));
                        trace("          Type=%s\n",
                              target_type(mixerlineW.Target.dwType));
                        trace("          Device=%d (%s) %d.%d (%d:%d)\n",
                              mixerlineW.Target.dwDeviceID,szPname,
                              mixerlineW.Target.vDriverVersion >> 8,
                              mixerlineW.Target.vDriverVersion & 0xff,
                              mixerlineW.Target.wMid, mixerlineW.Target.wPid);
                    }
                    if (mixerlineW.cControls) {
                        array=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
                            mixerlineW.cControls*sizeof(MIXERCONTROLW));
                        if (array) {
                            rc = mixerGetLineControlsW(mix, 0, MIXER_GETLINECONTROLSF_ALL);
                            ok(rc==MMSYSERR_INVALPARAM,
                               "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
                               "MMSYSERR_INVALPARAM expected, got %s\n",
                               mmsys_error(rc));
                            rc = mixerGetLineControlsW(mix, &controls, -1);
                            ok(rc==MMSYSERR_INVALFLAG||rc==MMSYSERR_INVALPARAM,
                               "mixerGetLineControlsW(-1): "
                               "MMSYSERR_INVALFLAG or MMSYSERR_INVALPARAM expected, got %s\n",
                               mmsys_error(rc));

                            controls.cbStruct = sizeof(MIXERLINECONTROLSW);
                            controls.cControls = mixerlineW.cControls;
                            controls.dwLineID = mixerlineW.dwLineID;
                            controls.pamxctrl = array;
                            controls.cbmxctrl = sizeof(MIXERCONTROLW);

                            /* FIXME: do MIXER_GETLINECONTROLSF_ONEBYID
                             * and MIXER_GETLINECONTROLSF_ONEBYTYPE
                             */
                            rc = mixerGetLineControlsW(mix, &controls, MIXER_GETLINECONTROLSF_ALL);
                            ok(rc==MMSYSERR_NOERROR,
                               "mixerGetLineControlsW(MIXER_GETLINECONTROLSF_ALL): "
                               "MMSYSERR_NOERROR expected, got %s\n",
                               mmsys_error(rc));
                            if (rc==MMSYSERR_NOERROR) {
                                for(nc=0;nc<mixerlineW.cControls;nc++) {
                                    if (winetest_interactive) {
                                        WideCharToMultiByte(CP_ACP,0,array[nc].szShortName,
                                            MIXER_SHORT_NAME_CHARS,szShortName,
                                            MIXER_SHORT_NAME_CHARS,NULL,NULL);
                                        WideCharToMultiByte(CP_ACP,0,array[nc].szName,
                                            MIXER_LONG_NAME_CHARS,szName,
                                            MIXER_LONG_NAME_CHARS,NULL,NULL);
                                        trace("        %d: \"%s\" (%s) ControlID=%d\n", nc,
                                              szShortName, szName, array[nc].dwControlID);
                                        trace("            ControlType=%s\n",
                                               control_type(array[nc].dwControlType));
                                        trace("            Control=0x%08x(%s)\n",
                                              array[nc].fdwControl,
                                              control_flags(array[nc].fdwControl));
                                        trace("            Items=%d Min=%d Max=%d Step=%d\n",
                                              array[nc].cMultipleItems,
                                              S1(array[nc].Bounds).dwMinimum,
                                              S1(array[nc].Bounds).dwMaximum,
                                              array[nc].Metrics.cSteps);
                                    }
                                    mixer_test_controlW(mix, &array[nc]);
                                }
                            }

                            HeapFree(GetProcessHeap(),0,array);
                        }
                    }
                }
            }
        }
        test_mixerClose((HMIXER)mix);
    }
}

static void mixer_testsA(void)
{
    MIXERCAPSA capsA;
    MMRESULT rc;
    UINT ndev, d;

    trace("--- Testing ASCII functions ---\n");

    ndev=mixerGetNumDevs();
    trace("found %d Mixer devices\n",ndev);

    rc=mixerGetDevCapsA(ndev+1,&capsA,sizeof(capsA));
    ok(rc==MMSYSERR_BADDEVICEID,
       "mixerGetDevCapsA: MMSYSERR_BADDEVICEID expected, got %s\n",
       mmsys_error(rc));

    for (d=0;d<ndev;d++)
        mixer_test_deviceA(d);
}

static void mixer_testsW(void)
{
    MIXERCAPSW capsW;
    MMRESULT rc;
    UINT ndev, d;

    trace("--- Testing WCHAR functions ---\n");

    ndev=mixerGetNumDevs();
    trace("found %d Mixer devices\n",ndev);

    rc=mixerGetDevCapsW(ndev+1,&capsW,sizeof(capsW));
    ok(rc==MMSYSERR_BADDEVICEID||rc==MMSYSERR_NOTSUPPORTED,
       "mixerGetDevCapsW: MMSYSERR_BADDEVICEID or MMSYSERR_NOTSUPPORTED "
       "expected, got %s\n", mmsys_error(rc));
    if (rc==MMSYSERR_NOTSUPPORTED)
        return;

    for (d=0;d<ndev;d++)
        mixer_test_deviceW(d);
}

static void test_mixerOpen(void)
{
    HMIXER mix;
    HANDLE event;
    MMRESULT rc;
    UINT ndev, d;

    ndev = mixerGetNumDevs();

    /* Test mixerOpen with invalid device ID values. */
    rc = mixerOpen(&mix, ndev + 1, 0, 0, 0);
    ok(rc == MMSYSERR_BADDEVICEID,
       "mixerOpen: MMSYSERR_BADDEVICEID expected, got %s\n",
       mmsys_error(rc));

    rc = mixerOpen(&mix, -1, 0, 0, 0);
    ok(rc == MMSYSERR_BADDEVICEID ||
       rc == MMSYSERR_INVALHANDLE, /* NT4/W2K */
       "mixerOpen: MMSYSERR_BADDEVICEID or MMSYSERR_INVALHANDLE expected, got %s\n",
       mmsys_error(rc));

    for (d = 0; d < ndev; d++) {
        /* Test mixerOpen with valid device ID values and invalid parameters. */
        rc = mixerOpen(&mix, d, 0, 0, CALLBACK_FUNCTION);
        ok(rc == MMSYSERR_INVALFLAG
           || rc == MMSYSERR_NOTSUPPORTED, /* 98/ME */
           "mixerOpen: MMSYSERR_INVALFLAG expected, got %s\n",
           mmsys_error(rc));

        rc = mixerOpen(&mix, d, 0xdeadbeef, 0, CALLBACK_WINDOW);
        ok(rc == MMSYSERR_INVALPARAM ||
           broken(rc == MMSYSERR_NOERROR /* 98 */),
           "mixerOpen: MMSYSERR_INVALPARAM expected, got %s\n",
           mmsys_error(rc));
        if (rc == MMSYSERR_NOERROR)
            test_mixerClose(mix);

        /* Test mixerOpen with a NULL dwCallback and CALLBACK_WINDOW flag. */
        rc = mixerOpen(&mix, d, 0, 0, CALLBACK_WINDOW);
        ok(rc == MMSYSERR_NOERROR,
           "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc == MMSYSERR_NOERROR)
            test_mixerClose(mix);

        rc = mixerOpen(&mix, d, 0, 0, CALLBACK_THREAD);
        ok(rc == MMSYSERR_NOERROR /* since w2k */ ||
           rc == MMSYSERR_NOTSUPPORTED, /* 98 */
           "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc == MMSYSERR_NOERROR)
            test_mixerClose(mix);

        rc = mixerOpen(&mix, d, 0, 0, CALLBACK_EVENT);
        ok(rc == MMSYSERR_NOERROR /* since w2k */ ||
           rc == MMSYSERR_NOTSUPPORTED, /* 98 */
           "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc == MMSYSERR_NOERROR)
            test_mixerClose(mix);

        event = CreateEventW(NULL, FALSE, FALSE, NULL);

        /* NOTSUPPORTED is not broken, but it enables the todo_wine marker. */
        rc = mixerOpen(&mix, d, (DWORD_PTR)event, 0, CALLBACK_EVENT);
        todo_wine
        ok(rc == MMSYSERR_NOERROR /* since w2k */ ||
           broken(rc == MMSYSERR_NOTSUPPORTED), /* 98 */
           "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));
        if (rc == MMSYSERR_NOERROR)
            test_mixerClose(mix);

        /* Test mixerOpen with normal parameters. */
        rc = mixerOpen(&mix, d, 0, 0, 0);
        ok(rc == MMSYSERR_NOERROR,
           "mixerOpen: MMSYSERR_NOERROR expected, got %s\n",
           mmsys_error(rc));

        if (rc == MMSYSERR_NOERROR)
            test_mixerClose(mix);

        rc = WaitForSingleObject(event, 0);
        ok(rc == WAIT_TIMEOUT, "WaitEvent %d\n", rc);
        CloseHandle(event);
    }
}

START_TEST(mixer)
{
    test_mixerOpen();
    mixer_testsA();
    mixer_testsW();
}
