/* -*- tab-width: 8; c-basic-offset: 4 -*- */

/*
 * MCI stringinterface
 *
 * Copyright 1995 Marcus Meissner
 */
/* FIXME: special commands of device drivers should be handled by those drivers
 */

/* FIXME: this current implementation does not allow commands like
 * capability <filename> can play
 * which is allowed by the MCI standard.
 */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "windows.h"
#include "heap.h"
#include "ldt.h"
#include "user.h"
#include "driver.h"
#include "mmsystem.h"
#include "multimedia.h"
#include "callback.h"
#include "debug.h"
#include "xmalloc.h"


extern struct WINE_MCIDRIVER mciDrv[MAXMCIDRIVERS];

#define mciGetDrv(wDevID) 	(&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
#define mciGetOpenDrv(wDevID) 	(&(mciGetDrv(wDevID)->mop))

extern int MMSYSTEM_DevIDToIndex(UINT16 wDevID);
extern UINT16 MMSYSTEM_FirstDevID(void);
extern UINT16 MMSYSTEM_NextDevID(UINT16 wDevID);
extern BOOL32 MMSYSTEM_DevIDValid(UINT16 wDevID);

LONG WINAPI DrvDefDriverProc(DWORD dwDevID, HDRVR16 hDriv, WORD wMsg, 
                             DWORD dwParam1, DWORD dwParam2);

/* The reason why I just don't lowercase the keywords array in 
 * mciSendString is left as an exercise to the reader.
 */
#define STRCMP(x,y) lstrcmpi32A(x,y)

/* standard functionparameters for all functions */
#define _MCISTR_PROTO_ \
	WORD wDevID,WORD uDevTyp,LPSTR lpstrReturnString,UINT16 uReturnLength,\
	LPCSTR dev,LPSTR *keywords,UINT16 nrofkeywords,DWORD dwFlags,\
        HWND16 hwndCallback

/* copy string to return pointer including necessary checks 
 * for use in mciSendString()
 */
#define _MCI_STR(s) do {\
	TRACE(mci,"->returns '%s'\n",s);\
	if (lpstrReturnString) {\
	    lstrcpyn32A(lpstrReturnString,s,uReturnLength);\
	    TRACE(mci,"-->'%s'\n",lpstrReturnString);\
	}\
} while(0)

/* calling DriverProc. We need to pass the struct as linear pointer. */
#define _MCI_CALL_DRIVER(cmd,params) \
	switch(uDevTyp) {\
	case MCI_DEVTYPE_CD_AUDIO:\
		res=CDAUDIO_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags, (DWORD)(params));\
		break;\
	case MCI_DEVTYPE_WAVEFORM_AUDIO:\
		res=WAVE_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
		break;\
	case MCI_DEVTYPE_SEQUENCER:\
		res=MIDI_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
		break;\
	case MCI_DEVTYPE_ANIMATION:\
		res=ANIM_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
		break;\
	case MCI_DEVTYPE_DIGITAL_VIDEO:\
		FIXME(mci,"_MCI_CALL_DRIVER: No DIGITAL_VIDEO yet !\n");\
		res=MCIERR_DEVICE_NOT_INSTALLED;\
		break;\
	default:\
		/*res = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverproc,mciGetDrv(wDevID)->modp.wDeviceID,mciGetDrv(wDevID)->hdrv,cmd,dwFlags,(DWORD)(params));\
		  break;*/\
		res = MCIERR_DEVICE_NOT_INSTALLED;\
		break;\
	}
/* print a DWORD in the specified timeformat */
static void
_MCISTR_printtf(char *buf,UINT16 uDevType,DWORD timef,DWORD val) {
    *buf='\0';
    switch (timef) {
    case MCI_FORMAT_MILLISECONDS:
    case MCI_FORMAT_FRAMES:
    case MCI_FORMAT_BYTES:
    case MCI_FORMAT_SAMPLES:
    case MCI_VD_FORMAT_TRACK:
	/*case MCI_SEQ_FORMAT_SONGPTR: sameas MCI_VD_FORMAT_TRACK */
	sprintf(buf,"%ld",val);
	break;
    case MCI_FORMAT_HMS:
	/* well, the macros have the same content*/
	/*FALLTRHOUGH*/
    case MCI_FORMAT_MSF:
	sprintf(buf,"%d:%d:%d",
		MCI_HMS_HOUR(val),
		MCI_HMS_MINUTE(val),
		MCI_HMS_SECOND(val)
		);
	break;
    case MCI_FORMAT_TMSF:
	sprintf(buf,"%d:%d:%d:%d",
		MCI_TMSF_TRACK(val),
		MCI_TMSF_MINUTE(val),
		MCI_TMSF_SECOND(val),
		MCI_TMSF_FRAME(val)
		);
	break;
    default:
	FIXME(mci, "missing timeformat for %ld, report.\n",timef);
	strcpy(buf,"0"); /* hmm */
	break;
    }
    return;
}
/* possible different return types */
#define _MCISTR_int	1
#define _MCISTR_time	2
#define _MCISTR_bool	3
#define _MCISTR_tfname	4
#define _MCISTR_mode	5
#define _MCISTR_divtype	6
#define _MCISTR_seqtype	7
#define _MCISTR_vdmtype	8
#define _MCISTR_devtype	9

static void
_MCISTR_convreturn(int type,DWORD dwReturn,LPSTR lpstrReturnString,
		   WORD uReturnLength,WORD uDevTyp,int timef
		   ) {
    switch (type) {
    case _MCISTR_vdmtype:
	switch (dwReturn) {
	case MCI_VD_MEDIA_CLV:_MCI_STR("CLV");break;
	case MCI_VD_MEDIA_CAV:_MCI_STR("CAV");break;
	default:
	case MCI_VD_MEDIA_OTHER:_MCI_STR("other");break;
	}
	break;
    case _MCISTR_seqtype:
	switch (dwReturn) {
	case MCI_SEQ_NONE:_MCI_STR("none");break;
	case MCI_SEQ_SMPTE:_MCI_STR("smpte");break;
	case MCI_SEQ_FILE:_MCI_STR("file");break;
	case MCI_SEQ_MIDI:_MCI_STR("midi");break;
	default:FIXME(mci,"missing sequencer mode %ld\n",dwReturn);
	}
	break;
    case _MCISTR_mode:
	switch (dwReturn) {
	case MCI_MODE_NOT_READY:_MCI_STR("not ready");break;
	case MCI_MODE_STOP:_MCI_STR("stopped");break;
	case MCI_MODE_PLAY:_MCI_STR("playing");break;
	case MCI_MODE_RECORD:_MCI_STR("recording");break;
	case MCI_MODE_SEEK:_MCI_STR("seeking");break;
	case MCI_MODE_PAUSE:_MCI_STR("paused");break;
	case MCI_MODE_OPEN:_MCI_STR("open");break;
	default:break;
	}
	break;
    case _MCISTR_bool:
	if (dwReturn)
	    _MCI_STR("true");
	else
	    _MCI_STR("false");
	break;
    case _MCISTR_int:{
	char	buf[16];
	sprintf(buf,"%ld",dwReturn);
	_MCI_STR(buf);
	break;
    }
    case _MCISTR_time: {	
	char	buf[100];
	_MCISTR_printtf(buf,uDevTyp,timef,dwReturn);
	_MCI_STR(buf);
	break;
    }
    case _MCISTR_tfname:
	switch (timef) {
	case MCI_FORMAT_MILLISECONDS:_MCI_STR("milliseconds");break;
	case MCI_FORMAT_FRAMES:_MCI_STR("frames");break;
	case MCI_FORMAT_BYTES:_MCI_STR("bytes");break;
	case MCI_FORMAT_SAMPLES:_MCI_STR("samples");break;
	case MCI_FORMAT_HMS:_MCI_STR("hms");break;
	case MCI_FORMAT_MSF:_MCI_STR("msf");break;
	case MCI_FORMAT_TMSF:_MCI_STR("tmsf");break;
	default:
	    FIXME(mci,"missing timefmt for %d, report.\n",timef);
	    break;
	}
	break;
    case _MCISTR_divtype:
	switch (dwReturn) {
	case MCI_SEQ_DIV_PPQN:_MCI_STR("PPQN");break;
	case MCI_SEQ_DIV_SMPTE_24:_MCI_STR("SMPTE 24 frame");break;
	case MCI_SEQ_DIV_SMPTE_25:_MCI_STR("SMPTE 25 frame");break;
	case MCI_SEQ_DIV_SMPTE_30:_MCI_STR("SMPTE 30 frame");break;
	case MCI_SEQ_DIV_SMPTE_30DROP:_MCI_STR("SMPTE 30 frame drop");break;
	}
    case _MCISTR_devtype:
	switch (dwReturn) {
	case MCI_DEVTYPE_VCR:_MCI_STR("vcr");break;
	case MCI_DEVTYPE_VIDEODISC:_MCI_STR("videodisc");break;
	case MCI_DEVTYPE_CD_AUDIO:_MCI_STR("cd audio");break;
	case MCI_DEVTYPE_OVERLAY:_MCI_STR("overlay");break;
	case MCI_DEVTYPE_DAT:_MCI_STR("dat");break;
	case MCI_DEVTYPE_SCANNER:_MCI_STR("scanner");break;
	case MCI_DEVTYPE_ANIMATION:_MCI_STR("animation");break;
	case MCI_DEVTYPE_DIGITAL_VIDEO:_MCI_STR("digital video");break;
	case MCI_DEVTYPE_OTHER:_MCI_STR("other");break;
	case MCI_DEVTYPE_WAVEFORM_AUDIO:_MCI_STR("waveform audio");break;
	case MCI_DEVTYPE_SEQUENCER:_MCI_STR("sequencer");break;
	default:FIXME(mci,"unknown device type %ld, report.\n",
		      dwReturn);break;
	}
	break;
    default:
	FIXME(mci,"unknown resulttype %d, report.\n",type);
	break;
    }
}

#define FLAG1(str,flag) \
	if (!STRCMP(keywords[i],str)) {\
		dwFlags |= flag;\
		i++;\
		continue;\
	}
#define FLAG2(str1,str2,flag) \
	if (!STRCMP(keywords[i],str1) && (i+1<nrofkeywords) && !STRCMP(keywords[i+1],str2)) {\
		dwFlags |= flag;\
		i+=2;\
		continue;\
	}

/* All known subcommands are implemented in single functions to avoid
 * bloat and a xxxx lines long mciSendString(). All commands are of the
 * format MCISTR_Cmd(_MCISTR_PROTO_) where _MCISTR_PROTO_ is the above
 * defined line of arguments. (This is just for easy enhanceability.)
 * All functions return the MCIERR_ errorvalue as DWORD. Returnvalues
 * for the calls are in lpstrReturnString (If I mention return values
 * in function headers, I mean returnvalues in lpstrReturnString.)
 * Integers are sprintf("%d")ed integers. Boolean values are 
 * "true" and "false". 
 * timeformat depending values are "%d" "%d:%d" "%d:%d:%d" "%d:%d:%d:%d"
 * FIXME: is above line correct?
 *
 * Preceding every function is a list of implemented/known arguments.
 * Feel free to add missing arguments.
 *
 */

