/***************************************************************************
*   NAME:  AUXDEV.C $Revision: 1.1 $
**  COPYRIGHT:
**  "Copyright (c) 1994,1995 by e-Tek Labs"
**
**       "This software is furnished under a license and may be used,
**       copied, or disclosed only in accordance with the terms of such
**       license and with the inclusion of the above copyright notice.
**       This software or any other copies thereof may not be provided or
**       otherwise made available to any other person. No title to and
**       ownership of the software is hereby transfered."
****************************************************************************
* $Log: auxdev.c $
* Revision 1.1  1995/02/23 15:14:59  sdsmith
* Initial revision
***************************************************************************/
#include <windows.h>
#include <mmsystem.h>
#include <mmddk.h>
#include "iw.h"
#include "iwatten.h"
#include "interwav.h"

typedef struct auxinfo_tag {
    DWORD dwControlID;
    DWORD dwLineID;
    DWORD cChannels;
    AUXCAPS caps;
} AUXINFO, *PAUXINFO, FAR *LPAUXINFO;

LPAUXINFO gAuxCaps;
char buf[32];
WORD gNumAuxDevs;
extern int num_outputs;

void auxInit(void)
{
    int i,j,k;
    HGLOBAL hAux;
    char *auxdev = "AuxDev0";
    MIXERLINE mxl, mxls;
    MIXERCONTROL mxctrl;
    MIXERLINECONTROLS mxlc;

    //gNumAuxDevs = GetProfileInt("interwav.drv","NumAuxDevs",2);
    gNumAuxDevs = 2;
    if (gNumAuxDevs) {
	hAux = GlobalAlloc(GHND, (gNumAuxDevs * sizeof(AUXINFO)));
	if (hAux) {
	    gAuxCaps = (LPAUXINFO)GlobalLock(hAux);
	    for (i=0; i<gNumAuxDevs; i++) {
		auxdev[6] = '0' + (i+1);
		//GetProfileString("interwav.drv",auxdev,"error",buf,sizeof(buf));
		//if (iwu_strcmp(buf,"error") != 0) {
		//}
		//else {
		    gAuxCaps[i].caps.wMid = MM_ETEK;
		    gAuxCaps[i].caps.wPid = MM_INTERWAVE_AUX;
		    gAuxCaps[i].caps.vDriverVersion = DRIVER_VERSION;
		    gAuxCaps[i].caps.wTechnology = i+1;
		    gAuxCaps[i].caps.dwSupport = AUXCAPS_VOLUME|AUXCAPS_LRVOLUME;

		    // Find the speaker output
		    for (j=0; j<num_outputs; j++) {
			mxl.cbStruct = sizeof(MIXERLINE);
			mxl.dwDestination = j;
			if (mxdGetLineInfo((LPMIXERLINE)&mxl, MIXER_GETLINEINFOF_DESTINATION) == MMSYSERR_NOERROR) {
			    if (mxl.dwComponentType == MIXERLINE_COMPONENTTYPE_DST_SPEAKERS) {
				mxls.cbStruct = sizeof(MIXERLINE);
				mxls.dwDestination = j;
				for (k=0; k<mxl.cConnections; k++) {
				    mxls.dwSource = k;
				    if (mxdGetLineInfo((LPMIXERLINE)&mxls, MIXER_GETLINEINFOF_SOURCE) == MMSYSERR_NOERROR) {
					if ((((i+1) == AUXCAPS_CDAUDIO) &&
					    (mxls.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC ||
					     mxls.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_AUXILIARY)
				           ) || (((i+1) == AUXCAPS_AUXIN) && (mxls.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_LINE)))
					{
				            gAuxCaps[i].dwLineID = mxls.dwLineID;
					    mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
					    mxlc.dwLineID = mxls.dwLineID;
					    mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
					    mxlc.cControls = 1;
					    mxlc.cbmxctrl = sizeof(MIXERCONTROL);
					    mxlc.pamxctrl = (LPMIXERCONTROL)&mxctrl;
					    if (mxdGetLineControls((LPMIXERLINECONTROLS)&mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE) == MMSYSERR_NOERROR) {
						gAuxCaps[i].dwControlID = mxctrl.dwControlID;
						gAuxCaps[i].cChannels = mxls.cChannels;
						_fmemcpy((LPSTR)(gAuxCaps[i].caps.szPname), (LPSTR)(mxls.szName), MAXPNAMELEN);
					    }
					}
				    }
				}
			    }
			}
		    }
		//}
	    }
	}
	else {
	    gNumAuxDevs = 0;
	}
    }
}

