/* -*- 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 "multimedia.h"
#include "heap.h"
#include "ldt.h"
#include "user.h"
#include "driver.h"
#include "callback.h"
#include "debug.h"
#include "xmalloc.h"

/* 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) lstrcmpiA(x,y)

/* standard function parameters 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) {					\
	lstrcpynA(lpstrReturnString, s, uReturnLength);		\
	TRACE(mci, "-->'%s'\n", lpstrReturnString);		\
    }								\
} while(0)

/* 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;
    }

    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++;
    }
    res = mciSendCommandA(0, MCI_OPEN, dwFlags, (DWORD)pU);

    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;
    res = mciSendCommandA(wDevID, MCI_STATUS, dwFlags, (DWORD)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;
    
    res = mciSendCommandA(wDevID, MCI_STATUS, dwFlags, (DWORD)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;
    res = mciSendCommandA(wDevID, MCI_SET, dwFlags, (DWORD)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;
	}
    }
    res = mciSendCommandA(wDevID, MCI_BREAK, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_GETDEVCAPS, dwFlags, (DWORD)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;
    res = mciSendCommandA(wDevID, MCI_RESUME, dwFlags, (DWORD)genParams);
    free(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;
    res = mciSendCommandA(wDevID, MCI_PAUSE, dwFlags, (DWORD)genParams);
    free(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;
    res = mciSendCommandA(wDevID, MCI_STOP, dwFlags, (DWORD)genParams);
    free(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++;
    }
    res = mciSendCommandA(wDevID, MCI_RECORD, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_PLAY, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_SEEK, dwFlags, (DWORD)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;
    
    res = mciSendCommandA(wDevID, MCI_CLOSE, dwFlags, (DWORD)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
     */
    res = mciSendCommandA(wDevID, MCI_INFO, dwFlags, (DWORD)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=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;
    res = mciSendCommandA(wDevID, MCI_LOAD, dwFlags, (DWORD)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;
    res = mciSendCommandA(wDevID, MCI_SAVE, dwFlags, (DWORD)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;
    
    for (i = 0; i < nrofkeywords; i++) {
	switch (uDevTyp) {
	case MCI_DEVTYPE_WAVEFORM_AUDIO:
	    FLAG1("input", MCI_WAVE_INPUT);
	    FLAG1("output", MCI_WAVE_OUTPUT);
	    break;
	}
    }
    res = mciSendCommandA(wDevID, MCI_CUE, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_DELETE, dwFlags, (DWORD)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;
    res = mciSendCommandA(wDevID, MCI_ESCAPE, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_UNFREEZE, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_FREEZE, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_PUT, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_REALIZE, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_SPIN, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_STEP, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_UPDATE, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_WHERE, dwFlags, (DWORD)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++;
    }
    res = mciSendCommandA(wDevID, MCI_WINDOW, dwFlags, (DWORD)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';
    CharUpperA(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++;
    }

    /* FIXME: this code should be moved to mmsystem.c */
    /* 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;
    }
    /* end of FIXME */

    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;
}

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

/**************************************************************************
 * 				mciSendStringW			[WINMM.52]
 */
DWORD WINAPI mciSendStringW(LPCWSTR lpwstrCommand, LPSTR lpstrReturnString, 
			    UINT uReturnLength, HWND hwndCallback)
{
    LPSTR 	lpstrCommand;
    UINT	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;
}

/**************************************************************************
 * 				mciExecute			[WINMM.38]
 */
DWORD WINAPI mciExecute(LPCSTR lpstrCommand)
{
    char	strRet[256];
    DWORD	ret;

    FIXME(mci, "(%s) stub!\n", lpstrCommand);

    ret = mciSendString16(lpstrCommand, strRet, sizeof(strRet), 0);
    if (ret != 0) {
	if (!mciGetErrorString16(ret, strRet, sizeof(strRet))) {
	    sprintf(strRet, "Unknown MCI Error (%ld)", ret);
	}
	MessageBoxA(0, strRet, "Error in mciExecute()", MB_OK); 
    }
    return 0;
}
