/*
 * Sample MIDI Wine Driver for Linux
 *
 * Copyright 1994 Martin Ayotte
 */

#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "windows.h"
#include "ldt.h"
#include "multimedia.h"
#include "user.h"
#include "driver.h"
#include "mmsystem.h"
#include "xmalloc.h"
#include "debug.h"

static LINUX_MIDIIN	MidiInDev[MAX_MIDIINDRV];
static LINUX_MIDIOUT	MidiOutDev[MAX_MIDIOUTDRV];
static LINUX_MCIMIDI	MCIMidiDev[MAX_MCIMIDIDRV];

/* this is the total number of MIDI devices found */
int MODM_NUMDEVS = 0;

/* this structure holds pointers with information for each MIDI
 * device found.
 */
LPMIDIOUTCAPS16 midiDevices[MAX_MIDIOUTDRV];

/**************************************************************************
 * 			MIDI_NotifyClient			[internal]
 */
static DWORD MIDI_NotifyClient(UINT16 wDevID, WORD wMsg, 
				DWORD dwParam1, DWORD dwParam2)
{
	TRACE(midi,"wDevID = %04X wMsg = %d dwParm1 = %04lX dwParam2 = %04lX\n",wDevID, wMsg, dwParam1, dwParam2);

	switch (wMsg) {
	case MOM_OPEN:
	case MOM_CLOSE:
	case MOM_DONE:
	  if (wDevID > MAX_MIDIOUTDRV) return MCIERR_INTERNAL;
	  
	  if (MidiOutDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
		MidiOutDev[wDevID].midiDesc.dwCallback, 
		MidiOutDev[wDevID].wFlags, 
		MidiOutDev[wDevID].midiDesc.hMidi, 
                wMsg, 
		MidiOutDev[wDevID].midiDesc.dwInstance, 
                dwParam1, 
                dwParam2)) {
	    WARN(midi,"can't notify client !\n");
	    return MMSYSERR_NOERROR;
	  }
	  break;

	case MIM_OPEN:
	case MIM_CLOSE:
	  if (wDevID > MAX_MIDIINDRV) return MCIERR_INTERNAL;
	  
	if (MidiInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
		MidiInDev[wDevID].midiDesc.dwCallback, MidiInDev[wDevID].wFlags, 
		MidiInDev[wDevID].midiDesc.hMidi, wMsg, 
		MidiInDev[wDevID].midiDesc.dwInstance, dwParam1, dwParam2)) {
	    WARN(mciwave,"can't notify client !\n");
		return MMSYSERR_NOERROR;
		}
	  break;
	}
        return 0;
}


/**************************************************************************
 * 				MIDI_ReadByte			[internal]	
 */
static DWORD MIDI_ReadByte(UINT16 wDevID, BYTE *lpbyt)
{
	if (lpbyt != NULL) {
		if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)lpbyt,
			(long) sizeof(BYTE)) == (long) sizeof(BYTE)) {
			return 0;
		}
	}
	WARN(midi, "error reading wDevID=%04X\n", wDevID);
	return MCIERR_INTERNAL;

}


/**************************************************************************
 * 				MIDI_ReadWord			[internal]	
 */
static DWORD MIDI_ReadWord(UINT16 wDevID, LPWORD lpw)
{
	BYTE	hibyte, lobyte;
	if (lpw != NULL) {
		if (MIDI_ReadByte(wDevID, &hibyte) == 0) {
			if (MIDI_ReadByte(wDevID, &lobyte) == 0) {
				*lpw = ((WORD)hibyte << 8) + lobyte;
				return 0;
			}
		}
	}
	WARN(midi, "error reading wDevID=%04X\n", wDevID);
	return MCIERR_INTERNAL;
}


/**************************************************************************
 * 				MIDI_ReadLong			[internal]	
 */
static DWORD MIDI_ReadLong(UINT16 wDevID, LPDWORD lpdw)
{
	WORD	hiword, loword;
	if (lpdw != NULL) {
		if (MIDI_ReadWord(wDevID, &hiword) == 0) {
			if (MIDI_ReadWord(wDevID, &loword) == 0) {
				*lpdw = MAKELONG(loword, hiword);
				return 0;
			}
		}
	}
	WARN(midi, "error reading wDevID=%04X\n", wDevID);
	return MCIERR_INTERNAL;
}


/**************************************************************************
 *  				MIDI_ReadVaryLen		[internal]	
 */
static DWORD MIDI_ReadVaryLen(UINT16 wDevID, LPDWORD lpdw)
{
	BYTE	byte;
	DWORD	value;
	if (lpdw == NULL) return MCIERR_INTERNAL;
	if (MIDI_ReadByte(wDevID, &byte) != 0) {
		WARN(midi, "error reading wDevID=%04X\n", wDevID);
		return MCIERR_INTERNAL;
	}
	value = (DWORD)(byte & 0x7F);
	while (byte & 0x80) {
		if (MIDI_ReadByte(wDevID, &byte) != 0) {
			WARN(midi, "error reading wDevID=%04X\n", wDevID);
			return MCIERR_INTERNAL;
		}
		value = (value << 7) + (byte & 0x7F);
	}
	*lpdw = value;
/*
	TRACE(midi, "val=%08lX \n", value);
*/
	return 0;
}


/**************************************************************************
 * 				MIDI_ReadMThd			[internal]	
 */