DWORD auxdmGetVolume(UINT device, LPDWORD volume)
{
    DWORD rc;
    MIXERCONTROLDETAILS mxcd;
    LPMIXERCONTROLDETAILS_UNSIGNED lpmxcd_u;
    HGLOBAL hmx;

    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = gAuxCaps[device].dwControlID;
    mxcd.cChannels = gAuxCaps[device].cChannels;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    hmx = GlobalAlloc(GHND, (mxcd.cChannels * mxcd.cbDetails));
    if (hmx) {
	mxcd.paDetails = (LPVOID)GlobalLock(hmx);
	*volume = 0;
	if ((rc = mxdGetControlDetails((LPMIXERCONTROLDETAILS)&mxcd, MIXER_GETCONTROLDETAILSF_VALUE)) == MMSYSERR_NOERROR) {
	    lpmxcd_u = (LPMIXERCONTROLDETAILS_UNSIGNED)mxcd.paDetails;
	    *volume = (lpmxcd_u[1].dwValue << 16) | lpmxcd_u[0].dwValue;
	}
	GlobalFree(hmx);
    }
    return(rc);
}

DWORD auxdmSetVolume(UINT device, DWORD volume)
{
    DWORD rc = MMSYSERR_NOTSUPPORTED;
    MIXERCONTROLDETAILS mxcd;
    LPMIXERCONTROLDETAILS_UNSIGNED lpmxcd_u;
    HGLOBAL hmx;

    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = gAuxCaps[device].dwControlID;
    mxcd.cChannels = gAuxCaps[device].cChannels;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    hmx = GlobalAlloc(GHND, (mxcd.cChannels * mxcd.cbDetails));
    if (hmx) {
	mxcd.paDetails = (LPVOID)GlobalLock(hmx);
	lpmxcd_u = (LPMIXERCONTROLDETAILS_UNSIGNED)mxcd.paDetails;
	lpmxcd_u[0].dwValue = (volume & 0x0000FFFF);
	lpmxcd_u[1].dwValue = (volume & 0xFFFF0000) >> 16;
	rc = mxdSetControlDetails((LPMIXERCONTROLDETAILS)&mxcd, MIXER_SETCONTROLDETAILSF_VALUE);
	GlobalFree(hmx);
    }
}


DWORD FAR PASCAL _loadds auxMessage(UINT uId, UINT uMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)
{
    DWORD rc = MMSYSERR_NOTSUPPORTED;

    switch (uMsg) {
	case AUXDM_GETNUMDEVS:
	    rc = gNumAuxDevs;
	    break;
	case AUXDM_GETDEVCAPS:
	    if(wIWDriverFlags & IWDF_WINDOWS95) {
		_fmemcpy(((MDEVICECAPSEX FAR *)dwParam1)->pCaps, (LPAUXCAPS)&(gAuxCaps[uId].caps), min(sizeof(AUXCAPS),((MDEVICECAPSEX FAR *)dwParam1)->cbSize));
	    }else {
		_fmemcpy((LPAUXCAPS)dwParam1, (LPAUXCAPS)&(gAuxCaps[uId].caps), min(sizeof(MIXERCAPS),(int)dwParam2));
	    }
	    rc = MMSYSERR_NOERROR;
	    break;
	case AUXDM_GETVOLUME:
	    rc = auxdmGetVolume(uId, (LPDWORD)dwParam1);
	    break;
	case AUXDM_SETVOLUME:
	    rc = auxdmSetVolume(uId, dwParam1);
	    break;
	default:
	    break;
    }
    return(rc);
}
