/*
 * Sample AUXILARY Wine Driver
 *
 * Copyright 1994 Martin Ayotte
 */

#define EMULATE_SB16

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "windows.h"
#include "user.h"
#include "driver.h"
#include "mmsystem.h"
#include "debug.h"

#ifdef HAVE_SYS_SOUNDCARD_H
# include <sys/soundcard.h>
#endif
#ifdef HAVE_MACHINE_SOUNDCARD_H
# include <machine/soundcard.h>
#endif

#define MIXER_DEV "/dev/mixer"

#ifdef SOUND_VERSION
#define IOCTL(a,b,c)		ioctl(a,b,&c)
#else
#define IOCTL(a,b,c)		(c = ioctl(a,b,c) )
#endif


static int	NumDev = 6;

/*-----------------------------------------------------------------------*/


/**************************************************************************
 * 				AUX_GetDevCaps			[internal]
 */
static DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPS16 lpCaps, DWORD dwSize)
{
#ifdef HAVE_OSS
	int 	mixer,volume;

	TRACE(mmaux,"(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
	if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
		WARN(mmaux, "mixer device not available !\n");
		return MMSYSERR_NOTENABLED;
	}
	if (ioctl(mixer, SOUND_MIXER_READ_LINE, &volume) == -1) {
		close(mixer);
		WARN(mmaux, "unable read mixer !\n");
		return MMSYSERR_NOTENABLED;
	}
	close(mixer);
#ifdef EMULATE_SB16
	lpCaps->wMid = 0x0002;
	lpCaps->vDriverVersion = 0x0200;
	lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
	switch (wDevID) {
		case 0:
			lpCaps->wPid = 0x0196;
			strcpy(lpCaps->szPname, "SB16 Aux: Wave");
			lpCaps->wTechnology = AUXCAPS_AUXIN;
			break;
		case 1:
			lpCaps->wPid = 0x0197;
			strcpy(lpCaps->szPname, "SB16 Aux: Midi Synth");
			lpCaps->wTechnology = AUXCAPS_AUXIN;
			break;
		case 2:
			lpCaps->wPid = 0x0191;
			strcpy(lpCaps->szPname, "SB16 Aux: CD");
			lpCaps->wTechnology = AUXCAPS_CDAUDIO;
			break;
		case 3:
			lpCaps->wPid = 0x0192;
			strcpy(lpCaps->szPname, "SB16 Aux: Line-In");
			lpCaps->wTechnology = AUXCAPS_AUXIN;
			break;
		case 4:
			lpCaps->wPid = 0x0193;
			strcpy(lpCaps->szPname, "SB16 Aux: Mic");
			lpCaps->wTechnology = AUXCAPS_AUXIN;
			break;
		case 5:
			lpCaps->wPid = 0x0194;
			strcpy(lpCaps->szPname, "SB16 Aux: Master");
			lpCaps->wTechnology = AUXCAPS_AUXIN;
			break;
		}
#else
	lpCaps->wMid = 0xAA;
	lpCaps->wPid = 0x55;
	lpCaps->vDriverVersion = 0x0100;
	strcpy(lpCaps->szPname, "Generic Linux Auxiliary Driver");
	lpCaps->wTechnology = AUXCAPS_CDAUDIO;
	lpCaps->dwSupport = AUXCAPS_VOLUME | AUXCAPS_LRVOLUME;
#endif
	return MMSYSERR_NOERROR;
#else
	return MMSYSERR_NOTENABLED;
#endif
}


/**************************************************************************
 * 				AUX_GetVolume			[internal]
 */