/*
 * Opens the specified MCI driver. 
 * Arguments: <name> 
 * Optional:
 *	"shareable"
 *	"alias <aliasname>"
 * 	"element <elementname>"
 * Additional:
 * waveform audio:
 *	"buffer <nrBytesPerSec>"
 * Animation:
 *	"nostatic"	increaste nr of nonstatic colours
 *	"parent <windowhandle>"
 *	"style <mask>"	bitmask of WS_xxxxx (see windows.h)
 *	"style child"	WS_CHILD
 *	"style overlap"	WS_OVERLAPPED
 *	"style popup"	WS_POPUP
 * Overlay:
 *	"parent <windowhandle>"
 *	"style <mask>"	bitmask of WS_xxxxx (see windows.h)
 *	"style child"	WS_CHILD
 *	"style overlap"	WS_OVERLAPPED
 *	"style popup"	WS_POPUP
 * Returns nothing.
 */
static DWORD
MCISTR_Open(_MCISTR_PROTO_) {
    int			res,i;
    char		*s;
    union U {
	MCI_OPEN_PARMS16	openParams;
	MCI_WAVE_OPEN_PARMS16	waveopenParams;
	MCI_ANIM_OPEN_PARMS16	animopenParams;
	MCI_OVLY_OPEN_PARMS16	ovlyopenParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    
    pU->openParams.lpstrElementName = NULL;
    s=strchr(dev,'!');
    if (s!=NULL) {
	*s++='\0';
	pU->openParams.lpstrElementName=strdup(s);
	dwFlags |= MCI_OPEN_ELEMENT;
    }
    if (!STRCMP(dev,"cdaudio")) {
	uDevTyp=MCI_DEVTYPE_CD_AUDIO;
    } else if (!STRCMP(dev,"waveaudio")) {
	uDevTyp=MCI_DEVTYPE_WAVEFORM_AUDIO;
    } else if (!STRCMP(dev,"sequencer")) {
	uDevTyp=MCI_DEVTYPE_SEQUENCER;
    } else if (!STRCMP(dev,"animation1")) {
	uDevTyp=MCI_DEVTYPE_ANIMATION;
    } else if (!STRCMP(dev,"avivideo")) {
	uDevTyp=MCI_DEVTYPE_DIGITAL_VIDEO;
    } else {
	free(pU->openParams.lpstrElementName);
	free(pU);
	return MCIERR_INVALID_DEVICE_NAME;
    }
    wDevID=MMSYSTEM_FirstDevID();
    while(mciGetDrv(wDevID)->modp.wType) {
	wDevID = MMSYSTEM_NextDevID(wDevID);
	if (!MMSYSTEM_DevIDValid(wDevID)) {
	    TRACE(mci, "MAXMCIDRIVERS reached (%x) !\n", wDevID);
	    free(pU->openParams.lpstrElementName);
	    free(pU);
	    return MCIERR_INTERNAL;
	}
    }
    mciGetDrv(wDevID)->modp.wType	= uDevTyp;
    mciGetDrv(wDevID)->modp.wDeviceID	= 0;  /* FIXME? for multiple devices */
    pU->openParams.dwCallback	= hwndCallback ;
    pU->openParams.wDeviceID	= wDevID;
    pU->openParams.wReserved0   = 0;
    pU->ovlyopenParams.dwStyle	= 0; 
    pU->animopenParams.dwStyle	= 0; 
    pU->openParams.lpstrDeviceType	= strdup(dev);
    pU->openParams.lpstrAlias	= NULL;
    dwFlags |= MCI_OPEN_TYPE;
    i=0;
    while (i<nrofkeywords) {
	FLAG1("shareable",MCI_OPEN_SHAREABLE);
	if (!STRCMP(keywords[i],"alias") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_OPEN_ALIAS;
	    pU->openParams.lpstrAlias=strdup(keywords[i+1]);
	    i+=2;
	    continue;
	}
	if (!STRCMP(keywords[i],"element") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_OPEN_ELEMENT;
	    pU->openParams.lpstrElementName=strdup(keywords[i+1]);
	    i+=2;
	    continue;
	}
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	case MCI_DEVTYPE_DIGITAL_VIDEO:
	    FLAG1("nostatic",MCI_ANIM_OPEN_NOSTATIC);
	    if (!STRCMP(keywords[i],"parent") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_ANIM_OPEN_PARENT;
		sscanf(keywords[i+1],"%hu",&(pU->animopenParams.hWndParent));
		i+=2;
		continue;
	    }
	    if (!STRCMP(keywords[i],"style") && (i+1<nrofkeywords)) {
		DWORD	st;
		
		dwFlags |= MCI_ANIM_OPEN_WS;
		if (!STRCMP(keywords[i+1],"popup")) {
		    pU->animopenParams.dwStyle |= WS_POPUP; 
		} else if (!STRCMP(keywords[i+1],"overlap")) {
		    pU->animopenParams.dwStyle |= WS_OVERLAPPED; 
		} else if (!STRCMP(keywords[i+1],"child")) {
		    pU->animopenParams.dwStyle |= WS_CHILD; 
		} else if (sscanf(keywords[i+1],"%ld",&st)) {
		    pU->animopenParams.dwStyle |= st; 
		} else
		    FIXME(mci,"unknown 'style' keyword %s, please report.\n",keywords[i+1]);
		i+=2;
		continue;
	    }
	    break;
	case MCI_DEVTYPE_WAVEFORM_AUDIO:
	    if (!STRCMP(keywords[i],"buffer") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_WAVE_OPEN_BUFFER;
		sscanf(keywords[i+1],"%ld",&(pU->waveopenParams.dwBufferSeconds));
	    }
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    /* looks just like anim, but without NOSTATIC */
	    if (!STRCMP(keywords[i],"parent") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_OVLY_OPEN_PARENT;
		sscanf(keywords[i+1],"%hd",&(pU->ovlyopenParams.hWndParent));
		i+=2;
		continue;
	    }
	    if (!STRCMP(keywords[i],"style") && (i+1<nrofkeywords)) {
		DWORD	st;
		
		dwFlags |= MCI_OVLY_OPEN_WS;
		if (!STRCMP(keywords[i+1],"popup")) {
		    pU->ovlyopenParams.dwStyle |= WS_POPUP; 
		} else if (!STRCMP(keywords[i+1],"overlap")) {
		    pU->ovlyopenParams.dwStyle |= WS_OVERLAPPED; 
		} else if (!STRCMP(keywords[i+1],"child")) {
		    pU->ovlyopenParams.dwStyle |= WS_CHILD; 
		} else if (sscanf(keywords[i+1],"%ld",&st)) {
		    pU->ovlyopenParams.dwStyle |= st; 
		} else
		    FIXME(mci,"unknown 'style' keyword %s, please report.\n",keywords[i+1]);
		i+=2;
		continue;
	    }
	    break;
	}
	FIXME(mci,"unknown parameter passed %s, please report.\n",
	      keywords[i]);
	i++;
    }
    _MCI_CALL_DRIVER(MCI_OPEN, pU);
    if (res==0)
	memcpy(mciGetOpenDrv(wDevID),&pU->openParams,sizeof(MCI_OPEN_PARMS16));
    else {
 	free(pU->openParams.lpstrElementName);
	free(pU->openParams.lpstrDeviceType);
	free(pU->openParams.lpstrAlias);
    }
    free(pU);
    return res;
}

/* A help function for a lot of others ... 
 * for instance status/play/record/seek etc.
 */
DWORD
_MCISTR_determine_timeformat(LPCSTR dev,WORD wDevID,WORD uDevTyp,int *timef)
{
    int			res;
    DWORD dwFlags = MCI_STATUS_ITEM;
    MCI_STATUS_PARMS *statusParams = xmalloc(sizeof(MCI_STATUS_PARMS));
    
    if (!statusParams) return 0;
    statusParams->dwItem	= MCI_STATUS_TIME_FORMAT;
    statusParams->dwReturn	= 0;
    _MCI_CALL_DRIVER( MCI_STATUS, statusParams );
    if (res==0) *timef = statusParams->dwReturn;
    free(statusParams);
    return res;
}

/* query status of MCI drivers
 * Arguments:
 * Required: 
 *	"mode"	- returns "not ready" "paused" "playing" "stopped" "open" 
 *		  "parked" "recording" "seeking" ....
 * Basics:
 *	"current track"	- returns current track as integer
 *	"length [track <nr>]"	- returns length [of track <nr>] in current 
 *				timeformat
 *	"number of tracks" - returns number of tracks as integer
 *	"position [track <nr>]" - returns position [in track <nr>] in current 
 *				timeformat
 *	"ready"			- checks if device is ready to play, -> bool
 *	"start position"	- returns start position in timeformat
 *	"time format"		- returns timeformat (list of possible values:
 * 				"ms" "msf" "milliseconds" "hmsf" "tmsf" "frames"
 *				"bytes" "samples" "hms")
 *	"media present"		- returns if media is present as bool
 * Animation:
 *	"forward"		- returns "true" if device is playing forwards
 *	"speed"			- returns speed for device
 *	"palette handle"	- returns palette handle
 *	"window handle"		- returns window handle
 * 	"stretch"		- returns stretch bool
 * MIDI sequencer:
 *	"division type"		- ? returns "PPQN" "SMPTE 24 frame" 
 * 			"SMPTE 25 frame" "SMPTE 30 frame" "SMPTE 30 drop frame"
 *	"tempo"			- current tempo in (PPQN? speed in frames, SMPTE*? speed in hsmf)
 *	"offset"		- offset in dito.
 *	"port"			- midi port as integer
 * 	"slave"			- slave device ("midi","file","none","smpte")
 *	"master"		- masterdevice (dito.)
 * Overlay:
 *	"window handle"		- see animation
 *	"stretch"		- dito
 * Video Disc:
 *	"speed"			- speed as integer
 *	"forward"		- returns bool (when playing forward)
 *	"side"			- returns 1 or 2
 *	"media type"		- returns "CAV" "CLV" "other"
 *	"disc size"		- returns "8" or "12"
 * WAVEFORM audio:
 *	"input"			- base queries on input set
 *	"output"		- base queries on output set
 *	"format tag"		- return integer format tag
 *	"channels"		- return integer nr of channels
 *	"bytespersec"		- return average nr of bytes/sec
 *	"samplespersec"		- return nr of samples per sec
 *	"bitspersample"		- return bitspersample
 *	"alignment"		- return block alignment
 *	"level"			- return level?
 */

#define ITEM1(str,item,xtype) \
	if (!STRCMP(keywords[i],str)) {\
		statusParams->dwItem = item;\
		type = xtype;\
		i++;\
		continue;\
	}