static DWORD MIDI_ReadMThd(UINT16 wDevID, DWORD dwOffset)
{
	DWORD	toberead;
	FOURCC	fourcc;
	TRACE(midi, "(%04X, %08lX);\n", wDevID, dwOffset);
	if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
		WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
		return MCIERR_INTERNAL;
	}
	if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC))
		return MCIERR_INTERNAL;
	if (MIDI_ReadLong(wDevID, &toberead) != 0)
		return MCIERR_INTERNAL;
	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].wFormat) != 0)
		return MCIERR_INTERNAL;
	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTracks) != 0)
		return MCIERR_INTERNAL;
	if (MIDI_ReadWord(wDevID, &MCIMidiDev[wDevID].nTempo) != 0)
		return MCIERR_INTERNAL;
	TRACE(midi, "toberead=%08lX, wFormat=%04X nTracks=%04X nTempo=%04X\n",
		toberead, MCIMidiDev[wDevID].wFormat,
		MCIMidiDev[wDevID].nTracks,
		MCIMidiDev[wDevID].nTempo);
	toberead -= 3 * sizeof(WORD);
/*
		ntrks = read16bit ();
		Mf_division = division = read16bit ();
*/
	return 0;
}


static DWORD MIDI_ReadMTrk(UINT16 wDevID, DWORD dwOffset)
{
	DWORD	toberead;
	FOURCC	fourcc;
	if (mmioSeek32(MCIMidiDev[wDevID].hFile, dwOffset, SEEK_SET) != dwOffset) {
		WARN(midi, "can't seek at %08lX begin of 'MThd' \n", dwOffset);
		}
	if (mmioRead32(MCIMidiDev[wDevID].hFile, (HPSTR)&fourcc,
		(long) sizeof(FOURCC)) != (long) sizeof(FOURCC)) {
		return MCIERR_INTERNAL;
		}
	if (MIDI_ReadLong(wDevID, &toberead) != 0) {
		return MCIERR_INTERNAL;
		}
	TRACE(midi, "toberead=%08lX\n", toberead);
	toberead -= 3 * sizeof(WORD);
	MCIMidiDev[wDevID].dwTotalLen = toberead;
	return 0;
}


/**************************************************************************
 * 				MIDI_mciOpen			[internal]	
 */
