/* -*- 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 MCI_GetDrv(wDevID) 	(&mciDrv[MCI_DevIDToIndex(wDevID)])
#define MCI_GetOpenDrv(wDevID) 	(&(MCI_GetDrv(wDevID)->mop))

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. */
#define _MCI_CALL_DRIVER(cmd,params) \
 	{ \
	    MCIPROC32	proc = MCI_GetProc32(uDevTyp); \
            res = (proc) ? (*proc)(MCI_GetDrv(wDevID)->modp.wDeviceID, 0, cmd, dwFlags, (DWORD)(params)) : MCIERR_DEVICE_NOT_INSTALLED;	\
	}

/* 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;
    }
    uDevTyp = MCI_GetDevType(dev);
    if (uDevTyp == 0) {
	free(pU->openParams.lpstrElementName);
	free(pU);
	return MCIERR_INVALID_DEVICE_NAME;
    }
    wDevID=MCI_FirstDevID();
    while(MCI_GetDrv(wDevID)->modp.wType) {
	wDevID = MCI_NextDevID(wDevID);
	if (!MCI_DevIDValid(wDevID)) {
	    TRACE(mci, "MAXMCIDRIVERS reached (%x) !\n", wDevID);
	    free(pU->openParams.lpstrElementName);
	    free(pU);
	    return MCIERR_INTERNAL;
	}
    }
    MCI_GetDrv(wDevID)->modp.wType	= uDevTyp;
    MCI_GetDrv(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(MCI_GetOpenDrv(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 = mciSendCommand16(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}
};

/**************************************************************************
 * 				mciSendString16			[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 mciSendString16(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 = MCI_FirstDevID();
	while (1) {
	    LPSTR	dname;
	    
	    dname=MCI_GetOpenDrv(wDevID)->lpstrAlias;
	    if (dname==NULL) 
		dname=MCI_GetOpenDrv(wDevID)->lpstrDeviceType;
	    if (dname != NULL && !STRCMP(dname,dev))
		break;
	    wDevID = MCI_NextDevID(wDevID);
	    if (!MCI_DevIDValid(wDevID)) {
		TRACE(mci, "MAXMCIDRIVERS reached!\n");
		free(keywords);free(cmd);
		return MCIERR_INVALID_DEVICE_NAME;
	    }
	}
	uDevTyp=MCI_GetDrv(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;
}

/**************************************************************************
 * 				mciSendString32A	[MMSYSTEM.702][WINMM.51]
 */
DWORD WINAPI mciSendString32A(LPCSTR lpstrCommand, LPSTR lpstrReturnString, 
			      UINT32 uReturnLength, HWND32 hwndCallback)
{
    return mciSendString16(lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);
}

/**************************************************************************
 * 				mciSendString32W	[WINMM.52]
 */
DWORD WINAPI mciSendString32W(LPCWSTR lpwstrCommand, LPSTR lpstrReturnString, 
			      UINT32 uReturnLength, HWND32 hwndCallback)
{
    LPSTR 	lpstrCommand;
    UINT32	ret;

    /* FIXME: is there something to do with lpstrReturnString ? */
    lpstrCommand = HEAP_strdupWtoA(GetProcessHeap(), 0, lpwstrCommand);
    ret = mciSendString16(lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);
    HeapFree(GetProcessHeap(), 0, lpstrCommand);
    return ret;
}