#define ITEM2(str1,str2,item,xtype) \
	if (	!STRCMP(keywords[i],str1) &&\
		(i+1<nrofkeywords) &&\
		!STRCMP(keywords[i+1],str2)\
	) {\
		statusParams->dwItem = item;\
		type = xtype;\
		i+=2;\
		continue;\
	}
#define ITEM3(str1,str2,str3,item,xtype) \
	if (	!STRCMP(keywords[i],str1) &&\
		(i+2<nrofkeywords) &&\
		!STRCMP(keywords[i+1],str2) &&\
		!STRCMP(keywords[i+2],str3)\
	) {\
		statusParams->dwItem = item;\
		type = xtype;\
		i+=3;\
		continue;\
	}
static DWORD
MCISTR_Status(_MCISTR_PROTO_) {
    MCI_STATUS_PARMS	*statusParams = xmalloc(sizeof(MCI_STATUS_PARMS));
    int			type = 0,i,res,timef;
    
    statusParams->dwCallback = hwndCallback;
    dwFlags	|= MCI_STATUS_ITEM;
    res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
    if (res) return res;
    
    statusParams->dwReturn	= 0;
    statusParams->dwItem	= 0;
    i = 0;
    
    while (i<nrofkeywords) {
	if (!STRCMP(keywords[i],"track") && (i+1<nrofkeywords)) {
	    sscanf(keywords[i+1],"%ld",&(statusParams->dwTrack));
	    dwFlags |= MCI_TRACK;
	    i+=2;
	    continue;
	}
	FLAG1("start",MCI_STATUS_START);
	/* generic things */
	ITEM2("current","track",MCI_STATUS_CURRENT_TRACK,_MCISTR_time);
	ITEM2("time","format",MCI_STATUS_TIME_FORMAT,_MCISTR_tfname);
	ITEM1("ready",MCI_STATUS_READY,_MCISTR_bool);
	ITEM1("mode",MCI_STATUS_MODE,_MCISTR_mode);
	ITEM3("number","of","tracks",MCI_STATUS_NUMBER_OF_TRACKS,_MCISTR_int);
	ITEM1("length",MCI_STATUS_LENGTH,_MCISTR_time);
	ITEM1("position",MCI_STATUS_POSITION,_MCISTR_time);
	ITEM2("media","present",MCI_STATUS_MEDIA_PRESENT,_MCISTR_bool);
	
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	case MCI_DEVTYPE_DIGITAL_VIDEO:
	    ITEM2("palette","handle",MCI_ANIM_STATUS_HPAL,_MCISTR_int);
	    ITEM2("window","handle",MCI_ANIM_STATUS_HWND,_MCISTR_int);
	    ITEM1("stretch",MCI_ANIM_STATUS_STRETCH,_MCISTR_bool);
	    ITEM1("speed",MCI_ANIM_STATUS_SPEED,_MCISTR_int);
	    ITEM1("forward",MCI_ANIM_STATUS_FORWARD,_MCISTR_bool);
	    break;
	case MCI_DEVTYPE_SEQUENCER:
	    /* just completing the list, not working correctly */
	    ITEM2("division","type",MCI_SEQ_STATUS_DIVTYPE,_MCISTR_divtype);
	    /* tempo ... PPQN in frames/second, SMPTE in hmsf */
	    ITEM1("tempo",MCI_SEQ_STATUS_TEMPO,_MCISTR_int);
	    ITEM1("port",MCI_SEQ_STATUS_PORT,_MCISTR_int);
	    ITEM1("slave",MCI_SEQ_STATUS_SLAVE,_MCISTR_seqtype);
	    ITEM1("master",MCI_SEQ_STATUS_SLAVE,_MCISTR_seqtype);
	    /* offset ... PPQN in frames/second, SMPTE in hmsf */
	    ITEM1("offset",MCI_SEQ_STATUS_SLAVE,_MCISTR_time);
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    ITEM2("window","handle",MCI_OVLY_STATUS_HWND,_MCISTR_int);
	    ITEM1("stretch",MCI_OVLY_STATUS_STRETCH,_MCISTR_bool);
	    break;
	case MCI_DEVTYPE_VIDEODISC:
	    ITEM1("speed",MCI_VD_STATUS_SPEED,_MCISTR_int);
	    ITEM1("forward",MCI_VD_STATUS_FORWARD,_MCISTR_bool);
	    ITEM1("side",MCI_VD_STATUS_SIDE,_MCISTR_int);
	    ITEM2("media","type",MCI_VD_STATUS_SIDE,_MCISTR_vdmtype);
	    /* returns 8 or 12 */
	    ITEM2("disc","size",MCI_VD_STATUS_DISC_SIZE,_MCISTR_int);
	    break;
	case MCI_DEVTYPE_WAVEFORM_AUDIO:
	    /* I am not quite sure if foll. 2 lines are right. */
	    FLAG1("input",MCI_WAVE_INPUT);
	    FLAG1("output",MCI_WAVE_OUTPUT);
	    
	    ITEM2("format","tag",MCI_WAVE_STATUS_FORMATTAG,_MCISTR_int);
	    ITEM1("channels",MCI_WAVE_STATUS_CHANNELS,_MCISTR_int);
	    ITEM1("bytespersec",MCI_WAVE_STATUS_AVGBYTESPERSEC,_MCISTR_int);
	    ITEM1("samplespersec",MCI_WAVE_STATUS_SAMPLESPERSEC,_MCISTR_int);
	    ITEM1("bitspersample",MCI_WAVE_STATUS_BITSPERSAMPLE,_MCISTR_int);
	    ITEM1("alignment",MCI_WAVE_STATUS_BLOCKALIGN,_MCISTR_int);
	    ITEM1("level",MCI_WAVE_STATUS_LEVEL,_MCISTR_int);
	    break;
	}
	FIXME(mci,"unknown keyword '%s'\n",keywords[i]);
	i++;
    }
    if (!statusParams->dwItem) 
	return MCIERR_MISSING_STRING_ARGUMENT;
    
    _MCI_CALL_DRIVER( MCI_STATUS, statusParams );
    if (res==0)
	_MCISTR_convreturn(type,statusParams->dwReturn,lpstrReturnString,uReturnLength,uDevTyp,timef);
    free(statusParams);
    return res;
}
#undef ITEM1
#undef ITEM2
#undef ITEM3

/* set specified parameters in respective MCI drivers
 * Arguments:
 *	"door open"	eject media or somesuch
 *	"door close"	load media
 *	"time format <timeformatname>"	"ms" "milliseconds" "msf" "hmsf" 
 *					"tmsf" "SMPTE 24" "SMPTE 25" "SMPTE 30"
 *					"SMPTE drop 30"
 *	"audio [all|left|right] [on|off]" sets specified audiochannel on or off
 *	"video [on|off]"		sets video on/off
 * Waveform audio:
 *	"formattag pcm"		sets format to pcm
 *	"formattag <nr>"	sets integer formattag value
 *	"any input"		accept input from any known source
 *	"any output"		output to any known destination
 *	"input <nr>"		input from source <nr>
 *	"output <nr>"		output to destination <nr>
 *	"channels <nr>"		sets nr of channels 
 *	"bytespersec <nr>"	sets average bytes per second
 *	"samplespersec <nr>"	sets average samples per second (1 sample can
 *				be 2 bytes!) 
 *	"alignment <nr>"	sets the blockalignment to <nr>
 *	"bitspersample <nr>"	sets the nr of bits per sample
 * Sequencer:
 *	"master [midi|file|smpte|none]" sets the midi master device
 *	"slave [midi|file|smpte|none]" sets the midi master device
 *	"port mapper"		midioutput to portmapper
 *	"port <nr>"		midioutput to specified port
 *	"tempo <nr>"		tempo of track (depends on timeformat/divtype)
 *	"offset <nr>"		start offset?
 */