static DWORD MIDI_mciOpen(UINT16 wDevID, DWORD dwFlags, LPMCI_OPEN_PARMS16 lpParms)
{
	MIDIOPENDESC 	MidiDesc;
	DWORD		dwRet;
	DWORD		dwOffset;
	LPSTR		lpstrElementName;
	char		str[128];

	TRACE(midi, "(%08lX, %p)\n", dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;

	if (MCIMidiDev[wDevID].nUseCount > 0) {
		/* The driver already open on this channel */
		/* If the driver was opened shareable before and this open specifies */
		/* shareable then increment the use count */
		if (MCIMidiDev[wDevID].fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
			++MCIMidiDev[wDevID].nUseCount;
		else
			return MCIERR_MUST_USE_SHAREABLE;
	} else {
		MCIMidiDev[wDevID].nUseCount = 1;
		MCIMidiDev[wDevID].fShareable = dwFlags & MCI_OPEN_SHAREABLE;
		MCIMidiDev[wDevID].hMidiHdr = USER_HEAP_ALLOC(sizeof(MIDIHDR));
	}

	TRACE(midi, "wDevID=%04X\n", wDevID);
/*	lpParms->wDeviceID = wDevID;*/
	TRACE(midi, "lpParms->wDevID=%04X\n", lpParms->wDeviceID);
	TRACE(midi, "before OPEN_ELEMENT\n");
	if (dwFlags & MCI_OPEN_ELEMENT) {
		lpstrElementName = (LPSTR)PTR_SEG_TO_LIN(lpParms->lpstrElementName);
		TRACE(midi, "MCI_OPEN_ELEMENT '%s' !\n", lpstrElementName);
		if (strlen(lpstrElementName) > 0) {
			strcpy(str, lpstrElementName);
			CharUpper32A(str);
			MCIMidiDev[wDevID].hFile = mmioOpen16(str, NULL, 
				MMIO_ALLOCBUF | MMIO_READWRITE | MMIO_EXCLUSIVE);
			if (MCIMidiDev[wDevID].hFile == 0) {
				WARN(midi, "can't find file='%s' !\n", str);
				return MCIERR_FILE_NOT_FOUND;
			}
		} else 
			MCIMidiDev[wDevID].hFile = 0;
	}
	TRACE(midi, "hFile=%u\n", MCIMidiDev[wDevID].hFile);
	memcpy(&MCIMidiDev[wDevID].openParms, lpParms, sizeof(MCI_OPEN_PARMS16));
	MCIMidiDev[wDevID].wNotifyDeviceID = lpParms->wDeviceID;
	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
	MCIMidiDev[wDevID].dwBeginData = 0;
	MCIMidiDev[wDevID].dwTotalLen = 0;
	MidiDesc.hMidi = 0;
	if (MCIMidiDev[wDevID].hFile != 0) {
		MMCKINFO	ckMainRIFF;
		if (mmioDescend(MCIMidiDev[wDevID].hFile, &ckMainRIFF, NULL, 0) != 0) {
			return MCIERR_INTERNAL;
		}
		TRACE(midi,"ParentChunk ckid=%.4s fccType=%.4s cksize=%08lX \n",
				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
				ckMainRIFF.cksize);
		dwOffset = 0;
		if (ckMainRIFF.ckid == mmioFOURCC('R', 'M', 'I', 'D')) {
			TRACE(midi, "is a 'RMID' file \n");
			dwOffset = ckMainRIFF.dwDataOffset;
		}
		if (ckMainRIFF.ckid != mmioFOURCC('M', 'T', 'h', 'd')) {
			WARN(midi, "unknown format !\n");
			return MCIERR_INTERNAL;
		}
		if (MIDI_ReadMThd(wDevID, dwOffset) != 0) {
			WARN(midi, "can't read 'MThd' header \n");
			return MCIERR_INTERNAL;
		}
		dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
		if (MIDI_ReadMTrk(wDevID, dwOffset) != 0) {
			WARN(midi, "can't read 'MTrk' header \n");
			return MCIERR_INTERNAL;
		}
		dwOffset = mmioSeek32(MCIMidiDev[wDevID].hFile, 0, SEEK_CUR);
		MCIMidiDev[wDevID].dwBeginData = dwOffset;
		TRACE(midi, "Chunk Found ckid=%.4s fccType=%.4s cksize=%08lX \n",
				(LPSTR)&ckMainRIFF.ckid, (LPSTR)&ckMainRIFF.fccType,
				ckMainRIFF.cksize);
	}

	dwRet = modMessage(wDevID, MODM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);
/*	dwRet = midMessage(wDevID, MIDM_OPEN, 0, (DWORD)&MidiDesc, CALLBACK_NULL);*/

	return 0;
}

/**************************************************************************
 * 				MIDI_mciStop			[internal]
 */
static DWORD MIDI_mciStop(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;
	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
	TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
			&MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
	return 0;
}


/**************************************************************************
 * 				MIDI_mciClose		[internal]
 */
static DWORD MIDI_mciClose(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
{
	DWORD		dwRet;

	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
	if (MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
		MIDI_mciStop(wDevID, MCI_WAIT, lpParms);
		}
	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
	MCIMidiDev[wDevID].nUseCount--;
	if (MCIMidiDev[wDevID].nUseCount == 0) {
		if (MCIMidiDev[wDevID].hFile != 0) {
			mmioClose32(MCIMidiDev[wDevID].hFile, 0);
			MCIMidiDev[wDevID].hFile = 0;
			TRACE(midi, "hFile closed !\n");
		}
		USER_HEAP_FREE(MCIMidiDev[wDevID].hMidiHdr);
		dwRet = modMessage(wDevID, MODM_CLOSE, 0, 0L, 0L);
		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
/*
		dwRet = midMessage(wDevID, MIDM_CLOSE, 0, 0L, 0L);
		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
*/
		}
	return 0;
}


/**************************************************************************
 * 				MIDI_mciPlay		[internal]
 */
static DWORD MIDI_mciPlay(UINT16 wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{
	int		count,start,end;
	LPMIDIHDR	lpMidiHdr;
	DWORD		dwData,dwRet;
	LPWORD		ptr;

	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (MCIMidiDev[wDevID].hFile == 0) {
		WARN(midi, "can't find file='%08lx' !\n", 
				(DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
		return MCIERR_FILE_NOT_FOUND;
	}
	start = 1; 		end = 99999;
	if (dwFlags & MCI_FROM) {
		start = lpParms->dwFrom; 
		TRACE(midi, "MCI_FROM=%d \n", start);
	}
	if (dwFlags & MCI_TO) {
		end = lpParms->dwTo;
		TRACE(midi, "MCI_TO=%d \n", end);
	}
#if 0
	if (dwFlags & MCI_NOTIFY) {
		TRACE(midi, "MCI_NOTIFY %08lX !\n", lpParms->dwCallback);
		switch(fork()) {
		case -1:
			WARN(midi, "Can't 'fork' process !\n");
			break;
		case 0:
			TRACE(midi, "process started ! play in background ...\n");
			break;
		default:
			TRACE(midi, "process started ! return to caller...\n");
			return 0;
		}
	}
#endif

	lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);

	lpMidiHdr->lpData = (LPSTR)xmalloc(1200);
	if (lpMidiHdr->lpData == NULL) return MCIERR_INTERNAL;
	lpMidiHdr->dwBufferLength = 1024;
	lpMidiHdr->dwUser = 0L;
	lpMidiHdr->dwFlags = 0L;
	dwRet = modMessage(wDevID, MODM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));

/*	TRACE(midi, "after MODM_PREPARE \n"); */

	MCIMidiDev[wDevID].dwStatus = MCI_MODE_PLAY;
	while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
		TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
			&MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);

		ptr = (LPWORD)lpMidiHdr->lpData;
		for (count = 0; count < lpMidiHdr->dwBufferLength; count++) {
			if (MIDI_ReadVaryLen(wDevID, &dwData) != 0) break;
			*ptr = LOWORD(dwData);
		}
/*
		count = mmioRead32(MCIMidiDev[wDevID].hFile, lpMidiHdr->lpData, lpMidiHdr->dwBufferLength);
*/
		TRACE(midi, "after read count = %d\n",count);

		if (count < 1) break;
		lpMidiHdr->dwBytesRecorded = count;
		TRACE(midi, "before MODM_LONGDATA lpMidiHdr=%p dwBytesRecorded=%lu\n",
					lpMidiHdr, lpMidiHdr->dwBytesRecorded);
		dwRet = modMessage(wDevID, MODM_LONGDATA, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
		if (dwRet != MMSYSERR_NOERROR) {
		  switch (dwRet) {
		  case MMSYSERR_NOTENABLED:
		    return MCIERR_DEVICE_NOT_READY;
		    
		  case MIDIERR_NODEVICE:
		    return MCIERR_INVALID_DEVICE_ID;

		  case MIDIERR_UNPREPARED:
		    return MCIERR_DRIVER_INTERNAL;

		  case MIDIERR_STILLPLAYING:
		    return MCIERR_SEQ_PORT_INUSE;

		  case MMSYSERR_INVALPARAM:
		    return MCIERR_CANNOT_LOAD_DRIVER;
		  
		  default:
		    return MCIERR_DRIVER;
		  }	
		}
	      }
	dwRet = modMessage(wDevID, MODM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
	if (lpMidiHdr->lpData != NULL) {
		free(lpMidiHdr->lpData);
		lpMidiHdr->lpData = NULL;
	}
	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
	if (dwFlags & MCI_NOTIFY) {
		TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
	}
	return 0;
      }


/**************************************************************************
 * 				MIDI_mciRecord			[internal]
 */
static DWORD MIDI_mciRecord(UINT16 wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
{
	int			start, end;
	LPMIDIHDR	lpMidiHdr;
	DWORD		dwRet;

	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (MCIMidiDev[wDevID].hFile == 0) {
		WARN(midi, "can't find file='%08lx' !\n", 
			(DWORD)MCIMidiDev[wDevID].openParms.lpstrElementName);
		return MCIERR_FILE_NOT_FOUND;
	}
	start = 1; 		end = 99999;
	if (dwFlags & MCI_FROM) {
		start = lpParms->dwFrom; 
		TRACE(midi, "MCI_FROM=%d \n", start);
	}
	if (dwFlags & MCI_TO) {
		end = lpParms->dwTo;
		TRACE(midi, "MCI_TO=%d \n", end);
	}
	lpMidiHdr = USER_HEAP_LIN_ADDR(MCIMidiDev[wDevID].hMidiHdr);
	lpMidiHdr->lpData = (LPSTR) xmalloc(1200);
	lpMidiHdr->dwBufferLength = 1024;
	lpMidiHdr->dwUser = 0L;
	lpMidiHdr->dwFlags = 0L;
	dwRet = midMessage(wDevID, MIDM_PREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
	TRACE(midi, "after MIDM_PREPARE \n");
	MCIMidiDev[wDevID].dwStatus = MCI_MODE_RECORD;
	while(MCIMidiDev[wDevID].dwStatus != MCI_MODE_STOP) {
		TRACE(midi, "MCIMidiDev[wDevID].dwStatus=%p %d\n",
			&MCIMidiDev[wDevID].dwStatus, MCIMidiDev[wDevID].dwStatus);
		lpMidiHdr->dwBytesRecorded = 0;
		dwRet = midMessage(wDevID, MIDM_START, 0, 0L, 0L);
		TRACE(midi, "after MIDM_START lpMidiHdr=%p dwBytesRecorded=%lu\n",
					lpMidiHdr, lpMidiHdr->dwBytesRecorded);
		if (lpMidiHdr->dwBytesRecorded == 0) break;
	}
	TRACE(midi, "before MIDM_UNPREPARE \n");
	dwRet = midMessage(wDevID, MIDM_UNPREPARE, 0, (DWORD)lpMidiHdr, sizeof(MIDIHDR));
	TRACE(midi, "after MIDM_UNPREPARE \n");
	if (lpMidiHdr->lpData != NULL) {
		free(lpMidiHdr->lpData);
		lpMidiHdr->lpData = NULL;
	}
	MCIMidiDev[wDevID].dwStatus = MCI_MODE_STOP;
	if (dwFlags & MCI_NOTIFY) {
		TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
	}
	return 0;
}


/**************************************************************************
 * 				MIDI_mciPause			[internal]
 */
static DWORD MIDI_mciPause(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;
	return 0;
}


/**************************************************************************
 * 				MIDI_mciResume			[internal]
 */
static DWORD MIDI_mciResume(UINT16 wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;
	return 0;
}


/**************************************************************************
 * 				MIDI_mciSet			[internal]
 */
static DWORD MIDI_mciSet(UINT16 wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
{
	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;
	TRACE(midi, "dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
	TRACE(midi, "dwAudio=%08lX\n", lpParms->dwAudio);
	if (dwFlags & MCI_SET_TIME_FORMAT) {
		switch (lpParms->dwTimeFormat) {
		case MCI_FORMAT_MILLISECONDS:
			TRACE(midi, "MCI_FORMAT_MILLISECONDS !\n");
			break;
		case MCI_FORMAT_BYTES:
			TRACE(midi, "MCI_FORMAT_BYTES !\n");
			break;
		case MCI_FORMAT_SAMPLES:
			TRACE(midi, "MCI_FORMAT_SAMPLES !\n");
			break;
		default:
			WARN(midi, "bad time format !\n");
			return MCIERR_BAD_TIME_FORMAT;
		}
	}
	if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
	if (dwFlags & MCI_SET_DOOR_OPEN) return MCIERR_UNSUPPORTED_FUNCTION;
	if (dwFlags & MCI_SET_DOOR_CLOSED) return MCIERR_UNSUPPORTED_FUNCTION;
	if (dwFlags & MCI_SET_AUDIO)
		TRACE(midi, "MCI_SET_AUDIO !\n");
	if (dwFlags && MCI_SET_ON) {
		TRACE(midi, "MCI_SET_ON !\n");
		if (dwFlags && MCI_SET_AUDIO_LEFT)
			TRACE(midi, "MCI_SET_AUDIO_LEFT !\n");
		if (dwFlags && MCI_SET_AUDIO_RIGHT)
			TRACE(midi, "MCI_SET_AUDIO_RIGHT !\n");
	}
	if (dwFlags & MCI_SET_OFF)
		TRACE(midi, "MCI_SET_OFF !\n");
	if (dwFlags & MCI_SEQ_SET_MASTER)
		TRACE(midi, "MCI_SEQ_SET_MASTER !\n");
	if (dwFlags & MCI_SEQ_SET_SLAVE)
		TRACE(midi, "MCI_SEQ_SET_SLAVE !\n");
	if (dwFlags & MCI_SEQ_SET_OFFSET)
		TRACE(midi, "MCI_SEQ_SET_OFFSET !\n");
	if (dwFlags & MCI_SEQ_SET_PORT)
		TRACE(midi, "MCI_SEQ_SET_PORT !\n");
	if (dwFlags & MCI_SEQ_SET_TEMPO)
		TRACE(midi, "MCI_SEQ_SET_TEMPO !\n");
 	return 0;
}


/**************************************************************************
 * 				MIDI_mciStatus		[internal]
 */
static DWORD MIDI_mciStatus(UINT16 wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
{
	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;
	if (dwFlags & MCI_STATUS_ITEM) {
		switch(lpParms->dwItem) {
		case MCI_STATUS_CURRENT_TRACK:
			lpParms->dwReturn = 1;
			break;
		case MCI_STATUS_LENGTH:
			lpParms->dwReturn = 5555;
			if (dwFlags & MCI_TRACK) {
				lpParms->dwTrack = 1;
				lpParms->dwReturn = 2222;
			}
			break;
		case MCI_STATUS_MODE:
			lpParms->dwReturn = MCI_MODE_STOP;
			break;
		case MCI_STATUS_MEDIA_PRESENT:
			TRACE(midi, "MCI_STATUS_MEDIA_PRESENT !\n");
			lpParms->dwReturn = TRUE;
			break;
		case MCI_STATUS_NUMBER_OF_TRACKS:
			lpParms->dwReturn = 1;
			break;
		case MCI_STATUS_POSITION:
			lpParms->dwReturn = 3333;
			if (dwFlags & MCI_STATUS_START)
				lpParms->dwItem = 1;
			if (dwFlags & MCI_TRACK) {
				lpParms->dwTrack = 1;
				lpParms->dwReturn = 777;
			}
			break;
		case MCI_STATUS_READY:
			TRACE(midi, "MCI_STATUS_READY !\n");
			lpParms->dwReturn = TRUE;
			break;
		case MCI_STATUS_TIME_FORMAT:
			TRACE(midi, "MCI_STATUS_TIME_FORMAT !\n");
			lpParms->dwReturn = MCI_FORMAT_MILLISECONDS;
			break;
		case MCI_SEQ_STATUS_DIVTYPE:
			TRACE(midi, "MCI_SEQ_STATUS_DIVTYPE !\n");
			lpParms->dwReturn = 0;
			break;
		case MCI_SEQ_STATUS_MASTER:
			TRACE(midi, "MCI_SEQ_STATUS_MASTER !\n");
			lpParms->dwReturn = 0;
			break;
		case MCI_SEQ_STATUS_SLAVE:
			TRACE(midi, "MCI_SEQ_STATUS_SLAVE !\n");
			lpParms->dwReturn = 0;
			break;
		case MCI_SEQ_STATUS_OFFSET:
			TRACE(midi, "MCI_SEQ_STATUS_OFFSET !\n");
			lpParms->dwReturn = 0;
			break;
		case MCI_SEQ_STATUS_PORT:
			TRACE(midi, "MCI_SEQ_STATUS_PORT !\n");
			lpParms->dwReturn = 0;
			break;
		case MCI_SEQ_STATUS_TEMPO:
			TRACE(midi, "MCI_SEQ_STATUS_TEMPO !\n");
			lpParms->dwReturn = 0;
			break;
		default:
			WARN(midi, "unknowm command %08lX !\n", lpParms->dwItem);
			return MCIERR_UNRECOGNIZED_COMMAND;
		}
	}
	if (dwFlags & MCI_NOTIFY) {
		TRACE(midi, "MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
		mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback), 
			MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
	}
 	return 0;
}

/**************************************************************************
 * 				MIDI_mciGetDevCaps		[internal]
 */
static DWORD MIDI_mciGetDevCaps(UINT16 wDevID, DWORD dwFlags, 
					LPMCI_GETDEVCAPS_PARMS lpParms)
{
	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;
	if (dwFlags & MCI_GETDEVCAPS_ITEM) {
		switch(lpParms->dwItem) {
		case MCI_GETDEVCAPS_CAN_RECORD:
			lpParms->dwReturn = TRUE;
			break;
		case MCI_GETDEVCAPS_HAS_AUDIO:
			lpParms->dwReturn = TRUE;
			break;
		case MCI_GETDEVCAPS_HAS_VIDEO:
			lpParms->dwReturn = FALSE;
			break;
		case MCI_GETDEVCAPS_DEVICE_TYPE:
			lpParms->dwReturn = MCI_DEVTYPE_SEQUENCER;
			break;
		case MCI_GETDEVCAPS_USES_FILES:
			lpParms->dwReturn = TRUE;
			break;
		case MCI_GETDEVCAPS_COMPOUND_DEVICE:
			lpParms->dwReturn = TRUE;
			break;
		case MCI_GETDEVCAPS_CAN_EJECT:
			lpParms->dwReturn = FALSE;
			break;
		case MCI_GETDEVCAPS_CAN_PLAY:
			lpParms->dwReturn = TRUE;
			break;
		case MCI_GETDEVCAPS_CAN_SAVE:
			lpParms->dwReturn = FALSE;
			break;
		default:
			return MCIERR_UNRECOGNIZED_COMMAND;
		}
	}
 	return 0;
}


/**************************************************************************
 * 				MIDI_mciInfo			[internal]
 */
static DWORD MIDI_mciInfo(UINT16 wDevID, DWORD dwFlags, LPMCI_INFO_PARMS16 lpParms)
{
	TRACE(midi, "(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
	if (lpParms == NULL) return MCIERR_INTERNAL;
	lpParms->lpstrReturn = NULL;
	switch(dwFlags) {
	case MCI_INFO_PRODUCT:
		lpParms->lpstrReturn = "Linux Sound System 0.5";
		break;
	case MCI_INFO_FILE:
		lpParms->lpstrReturn = "FileName";
		break;
	default:
		return MCIERR_UNRECOGNIZED_COMMAND;
	}
	if (lpParms->lpstrReturn != NULL)
		lpParms->dwRetSize = strlen(lpParms->lpstrReturn);
	else
		lpParms->dwRetSize = 0;
 	return 0;
}


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


/**************************************************************************
 * 				midGetDevCaps			[internal]
 */
static DWORD midGetDevCaps(WORD wDevID, LPMIDIINCAPS16 lpCaps, DWORD dwSize)
{
	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
	lpCaps->wMid = 0x00FF; 	        /* Manufac ID */
	lpCaps->wPid = 0x0001; 	        /* Product ID */
	lpCaps->vDriverVersion = 0x001; /* Product Version */
	strcpy(lpCaps->szPname, "Linux MIDIIN Driver");

	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			midOpen					[internal]
 */
static DWORD midOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
{
	int		midi;
	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
	if (lpDesc == NULL) {
		WARN(midi, "Invalid Parameter !\n");
		return MMSYSERR_INVALPARAM;
	}
	if (wDevID >= MAX_MIDIINDRV) {
		TRACE(midi,"MAX_MIDIINDRV reached !\n");
		return MMSYSERR_ALLOCATED;
	}
	MidiInDev[wDevID].unixdev = 0;
	midi = open (MIDI_DEV, O_RDONLY, 0);
	if (midi == -1) {
		WARN(midi,"can't open !\n");
		return MMSYSERR_NOTENABLED;
	}
	MidiInDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
	switch(MidiInDev[wDevID].wFlags) {
		case DCB_NULL:
			TRACE(midi,"CALLBACK_NULL !\n");
			break;
		case DCB_WINDOW:
			TRACE(midi, "CALLBACK_WINDOW !\n");
			break;
		case DCB_TASK:
			TRACE(midi, "CALLBACK_TASK !\n");
			break;
		case DCB_FUNCTION:
			TRACE(midi, "CALLBACK_FUNCTION !\n");
			break;
	}
	MidiInDev[wDevID].lpQueueHdr = NULL;
	MidiInDev[wDevID].unixdev = midi;
	MidiInDev[wDevID].dwTotalPlayed = 0;
	MidiInDev[wDevID].bufsize = 0x3FFF;
	if (MIDI_NotifyClient(wDevID, MIM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
		WARN(midi,"can't notify client !\n");
		return MMSYSERR_INVALPARAM;
	}
	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			midClose				[internal]
 */
static DWORD midClose(WORD wDevID)
{
	TRACE(midi, "(%04X);\n", wDevID);
	if (MidiInDev[wDevID].unixdev == 0) {
		WARN(midi,"can't close !\n");
		return MMSYSERR_NOTENABLED;
	}
	close(MidiInDev[wDevID].unixdev);
	MidiInDev[wDevID].unixdev = 0;
	MidiInDev[wDevID].bufsize = 0;
	if (MIDI_NotifyClient(wDevID, MIM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
		WARN(midi,"can't notify client !\n");
		return MMSYSERR_INVALPARAM;
	}
	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				midAddBuffer		[internal]
 */
static DWORD midAddBuffer(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
	return MMSYSERR_NOTENABLED;
}

/**************************************************************************
 * 				midPrepare			[internal]
 */
static DWORD midPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
	return MMSYSERR_NOTENABLED;
}

/**************************************************************************
 * 				midUnprepare			[internal]
 */
static DWORD midUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
	return MMSYSERR_NOTENABLED;
}

/**************************************************************************
 * 			midReset				[internal]
 */
static DWORD midReset(WORD wDevID)
{
	TRACE(midi, "(%04X);\n", wDevID);
	return MMSYSERR_NOTENABLED;
}


/**************************************************************************
 * 			midStart				[internal]
 */
static DWORD midStart(WORD wDevID)
{
	TRACE(midi, "(%04X);\n", wDevID);
	return MMSYSERR_NOTENABLED;
}


/**************************************************************************
 *			midStop					[internal]
 */
static DWORD midStop(WORD wDevID)
{
	TRACE(midi, "(%04X);\n", wDevID);
	return MMSYSERR_NOTENABLED;
}


/**************************************************************************
 * 			midMessage				[sample driver]
 */
DWORD WINAPI midMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
					DWORD dwParam1, DWORD dwParam2)
{
	TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n", 
			wDevID, wMsg, dwUser, dwParam1, dwParam2);
	switch(wMsg) {
	case MIDM_OPEN:
		return midOpen(wDevID,(LPMIDIOPENDESC)dwParam1, dwParam2);
	case MIDM_CLOSE:
		return midClose(wDevID);
	case MIDM_ADDBUFFER:
		return midAddBuffer(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
	case MIDM_PREPARE:
		return midPrepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
	case MIDM_UNPREPARE:
		return midUnprepare(wDevID,(LPMIDIHDR)dwParam1, dwParam2);
	case MIDM_GETDEVCAPS:
		return midGetDevCaps(wDevID,(LPMIDIINCAPS16)dwParam1,dwParam2);
	case MIDM_GETNUMDEVS:
		return 0;
	case MIDM_RESET:
		return midReset(wDevID);
	case MIDM_START:
		return midStart(wDevID);
	case MIDM_STOP:
		return midStop(wDevID);
	}
	return MMSYSERR_NOTSUPPORTED;
}

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

/**************************************************************************
 * 				modGetDevCaps			[internal]
 */
static DWORD modGetDevCaps(WORD wDevID, LPMIDIOUTCAPS16 lpCaps, DWORD dwSize)
{
  LPMIDIOUTCAPS16 tmplpCaps;

	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpCaps, dwSize);
  if (wDevID == (WORD) MIDI_MAPPER) { 
	lpCaps->wMid = 0x00FF; 	/* Manufac ID */
	lpCaps->wPid = 0x0001; 	/* Product ID */
	lpCaps->vDriverVersion = 0x001; /* Product Version */
    strcpy(lpCaps->szPname, "MIDI Maper (not functional yet)");
    lpCaps->wTechnology = MOD_FMSYNTH; /* FIXME Does it make any difference ? */
    lpCaps->wVoices     = 14;       /* FIXME */
    lpCaps->wNotes      = 14;       /* FIXME */
    lpCaps->dwSupport   = MIDICAPS_VOLUME|MIDICAPS_LRVOLUME; /* FIXME Does it make any difference ? */
  } else {
    /* FIXME There is a way to do it so easily, but I'm too
     * sleepy to think and I want to test
*/
    tmplpCaps = midiDevices [wDevID];
    lpCaps->wMid = tmplpCaps->wMid;  
    lpCaps->wPid = tmplpCaps->wPid;  
    lpCaps->vDriverVersion = tmplpCaps->vDriverVersion;  
    strcpy(lpCaps->szPname, tmplpCaps->szPname);    
    lpCaps->wTechnology = tmplpCaps->wTechnology;
    lpCaps->wVoices = tmplpCaps->wVoices;  
    lpCaps->wNotes = tmplpCaps->wNotes;  
    lpCaps->dwSupport = tmplpCaps->dwSupport;  
  }
	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			modOpen					[internal]
 */
static DWORD modOpen(WORD wDevID, LPMIDIOPENDESC lpDesc, DWORD dwFlags)
{
	int		midi;

	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
	if (lpDesc == NULL) {
		WARN(midi, "Invalid Parameter !\n");
		return MMSYSERR_INVALPARAM;
	}
	if (wDevID>= MAX_MIDIOUTDRV) {
		TRACE(midi,"MAX_MIDIOUTDRV reached !\n");
		return MMSYSERR_ALLOCATED; /* FIXME isn't MMSYSERR_BADDEVICEID the right answer ? */
	}
	MidiOutDev[wDevID].unixdev = 0;
	midi = open (MIDI_DEV, O_WRONLY, 0);
	if (midi == -1) {
		WARN(midi, "can't open !\n");
		return MMSYSERR_NOTENABLED;
	}
	MidiOutDev[wDevID].wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK);
	switch(MidiOutDev[wDevID].wFlags) {
	case DCB_NULL:
		TRACE(midi,"CALLBACK_NULL !\n");
		break;
	case DCB_WINDOW:
		TRACE(midi, "CALLBACK_WINDOW !\n");
		break;
	case DCB_TASK:
		TRACE(midi, "CALLBACK_TASK !\n");
		break;
	case DCB_FUNCTION:
		TRACE(midi, "CALLBACK_FUNCTION !\n");
		break;
	}
	MidiOutDev[wDevID].lpQueueHdr = NULL;
	MidiOutDev[wDevID].unixdev = midi;
	MidiOutDev[wDevID].dwTotalPlayed = 0;
	MidiOutDev[wDevID].bufsize = 0x3FFF;
	if (MIDI_NotifyClient(wDevID, MOM_OPEN, 0L, 0L) != MMSYSERR_NOERROR) {
		WARN(midi,"can't notify client !\n");
		return MMSYSERR_INVALPARAM;
	}
	TRACE(midi, "Succesful unixdev=%d !\n", midi);
	return MMSYSERR_NOERROR;
}


/**************************************************************************
 * 			modClose				[internal]
 */
static DWORD modClose(WORD wDevID)
{
	TRACE(midi, "(%04X);\n", wDevID);
	if (MidiOutDev[wDevID].unixdev == 0) {
		WARN(midi,"can't close !\n");
		return MMSYSERR_NOTENABLED;
	}
	close(MidiOutDev[wDevID].unixdev);
	MidiOutDev[wDevID].unixdev = 0;
	MidiOutDev[wDevID].bufsize = 0;
	if (MIDI_NotifyClient(wDevID, MOM_CLOSE, 0L, 0L) != MMSYSERR_NOERROR) {
		WARN(midi,"can't notify client !\n");
		return MMSYSERR_INVALPARAM;
	}
	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			modData					[internal]
 */
static DWORD modData(WORD wDevID, DWORD dwParam)
{
	WORD	event;

	TRACE(midi, "(%04X, %08lX);\n", wDevID, dwParam);
	if (MidiOutDev[wDevID].unixdev == 0) {
        	WARN(midi,"can't play !\n");
		return MIDIERR_NODEVICE;
	}
	event = LOWORD(dwParam);
	if (write (MidiOutDev[wDevID].unixdev, 
		&event, sizeof(WORD)) != sizeof(WORD)) {
		WARN(midi, "error writting unixdev !\n");
	}
	return MMSYSERR_NOTENABLED;
}

/**************************************************************************
 *		modLongData					[internal]
 */
static DWORD modLongData(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
	int		count;
	LPWORD	ptr;
	int     en;

	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
	if (MidiOutDev[wDevID].unixdev == 0) {
        WARN(midi,"can't play !\n");
		return MIDIERR_NODEVICE;
		}
	if (lpMidiHdr->lpData == NULL) return MIDIERR_UNPREPARED;
	if (!(lpMidiHdr->dwFlags & MHDR_PREPARED)) return MIDIERR_UNPREPARED;
	if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
	lpMidiHdr->dwFlags &= ~MHDR_DONE;
	lpMidiHdr->dwFlags |= MHDR_INQUEUE;
	TRACE(midi, "dwBytesRecorded %lu !\n", lpMidiHdr->dwBytesRecorded);
	TRACE(midi, "                 %02X %02X %02X %02X\n",
		     lpMidiHdr->lpData[0], lpMidiHdr->lpData[1],
		     lpMidiHdr->lpData[2], lpMidiHdr->lpData[3]);
/*
	count = write (MidiOutDev[wDevID].unixdev, 
		lpMidiHdr->lpData, lpMidiHdr->dwBytesRecorded);
*/
	ptr = (LPWORD)lpMidiHdr->lpData;
	for (count = 0; count < lpMidiHdr->dwBytesRecorded; count++) {
		if (write (MidiOutDev[wDevID].unixdev, ptr, 
			sizeof(WORD)) != sizeof(WORD)) break;
		ptr++;
	}

	en = errno;
	TRACE(midi, "after write count = %d\n",count);
	if (count != lpMidiHdr->dwBytesRecorded) {
		WARN(midi, "error writting unixdev #%d ! (%d != %ld)\n",
			     MidiOutDev[wDevID].unixdev, count, 
			     lpMidiHdr->dwBytesRecorded);
		TRACE(midi, "\terrno = %d error = %s\n",en,strerror(en));
		return MMSYSERR_NOTENABLED;
	}
	lpMidiHdr->dwFlags &= ~MHDR_INQUEUE;
	lpMidiHdr->dwFlags |= MHDR_DONE;
	if (MIDI_NotifyClient(wDevID, MOM_DONE, 0L, 0L) != MMSYSERR_NOERROR) {
		WARN(midi,"can't notify client !\n");
		return MMSYSERR_INVALPARAM;
	}
	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			modPrepare				[internal]
 */
static DWORD modPrepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
	if (MidiOutDev[wDevID].unixdev == 0) {
		WARN(midi,"can't prepare !\n");
		return MMSYSERR_NOTENABLED;
	}
	if (MidiOutDev[wDevID].lpQueueHdr != NULL) {
		TRACE(midi,"already prepare !\n");
		return MMSYSERR_NOTENABLED;
	}
	MidiOutDev[wDevID].dwTotalPlayed = 0;
	MidiOutDev[wDevID].lpQueueHdr = PTR_SEG_TO_LIN(lpMidiHdr);
	if (lpMidiHdr->dwFlags & MHDR_INQUEUE) return MIDIERR_STILLPLAYING;
	lpMidiHdr->dwFlags |= MHDR_PREPARED;
	lpMidiHdr->dwFlags &= ~MHDR_DONE;
	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 				modUnprepare			[internal]
 */
static DWORD modUnprepare(WORD wDevID, LPMIDIHDR lpMidiHdr, DWORD dwSize)
{
	TRACE(midi, "(%04X, %p, %08lX);\n", wDevID, lpMidiHdr, dwSize);
	if (MidiOutDev[wDevID].unixdev == 0) {
		WARN(midi,"can't unprepare !\n");
		return MMSYSERR_NOTENABLED;
	}
	return MMSYSERR_NOERROR;
}

/**************************************************************************
 * 			modReset				[internal]
 */
static DWORD modReset(WORD wDevID)
{
	TRACE(midi, "(%04X);\n", wDevID);
	return MMSYSERR_NOTENABLED;
}


/**************************************************************************
 * 				modMessage			[sample driver]
 */
DWORD WINAPI modMessage(WORD wDevID, WORD wMsg, DWORD dwUser, 
					DWORD dwParam1, DWORD dwParam2)
{
	TRACE(midi, "(%04X, %04X, %08lX, %08lX, %08lX);\n", 
			wDevID, wMsg, dwUser, dwParam1, dwParam2);
	switch(wMsg) {
	case MODM_OPEN:
		return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
	case MODM_CLOSE:
		return modClose(wDevID);
	case MODM_DATA:
		return modData(wDevID, dwParam1);
	case MODM_LONGDATA:
		return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
	case MODM_PREPARE:
		return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
	case MODM_UNPREPARE:
		return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
	case MODM_GETDEVCAPS:
		return modGetDevCaps(wDevID,(LPMIDIOUTCAPS16)dwParam1,dwParam2);
	case MODM_GETNUMDEVS:
		return MODM_NUMDEVS;
	case MODM_GETVOLUME:
		return 0;
	case MODM_SETVOLUME:
		return 0;
	case MODM_RESET:
		return modReset(wDevID);
	}
	return MMSYSERR_NOTSUPPORTED;
}


/**************************************************************************
 * 				MIDI_DriverProc		[sample driver]
 */
LONG MIDI_DriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
		     DWORD dwParam1, DWORD dwParam2)
{
	switch(wMsg) {
	case DRV_LOAD:
		return 1;
	case DRV_FREE:
		return 1;
	case DRV_OPEN:
		return 1;
	case DRV_CLOSE:
		return 1;
	case DRV_ENABLE:
		return 1;
	case DRV_DISABLE:
		return 1;
	case DRV_QUERYCONFIGURE:
		return 1;
	case DRV_CONFIGURE:
		MessageBox16(0, "Sample Midi Linux Driver !", 
			     "MMLinux Driver", MB_OK);
		return 1;
	case DRV_INSTALL:
		return DRVCNF_RESTART;
	case DRV_REMOVE:
		return DRVCNF_RESTART;
	case MCI_OPEN_DRIVER:
	case MCI_OPEN:
		return MIDI_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(dwParam2));
	case MCI_CLOSE_DRIVER:
	case MCI_CLOSE:
		return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_PLAY:
		return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_RECORD:
		return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_STOP:
		return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_SET:
		return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_PAUSE:
		return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_RESUME:
		return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_STATUS:
		return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_GETDEVCAPS:
		return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
	case MCI_INFO:
		return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(dwParam2));
	default:
		return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
	}
}
/*-----------------------------------------------------------------------*/