static DWORD AUX_GetVolume(WORD wDevID, LPDWORD lpdwVol)
{
#ifdef HAVE_OSS
	int 	mixer,volume,left,right,cmd;

	TRACE(mmaux,"(%04X, %p);\n", wDevID, lpdwVol);
	if (lpdwVol == NULL) return MMSYSERR_NOTENABLED;
	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
		WARN(mmaux, "mixer device not available !\n");
		return MMSYSERR_NOTENABLED;
	}
	switch(wDevID) {
		case 0:
			TRACE(mmaux,"SOUND_MIXER_READ_PCM !\n");
			cmd = SOUND_MIXER_READ_PCM;
			break;
		case 1:
			TRACE(mmaux,"SOUND_MIXER_READ_SYNTH !\n");
			cmd = SOUND_MIXER_READ_SYNTH;
			break;
		case 2:
			TRACE(mmaux,"SOUND_MIXER_READ_CD !\n");
			cmd = SOUND_MIXER_READ_CD;
			break;
		case 3:
			TRACE(mmaux,"SOUND_MIXER_READ_LINE !\n");
			cmd = SOUND_MIXER_READ_LINE;
			break;
		case 4:
			TRACE(mmaux,"SOUND_MIXER_READ_MIC !\n");
			cmd = SOUND_MIXER_READ_MIC;
			break;
		case 5:
			TRACE(mmaux,"SOUND_MIXER_READ_VOLUME !\n");
			cmd = SOUND_MIXER_READ_VOLUME;
			break;
		default:
			WARN(mmaux, "invalid device id=%04X !\n", wDevID);
			return MMSYSERR_NOTENABLED;
		}
	if (ioctl(mixer, cmd, &volume) == -1) {
		WARN(mmaux, "unable read mixer !\n");
		return MMSYSERR_NOTENABLED;
	}
	close(mixer);
	left = volume & 0x7F;
	right = (volume >> 8) & 0x7F;
	TRACE(mmaux,"left=%d right=%d !\n", left, right);
	*lpdwVol = MAKELONG(left << 9, right << 9);
	return MMSYSERR_NOERROR;
#else
	return MMSYSERR_NOTENABLED;
#endif
}

/**************************************************************************
 * 				AUX_SetVolume			[internal]
 */
static DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
{
#ifdef HAVE_OSS
	int 	mixer;
	int		volume;
	int		cmd;
	TRACE(mmaux,"(%04X, %08lX);\n", wDevID, dwParam);
	volume = (LOWORD(dwParam) >> 9 & 0x7F) + 
		((HIWORD(dwParam) >> 9  & 0x7F) << 8);
	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
		WARN(mmaux, "mixer device not available !\n");
		return MMSYSERR_NOTENABLED;
		}
	switch(wDevID) {
		case 0:
			TRACE(mmaux,"SOUND_MIXER_WRITE_PCM !\n");
			cmd = SOUND_MIXER_WRITE_PCM;
			break;
		case 1:
			TRACE(mmaux,"SOUND_MIXER_WRITE_SYNTH !\n");
			cmd = SOUND_MIXER_WRITE_SYNTH;
			break;
		case 2:
			TRACE(mmaux,"SOUND_MIXER_WRITE_CD !\n");
			cmd = SOUND_MIXER_WRITE_CD;
			break;
		case 3:
			TRACE(mmaux,"SOUND_MIXER_WRITE_LINE !\n");
			cmd = SOUND_MIXER_WRITE_LINE;
			break;
		case 4:
			TRACE(mmaux,"SOUND_MIXER_WRITE_MIC !\n");
			cmd = SOUND_MIXER_WRITE_MIC;
			break;
		case 5:
			TRACE(mmaux,"SOUND_MIXER_WRITE_VOLUME !\n");
			cmd = SOUND_MIXER_WRITE_VOLUME;
			break;
		default:
			WARN(mmaux,"invalid device id=%04X !\n", wDevID);
			return MMSYSERR_NOTENABLED;
		}
    if (ioctl(mixer, cmd, &volume) == -1) {
		WARN(mmaux, "unable set mixer !\n");
		return MMSYSERR_NOTENABLED;
		}
	close(mixer);
	return MMSYSERR_NOERROR;
#else
	return MMSYSERR_NOTENABLED;
#endif
}


/**************************************************************************
 * 				auxMessage			[sample driver]
 */
DWORD auxMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
					DWORD dwParam1, DWORD dwParam2)
{
	TRACE(mmaux,"(%04X, %04X, %08lX, %08lX, %08lX);\n", 
			wDevID, wMsg, dwUser, dwParam1, dwParam2);
	switch(wMsg) {
	case AUXDM_GETDEVCAPS:
		return AUX_GetDevCaps(wDevID,(LPAUXCAPS16)dwParam1,dwParam2);
	case AUXDM_GETNUMDEVS:
		TRACE(mmaux,"return %d;\n", NumDev);
		return NumDev;
	case AUXDM_GETVOLUME:
		return AUX_GetVolume(wDevID,(LPDWORD)dwParam1);
	case AUXDM_SETVOLUME:
		return AUX_SetVolume(wDevID,dwParam1);
	default:
		WARN(mmaux, "unknown message !\n");
	}
	return MMSYSERR_NOTSUPPORTED;
}