static DWORD
MCISTR_Set(_MCISTR_PROTO_) {
    union U {
	MCI_SET_PARMS		setParams;
	MCI_WAVE_SET_PARMS16	wavesetParams;
	MCI_SEQ_SET_PARMS	seqsetParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    int	i,res;
    
    pU->setParams.dwCallback = hwndCallback;
    i = 0;
    while (i<nrofkeywords) {
	FLAG2("door","open",MCI_SET_DOOR_OPEN);
	FLAG2("door","closed",MCI_SET_DOOR_CLOSED);
	
	if (	!STRCMP(keywords[i],"time") && 
		(i+2<nrofkeywords) &&
		!STRCMP(keywords[i+1],"format")
		) {
	    dwFlags |= MCI_SET_TIME_FORMAT;
	    
	    /* FIXME:is this a shortcut for milliseconds or
	     *	 minutes:seconds? */
	    if (!STRCMP(keywords[i+2],"ms"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
	    
	    if (!STRCMP(keywords[i+2],"milliseconds"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
	    if (!STRCMP(keywords[i+2],"msf"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_MSF;
	    if (!STRCMP(keywords[i+2],"hms"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_HMS;
	    if (!STRCMP(keywords[i+2],"frames"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_FRAMES;
	    if (!STRCMP(keywords[i+2],"track"))
		pU->setParams.dwTimeFormat = MCI_VD_FORMAT_TRACK;
	    if (!STRCMP(keywords[i+2],"bytes"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_BYTES;
	    if (!STRCMP(keywords[i+2],"samples"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_SAMPLES;
	    if (!STRCMP(keywords[i+2],"tmsf"))
		pU->setParams.dwTimeFormat = MCI_FORMAT_TMSF;
	    if (	!STRCMP(keywords[i+2],"song") && 
			(i+3<nrofkeywords) &&
			!STRCMP(keywords[i+3],"pointer")
			)
		pU->setParams.dwTimeFormat = MCI_SEQ_FORMAT_SONGPTR;
	    if (!STRCMP(keywords[i+2],"smpte") && (i+3<nrofkeywords)) {
		if (!STRCMP(keywords[i+3],"24"))
		    pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_24;
		if (!STRCMP(keywords[i+3],"25"))
		    pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_25;
		if (!STRCMP(keywords[i+3],"30"))
		    pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30;
		if (!STRCMP(keywords[i+3],"drop") && (i+4<nrofkeywords) && !STRCMP(keywords[i+4],"30")) {
		    pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30DROP;
		    i++;
		}
		i++;
				/*FALLTHROUGH*/
	    }
	    i+=3;
	    continue;
	}
	if (!STRCMP(keywords[i],"audio") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_SET_AUDIO;
	    if (!STRCMP(keywords[i+1],"all"))
		pU->setParams.dwAudio = MCI_SET_AUDIO_ALL;
	    if (!STRCMP(keywords[i+1],"left"))
		pU->setParams.dwAudio = MCI_SET_AUDIO_LEFT;
	    if (!STRCMP(keywords[i+1],"right"))
		pU->setParams.dwAudio = MCI_SET_AUDIO_RIGHT;
	    i+=2;
	    continue;
	}
	FLAG1("video",MCI_SET_VIDEO);
	FLAG1("on",MCI_SET_ON);
	FLAG1("off",MCI_SET_OFF);
	switch (uDevTyp) {
	case MCI_DEVTYPE_WAVEFORM_AUDIO:
	    FLAG2("any","input",MCI_WAVE_SET_ANYINPUT);
	    FLAG2("any","output",MCI_WAVE_SET_ANYOUTPUT);
	    
	    if (	!STRCMP(keywords[i],"formattag") && 
			(i+1<nrofkeywords) &&
			!STRCMP(keywords[i+1],"pcm")
			) {
		dwFlags |= MCI_WAVE_SET_FORMATTAG;
		pU->wavesetParams.wFormatTag = WAVE_FORMAT_PCM;
		i+=2;
		continue;
	    }
	    
	    /* <keyword> <integer> */
#define WII(str,flag,fmt,element) \
			if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
				sscanf(keywords[i+1],fmt,&(pU->wavesetParams. element ));\
				dwFlags |= flag;\
				i+=2;\
				continue;\
			}
	    WII("formattag",MCI_WAVE_SET_FORMATTAG,"%hu",wFormatTag);
	    WII("channels",MCI_WAVE_SET_CHANNELS,"%hu",nChannels);
	    WII("bytespersec",MCI_WAVE_SET_AVGBYTESPERSEC,"%lu",nAvgBytesPerSec);
	    WII("samplespersec",MCI_WAVE_SET_SAMPLESPERSEC,"%lu",nSamplesPerSec);
	    WII("alignment",MCI_WAVE_SET_BLOCKALIGN,"%hu",nBlockAlign);
	    WII("bitspersample",MCI_WAVE_SET_BITSPERSAMPLE,"%hu",wBitsPerSample);
	    WII("input",MCI_WAVE_INPUT,"%hu",wInput);
	    WII("output",MCI_WAVE_OUTPUT,"%hu",wOutput);
#undef WII
	    break;
	case MCI_DEVTYPE_SEQUENCER:
	    if (!STRCMP(keywords[i],"master") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_SEQ_SET_MASTER;
		if (!STRCMP(keywords[i+1],"midi"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_MIDI;
		if (!STRCMP(keywords[i+1],"file"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_FILE;
		if (!STRCMP(keywords[i+1],"smpte"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_SMPTE;
		if (!STRCMP(keywords[i+1],"none"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_NONE;
		i+=2;
		continue;
	    }
	    if (!STRCMP(keywords[i],"slave") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_SEQ_SET_SLAVE;
		if (!STRCMP(keywords[i+1],"midi"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_MIDI;
		if (!STRCMP(keywords[i+1],"file"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_FILE;
		if (!STRCMP(keywords[i+1],"smpte"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_SMPTE;
		if (!STRCMP(keywords[i+1],"none"))
		    pU->seqsetParams.dwMaster = MCI_SEQ_NONE;
		i+=2;
		continue;
	    }
	    if (	!STRCMP(keywords[i],"port") && 
			(i+1<nrofkeywords) &&
			!STRCMP(keywords[i+1],"mapper")
			) {
		pU->seqsetParams.dwPort=-1;/* FIXME:not sure*/
		dwFlags |= MCI_SEQ_SET_PORT;
		i+=2;
		continue;
	    }
#define SII(str,flag,element) \
			if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
				sscanf(keywords[i+1],"%ld",&(pU->seqsetParams. element ));\
				dwFlags |= flag;\
				i+=2;\
				continue;\
			}
	    SII("tempo",MCI_SEQ_SET_TEMPO,dwTempo);
	    SII("port",MCI_SEQ_SET_PORT,dwPort);
	    SII("offset",MCI_SEQ_SET_PORT,dwOffset);
	}
	i++;
    }
    if (!dwFlags)
	return MCIERR_MISSING_STRING_ARGUMENT;
    _MCI_CALL_DRIVER( MCI_SET, pU );
    free(pU);
    return res;
}

/* specify break key
 * Arguments: 
 *	"off"		disable break
 *	"on <keyid>"	enable break on key with keyid
 * (I strongly suspect, that there is another parameter:
 *	"window <handle>"	
 * but I don't see it mentioned in my documentation.
 * Returns nothing.
 */
static DWORD
MCISTR_Break(_MCISTR_PROTO_)
{
    MCI_BREAK_PARMS16 *breakParams = xmalloc(sizeof(MCI_BREAK_PARMS16));
    int res,i;
    
    if (!breakParams) return 0;
    /*breakParams.hwndBreak ? */
    for (i = 0; i < nrofkeywords; i++) {
	FLAG1("off",MCI_BREAK_OFF);
	if (!strcmp(keywords[i],"on") && (nrofkeywords>i+1)) {
	    dwFlags&=~MCI_BREAK_OFF;
	    dwFlags|=MCI_BREAK_KEY;
	    sscanf(keywords[i+1],"%hd",&(breakParams->nVirtKey));
	    i+=2;
	    continue;
	}
    }
    _MCI_CALL_DRIVER( MCI_BREAK, breakParams );
    free(breakParams);
    return res;
}

#define ITEM1(str,item,xtype) \
	if (!STRCMP(keywords[i],str)) {\
		gdcParams->dwItem = item;\
		type = xtype;\
		i++;\
		continue;\
	}
#define ITEM2(str1,str2,item,xtype) \
	if (	!STRCMP(keywords[i],str1) &&\
		(i+1<nrofkeywords) &&\
		!STRCMP(keywords[i+1],str2)\
	) {\
		gdcParams->dwItem = item;\
		type = xtype;\
		i+=2;\
		continue;\
	}
#define ITEM3(str1,str2,str3,item,xtype) \
	if (	!STRCMP(keywords[i],str1) &&\
		(i+2<nrofkeywords) &&\
		!STRCMP(keywords[i+1],str2) &&\
		!STRCMP(keywords[i+2],str3)\
	) {\
		gdcParams->dwItem = item;\
		type = xtype;\
		i+=3;\
		continue;\
	}
/* get device capabilities of MCI drivers
 * Arguments:
 * Generic:
 *	"device type"	returns device name as string
 *	"has audio"	returns bool
 *	"has video"	returns bool
 *	"uses files"	returns bool
 *	"compound device"	returns bool
 *	"can record"	returns bool
 *	"can play"	returns bool
 *	"can eject"	returns bool
 *	"can save"	returns bool
 * Animation:
 *	"palettes"	returns nr of available palette entries
 *	"windows"	returns nr of available windows
 *	"can reverse"	returns bool
 *	"can stretch"	returns bool
 *	"slow play rate"	returns the slow playrate
 *	"fast play rate"	returns the fast playrate
 *	"normal play rate"	returns the normal playrate
 * Overlay:
 *	"windows"	returns nr of available windows
 *	"can stretch"	returns bool
 *	"can freeze"	returns bool
 * Videodisc:
 *	"cav"		assume CAV discs (default if no disk inserted)
 *	"clv"		assume CLV discs 
 *	"can reverse"	returns bool
 *	"slow play rate"	returns the slow playrate
 *	"fast play rate"	returns the fast playrate
 *	"normal play rate"	returns the normal playrate
 * Waveform audio:
 *	"inputs"	returns nr of inputdevices
 *	"outputs"	returns nr of outputdevices
 */
static DWORD
MCISTR_Capability(_MCISTR_PROTO_) {
    MCI_GETDEVCAPS_PARMS *gdcParams = xmalloc(sizeof(MCI_GETDEVCAPS_PARMS));
    int	type=0,i,res;
    
    gdcParams->dwCallback = hwndCallback;
    if (!nrofkeywords)
	return MCIERR_MISSING_STRING_ARGUMENT;
    /* well , thats default */
    dwFlags |= MCI_GETDEVCAPS_ITEM;
    gdcParams->dwItem = 0;
    i=0;
    while (i<nrofkeywords) {
	ITEM2("device","type",MCI_GETDEVCAPS_DEVICE_TYPE,_MCISTR_devtype);
	ITEM2("has","audio",MCI_GETDEVCAPS_HAS_AUDIO,_MCISTR_bool);
	ITEM2("has","video",MCI_GETDEVCAPS_HAS_VIDEO,_MCISTR_bool);
	ITEM2("uses","files",MCI_GETDEVCAPS_USES_FILES,_MCISTR_bool);
	ITEM2("compound","device",MCI_GETDEVCAPS_COMPOUND_DEVICE,_MCISTR_bool);
	ITEM2("can","record",MCI_GETDEVCAPS_CAN_RECORD,_MCISTR_bool);
	ITEM2("can","play",MCI_GETDEVCAPS_CAN_PLAY,_MCISTR_bool);
	ITEM2("can","eject",MCI_GETDEVCAPS_CAN_EJECT,_MCISTR_bool);
	ITEM2("can","save",MCI_GETDEVCAPS_CAN_SAVE,_MCISTR_bool);
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	    ITEM1("palettes",MCI_ANIM_GETDEVCAPS_PALETTES,_MCISTR_int);
	    ITEM1("windows",MCI_ANIM_GETDEVCAPS_MAX_WINDOWS,_MCISTR_int);
	    ITEM2("can","reverse",MCI_ANIM_GETDEVCAPS_CAN_REVERSE,_MCISTR_bool);
	    ITEM2("can","stretch",MCI_ANIM_GETDEVCAPS_CAN_STRETCH,_MCISTR_bool);
	    ITEM3("slow","play","rate",MCI_ANIM_GETDEVCAPS_SLOW_RATE,_MCISTR_int);
	    ITEM3("fast","play","rate",MCI_ANIM_GETDEVCAPS_FAST_RATE,_MCISTR_int);
	    ITEM3("normal","play","rate",MCI_ANIM_GETDEVCAPS_NORMAL_RATE,_MCISTR_int);
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    ITEM1("windows",MCI_OVLY_GETDEVCAPS_MAX_WINDOWS,_MCISTR_int);
	    ITEM2("can","freeze",MCI_OVLY_GETDEVCAPS_CAN_FREEZE,_MCISTR_bool);
	    ITEM2("can","stretch",MCI_OVLY_GETDEVCAPS_CAN_STRETCH,_MCISTR_bool);
	    break;
	case MCI_DEVTYPE_VIDEODISC:
	    FLAG1("cav",MCI_VD_GETDEVCAPS_CAV);
	    FLAG1("clv",MCI_VD_GETDEVCAPS_CLV);
	    ITEM2("can","reverse",MCI_VD_GETDEVCAPS_CAN_REVERSE,_MCISTR_bool);
	    ITEM3("slow","play","rate",MCI_VD_GETDEVCAPS_SLOW_RATE,_MCISTR_int);
	    ITEM3("fast","play","rate",MCI_VD_GETDEVCAPS_FAST_RATE,_MCISTR_int);
	    ITEM3("normal","play","rate",MCI_VD_GETDEVCAPS_NORMAL_RATE,_MCISTR_int);
	    break;
	case MCI_DEVTYPE_WAVEFORM_AUDIO:
	    ITEM1("inputs",MCI_WAVE_GETDEVCAPS_INPUTS,_MCISTR_int);
	    ITEM1("outputs",MCI_WAVE_GETDEVCAPS_OUTPUTS,_MCISTR_int);
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_GETDEVCAPS, gdcParams );
    /* no timeformat needed */
    if (res==0)
	_MCISTR_convreturn( type, gdcParams->dwReturn, lpstrReturnString,
			    uReturnLength, uDevTyp, 0 );
    free(gdcParams);
    return res;
}
#undef ITEM1
#undef ITEM2
#undef ITEM3
/* resumes operation of device. no arguments, no return values */
static DWORD
MCISTR_Resume(_MCISTR_PROTO_)
{
    MCI_GENERIC_PARMS *genParams = xmalloc(sizeof(MCI_GENERIC_PARMS));
    int	res;
    genParams->dwCallback = hwndCallback;
    _MCI_CALL_DRIVER( MCI_RESUME, genParams );
    return res;
}

/* pauses operation of device. no arguments, no return values */
static DWORD
MCISTR_Pause(_MCISTR_PROTO_)
{
    MCI_GENERIC_PARMS *genParams = xmalloc(sizeof(MCI_GENERIC_PARMS));
    int res;
    genParams->dwCallback = hwndCallback;
    _MCI_CALL_DRIVER( MCI_PAUSE, genParams );
    return res;
}

/* stops operation of device. no arguments, no return values */
static DWORD
MCISTR_Stop(_MCISTR_PROTO_)
{
    MCI_GENERIC_PARMS *genParams = xmalloc(sizeof(MCI_GENERIC_PARMS));
    int res;
    genParams->dwCallback = hwndCallback;
    _MCI_CALL_DRIVER( MCI_STOP, genParams );
    return res;
}

/* starts recording.
 * Arguments:
 *	"overwrite"	overwrite existing things
 *	"insert"	insert at current position
 *	"to <time>"	record up to <time> (specified in timeformat)
 *	"from <time>"	record from <time> (specified in timeformat)
 */
static DWORD
MCISTR_Record(_MCISTR_PROTO_) {
    int			i,res,timef,nrargs,j,k,a[4];
    char			*parsestr;
    MCI_RECORD_PARMS	*recordParams = xmalloc(sizeof(MCI_RECORD_PARMS));
    
    res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
    if (res) return res;
    
    switch (timef) {
    case MCI_FORMAT_MILLISECONDS:
    case MCI_FORMAT_FRAMES:
    case MCI_FORMAT_BYTES:
    case MCI_FORMAT_SAMPLES:
	nrargs=1;
	parsestr="%d";
	break;
    case MCI_FORMAT_HMS:
    case MCI_FORMAT_MSF:
	parsestr="%d:%d:%d";
	nrargs=3;
	break;
    case MCI_FORMAT_TMSF:
	parsestr="%d:%d:%d:%d";
	nrargs=4;
	break;
    default:FIXME(mci,"unknown timeformat %d, please report.\n",timef);
	parsestr="%d";
	nrargs=1;
	break;
    }
    recordParams->dwCallback = hwndCallback;
    i = 0;
    while (i<nrofkeywords) {
	if (!strcmp(keywords[i],"to") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_TO;
	    a[0]=a[1]=a[2]=a[3]=0;
	    j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
	    /* add up all integers we got, if we have more 
	     * shift them. (Well I should use the macros in 
	     * mmsystem.h, right).
	     */
	    recordParams->dwTo=0;
	    for (k=0;k<j;k++)
		recordParams->dwTo+=a[k]<<(8*(nrargs-k));
	    i+=2;
	    continue;
	}
	if (!strcmp(keywords[i],"from") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_FROM;
	    a[0]=a[1]=a[2]=a[3]=0;
	    j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
	    /* dito. */
	    recordParams->dwFrom=0;
	    for (k=0;k<j;k++)
		recordParams->dwFrom+=a[k]<<(8*(nrargs-k));
	    i+=2;
	    continue;
	}
	FLAG1("insert",MCI_RECORD_INSERT);
	FLAG1("overwrite",MCI_RECORD_OVERWRITE);
	i++;
    }
    _MCI_CALL_DRIVER( MCI_RECORD, recordParams );
    free(recordParams);
    return res;
}

/* play media
 * Arguments:
 * 	"to <time>"	play up to <time> (specified in set timeformat)
 * 	"from <time>"	play from <time> (specified in set timeformat)
 * Animation:
 *	"slow"		play slow
 *	"fast"		play fast 
 *	"scan"		play as fast as possible (with audio disabled perhaps)
 *	"reverse"	play reverse
 *	"speed <fps>"	play with specified frames per second
 * Videodisc:
 *	"slow"		play slow
 *	"fast"		play fast 
 *	"scan"		play as fast as possible (with audio disabled perhaps)
 *	"reverse"	play reverse
 *	"speed <fps>"	play with specified frames per second
 */
static DWORD
MCISTR_Play(_MCISTR_PROTO_) {
    int			i,res,timef,nrargs,j,k,a[4];
    char			*parsestr;
    union U {
	MCI_PLAY_PARMS		playParams;
	MCI_VD_PLAY_PARMS	vdplayParams;
	MCI_ANIM_PLAY_PARMS	animplayParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    
    res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
    if (res) return res;
    switch (timef) {
    case MCI_FORMAT_MILLISECONDS:
    case MCI_FORMAT_FRAMES:
    case MCI_FORMAT_BYTES:
    case MCI_FORMAT_SAMPLES:
	nrargs=1;
	parsestr="%d";
	break;
    case MCI_FORMAT_HMS:
    case MCI_FORMAT_MSF:
	parsestr="%d:%d:%d";
	nrargs=3;
	break;
    case MCI_FORMAT_TMSF:
	parsestr="%d:%d:%d:%d";
	nrargs=4;
	break;
    default:FIXME(mci,"unknown timeformat %d, please report.\n",timef);
	parsestr="%d";
	nrargs=1;
	break;
    }
    pU->playParams.dwCallback=hwndCallback;
    i=0;
    while (i<nrofkeywords) {
	if (!strcmp(keywords[i],"to") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_TO;
	    a[0]=a[1]=a[2]=a[3]=0;
	    j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
	    /* add up all integers we got, if we have more 
	     * shift them. (Well I should use the macros in 
	     * mmsystem.h, right).
	     */
	    pU->playParams.dwTo=0;
	    for (k=0;k<j;k++)
		pU->playParams.dwTo+=a[k]<<(8*(nrargs-k));
	    i+=2;
	    continue;
	}
	if (!strcmp(keywords[i],"from") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_FROM;
	    a[0]=a[1]=a[2]=a[3]=0;
	    j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
	    /* dito. */
	    pU->playParams.dwFrom=0;
	    for (k=0;k<j;k++)
		pU->playParams.dwFrom+=a[k]<<(8*(nrargs-k));
	    i+=2;
	    continue;
	}
	switch (uDevTyp) {
	case MCI_DEVTYPE_VIDEODISC:
	    FLAG1("slow",MCI_VD_PLAY_SLOW);
	    FLAG1("fast",MCI_VD_PLAY_FAST);
	    FLAG1("scan",MCI_VD_PLAY_SCAN);
	    FLAG1("reverse",MCI_VD_PLAY_REVERSE);
	    if (!STRCMP(keywords[i],"speed") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_VD_PLAY_SPEED;
		sscanf(keywords[i+1],"%ld",&(pU->vdplayParams.dwSpeed));
		i+=2;
		continue;
	    }
	    break;
	case MCI_DEVTYPE_ANIMATION:
	    FLAG1("slow",MCI_ANIM_PLAY_SLOW);
	    FLAG1("fast",MCI_ANIM_PLAY_FAST);
	    FLAG1("scan",MCI_ANIM_PLAY_SCAN);
	    FLAG1("reverse",MCI_ANIM_PLAY_REVERSE);
	    if (!STRCMP(keywords[i],"speed") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_ANIM_PLAY_SPEED;
		sscanf(keywords[i+1],"%ld",&(pU->animplayParams.dwSpeed));
		i+=2;
		continue;
	    }
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_PLAY, pU );
    free(pU);
    return res;
}

/* seek to a specified position
 * Arguments:
 *	"to start"	seek to start of medium
 *	"to end"	seek to end of medium
 * 	"to <time>"	seek to <time> specified in current timeformat
 */
static DWORD
MCISTR_Seek(_MCISTR_PROTO_) {
    int		i,res,timef,nrargs,j,k,a[4];
    char		*parsestr;
    MCI_SEEK_PARMS	*seekParams = xmalloc(sizeof(MCI_SEEK_PARMS));
    
    res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
    if (res) return res;
    switch (timef) {
    case MCI_FORMAT_MILLISECONDS:
    case MCI_FORMAT_FRAMES:
    case MCI_FORMAT_BYTES:
    case MCI_FORMAT_SAMPLES:
	nrargs=1;
	parsestr="%d";
	break;
    case MCI_FORMAT_HMS:
    case MCI_FORMAT_MSF:
	parsestr="%d:%d:%d";
	nrargs=3;
	break;
    case MCI_FORMAT_TMSF:
	parsestr="%d:%d:%d:%d";
	nrargs=4;
	break;
    default:FIXME(mci,"unknown timeformat %d, please report.\n",timef);
	parsestr="%d";
	nrargs=1;
	break;
    }
    seekParams->dwCallback=hwndCallback;
    i=0;
    while (i<nrofkeywords) {
	if (	!STRCMP(keywords[i],"to") && (i+1<nrofkeywords)) {
	    if (!STRCMP(keywords[i+1],"start")) {
		dwFlags|=MCI_SEEK_TO_START;
		seekParams->dwTo=0;
		i+=2;
		continue;
	    }
	    if (!STRCMP(keywords[i+1],"end")) {
		dwFlags|=MCI_SEEK_TO_END;
		seekParams->dwTo=0;
		i+=2;
		continue;
	    }
	    dwFlags|=MCI_TO;
	    i+=2;
	    a[0]=a[1]=a[2]=a[3]=0;
	    j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
	    seekParams->dwTo=0;
	    for (k=0;k<j;k++)
		seekParams->dwTo+=a[k]<<(8*(nrargs-k));
	    continue;
	}
	switch (uDevTyp) {
	case MCI_DEVTYPE_VIDEODISC:
	    FLAG1("reverse",MCI_VD_SEEK_REVERSE);
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_SEEK, seekParams );
    free(seekParams);
    return res;
}

/* close media/driver */
static DWORD
MCISTR_Close(_MCISTR_PROTO_)
{
    MCI_GENERIC_PARMS *closeParams = xmalloc(sizeof(MCI_GENERIC_PARMS));
    int res;
    _MCI_CALL_DRIVER( MCI_CLOSE, closeParams );
    free(closeParams);
    return res;
}

/* return information.
 * Arguments:
 *	"product"	return product name (human readable)
 *	"file"		return filename
 * Animation:
 *	"text"		returns text?
 * Overlay:
 *	"text"		returns text?
 */
static DWORD
MCISTR_Info(_MCISTR_PROTO_)
{
    MCI_INFO_PARMS16 *infoParams = xmalloc(sizeof(MCI_INFO_PARMS16));
    DWORD		sflags;
    int		i,res;
    
    sflags = dwFlags;
    i=0;while (i<nrofkeywords) {
	FLAG1("product",MCI_INFO_PRODUCT);
	FLAG1("file",MCI_INFO_FILE);
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	    FLAG1("text",MCI_ANIM_INFO_TEXT);
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    FLAG1("text",MCI_OVLY_INFO_TEXT);
	    break;
	}
	i++;
    }
    if (dwFlags == sflags)
	return MCIERR_MISSING_STRING_ARGUMENT;
    /* MCI driver will fill in lpstrReturn, dwRetSize.
     * FIXME: I don't know if this is correct behaviour
     */
    _MCI_CALL_DRIVER( MCI_INFO, infoParams );
    if (res==0)
	_MCI_STR(infoParams->lpstrReturn);
    free(infoParams);
    return res;
}

/* query MCI driver itself for information
 * Arguments:
 *	"installname"	return install name of <device> (system.ini)
 *	"quantity"	return nr of installed drivers
 *	"open"		open drivers only (additional flag)
 *	"name <nr>"	return nr of devices with <devicetyp>
 *	"name all"	return nr of all devices
 *
 * FIXME: mciSysInfo16() is broken I think.
 */
static DWORD
MCISTR_Sysinfo(_MCISTR_PROTO_) {
    MCI_SYSINFO_PARMS16	sysinfoParams;
    int			i,res;
    
    sysinfoParams.lpstrReturn	= lpstrReturnString;
    sysinfoParams.dwRetSize	= uReturnLength;
    sysinfoParams.wDeviceType	= uDevTyp;
    
    for (i = 0; i < nrofkeywords; i++) {
	FLAG1("installname",MCI_SYSINFO_INSTALLNAME);
	FLAG1("quantity",MCI_SYSINFO_INSTALLNAME);
	FLAG1("open",MCI_SYSINFO_OPEN);
	if (!strcmp(keywords[i],"name") && (i+1<nrofkeywords)) {
	    sscanf(keywords[i+1],"%ld",&(sysinfoParams.dwNumber));
	    dwFlags |= MCI_SYSINFO_NAME;
	    i++;
	}
    }
    res = mciSendCommand(0, MCI_SYSINFO, dwFlags, (DWORD)&sysinfoParams);

    if (dwFlags & MCI_SYSINFO_QUANTITY) {
	char	buf[100];
	
	sprintf(buf,"%ld",*(long*)lpstrReturnString);
	_MCI_STR(buf);
    }
    /* no need to copy anything back, mciSysInfo did it for us */
    return res;
}

/* load file
 * Argument: "<filename>"
 * Overlay: "at <left> <top> <right> <bottom>" additional
 */
static DWORD
MCISTR_Load(_MCISTR_PROTO_) {
    union U {
	MCI_LOAD_PARMS16	loadParams;
	MCI_OVLY_LOAD_PARMS16	ovlyloadParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    int		i,len,res;
    char		*s;
    
    i=0;len=0;
    while (i<nrofkeywords) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_OVERLAY:
	    if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
		dwFlags |= MCI_OVLY_RECT;
		sscanf(keywords[i+1],"%hd",&(pU->ovlyloadParams.rc.left));
		sscanf(keywords[i+2],"%hd",&(pU->ovlyloadParams.rc.top));
		sscanf(keywords[i+3],"%hd",&(pU->ovlyloadParams.rc.right));
		sscanf(keywords[i+4],"%hd",&(pU->ovlyloadParams.rc.bottom));
		memcpy(keywords+i,keywords+(i+5),nrofkeywords-(i+5));
		continue;
	    }
	    break;
	}
	len+=strlen(keywords[i])+1;
	i++;
    }
    s=(char*)xmalloc(len);
    *s='\0';
    while (i<nrofkeywords) {
	strcat(s,keywords[i]);
	i++;
	if (i<nrofkeywords) strcat(s," ");
    }
    pU->loadParams.lpfilename=s;
    dwFlags |= MCI_LOAD_FILE;
    _MCI_CALL_DRIVER( MCI_LOAD, pU );
    free(s);
    free(pU);
    return res;
}

/* save to file
 * Argument: "<filename>"
 * Overlay: "at <left> <top> <right> <bottom>" additional
 */
static DWORD
MCISTR_Save(_MCISTR_PROTO_) {
    union U {
	MCI_SAVE_PARMS	saveParams;
	MCI_OVLY_SAVE_PARMS16	ovlysaveParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    int		i,len,res;
    char		*s;
    
    i=0;len=0;
    while (i<nrofkeywords) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_OVERLAY:
	    if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
		dwFlags |= MCI_OVLY_RECT;
		sscanf(keywords[i+1],"%hd",&(pU->ovlysaveParams.rc.left));
		sscanf(keywords[i+2],"%hd",&(pU->ovlysaveParams.rc.top));
		sscanf(keywords[i+3],"%hd",&(pU->ovlysaveParams.rc.right));
		sscanf(keywords[i+4],"%hd",&(pU->ovlysaveParams.rc.bottom));
		memcpy(keywords+i,keywords+(i+5),nrofkeywords-(i+5));
		continue;
	    }
	    break;
	}
	len+=strlen(keywords[i])+1;
	i++;
    }
    s=(char*)xmalloc(len);
    *s='\0';
    while (i<nrofkeywords) {
	strcat(s,keywords[i]);
	i++;
	if (i<nrofkeywords) strcat(s," ");
    }
    pU->saveParams.lpfilename=s;
    dwFlags |= MCI_LOAD_FILE;
    _MCI_CALL_DRIVER( MCI_SAVE, pU );
    free(s);
    free(pU);
    return res;
}

/* prepare device for input/output
 * (only applyable to waveform audio)
 */
static DWORD
MCISTR_Cue(_MCISTR_PROTO_) {
    MCI_GENERIC_PARMS	*cueParams = xmalloc(sizeof(MCI_GENERIC_PARMS));
    int			i,res;
    
    i=0;
    while (i<nrofkeywords) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_WAVEFORM_AUDIO:
	    FLAG1("input",MCI_WAVE_INPUT);
	    FLAG1("output",MCI_WAVE_OUTPUT);
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_CUE, cueParams );
    free(cueParams);
    return res;
}

/* delete information */
static DWORD
MCISTR_Delete(_MCISTR_PROTO_) {
    int	timef,nrargs,i,j,k,a[4],res;
    char	*parsestr;
    MCI_WAVE_DELETE_PARMS *deleteParams = xmalloc(sizeof(MCI_WAVE_DELETE_PARMS));
    
    /* only implemented for waveform audio */
    if (uDevTyp != MCI_DEVTYPE_WAVEFORM_AUDIO)
	return MCIERR_UNSUPPORTED_FUNCTION; /* well it fits */
    res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
    if (res) return res;
    switch (timef) {
    case MCI_FORMAT_MILLISECONDS:
    case MCI_FORMAT_FRAMES:
    case MCI_FORMAT_BYTES:
    case MCI_FORMAT_SAMPLES:
	nrargs=1;
	parsestr="%d";
	break;
    case MCI_FORMAT_HMS:
    case MCI_FORMAT_MSF:
	parsestr="%d:%d:%d";
	nrargs=3;
	break;
    case MCI_FORMAT_TMSF:
	parsestr="%d:%d:%d:%d";
	nrargs=4;
	break;
    default:FIXME(mci,"unknown timeformat %d, please report.\n",timef);
	parsestr="%d";
	nrargs=1;
	break;
    }
    i=0;
    while (i<nrofkeywords) {
	if (!strcmp(keywords[i],"to") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_TO;
	    a[0]=a[1]=a[2]=a[3]=0;
	    j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
	    /* add up all integers we got, if we have more 
	     * shift them. (Well I should use the macros in 
	     * mmsystem.h, right).
	     */
	    deleteParams->dwTo=0;
	    for (k=0;k<j;k++)
		deleteParams->dwTo+=a[k]<<(8*(nrargs-k));
	    i+=2;
	    continue;
	}
	if (!strcmp(keywords[i],"from") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_FROM;
	    a[0]=a[1]=a[2]=a[3]=0;
	    j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
	    /* dito. */
	    deleteParams->dwFrom=0;
	    for (k=0;k<j;k++)
		deleteParams->dwFrom+=a[k]<<(8*(nrargs-k));
	    i+=2;
	    continue;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_DELETE, deleteParams );
    free(deleteParams);
    return res;
}

/* send command to device. only applies to videodisc */
static DWORD
MCISTR_Escape(_MCISTR_PROTO_)
{
    MCI_VD_ESCAPE_PARMS16 *escapeParams = xmalloc(sizeof(MCI_VD_ESCAPE_PARMS16));
    int			i,len,res;
    char		*s;
    
    if (uDevTyp != MCI_DEVTYPE_VIDEODISC)
	return MCIERR_UNSUPPORTED_FUNCTION;
    i=0;len=0;
    while (i<nrofkeywords) {
	len+=strlen(keywords[i])+1;
	i++;
    }
    s=(char*)malloc(len);
    *s='\0';
    while (i<nrofkeywords) {
	strcat(s,keywords[i]);
	i++;
	if (i<nrofkeywords) strcat(s," ");
    }
    escapeParams->lpstrCommand = s;
    dwFlags |= MCI_VD_ESCAPE_STRING;
    _MCI_CALL_DRIVER( MCI_ESCAPE, escapeParams );
    free(s);
    free(escapeParams);
    return res;
}

/* unfreeze [part of] the overlayed video 
 * only applyable to Overlay devices
 */
static DWORD
MCISTR_Unfreeze(_MCISTR_PROTO_)
{
    MCI_OVLY_RECT_PARMS16 *unfreezeParams = xmalloc(sizeof(MCI_OVLY_RECT_PARMS16));
    int			i,res;
    
    if (uDevTyp != MCI_DEVTYPE_OVERLAY)
	return MCIERR_UNSUPPORTED_FUNCTION;
    i=0;while (i<nrofkeywords) {
	if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
	    sscanf(keywords[i+1],"%hd",&(unfreezeParams->rc.left));
	    sscanf(keywords[i+2],"%hd",&(unfreezeParams->rc.top));
	    sscanf(keywords[i+3],"%hd",&(unfreezeParams->rc.right));
	    sscanf(keywords[i+4],"%hd",&(unfreezeParams->rc.bottom));
	    dwFlags |= MCI_OVLY_RECT;
	    i+=5;
	    continue;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_UNFREEZE, unfreezeParams );
    free(unfreezeParams);
    return res;
}
/* freeze [part of] the overlayed video 
 * only applyable to Overlay devices
 */
static DWORD
MCISTR_Freeze(_MCISTR_PROTO_)
{
    MCI_OVLY_RECT_PARMS16 *freezeParams = xmalloc(sizeof(MCI_OVLY_RECT_PARMS16));
    int			i,res;
    
    if (uDevTyp != MCI_DEVTYPE_OVERLAY)
	return MCIERR_UNSUPPORTED_FUNCTION;
    i=0;while (i<nrofkeywords) {
	if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
	    sscanf(keywords[i+1],"%hd",&(freezeParams->rc.left));
	    sscanf(keywords[i+2],"%hd",&(freezeParams->rc.top));
	    sscanf(keywords[i+3],"%hd",&(freezeParams->rc.right));
	    sscanf(keywords[i+4],"%hd",&(freezeParams->rc.bottom));
	    dwFlags |= MCI_OVLY_RECT;
	    i+=5;
	    continue;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_FREEZE, freezeParams );
    free(freezeParams);
    return res;
}

/* copy parts of image to somewhere else 
 * "source [at <left> <top> <right> <bottom>]"	source is framebuffer [or rect]
 * "destination [at <left> <top> <right> <bottom>]"	destination is framebuffer [or rect]
 * Overlay:
 * "frame [at <left> <top> <right> <bottom>]"	frame is framebuffer [or rect]
 * 						where the video input is placed
 * "video [at <left> <top> <right> <bottom>]"	video is whole video [or rect]
 *						(defining part of input to
 *						be displayed)
 *
 * FIXME: This whole junk is passing multiple rectangles.
 *	I don't know how to do that with the present interface.
 *	(Means code below is broken)
 */
static DWORD
MCISTR_Put(_MCISTR_PROTO_) {
    union U {
	MCI_OVLY_RECT_PARMS16	ovlyputParams;
	MCI_ANIM_RECT_PARMS16	animputParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    int	i,res;
    i=0;while (i<nrofkeywords) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	    FLAG1("source",MCI_ANIM_PUT_SOURCE);
	    FLAG1("destination",MCI_ANIM_PUT_DESTINATION);
	    if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
		sscanf(keywords[i+1],"%hd",&(pU->animputParams.rc.left));
		sscanf(keywords[i+2],"%hd",&(pU->animputParams.rc.top));
		sscanf(keywords[i+3],"%hd",&(pU->animputParams.rc.right));
		sscanf(keywords[i+4],"%hd",&(pU->animputParams.rc.bottom));
		dwFlags |= MCI_ANIM_RECT;
		i+=5;
		continue;
	    }
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    FLAG1("source",MCI_OVLY_PUT_SOURCE);
	    FLAG1("destination",MCI_OVLY_PUT_DESTINATION);
	    FLAG1("video",MCI_OVLY_PUT_VIDEO);
	    FLAG1("frame",MCI_OVLY_PUT_FRAME);
	    if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
		sscanf(keywords[i+1],"%hd",&(pU->ovlyputParams.rc.left));
		sscanf(keywords[i+2],"%hd",&(pU->ovlyputParams.rc.top));
		sscanf(keywords[i+3],"%hd",&(pU->ovlyputParams.rc.right));
		sscanf(keywords[i+4],"%hd",&(pU->ovlyputParams.rc.bottom));
		dwFlags |= MCI_OVLY_RECT;
		i+=5;
		continue;
	    }
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_PUT, pU );
    free(pU);
    return res;
}

/* palette behaviour changing
 * (Animation only)
 * 	"normal"	realize the palette normally
 * 	"background"	realize the palette as background palette
 */
static DWORD
MCISTR_Realize(_MCISTR_PROTO_)
{
    MCI_GENERIC_PARMS	*realizeParams = xmalloc(sizeof(MCI_GENERIC_PARMS));
    int			i,res;
    
    if (uDevTyp != MCI_DEVTYPE_ANIMATION)
	return MCIERR_UNSUPPORTED_FUNCTION;
    i=0;
    while (i<nrofkeywords) {
	FLAG1("background",MCI_ANIM_REALIZE_BKGD);
	FLAG1("normal",MCI_ANIM_REALIZE_NORM);
	i++;
    }
    _MCI_CALL_DRIVER( MCI_REALIZE, realizeParams );
    free(realizeParams);
    return res;
}

/* videodisc spinning
 *	"up"
 *	"down"
 */
static DWORD
MCISTR_Spin(_MCISTR_PROTO_)
{
    MCI_GENERIC_PARMS	*spinParams = xmalloc(sizeof(MCI_GENERIC_PARMS));
    int			i,res;
    
    if (uDevTyp != MCI_DEVTYPE_VIDEODISC)
	return MCIERR_UNSUPPORTED_FUNCTION;
    i=0;
    while (i<nrofkeywords) {
	FLAG1("up",MCI_VD_SPIN_UP);
	FLAG1("down",MCI_VD_SPIN_UP);
	i++;
    }
    _MCI_CALL_DRIVER( MCI_SPIN, spinParams );
    free(spinParams);
    return res;
}

/* step single frames
 * 	"reverse"	optional flag
 *	"by <nr>"	for <nr> frames
 */
static DWORD
MCISTR_Step(_MCISTR_PROTO_) {
    union U {
	MCI_ANIM_STEP_PARMS	animstepParams;
	MCI_VD_STEP_PARMS	vdstepParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    int	i,res;
    
    i=0;
    while (i<nrofkeywords) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	    FLAG1("reverse",MCI_ANIM_STEP_REVERSE);
	    if (!STRCMP(keywords[i],"by") && (i+1<nrofkeywords)) {
		sscanf(keywords[i+1],"%ld",&(pU->animstepParams.dwFrames));
		dwFlags |= MCI_ANIM_STEP_FRAMES;
		i+=2;
		continue;
	    }
	    break;
	case MCI_DEVTYPE_VIDEODISC:
	    FLAG1("reverse",MCI_VD_STEP_REVERSE);
	    if (!STRCMP(keywords[i],"by") && (i+1<nrofkeywords)) {
		sscanf(keywords[i+1],"%ld",&(pU->vdstepParams.dwFrames));
		dwFlags |= MCI_VD_STEP_FRAMES;
		i+=2;
		continue;
	    }
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_STEP, pU );
    free(pU);
    return res;
}

/* update animation window
 * Arguments:
 *	"at <left> <top> <right> <bottom>" only in this rectangle
 *	"hdc"		device context
 */
static DWORD
MCISTR_Update(_MCISTR_PROTO_) {
    int		i,res;
    MCI_ANIM_UPDATE_PARMS16 *updateParams = xmalloc(sizeof(MCI_ANIM_UPDATE_PARMS16));
    
    i=0;
    while (i<nrofkeywords) {
	if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
	    sscanf(keywords[i+1],"%hd",&(updateParams->rc.left));
	    sscanf(keywords[i+2],"%hd",&(updateParams->rc.top));
	    sscanf(keywords[i+3],"%hd",&(updateParams->rc.right));
	    sscanf(keywords[i+4],"%hd",&(updateParams->rc.bottom));
	    dwFlags |= MCI_ANIM_RECT;
	    i+=5;
	    continue;
	}
	if (!STRCMP(keywords[i],"hdc") && (i+1<nrofkeywords)) {
	    dwFlags |= MCI_ANIM_UPDATE_HDC;
	    sscanf(keywords[i+1],"%hd",&(updateParams->hDC));
	    i+=2;
	    continue;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_UPDATE, updateParams );
    free(updateParams);
    return res;
}

/* where command for animation and overlay drivers.
 * just returns the specified rectangle as a string
 * Arguments:
 *	"source"
 *	"destination"
 * Overlay special:
 *	"video"
 *	"frame"
 */
static DWORD
MCISTR_Where(_MCISTR_PROTO_) {
    union U {
	MCI_ANIM_RECT_PARMS16	animwhereParams;
	MCI_OVLY_RECT_PARMS16	ovlywhereParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    int	i,res;
    
    i=0;
    while (i<nrofkeywords) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	    FLAG1("source",MCI_ANIM_WHERE_SOURCE);
	    FLAG1("destination",MCI_ANIM_WHERE_DESTINATION);
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    FLAG1("source",MCI_OVLY_WHERE_SOURCE);
	    FLAG1("destination",MCI_OVLY_WHERE_DESTINATION);
	    FLAG1("video",MCI_OVLY_WHERE_VIDEO);
	    FLAG1("frame",MCI_OVLY_WHERE_FRAME);
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_WHERE, pU );
    if (res==0) {
	char	buf[100];
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	    sprintf(buf,"%d %d %d %d",
		    pU->animwhereParams.rc.left,
		    pU->animwhereParams.rc.top,
		    pU->animwhereParams.rc.right,
		    pU->animwhereParams.rc.bottom
		    );
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    sprintf(buf,"%d %d %d %d",
		    pU->ovlywhereParams.rc.left,
		    pU->ovlywhereParams.rc.top,
		    pU->ovlywhereParams.rc.right,
		    pU->ovlywhereParams.rc.bottom
		    );
	    break;
	default:strcpy(buf,"0 0 0 0");break;
	}
	_MCI_STR(buf);
    }
    free(pU);
    return	res;
}

static DWORD
MCISTR_Window(_MCISTR_PROTO_) {
    int	i,res;
    char	*s;
    union U {
	MCI_ANIM_WINDOW_PARMS16	animwindowParams;
	MCI_OVLY_WINDOW_PARMS16	ovlywindowParams;
    };
    union U *pU = xmalloc(sizeof(union U));
    
    s=NULL;
    i=0;
    while (i<nrofkeywords) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_ANIMATION:
	    if (!STRCMP(keywords[i],"handle") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_ANIM_WINDOW_HWND;
		if (!STRCMP(keywords[i+1],"default")) 
		    pU->animwindowParams.hWnd = MCI_OVLY_WINDOW_DEFAULT;
		else
		    sscanf(keywords[i+1],"%hd",&(pU->animwindowParams.hWnd));
		i+=2;
		continue;
	    }
	    if (!STRCMP(keywords[i],"state") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_ANIM_WINDOW_STATE;
		if (!STRCMP(keywords[i+1],"hide"))
		    pU->animwindowParams.nCmdShow = SW_HIDE;
		if (!STRCMP(keywords[i+1],"iconic"))
		    pU->animwindowParams.nCmdShow = SW_SHOWMINNOACTIVE; /* correct? */
		if (!STRCMP(keywords[i+1],"minimized"))
		    pU->animwindowParams.nCmdShow = SW_SHOWMINIMIZED;
		if (!STRCMP(keywords[i+1],"maximized"))
		    pU->animwindowParams.nCmdShow = SW_SHOWMAXIMIZED;
		if (!STRCMP(keywords[i+1],"minimize"))
		    pU->animwindowParams.nCmdShow = SW_MINIMIZE;
		if (!STRCMP(keywords[i+1],"normal"))
		    pU->animwindowParams.nCmdShow = SW_NORMAL;
		if (!STRCMP(keywords[i+1],"show"))
		    pU->animwindowParams.nCmdShow = SW_SHOW;
		if (!STRCMP(keywords[i+1],"no") && (i+2<nrofkeywords)) {
		    if (!STRCMP(keywords[i+2],"active"))
			pU->animwindowParams.nCmdShow = SW_SHOWNOACTIVATE;
		    if (!STRCMP(keywords[i+2],"action"))
			pU->animwindowParams.nCmdShow = SW_SHOWNA;/* correct?*/
		    i++;
		}
		i+=2;
		continue;
	    }
	    /* text is enclosed in " ... " as it seems */
	    if (!STRCMP(keywords[i],"text")) {
		char	*t;
		int	len,j,k;
		
		if (keywords[i+1][0]!='"') {
		    i++;
		    continue;
		}
		dwFlags |= MCI_ANIM_WINDOW_TEXT;
		len	= strlen(keywords[i+1])+1;
		j	= i+2;
		while (j<nrofkeywords) {
		    len += strlen(keywords[j])+1;
		    if (strchr(keywords[j],'"'))
			break;
		    j++;
		}
		s=(char*)xmalloc(len);
		strcpy(s,keywords[i+1]+1);
		k=j;j=i+2;
		while (j<=k) {
		    strcat(s," ");
		    strcat(s,keywords[j]);
		}
		if ((t=strchr(s,'"'))) *t='\0';
				/* FIXME: segmented pointer? */
		pU->animwindowParams.lpstrText = s;
		i=k+1;
		continue;
	    }
	    FLAG1("stretch",MCI_ANIM_WINDOW_ENABLE_STRETCH);
	    break;
	case MCI_DEVTYPE_OVERLAY:
	    if (!STRCMP(keywords[i],"handle") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_OVLY_WINDOW_HWND;
		if (!STRCMP(keywords[i+1],"default")) 
		    pU->ovlywindowParams.hWnd = MCI_OVLY_WINDOW_DEFAULT;
		else
		    sscanf(keywords[i+1],"%hd",&(pU->ovlywindowParams.hWnd));
		i+=2;
		continue;
	    }
	    if (!STRCMP(keywords[i],"state") && (i+1<nrofkeywords)) {
		dwFlags |= MCI_OVLY_WINDOW_STATE;
		if (!STRCMP(keywords[i+1],"hide"))
		    pU->ovlywindowParams.nCmdShow = SW_HIDE;
		if (!STRCMP(keywords[i+1],"iconic"))
		    pU->ovlywindowParams.nCmdShow = SW_SHOWMINNOACTIVE; /* correct? */
		if (!STRCMP(keywords[i+1],"minimized"))
		    pU->ovlywindowParams.nCmdShow = SW_SHOWMINIMIZED;
		if (!STRCMP(keywords[i+1],"maximized"))
		    pU->ovlywindowParams.nCmdShow = SW_SHOWMAXIMIZED;
		if (!STRCMP(keywords[i+1],"minimize"))
		    pU->ovlywindowParams.nCmdShow = SW_MINIMIZE;
		if (!STRCMP(keywords[i+1],"normal"))
		    pU->ovlywindowParams.nCmdShow = SW_NORMAL;
		if (!STRCMP(keywords[i+1],"show"))
		    pU->ovlywindowParams.nCmdShow = SW_SHOW;
		if (!STRCMP(keywords[i+1],"no") && (i+2<nrofkeywords)) {
		    if (!STRCMP(keywords[i+2],"active"))
			pU->ovlywindowParams.nCmdShow = SW_SHOWNOACTIVATE;
		    if (!STRCMP(keywords[i+2],"action"))
			pU->ovlywindowParams.nCmdShow = SW_SHOWNA;/* correct?*/
		    i++;
		}
		i+=2;
		continue;
	    }
	    /* text is enclosed in " ... " as it seems */
	    if (!STRCMP(keywords[i],"text")) {
		char	*t;
		int	len,j,k;
		
		if (keywords[i+1][0]!='"') {
		    i++;
		    continue;
		}
		dwFlags |= MCI_OVLY_WINDOW_TEXT;
		len	= strlen(keywords[i+1])+1;
		j	= i+2;
		while (j<nrofkeywords) {
		    len += strlen(keywords[j])+1;
		    if (strchr(keywords[j],'"'))
			break;
		    j++;
		}
		s=(char*)xmalloc(len);
		strcpy(s,keywords[i+1]+1);
		k=j;j=i+2;
		while (j<=k) {
		    strcat(s," ");
		    strcat(s,keywords[j]);
		}
		if ((t=strchr(s,'"'))) *t='\0';
				/* FIXME: segmented pointer? */
		pU->ovlywindowParams.lpstrText = s;
		i=k+1;
		continue;
	    }
	    FLAG1("stretch",MCI_OVLY_WINDOW_ENABLE_STRETCH);
	    break;
	}
	i++;
    }
    _MCI_CALL_DRIVER( MCI_WINDOW, pU );
    if (s) free(s);
    free(pU);
    return res;
}

struct	_MCISTR_cmdtable {
    char	*cmd;
    DWORD	(*fun)(_MCISTR_PROTO_);
} MCISTR_cmdtable[]={
    {"break",		MCISTR_Break},
    {"capability",	MCISTR_Capability},
    {"close",		MCISTR_Close},
    {"cue",		MCISTR_Cue},
    {"delete",		MCISTR_Delete},
    {"escape",		MCISTR_Escape},
    {"freeze",		MCISTR_Freeze},
    {"info",		MCISTR_Info},
    {"load",		MCISTR_Load},
    {"open",		MCISTR_Open},
    {"pause",		MCISTR_Pause},
    {"play",		MCISTR_Play},
    {"put",		MCISTR_Put},
    {"realize",		MCISTR_Realize},
    {"record",		MCISTR_Record},
    {"resume",		MCISTR_Resume},
    {"save",		MCISTR_Save},
    {"seek",		MCISTR_Seek},
    {"set",		MCISTR_Set},
    {"spin",		MCISTR_Spin},
    {"status",		MCISTR_Status},
    {"step",		MCISTR_Step},
    {"stop",		MCISTR_Stop},
    {"sysinfo",		MCISTR_Sysinfo},
    {"unfreeze",	MCISTR_Unfreeze},
    {"update",		MCISTR_Update},
    {"where",		MCISTR_Where},
    {"window",		MCISTR_Window},
    {NULL,		NULL}
};
/**************************************************************************
 * 				mciSendString			[MMSYSTEM.702]
 */
/* The usercode sends a string with a command (and flags) expressed in 
 * words in it... We do our best to call aprobiate drivers,
 * and return a errorcode AND a readable string (if lpstrRS!=NULL)
 * Info gathered by watching cool134.exe and from Borland's mcistrwh.hlp
 */
/* FIXME: "all" is a valid devicetype and we should access all devices if
 * it is used. (imagine "close all"). Not implemented yet.
 */
DWORD WINAPI mciSendString (LPCSTR lpstrCommand, LPSTR lpstrReturnString, 
                            UINT16 uReturnLength, HWND16 hwndCallback)
{
    char	*cmd,*dev,*args,**keywords,*filename;
    WORD	uDevTyp=0,wDevID=0;
    DWORD	dwFlags;
    int	res=0,i,nrofkeywords;
    
    TRACE(mci,"('%s', %p, %d, %X)\n", lpstrCommand, 
	  lpstrReturnString, uReturnLength, hwndCallback
	  );
    /* format is <command> <device> <optargs> */
    cmd=strdup(lpstrCommand);
    dev=strchr(cmd,' ');
    if (dev==NULL) {
	free(cmd);
	return MCIERR_MISSING_DEVICE_NAME;
    }
    *dev++='\0';
    args=strchr(dev,' ');
    if (args!=NULL) *args++='\0';
    CharUpper32A(dev);
    if (args!=NULL) {
	char	*s;
	i=1;/* nrofkeywords = nrofspaces+1 */
	s=args;
	while ((s=strchr(s,' '))!=NULL) i++,s++;
	keywords=(char**)xmalloc(sizeof(char*)*(i+2));
	nrofkeywords=i;
	s=args;i=0;
	while (s && i<nrofkeywords) {
	    keywords[i++]=s;
	    s=strchr(s,' ');
	    if (s) *s++='\0';
	}
	keywords[i]=NULL;
    } else {
	nrofkeywords=0;
	keywords=(char**)xmalloc(sizeof(char*));
    }
    dwFlags = 0; /* default flags */
    for (i=0;i<nrofkeywords;) {
	/* take care, there is also a "device type" capability */
	if ((!STRCMP(keywords[i],"type")) && (i<nrofkeywords-1)) {
	    filename = dev;
	    dev = keywords[i+1];
	    memcpy(keywords+i,keywords+(i+2),(nrofkeywords-i-2)*sizeof(char *));
	    nrofkeywords -= 2;
	    continue;
	}
	if (!STRCMP(keywords[i],"wait")) {
	    dwFlags |= MCI_WAIT;
	    memcpy(keywords+i,keywords+(i+1),(nrofkeywords-i-1)*sizeof(char *));
	    nrofkeywords--;
	    continue;
	}
	if (!STRCMP(keywords[i],"notify")) {
	    dwFlags |= MCI_NOTIFY;
	    memcpy(keywords+i,keywords+(i+1),(nrofkeywords-i-1)*sizeof(char *));
	    nrofkeywords--;
	    continue;
	}
	i++;
    }
    
    /* determine wDevID and uDevTyp for all commands except "open" */
    if (STRCMP(cmd,"open")!=0) {
	wDevID = MMSYSTEM_FirstDevID();
	while (1) {
	    LPSTR	dname;
	    
	    dname=mciGetOpenDrv(wDevID)->lpstrAlias;
	    if (dname==NULL) 
		dname=mciGetOpenDrv(wDevID)->lpstrDeviceType;
	    if (dname != NULL && !STRCMP(dname,dev))
		break;
	    wDevID = MMSYSTEM_NextDevID(wDevID);
	    if (!MMSYSTEM_DevIDValid(wDevID)) {
		TRACE(mci, "MAXMCIDRIVERS reached!\n");
		free(keywords);free(cmd);
		return MCIERR_INVALID_DEVICE_NAME;
	    }
	}
	uDevTyp=mciGetDrv(wDevID)->modp.wType;
    }
    
    for (i=0;MCISTR_cmdtable[i].cmd!=NULL;i++) {
	if (!STRCMP(MCISTR_cmdtable[i].cmd,cmd)) {
	    res=MCISTR_cmdtable[i].fun(
				       wDevID,uDevTyp,lpstrReturnString,
				       uReturnLength,dev,(LPSTR*)keywords,nrofkeywords,
				       dwFlags,hwndCallback
				       );
	    break;
	}
    }
    if (MCISTR_cmdtable[i].cmd!=NULL) {
	free(keywords);free(cmd);
	return	res;
    }
    FIXME(mci,"('%s', %p, %u, %X): unimplemented, please report.\n", 
	  lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);
    free(keywords);free(cmd);
    return MCIERR_MISSING_COMMAND_STRING;
}
