/*
 * Sample MIXER Wine Driver for Linux
 *
 * Copyright 1997 Marcus Meissner
 */

#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 linux
#include <linux/soundcard.h>
#elif __FreeBSD__
#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


/**************************************************************************
 * 				MIX_GetDevCaps			[internal]
 */
static DWORD MIX_GetDevCaps(WORD wDevID, LPMIXERCAPS16 lpCaps, DWORD dwSize)
{
#ifdef linux
	int 		mixer,mask;

	dprintf_info(mmaux,"MIX_GetDevCaps(%04X, %p, %lu);\n", wDevID, lpCaps, dwSize);
	if (lpCaps == NULL) return MMSYSERR_NOTENABLED;
	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0) {
		dprintf_warn(mmaux, "MIX_GetDevCaps // mixer device not available !\n");
		return MMSYSERR_NOTENABLED;
	}
	lpCaps->wMid = 0xAA;
	lpCaps->wPid = 0x55;
	lpCaps->vDriverVersion = 0x0100;
	strcpy(lpCaps->szPname,"WINE Generic Mixer");
	if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &mask) == -1) {
		close(mixer);
		perror("ioctl mixer SOUND_MIXER_DEVMASK");
		return MMSYSERR_NOTENABLED;
	}
	/* FIXME: can the Linux Mixer differ between multiple mixertargets? */
	lpCaps->cDestinations = 1;
	lpCaps->fdwSupport = 0; /* No bits defined yet */

	close(mixer);
	return MMSYSERR_NOERROR;
#else
	return MMSYSERR_NOTENABLED;
#endif
}

#ifdef linux
static char *sdlabels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
static char *sdnames[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
#endif

/**************************************************************************
 * 				MIX_GetLineInfo			[internal]
 */
static DWORD MIX_GetLineInfo(WORD wDevID, LPMIXERLINE16 lpml, DWORD fdwInfo)
{
#ifdef linux
	int 		mixer,i,j,devmask,recsrc,recmask;

	dprintf_info(mmaux,"MIX_GetDevLineInfo(%04X, %p, %lu);\n", wDevID, lpml, fdwInfo);
	if (lpml == NULL) return MMSYSERR_NOTENABLED;
	if ((mixer = open(MIXER_DEV, O_RDWR)) < 0)
		return MMSYSERR_NOTENABLED;

	if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1) {
		close(mixer);
		perror("ioctl mixer SOUND_MIXER_DEVMASK");
		return MMSYSERR_NOTENABLED;
	}
	if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1) {
		close(mixer);
		perror("ioctl mixer SOUND_MIXER_RECSRC");
		return MMSYSERR_NOTENABLED;
	}
	if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1) {
		close(mixer);
		perror("ioctl mixer SOUND_MIXER_RECMASK");
		return MMSYSERR_NOTENABLED;
	}
	lpml->cbStruct = sizeof(MIXERLINE16);
	/* FIXME: set all the variables correctly... the lines below
	 * are very wrong...
	 */
	lpml->fdwLine	= MIXERLINE_LINEF_ACTIVE;
	lpml->cChannels	= 2;

	switch (fdwInfo & MIXER_GETLINEINFOF_QUERYMASK) {
	case MIXER_GETLINEINFOF_DESTINATION:
		/* FIXME: Linux doesn't seem to support multiple outputs? 
		 * So we have only one outputtype, Speaker.
		 */
		lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
		/* we have all connections found in the devmask */
		lpml->cConnections = 0;
		for (j=0;j<31;j++)
			if (devmask & (1<<j))
				lpml->cConnections++;
		break;
	case MIXER_GETLINEINFOF_SOURCE:
		for (i=j=0;j<31;j++) {
			if (devmask & (1<<j)) {
				if (lpml->dwSource == i)
					break;
				i++;
			}
		}
		strcpy(lpml->szShortName,sdlabels[i]);
		strcpy(lpml->szName,sdnames[i]);
		lpml->dwLineID = i;
		switch (i) {
		case SOUND_MIXER_SYNTH:
			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER;
			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
			break;
		case SOUND_MIXER_CD:
			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC;
			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
			break;
		case SOUND_MIXER_LINE:
			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_LINE;
			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
			break;
		case SOUND_MIXER_MIC:
			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE;
			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
			break;
		case SOUND_MIXER_PCM:
			lpml->dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT;
			lpml->fdwLine	|= MIXERLINE_LINEF_SOURCE;
			break;
		default:
			fprintf(stderr,"MIX_GetLineInfo:mixertype %d not handle.\n",i);
			break;
		}
		break;
	case MIXER_GETLINEINFOF_LINEID:
		fprintf(stderr,"MIX_GetLineInfo: _LINEID (%ld) not implemented yet.\n",lpml->dwLineID);
		break;
	case MIXER_GETLINEINFOF_COMPONENTTYPE:
		fprintf(stderr,"MIX_GetLineInfo: _COMPONENTTYPE not implemented yet.\n");
		break;
	case MIXER_GETLINEINFOF_TARGETTYPE:
		fprintf(stderr,"MIX_GetLineInfo: _TARGETTYPE not implemented yet.\n");
		break;
	}
	lpml->Target.dwType = MIXERLINE_TARGETTYPE_AUX;
	close(mixer);
	return MMSYSERR_NOERROR;
#else
	return MMSYSERR_NOTENABLED;
#endif
}

/**************************************************************************
 * 				MIX_GetLineInfo			[internal]
 */
static DWORD MIX_Open(WORD wDevID, LPMIXEROPENDESC lpmod, DWORD flags)
{
#ifdef linux

	dprintf_info(mmaux,"MIX_Open(%04X, %p, %lu);\n",wDevID,lpmod,flags);
	if (lpmod == NULL) return MMSYSERR_NOTENABLED;
	/* hmm. We don't keep the mixer device open. So just pretend it works */
	return MMSYSERR_NOERROR;
#else
	return MMSYSERR_NOTENABLED;
#endif
}

/**************************************************************************
 * 				mixMessage			[sample driver]
 */
DWORD mixMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
					DWORD dwParam1, DWORD dwParam2)
{
	dprintf_info(mmaux,"mixMessage(%04X, %04X, %08lX, %08lX, %08lX);\n", 
			wDevID, wMsg, dwUser, dwParam1, dwParam2);
	switch(wMsg) {
	case MXDM_GETDEVCAPS:
		return MIX_GetDevCaps(wDevID,(LPMIXERCAPS16)dwParam1,dwParam2);
	case MXDM_GETLINEINFO:
		return MIX_GetLineInfo(wDevID,(LPMIXERLINE16)dwParam1,dwParam2);
	case MXDM_GETNUMDEVS:
		dprintf_info(mmsys,"MIX_GetNumDevs() return 1;\n");
		return 1;
	case MXDM_OPEN:
		return MIX_Open(wDevID,(LPMIXEROPENDESC)dwParam1,dwParam2);
	default:
		dprintf_warn(mmaux,"mixMessage // unknown message %d!\n",wMsg);
	}
	return MMSYSERR_NOTSUPPORTED;
}
