1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1995 Marcus Meissner
8 /* FIXME: special commands of device drivers should be handled by those drivers
11 /* FIXME: this current implementation does not allow commands like
12 * capability <filename> can play
13 * which is allowed by the MCI standard.
20 #include <sys/ioctl.h>
27 #include "multimedia.h"
33 extern struct WINE_MCIDRIVER mciDrv
[MAXMCIDRIVERS
];
35 #define mciGetDrv(wDevID) (&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
36 #define mciGetOpenDrv(wDevID) (&(mciGetDrv(wDevID)->mop))
38 extern int MMSYSTEM_DevIDToIndex(UINT16 wDevID
);
39 extern UINT16
MMSYSTEM_FirstDevID(void);
40 extern UINT16
MMSYSTEM_NextDevID(UINT16 wDevID
);
41 extern BOOL32
MMSYSTEM_DevIDValid(UINT16 wDevID
);
43 LONG WINAPI
DrvDefDriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
44 DWORD dwParam1
, DWORD dwParam2
);
46 /* The reason why I just don't lowercase the keywords array in
47 * mciSendString is left as an exercise to the reader.
49 #define STRCMP(x,y) lstrcmpi32A(x,y)
51 /* standard functionparameters for all functions */
52 #define _MCISTR_PROTO_ \
53 WORD wDevID,WORD uDevTyp,LPSTR lpstrReturnString,UINT16 uReturnLength,\
54 LPCSTR dev,LPSTR *keywords,UINT16 nrofkeywords,DWORD dwFlags,\
57 /* copy string to return pointer including necessary checks
58 * for use in mciSendString()
60 #define _MCI_STR(s) do {\
61 TRACE(mci,"->returns '%s'\n",s);\
62 if (lpstrReturnString) {\
63 lstrcpyn32A(lpstrReturnString,s,uReturnLength);\
64 TRACE(mci,"-->'%s'\n",lpstrReturnString);\
68 /* calling DriverProc. We need to pass the struct as linear pointer. */
69 #define _MCI_CALL_DRIVER(cmd,params) \
71 case MCI_DEVTYPE_CD_AUDIO:\
72 res=CDAUDIO_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags, (DWORD)(params));\
74 case MCI_DEVTYPE_WAVEFORM_AUDIO:\
75 res=WAVE_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
77 case MCI_DEVTYPE_SEQUENCER:\
78 res=MIDI_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
80 case MCI_DEVTYPE_ANIMATION:\
81 res=ANIM_DriverProc32(mciGetDrv(wDevID)->modp.wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
83 case MCI_DEVTYPE_DIGITAL_VIDEO:\
84 FIXME(mci,"_MCI_CALL_DRIVER: No DIGITAL_VIDEO yet !\n");\
85 res=MCIERR_DEVICE_NOT_INSTALLED;\
88 /*res = Callbacks->CallDriverProc(mciGetDrv(wDevID)->driverproc,mciGetDrv(wDevID)->modp.wDeviceID,mciGetDrv(wDevID)->hdrv,cmd,dwFlags,(DWORD)(params));\
90 res = MCIERR_DEVICE_NOT_INSTALLED;\
93 /* print a DWORD in the specified timeformat */
95 _MCISTR_printtf(char *buf
,UINT16 uDevType
,DWORD timef
,DWORD val
) {
98 case MCI_FORMAT_MILLISECONDS
:
99 case MCI_FORMAT_FRAMES
:
100 case MCI_FORMAT_BYTES
:
101 case MCI_FORMAT_SAMPLES
:
102 case MCI_VD_FORMAT_TRACK
:
103 /*case MCI_SEQ_FORMAT_SONGPTR: sameas MCI_VD_FORMAT_TRACK */
104 sprintf(buf
,"%ld",val
);
107 /* well, the macros have the same content*/
110 sprintf(buf
,"%d:%d:%d",
116 case MCI_FORMAT_TMSF
:
117 sprintf(buf
,"%d:%d:%d:%d",
119 MCI_TMSF_MINUTE(val
),
120 MCI_TMSF_SECOND(val
),
125 FIXME(mci
, "missing timeformat for %ld, report.\n",timef
);
126 strcpy(buf
,"0"); /* hmm */
131 /* possible different return types */
132 #define _MCISTR_int 1
133 #define _MCISTR_time 2
134 #define _MCISTR_bool 3
135 #define _MCISTR_tfname 4
136 #define _MCISTR_mode 5
137 #define _MCISTR_divtype 6
138 #define _MCISTR_seqtype 7
139 #define _MCISTR_vdmtype 8
140 #define _MCISTR_devtype 9
143 _MCISTR_convreturn(int type
,DWORD dwReturn
,LPSTR lpstrReturnString
,
144 WORD uReturnLength
,WORD uDevTyp
,int timef
147 case _MCISTR_vdmtype
:
149 case MCI_VD_MEDIA_CLV
:_MCI_STR("CLV");break;
150 case MCI_VD_MEDIA_CAV
:_MCI_STR("CAV");break;
152 case MCI_VD_MEDIA_OTHER
:_MCI_STR("other");break;
155 case _MCISTR_seqtype
:
157 case MCI_SEQ_NONE
:_MCI_STR("none");break;
158 case MCI_SEQ_SMPTE
:_MCI_STR("smpte");break;
159 case MCI_SEQ_FILE
:_MCI_STR("file");break;
160 case MCI_SEQ_MIDI
:_MCI_STR("midi");break;
161 default:FIXME(mci
,"missing sequencer mode %ld\n",dwReturn
);
166 case MCI_MODE_NOT_READY
:_MCI_STR("not ready");break;
167 case MCI_MODE_STOP
:_MCI_STR("stopped");break;
168 case MCI_MODE_PLAY
:_MCI_STR("playing");break;
169 case MCI_MODE_RECORD
:_MCI_STR("recording");break;
170 case MCI_MODE_SEEK
:_MCI_STR("seeking");break;
171 case MCI_MODE_PAUSE
:_MCI_STR("paused");break;
172 case MCI_MODE_OPEN
:_MCI_STR("open");break;
184 sprintf(buf
,"%ld",dwReturn
);
190 _MCISTR_printtf(buf
,uDevTyp
,timef
,dwReturn
);
196 case MCI_FORMAT_MILLISECONDS
:_MCI_STR("milliseconds");break;
197 case MCI_FORMAT_FRAMES
:_MCI_STR("frames");break;
198 case MCI_FORMAT_BYTES
:_MCI_STR("bytes");break;
199 case MCI_FORMAT_SAMPLES
:_MCI_STR("samples");break;
200 case MCI_FORMAT_HMS
:_MCI_STR("hms");break;
201 case MCI_FORMAT_MSF
:_MCI_STR("msf");break;
202 case MCI_FORMAT_TMSF
:_MCI_STR("tmsf");break;
204 FIXME(mci
,"missing timefmt for %d, report.\n",timef
);
208 case _MCISTR_divtype
:
210 case MCI_SEQ_DIV_PPQN
:_MCI_STR("PPQN");break;
211 case MCI_SEQ_DIV_SMPTE_24
:_MCI_STR("SMPTE 24 frame");break;
212 case MCI_SEQ_DIV_SMPTE_25
:_MCI_STR("SMPTE 25 frame");break;
213 case MCI_SEQ_DIV_SMPTE_30
:_MCI_STR("SMPTE 30 frame");break;
214 case MCI_SEQ_DIV_SMPTE_30DROP
:_MCI_STR("SMPTE 30 frame drop");break;
216 case _MCISTR_devtype
:
218 case MCI_DEVTYPE_VCR
:_MCI_STR("vcr");break;
219 case MCI_DEVTYPE_VIDEODISC
:_MCI_STR("videodisc");break;
220 case MCI_DEVTYPE_CD_AUDIO
:_MCI_STR("cd audio");break;
221 case MCI_DEVTYPE_OVERLAY
:_MCI_STR("overlay");break;
222 case MCI_DEVTYPE_DAT
:_MCI_STR("dat");break;
223 case MCI_DEVTYPE_SCANNER
:_MCI_STR("scanner");break;
224 case MCI_DEVTYPE_ANIMATION
:_MCI_STR("animation");break;
225 case MCI_DEVTYPE_DIGITAL_VIDEO
:_MCI_STR("digital video");break;
226 case MCI_DEVTYPE_OTHER
:_MCI_STR("other");break;
227 case MCI_DEVTYPE_WAVEFORM_AUDIO
:_MCI_STR("waveform audio");break;
228 case MCI_DEVTYPE_SEQUENCER
:_MCI_STR("sequencer");break;
229 default:FIXME(mci
,"unknown device type %ld, report.\n",
234 FIXME(mci
,"unknown resulttype %d, report.\n",type
);
239 #define FLAG1(str,flag) \
240 if (!STRCMP(keywords[i],str)) {\
245 #define FLAG2(str1,str2,flag) \
246 if (!STRCMP(keywords[i],str1) && (i+1<nrofkeywords) && !STRCMP(keywords[i+1],str2)) {\
252 /* All known subcommands are implemented in single functions to avoid
253 * bloat and a xxxx lines long mciSendString(). All commands are of the
254 * format MCISTR_Cmd(_MCISTR_PROTO_) where _MCISTR_PROTO_ is the above
255 * defined line of arguments. (This is just for easy enhanceability.)
256 * All functions return the MCIERR_ errorvalue as DWORD. Returnvalues
257 * for the calls are in lpstrReturnString (If I mention return values
258 * in function headers, I mean returnvalues in lpstrReturnString.)
259 * Integers are sprintf("%d")ed integers. Boolean values are
260 * "true" and "false".
261 * timeformat depending values are "%d" "%d:%d" "%d:%d:%d" "%d:%d:%d:%d"
262 * FIXME: is above line correct?
264 * Preceding every function is a list of implemented/known arguments.
265 * Feel free to add missing arguments.
270 * Opens the specified MCI driver.
274 * "alias <aliasname>"
275 * "element <elementname>"
278 * "buffer <nrBytesPerSec>"
280 * "nostatic" increaste nr of nonstatic colours
281 * "parent <windowhandle>"
282 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
283 * "style child" WS_CHILD
284 * "style overlap" WS_OVERLAPPED
285 * "style popup" WS_POPUP
287 * "parent <windowhandle>"
288 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
289 * "style child" WS_CHILD
290 * "style overlap" WS_OVERLAPPED
291 * "style popup" WS_POPUP
295 MCISTR_Open(_MCISTR_PROTO_
) {
299 MCI_OPEN_PARMS16 openParams
;
300 MCI_WAVE_OPEN_PARMS16 waveopenParams
;
301 MCI_ANIM_OPEN_PARMS16 animopenParams
;
302 MCI_OVLY_OPEN_PARMS16 ovlyopenParams
;
304 union U
*pU
= xmalloc(sizeof(union U
));
306 pU
->openParams
.lpstrElementName
= NULL
;
310 pU
->openParams
.lpstrElementName
=strdup(s
);
311 dwFlags
|= MCI_OPEN_ELEMENT
;
313 if (!STRCMP(dev
,"cdaudio")) {
314 uDevTyp
=MCI_DEVTYPE_CD_AUDIO
;
315 } else if (!STRCMP(dev
,"waveaudio")) {
316 uDevTyp
=MCI_DEVTYPE_WAVEFORM_AUDIO
;
317 } else if (!STRCMP(dev
,"sequencer")) {
318 uDevTyp
=MCI_DEVTYPE_SEQUENCER
;
319 } else if (!STRCMP(dev
,"animation1")) {
320 uDevTyp
=MCI_DEVTYPE_ANIMATION
;
321 } else if (!STRCMP(dev
,"avivideo")) {
322 uDevTyp
=MCI_DEVTYPE_DIGITAL_VIDEO
;
324 free(pU
->openParams
.lpstrElementName
);
326 return MCIERR_INVALID_DEVICE_NAME
;
328 wDevID
=MMSYSTEM_FirstDevID();
329 while(mciGetDrv(wDevID
)->modp
.wType
) {
330 wDevID
= MMSYSTEM_NextDevID(wDevID
);
331 if (!MMSYSTEM_DevIDValid(wDevID
)) {
332 TRACE(mci
, "MAXMCIDRIVERS reached (%x) !\n", wDevID
);
333 free(pU
->openParams
.lpstrElementName
);
335 return MCIERR_INTERNAL
;
338 mciGetDrv(wDevID
)->modp
.wType
= uDevTyp
;
339 mciGetDrv(wDevID
)->modp
.wDeviceID
= 0; /* FIXME? for multiple devices */
340 pU
->openParams
.dwCallback
= hwndCallback
;
341 pU
->openParams
.wDeviceID
= wDevID
;
342 pU
->openParams
.wReserved0
= 0;
343 pU
->ovlyopenParams
.dwStyle
= 0;
344 pU
->animopenParams
.dwStyle
= 0;
345 pU
->openParams
.lpstrDeviceType
= strdup(dev
);
346 pU
->openParams
.lpstrAlias
= NULL
;
347 dwFlags
|= MCI_OPEN_TYPE
;
349 while (i
<nrofkeywords
) {
350 FLAG1("shareable",MCI_OPEN_SHAREABLE
);
351 if (!STRCMP(keywords
[i
],"alias") && (i
+1<nrofkeywords
)) {
352 dwFlags
|= MCI_OPEN_ALIAS
;
353 pU
->openParams
.lpstrAlias
=strdup(keywords
[i
+1]);
357 if (!STRCMP(keywords
[i
],"element") && (i
+1<nrofkeywords
)) {
358 dwFlags
|= MCI_OPEN_ELEMENT
;
359 pU
->openParams
.lpstrElementName
=strdup(keywords
[i
+1]);
364 case MCI_DEVTYPE_ANIMATION
:
365 case MCI_DEVTYPE_DIGITAL_VIDEO
:
366 FLAG1("nostatic",MCI_ANIM_OPEN_NOSTATIC
);
367 if (!STRCMP(keywords
[i
],"parent") && (i
+1<nrofkeywords
)) {
368 dwFlags
|= MCI_ANIM_OPEN_PARENT
;
369 sscanf(keywords
[i
+1],"%hu",&(pU
->animopenParams
.hWndParent
));
373 if (!STRCMP(keywords
[i
],"style") && (i
+1<nrofkeywords
)) {
376 dwFlags
|= MCI_ANIM_OPEN_WS
;
377 if (!STRCMP(keywords
[i
+1],"popup")) {
378 pU
->animopenParams
.dwStyle
|= WS_POPUP
;
379 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
380 pU
->animopenParams
.dwStyle
|= WS_OVERLAPPED
;
381 } else if (!STRCMP(keywords
[i
+1],"child")) {
382 pU
->animopenParams
.dwStyle
|= WS_CHILD
;
383 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
384 pU
->animopenParams
.dwStyle
|= st
;
386 FIXME(mci
,"unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
391 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
392 if (!STRCMP(keywords
[i
],"buffer") && (i
+1<nrofkeywords
)) {
393 dwFlags
|= MCI_WAVE_OPEN_BUFFER
;
394 sscanf(keywords
[i
+1],"%ld",&(pU
->waveopenParams
.dwBufferSeconds
));
397 case MCI_DEVTYPE_OVERLAY
:
398 /* looks just like anim, but without NOSTATIC */
399 if (!STRCMP(keywords
[i
],"parent") && (i
+1<nrofkeywords
)) {
400 dwFlags
|= MCI_OVLY_OPEN_PARENT
;
401 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyopenParams
.hWndParent
));
405 if (!STRCMP(keywords
[i
],"style") && (i
+1<nrofkeywords
)) {
408 dwFlags
|= MCI_OVLY_OPEN_WS
;
409 if (!STRCMP(keywords
[i
+1],"popup")) {
410 pU
->ovlyopenParams
.dwStyle
|= WS_POPUP
;
411 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
412 pU
->ovlyopenParams
.dwStyle
|= WS_OVERLAPPED
;
413 } else if (!STRCMP(keywords
[i
+1],"child")) {
414 pU
->ovlyopenParams
.dwStyle
|= WS_CHILD
;
415 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
416 pU
->ovlyopenParams
.dwStyle
|= st
;
418 FIXME(mci
,"unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
424 FIXME(mci
,"unknown parameter passed %s, please report.\n",
428 _MCI_CALL_DRIVER(MCI_OPEN
, pU
);
430 memcpy(mciGetOpenDrv(wDevID
),&pU
->openParams
,sizeof(MCI_OPEN_PARMS16
));
432 free(pU
->openParams
.lpstrElementName
);
433 free(pU
->openParams
.lpstrDeviceType
);
434 free(pU
->openParams
.lpstrAlias
);
440 /* A help function for a lot of others ...
441 * for instance status/play/record/seek etc.
444 _MCISTR_determine_timeformat(LPCSTR dev
,WORD wDevID
,WORD uDevTyp
,int *timef
)
447 DWORD dwFlags
= MCI_STATUS_ITEM
;
448 MCI_STATUS_PARMS
*statusParams
= xmalloc(sizeof(MCI_STATUS_PARMS
));
450 if (!statusParams
) return 0;
451 statusParams
->dwItem
= MCI_STATUS_TIME_FORMAT
;
452 statusParams
->dwReturn
= 0;
453 _MCI_CALL_DRIVER( MCI_STATUS
, statusParams
);
454 if (res
==0) *timef
= statusParams
->dwReturn
;
459 /* query status of MCI drivers
462 * "mode" - returns "not ready" "paused" "playing" "stopped" "open"
463 * "parked" "recording" "seeking" ....
465 * "current track" - returns current track as integer
466 * "length [track <nr>]" - returns length [of track <nr>] in current
468 * "number of tracks" - returns number of tracks as integer
469 * "position [track <nr>]" - returns position [in track <nr>] in current
471 * "ready" - checks if device is ready to play, -> bool
472 * "start position" - returns start position in timeformat
473 * "time format" - returns timeformat (list of possible values:
474 * "ms" "msf" "milliseconds" "hmsf" "tmsf" "frames"
475 * "bytes" "samples" "hms")
476 * "media present" - returns if media is present as bool
478 * "forward" - returns "true" if device is playing forwards
479 * "speed" - returns speed for device
480 * "palette handle" - returns palette handle
481 * "window handle" - returns window handle
482 * "stretch" - returns stretch bool
484 * "division type" - ? returns "PPQN" "SMPTE 24 frame"
485 * "SMPTE 25 frame" "SMPTE 30 frame" "SMPTE 30 drop frame"
486 * "tempo" - current tempo in (PPQN? speed in frames, SMPTE*? speed in hsmf)
487 * "offset" - offset in dito.
488 * "port" - midi port as integer
489 * "slave" - slave device ("midi","file","none","smpte")
490 * "master" - masterdevice (dito.)
492 * "window handle" - see animation
495 * "speed" - speed as integer
496 * "forward" - returns bool (when playing forward)
497 * "side" - returns 1 or 2
498 * "media type" - returns "CAV" "CLV" "other"
499 * "disc size" - returns "8" or "12"
501 * "input" - base queries on input set
502 * "output" - base queries on output set
503 * "format tag" - return integer format tag
504 * "channels" - return integer nr of channels
505 * "bytespersec" - return average nr of bytes/sec
506 * "samplespersec" - return nr of samples per sec
507 * "bitspersample" - return bitspersample
508 * "alignment" - return block alignment
509 * "level" - return level?
512 #define ITEM1(str,item,xtype) \
513 if (!STRCMP(keywords[i],str)) {\
514 statusParams->dwItem = item;\
519 #define ITEM2(str1,str2,item,xtype) \
520 if ( !STRCMP(keywords[i],str1) &&\
521 (i+1<nrofkeywords) &&\
522 !STRCMP(keywords[i+1],str2)\
524 statusParams->dwItem = item;\
529 #define ITEM3(str1,str2,str3,item,xtype) \
530 if ( !STRCMP(keywords[i],str1) &&\
531 (i+2<nrofkeywords) &&\
532 !STRCMP(keywords[i+1],str2) &&\
533 !STRCMP(keywords[i+2],str3)\
535 statusParams->dwItem = item;\
541 MCISTR_Status(_MCISTR_PROTO_
) {
542 MCI_STATUS_PARMS
*statusParams
= xmalloc(sizeof(MCI_STATUS_PARMS
));
543 int type
= 0,i
,res
,timef
;
545 statusParams
->dwCallback
= hwndCallback
;
546 dwFlags
|= MCI_STATUS_ITEM
;
547 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
550 statusParams
->dwReturn
= 0;
551 statusParams
->dwItem
= 0;
554 while (i
<nrofkeywords
) {
555 if (!STRCMP(keywords
[i
],"track") && (i
+1<nrofkeywords
)) {
556 sscanf(keywords
[i
+1],"%ld",&(statusParams
->dwTrack
));
557 dwFlags
|= MCI_TRACK
;
561 FLAG1("start",MCI_STATUS_START
);
563 ITEM2("current","track",MCI_STATUS_CURRENT_TRACK
,_MCISTR_time
);
564 ITEM2("time","format",MCI_STATUS_TIME_FORMAT
,_MCISTR_tfname
);
565 ITEM1("ready",MCI_STATUS_READY
,_MCISTR_bool
);
566 ITEM1("mode",MCI_STATUS_MODE
,_MCISTR_mode
);
567 ITEM3("number","of","tracks",MCI_STATUS_NUMBER_OF_TRACKS
,_MCISTR_int
);
568 ITEM1("length",MCI_STATUS_LENGTH
,_MCISTR_time
);
569 ITEM1("position",MCI_STATUS_POSITION
,_MCISTR_time
);
570 ITEM2("media","present",MCI_STATUS_MEDIA_PRESENT
,_MCISTR_bool
);
573 case MCI_DEVTYPE_ANIMATION
:
574 case MCI_DEVTYPE_DIGITAL_VIDEO
:
575 ITEM2("palette","handle",MCI_ANIM_STATUS_HPAL
,_MCISTR_int
);
576 ITEM2("window","handle",MCI_ANIM_STATUS_HWND
,_MCISTR_int
);
577 ITEM1("stretch",MCI_ANIM_STATUS_STRETCH
,_MCISTR_bool
);
578 ITEM1("speed",MCI_ANIM_STATUS_SPEED
,_MCISTR_int
);
579 ITEM1("forward",MCI_ANIM_STATUS_FORWARD
,_MCISTR_bool
);
581 case MCI_DEVTYPE_SEQUENCER
:
582 /* just completing the list, not working correctly */
583 ITEM2("division","type",MCI_SEQ_STATUS_DIVTYPE
,_MCISTR_divtype
);
584 /* tempo ... PPQN in frames/second, SMPTE in hmsf */
585 ITEM1("tempo",MCI_SEQ_STATUS_TEMPO
,_MCISTR_int
);
586 ITEM1("port",MCI_SEQ_STATUS_PORT
,_MCISTR_int
);
587 ITEM1("slave",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
588 ITEM1("master",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
589 /* offset ... PPQN in frames/second, SMPTE in hmsf */
590 ITEM1("offset",MCI_SEQ_STATUS_SLAVE
,_MCISTR_time
);
592 case MCI_DEVTYPE_OVERLAY
:
593 ITEM2("window","handle",MCI_OVLY_STATUS_HWND
,_MCISTR_int
);
594 ITEM1("stretch",MCI_OVLY_STATUS_STRETCH
,_MCISTR_bool
);
596 case MCI_DEVTYPE_VIDEODISC
:
597 ITEM1("speed",MCI_VD_STATUS_SPEED
,_MCISTR_int
);
598 ITEM1("forward",MCI_VD_STATUS_FORWARD
,_MCISTR_bool
);
599 ITEM1("side",MCI_VD_STATUS_SIDE
,_MCISTR_int
);
600 ITEM2("media","type",MCI_VD_STATUS_SIDE
,_MCISTR_vdmtype
);
601 /* returns 8 or 12 */
602 ITEM2("disc","size",MCI_VD_STATUS_DISC_SIZE
,_MCISTR_int
);
604 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
605 /* I am not quite sure if foll. 2 lines are right. */
606 FLAG1("input",MCI_WAVE_INPUT
);
607 FLAG1("output",MCI_WAVE_OUTPUT
);
609 ITEM2("format","tag",MCI_WAVE_STATUS_FORMATTAG
,_MCISTR_int
);
610 ITEM1("channels",MCI_WAVE_STATUS_CHANNELS
,_MCISTR_int
);
611 ITEM1("bytespersec",MCI_WAVE_STATUS_AVGBYTESPERSEC
,_MCISTR_int
);
612 ITEM1("samplespersec",MCI_WAVE_STATUS_SAMPLESPERSEC
,_MCISTR_int
);
613 ITEM1("bitspersample",MCI_WAVE_STATUS_BITSPERSAMPLE
,_MCISTR_int
);
614 ITEM1("alignment",MCI_WAVE_STATUS_BLOCKALIGN
,_MCISTR_int
);
615 ITEM1("level",MCI_WAVE_STATUS_LEVEL
,_MCISTR_int
);
618 FIXME(mci
,"unknown keyword '%s'\n",keywords
[i
]);
621 if (!statusParams
->dwItem
)
622 return MCIERR_MISSING_STRING_ARGUMENT
;
624 _MCI_CALL_DRIVER( MCI_STATUS
, statusParams
);
626 _MCISTR_convreturn(type
,statusParams
->dwReturn
,lpstrReturnString
,uReturnLength
,uDevTyp
,timef
);
634 /* set specified parameters in respective MCI drivers
636 * "door open" eject media or somesuch
637 * "door close" load media
638 * "time format <timeformatname>" "ms" "milliseconds" "msf" "hmsf"
639 * "tmsf" "SMPTE 24" "SMPTE 25" "SMPTE 30"
641 * "audio [all|left|right] [on|off]" sets specified audiochannel on or off
642 * "video [on|off]" sets video on/off
644 * "formattag pcm" sets format to pcm
645 * "formattag <nr>" sets integer formattag value
646 * "any input" accept input from any known source
647 * "any output" output to any known destination
648 * "input <nr>" input from source <nr>
649 * "output <nr>" output to destination <nr>
650 * "channels <nr>" sets nr of channels
651 * "bytespersec <nr>" sets average bytes per second
652 * "samplespersec <nr>" sets average samples per second (1 sample can
654 * "alignment <nr>" sets the blockalignment to <nr>
655 * "bitspersample <nr>" sets the nr of bits per sample
657 * "master [midi|file|smpte|none]" sets the midi master device
658 * "slave [midi|file|smpte|none]" sets the midi master device
659 * "port mapper" midioutput to portmapper
660 * "port <nr>" midioutput to specified port
661 * "tempo <nr>" tempo of track (depends on timeformat/divtype)
662 * "offset <nr>" start offset?
665 MCISTR_Set(_MCISTR_PROTO_
) {
667 MCI_SET_PARMS setParams
;
668 MCI_WAVE_SET_PARMS16 wavesetParams
;
669 MCI_SEQ_SET_PARMS seqsetParams
;
671 union U
*pU
= xmalloc(sizeof(union U
));
674 pU
->setParams
.dwCallback
= hwndCallback
;
676 while (i
<nrofkeywords
) {
677 FLAG2("door","open",MCI_SET_DOOR_OPEN
);
678 FLAG2("door","closed",MCI_SET_DOOR_CLOSED
);
680 if ( !STRCMP(keywords
[i
],"time") &&
681 (i
+2<nrofkeywords
) &&
682 !STRCMP(keywords
[i
+1],"format")
684 dwFlags
|= MCI_SET_TIME_FORMAT
;
686 /* FIXME:is this a shortcut for milliseconds or
687 * minutes:seconds? */
688 if (!STRCMP(keywords
[i
+2],"ms"))
689 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
691 if (!STRCMP(keywords
[i
+2],"milliseconds"))
692 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
693 if (!STRCMP(keywords
[i
+2],"msf"))
694 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MSF
;
695 if (!STRCMP(keywords
[i
+2],"hms"))
696 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_HMS
;
697 if (!STRCMP(keywords
[i
+2],"frames"))
698 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_FRAMES
;
699 if (!STRCMP(keywords
[i
+2],"track"))
700 pU
->setParams
.dwTimeFormat
= MCI_VD_FORMAT_TRACK
;
701 if (!STRCMP(keywords
[i
+2],"bytes"))
702 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_BYTES
;
703 if (!STRCMP(keywords
[i
+2],"samples"))
704 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SAMPLES
;
705 if (!STRCMP(keywords
[i
+2],"tmsf"))
706 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_TMSF
;
707 if ( !STRCMP(keywords
[i
+2],"song") &&
708 (i
+3<nrofkeywords
) &&
709 !STRCMP(keywords
[i
+3],"pointer")
711 pU
->setParams
.dwTimeFormat
= MCI_SEQ_FORMAT_SONGPTR
;
712 if (!STRCMP(keywords
[i
+2],"smpte") && (i
+3<nrofkeywords
)) {
713 if (!STRCMP(keywords
[i
+3],"24"))
714 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_24
;
715 if (!STRCMP(keywords
[i
+3],"25"))
716 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_25
;
717 if (!STRCMP(keywords
[i
+3],"30"))
718 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30
;
719 if (!STRCMP(keywords
[i
+3],"drop") && (i
+4<nrofkeywords
) && !STRCMP(keywords
[i
+4],"30")) {
720 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30DROP
;
729 if (!STRCMP(keywords
[i
],"audio") && (i
+1<nrofkeywords
)) {
730 dwFlags
|= MCI_SET_AUDIO
;
731 if (!STRCMP(keywords
[i
+1],"all"))
732 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_ALL
;
733 if (!STRCMP(keywords
[i
+1],"left"))
734 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_LEFT
;
735 if (!STRCMP(keywords
[i
+1],"right"))
736 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_RIGHT
;
740 FLAG1("video",MCI_SET_VIDEO
);
741 FLAG1("on",MCI_SET_ON
);
742 FLAG1("off",MCI_SET_OFF
);
744 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
745 FLAG2("any","input",MCI_WAVE_SET_ANYINPUT
);
746 FLAG2("any","output",MCI_WAVE_SET_ANYOUTPUT
);
748 if ( !STRCMP(keywords
[i
],"formattag") &&
749 (i
+1<nrofkeywords
) &&
750 !STRCMP(keywords
[i
+1],"pcm")
752 dwFlags
|= MCI_WAVE_SET_FORMATTAG
;
753 pU
->wavesetParams
.wFormatTag
= WAVE_FORMAT_PCM
;
758 /* <keyword> <integer> */
759 #define WII(str,flag,fmt,element) \
760 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
761 sscanf(keywords[i+1],fmt,&(pU->wavesetParams. element ));\
766 WII("formattag",MCI_WAVE_SET_FORMATTAG
,"%hu",wFormatTag
);
767 WII("channels",MCI_WAVE_SET_CHANNELS
,"%hu",nChannels
);
768 WII("bytespersec",MCI_WAVE_SET_AVGBYTESPERSEC
,"%lu",nAvgBytesPerSec
);
769 WII("samplespersec",MCI_WAVE_SET_SAMPLESPERSEC
,"%lu",nSamplesPerSec
);
770 WII("alignment",MCI_WAVE_SET_BLOCKALIGN
,"%hu",nBlockAlign
);
771 WII("bitspersample",MCI_WAVE_SET_BITSPERSAMPLE
,"%hu",wBitsPerSample
);
772 WII("input",MCI_WAVE_INPUT
,"%hu",wInput
);
773 WII("output",MCI_WAVE_OUTPUT
,"%hu",wOutput
);
776 case MCI_DEVTYPE_SEQUENCER
:
777 if (!STRCMP(keywords
[i
],"master") && (i
+1<nrofkeywords
)) {
778 dwFlags
|= MCI_SEQ_SET_MASTER
;
779 if (!STRCMP(keywords
[i
+1],"midi"))
780 pU
->seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
781 if (!STRCMP(keywords
[i
+1],"file"))
782 pU
->seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
783 if (!STRCMP(keywords
[i
+1],"smpte"))
784 pU
->seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
785 if (!STRCMP(keywords
[i
+1],"none"))
786 pU
->seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
790 if (!STRCMP(keywords
[i
],"slave") && (i
+1<nrofkeywords
)) {
791 dwFlags
|= MCI_SEQ_SET_SLAVE
;
792 if (!STRCMP(keywords
[i
+1],"midi"))
793 pU
->seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
794 if (!STRCMP(keywords
[i
+1],"file"))
795 pU
->seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
796 if (!STRCMP(keywords
[i
+1],"smpte"))
797 pU
->seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
798 if (!STRCMP(keywords
[i
+1],"none"))
799 pU
->seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
803 if ( !STRCMP(keywords
[i
],"port") &&
804 (i
+1<nrofkeywords
) &&
805 !STRCMP(keywords
[i
+1],"mapper")
807 pU
->seqsetParams
.dwPort
=-1;/* FIXME:not sure*/
808 dwFlags
|= MCI_SEQ_SET_PORT
;
812 #define SII(str,flag,element) \
813 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
814 sscanf(keywords[i+1],"%ld",&(pU->seqsetParams. element ));\
819 SII("tempo",MCI_SEQ_SET_TEMPO
,dwTempo
);
820 SII("port",MCI_SEQ_SET_PORT
,dwPort
);
821 SII("offset",MCI_SEQ_SET_PORT
,dwOffset
);
826 return MCIERR_MISSING_STRING_ARGUMENT
;
827 _MCI_CALL_DRIVER( MCI_SET
, pU
);
834 * "off" disable break
835 * "on <keyid>" enable break on key with keyid
836 * (I strongly suspect, that there is another parameter:
838 * but I don't see it mentioned in my documentation.
842 MCISTR_Break(_MCISTR_PROTO_
)
844 MCI_BREAK_PARMS16
*breakParams
= xmalloc(sizeof(MCI_BREAK_PARMS16
));
847 if (!breakParams
) return 0;
848 /*breakParams.hwndBreak ? */
849 for (i
= 0; i
< nrofkeywords
; i
++) {
850 FLAG1("off",MCI_BREAK_OFF
);
851 if (!strcmp(keywords
[i
],"on") && (nrofkeywords
>i
+1)) {
852 dwFlags
&=~MCI_BREAK_OFF
;
853 dwFlags
|=MCI_BREAK_KEY
;
854 sscanf(keywords
[i
+1],"%hd",&(breakParams
->nVirtKey
));
859 _MCI_CALL_DRIVER( MCI_BREAK
, breakParams
);
864 #define ITEM1(str,item,xtype) \
865 if (!STRCMP(keywords[i],str)) {\
866 gdcParams->dwItem = item;\
871 #define ITEM2(str1,str2,item,xtype) \
872 if ( !STRCMP(keywords[i],str1) &&\
873 (i+1<nrofkeywords) &&\
874 !STRCMP(keywords[i+1],str2)\
876 gdcParams->dwItem = item;\
881 #define ITEM3(str1,str2,str3,item,xtype) \
882 if ( !STRCMP(keywords[i],str1) &&\
883 (i+2<nrofkeywords) &&\
884 !STRCMP(keywords[i+1],str2) &&\
885 !STRCMP(keywords[i+2],str3)\
887 gdcParams->dwItem = item;\
892 /* get device capabilities of MCI drivers
895 * "device type" returns device name as string
896 * "has audio" returns bool
897 * "has video" returns bool
898 * "uses files" returns bool
899 * "compound device" returns bool
900 * "can record" returns bool
901 * "can play" returns bool
902 * "can eject" returns bool
903 * "can save" returns bool
905 * "palettes" returns nr of available palette entries
906 * "windows" returns nr of available windows
907 * "can reverse" returns bool
908 * "can stretch" returns bool
909 * "slow play rate" returns the slow playrate
910 * "fast play rate" returns the fast playrate
911 * "normal play rate" returns the normal playrate
913 * "windows" returns nr of available windows
914 * "can stretch" returns bool
915 * "can freeze" returns bool
917 * "cav" assume CAV discs (default if no disk inserted)
918 * "clv" assume CLV discs
919 * "can reverse" returns bool
920 * "slow play rate" returns the slow playrate
921 * "fast play rate" returns the fast playrate
922 * "normal play rate" returns the normal playrate
924 * "inputs" returns nr of inputdevices
925 * "outputs" returns nr of outputdevices
928 MCISTR_Capability(_MCISTR_PROTO_
) {
929 MCI_GETDEVCAPS_PARMS
*gdcParams
= xmalloc(sizeof(MCI_GETDEVCAPS_PARMS
));
932 gdcParams
->dwCallback
= hwndCallback
;
934 return MCIERR_MISSING_STRING_ARGUMENT
;
935 /* well , thats default */
936 dwFlags
|= MCI_GETDEVCAPS_ITEM
;
937 gdcParams
->dwItem
= 0;
939 while (i
<nrofkeywords
) {
940 ITEM2("device","type",MCI_GETDEVCAPS_DEVICE_TYPE
,_MCISTR_devtype
);
941 ITEM2("has","audio",MCI_GETDEVCAPS_HAS_AUDIO
,_MCISTR_bool
);
942 ITEM2("has","video",MCI_GETDEVCAPS_HAS_VIDEO
,_MCISTR_bool
);
943 ITEM2("uses","files",MCI_GETDEVCAPS_USES_FILES
,_MCISTR_bool
);
944 ITEM2("compound","device",MCI_GETDEVCAPS_COMPOUND_DEVICE
,_MCISTR_bool
);
945 ITEM2("can","record",MCI_GETDEVCAPS_CAN_RECORD
,_MCISTR_bool
);
946 ITEM2("can","play",MCI_GETDEVCAPS_CAN_PLAY
,_MCISTR_bool
);
947 ITEM2("can","eject",MCI_GETDEVCAPS_CAN_EJECT
,_MCISTR_bool
);
948 ITEM2("can","save",MCI_GETDEVCAPS_CAN_SAVE
,_MCISTR_bool
);
950 case MCI_DEVTYPE_ANIMATION
:
951 ITEM1("palettes",MCI_ANIM_GETDEVCAPS_PALETTES
,_MCISTR_int
);
952 ITEM1("windows",MCI_ANIM_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
953 ITEM2("can","reverse",MCI_ANIM_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
954 ITEM2("can","stretch",MCI_ANIM_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
955 ITEM3("slow","play","rate",MCI_ANIM_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
956 ITEM3("fast","play","rate",MCI_ANIM_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
957 ITEM3("normal","play","rate",MCI_ANIM_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
959 case MCI_DEVTYPE_OVERLAY
:
960 ITEM1("windows",MCI_OVLY_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
961 ITEM2("can","freeze",MCI_OVLY_GETDEVCAPS_CAN_FREEZE
,_MCISTR_bool
);
962 ITEM2("can","stretch",MCI_OVLY_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
964 case MCI_DEVTYPE_VIDEODISC
:
965 FLAG1("cav",MCI_VD_GETDEVCAPS_CAV
);
966 FLAG1("clv",MCI_VD_GETDEVCAPS_CLV
);
967 ITEM2("can","reverse",MCI_VD_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
968 ITEM3("slow","play","rate",MCI_VD_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
969 ITEM3("fast","play","rate",MCI_VD_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
970 ITEM3("normal","play","rate",MCI_VD_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
972 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
973 ITEM1("inputs",MCI_WAVE_GETDEVCAPS_INPUTS
,_MCISTR_int
);
974 ITEM1("outputs",MCI_WAVE_GETDEVCAPS_OUTPUTS
,_MCISTR_int
);
979 _MCI_CALL_DRIVER( MCI_GETDEVCAPS
, gdcParams
);
980 /* no timeformat needed */
982 _MCISTR_convreturn( type
, gdcParams
->dwReturn
, lpstrReturnString
,
983 uReturnLength
, uDevTyp
, 0 );
990 /* resumes operation of device. no arguments, no return values */
992 MCISTR_Resume(_MCISTR_PROTO_
)
994 MCI_GENERIC_PARMS
*genParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
996 genParams
->dwCallback
= hwndCallback
;
997 _MCI_CALL_DRIVER( MCI_RESUME
, genParams
);
1001 /* pauses operation of device. no arguments, no return values */
1003 MCISTR_Pause(_MCISTR_PROTO_
)
1005 MCI_GENERIC_PARMS
*genParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1007 genParams
->dwCallback
= hwndCallback
;
1008 _MCI_CALL_DRIVER( MCI_PAUSE
, genParams
);
1012 /* stops operation of device. no arguments, no return values */
1014 MCISTR_Stop(_MCISTR_PROTO_
)
1016 MCI_GENERIC_PARMS
*genParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1018 genParams
->dwCallback
= hwndCallback
;
1019 _MCI_CALL_DRIVER( MCI_STOP
, genParams
);
1023 /* starts recording.
1025 * "overwrite" overwrite existing things
1026 * "insert" insert at current position
1027 * "to <time>" record up to <time> (specified in timeformat)
1028 * "from <time>" record from <time> (specified in timeformat)
1031 MCISTR_Record(_MCISTR_PROTO_
) {
1032 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1034 MCI_RECORD_PARMS
*recordParams
= xmalloc(sizeof(MCI_RECORD_PARMS
));
1036 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1037 if (res
) return res
;
1040 case MCI_FORMAT_MILLISECONDS
:
1041 case MCI_FORMAT_FRAMES
:
1042 case MCI_FORMAT_BYTES
:
1043 case MCI_FORMAT_SAMPLES
:
1047 case MCI_FORMAT_HMS
:
1048 case MCI_FORMAT_MSF
:
1049 parsestr
="%d:%d:%d";
1052 case MCI_FORMAT_TMSF
:
1053 parsestr
="%d:%d:%d:%d";
1056 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1061 recordParams
->dwCallback
= hwndCallback
;
1063 while (i
<nrofkeywords
) {
1064 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1066 a
[0]=a
[1]=a
[2]=a
[3]=0;
1067 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1068 /* add up all integers we got, if we have more
1069 * shift them. (Well I should use the macros in
1070 * mmsystem.h, right).
1072 recordParams
->dwTo
=0;
1074 recordParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1078 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1079 dwFlags
|= MCI_FROM
;
1080 a
[0]=a
[1]=a
[2]=a
[3]=0;
1081 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1083 recordParams
->dwFrom
=0;
1085 recordParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1089 FLAG1("insert",MCI_RECORD_INSERT
);
1090 FLAG1("overwrite",MCI_RECORD_OVERWRITE
);
1093 _MCI_CALL_DRIVER( MCI_RECORD
, recordParams
);
1100 * "to <time>" play up to <time> (specified in set timeformat)
1101 * "from <time>" play from <time> (specified in set timeformat)
1105 * "scan" play as fast as possible (with audio disabled perhaps)
1106 * "reverse" play reverse
1107 * "speed <fps>" play with specified frames per second
1111 * "scan" play as fast as possible (with audio disabled perhaps)
1112 * "reverse" play reverse
1113 * "speed <fps>" play with specified frames per second
1116 MCISTR_Play(_MCISTR_PROTO_
) {
1117 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1120 MCI_PLAY_PARMS playParams
;
1121 MCI_VD_PLAY_PARMS vdplayParams
;
1122 MCI_ANIM_PLAY_PARMS animplayParams
;
1124 union U
*pU
= xmalloc(sizeof(union U
));
1126 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1127 if (res
) return res
;
1129 case MCI_FORMAT_MILLISECONDS
:
1130 case MCI_FORMAT_FRAMES
:
1131 case MCI_FORMAT_BYTES
:
1132 case MCI_FORMAT_SAMPLES
:
1136 case MCI_FORMAT_HMS
:
1137 case MCI_FORMAT_MSF
:
1138 parsestr
="%d:%d:%d";
1141 case MCI_FORMAT_TMSF
:
1142 parsestr
="%d:%d:%d:%d";
1145 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1150 pU
->playParams
.dwCallback
=hwndCallback
;
1152 while (i
<nrofkeywords
) {
1153 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1155 a
[0]=a
[1]=a
[2]=a
[3]=0;
1156 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1157 /* add up all integers we got, if we have more
1158 * shift them. (Well I should use the macros in
1159 * mmsystem.h, right).
1161 pU
->playParams
.dwTo
=0;
1163 pU
->playParams
.dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1167 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1168 dwFlags
|= MCI_FROM
;
1169 a
[0]=a
[1]=a
[2]=a
[3]=0;
1170 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1172 pU
->playParams
.dwFrom
=0;
1174 pU
->playParams
.dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1179 case MCI_DEVTYPE_VIDEODISC
:
1180 FLAG1("slow",MCI_VD_PLAY_SLOW
);
1181 FLAG1("fast",MCI_VD_PLAY_FAST
);
1182 FLAG1("scan",MCI_VD_PLAY_SCAN
);
1183 FLAG1("reverse",MCI_VD_PLAY_REVERSE
);
1184 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1185 dwFlags
|= MCI_VD_PLAY_SPEED
;
1186 sscanf(keywords
[i
+1],"%ld",&(pU
->vdplayParams
.dwSpeed
));
1191 case MCI_DEVTYPE_ANIMATION
:
1192 FLAG1("slow",MCI_ANIM_PLAY_SLOW
);
1193 FLAG1("fast",MCI_ANIM_PLAY_FAST
);
1194 FLAG1("scan",MCI_ANIM_PLAY_SCAN
);
1195 FLAG1("reverse",MCI_ANIM_PLAY_REVERSE
);
1196 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1197 dwFlags
|= MCI_ANIM_PLAY_SPEED
;
1198 sscanf(keywords
[i
+1],"%ld",&(pU
->animplayParams
.dwSpeed
));
1206 _MCI_CALL_DRIVER( MCI_PLAY
, pU
);
1211 /* seek to a specified position
1213 * "to start" seek to start of medium
1214 * "to end" seek to end of medium
1215 * "to <time>" seek to <time> specified in current timeformat
1218 MCISTR_Seek(_MCISTR_PROTO_
) {
1219 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1221 MCI_SEEK_PARMS
*seekParams
= xmalloc(sizeof(MCI_SEEK_PARMS
));
1223 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1224 if (res
) return res
;
1226 case MCI_FORMAT_MILLISECONDS
:
1227 case MCI_FORMAT_FRAMES
:
1228 case MCI_FORMAT_BYTES
:
1229 case MCI_FORMAT_SAMPLES
:
1233 case MCI_FORMAT_HMS
:
1234 case MCI_FORMAT_MSF
:
1235 parsestr
="%d:%d:%d";
1238 case MCI_FORMAT_TMSF
:
1239 parsestr
="%d:%d:%d:%d";
1242 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1247 seekParams
->dwCallback
=hwndCallback
;
1249 while (i
<nrofkeywords
) {
1250 if ( !STRCMP(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1251 if (!STRCMP(keywords
[i
+1],"start")) {
1252 dwFlags
|=MCI_SEEK_TO_START
;
1257 if (!STRCMP(keywords
[i
+1],"end")) {
1258 dwFlags
|=MCI_SEEK_TO_END
;
1265 a
[0]=a
[1]=a
[2]=a
[3]=0;
1266 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1269 seekParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1273 case MCI_DEVTYPE_VIDEODISC
:
1274 FLAG1("reverse",MCI_VD_SEEK_REVERSE
);
1279 _MCI_CALL_DRIVER( MCI_SEEK
, seekParams
);
1284 /* close media/driver */
1286 MCISTR_Close(_MCISTR_PROTO_
)
1288 MCI_GENERIC_PARMS
*closeParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1290 _MCI_CALL_DRIVER( MCI_CLOSE
, closeParams
);
1295 /* return information.
1297 * "product" return product name (human readable)
1298 * "file" return filename
1300 * "text" returns text?
1302 * "text" returns text?
1305 MCISTR_Info(_MCISTR_PROTO_
)
1307 MCI_INFO_PARMS16
*infoParams
= xmalloc(sizeof(MCI_INFO_PARMS16
));
1312 i
=0;while (i
<nrofkeywords
) {
1313 FLAG1("product",MCI_INFO_PRODUCT
);
1314 FLAG1("file",MCI_INFO_FILE
);
1316 case MCI_DEVTYPE_ANIMATION
:
1317 FLAG1("text",MCI_ANIM_INFO_TEXT
);
1319 case MCI_DEVTYPE_OVERLAY
:
1320 FLAG1("text",MCI_OVLY_INFO_TEXT
);
1325 if (dwFlags
== sflags
)
1326 return MCIERR_MISSING_STRING_ARGUMENT
;
1327 /* MCI driver will fill in lpstrReturn, dwRetSize.
1328 * FIXME: I don't know if this is correct behaviour
1330 _MCI_CALL_DRIVER( MCI_INFO
, infoParams
);
1332 _MCI_STR(infoParams
->lpstrReturn
);
1337 /* query MCI driver itself for information
1339 * "installname" return install name of <device> (system.ini)
1340 * "quantity" return nr of installed drivers
1341 * "open" open drivers only (additional flag)
1342 * "name <nr>" return nr of devices with <devicetyp>
1343 * "name all" return nr of all devices
1345 * FIXME: mciSysInfo16() is broken I think.
1348 MCISTR_Sysinfo(_MCISTR_PROTO_
) {
1349 MCI_SYSINFO_PARMS16 sysinfoParams
;
1352 sysinfoParams
.lpstrReturn
= lpstrReturnString
;
1353 sysinfoParams
.dwRetSize
= uReturnLength
;
1354 sysinfoParams
.wDeviceType
= uDevTyp
;
1356 for (i
= 0; i
< nrofkeywords
; i
++) {
1357 FLAG1("installname",MCI_SYSINFO_INSTALLNAME
);
1358 FLAG1("quantity",MCI_SYSINFO_INSTALLNAME
);
1359 FLAG1("open",MCI_SYSINFO_OPEN
);
1360 if (!strcmp(keywords
[i
],"name") && (i
+1<nrofkeywords
)) {
1361 sscanf(keywords
[i
+1],"%ld",&(sysinfoParams
.dwNumber
));
1362 dwFlags
|= MCI_SYSINFO_NAME
;
1366 res
= mciSendCommand(0, MCI_SYSINFO
, dwFlags
, (DWORD
)&sysinfoParams
);
1368 if (dwFlags
& MCI_SYSINFO_QUANTITY
) {
1371 sprintf(buf
,"%ld",*(long*)lpstrReturnString
);
1374 /* no need to copy anything back, mciSysInfo did it for us */
1379 * Argument: "<filename>"
1380 * Overlay: "at <left> <top> <right> <bottom>" additional
1383 MCISTR_Load(_MCISTR_PROTO_
) {
1385 MCI_LOAD_PARMS16 loadParams
;
1386 MCI_OVLY_LOAD_PARMS16 ovlyloadParams
;
1388 union U
*pU
= xmalloc(sizeof(union U
));
1393 while (i
<nrofkeywords
) {
1395 case MCI_DEVTYPE_OVERLAY
:
1396 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1397 dwFlags
|= MCI_OVLY_RECT
;
1398 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyloadParams
.rc
.left
));
1399 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyloadParams
.rc
.top
));
1400 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyloadParams
.rc
.right
));
1401 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyloadParams
.rc
.bottom
));
1402 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1407 len
+=strlen(keywords
[i
])+1;
1410 s
=(char*)xmalloc(len
);
1412 while (i
<nrofkeywords
) {
1413 strcat(s
,keywords
[i
]);
1415 if (i
<nrofkeywords
) strcat(s
," ");
1417 pU
->loadParams
.lpfilename
=s
;
1418 dwFlags
|= MCI_LOAD_FILE
;
1419 _MCI_CALL_DRIVER( MCI_LOAD
, pU
);
1426 * Argument: "<filename>"
1427 * Overlay: "at <left> <top> <right> <bottom>" additional
1430 MCISTR_Save(_MCISTR_PROTO_
) {
1432 MCI_SAVE_PARMS saveParams
;
1433 MCI_OVLY_SAVE_PARMS16 ovlysaveParams
;
1435 union U
*pU
= xmalloc(sizeof(union U
));
1440 while (i
<nrofkeywords
) {
1442 case MCI_DEVTYPE_OVERLAY
:
1443 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1444 dwFlags
|= MCI_OVLY_RECT
;
1445 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlysaveParams
.rc
.left
));
1446 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlysaveParams
.rc
.top
));
1447 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlysaveParams
.rc
.right
));
1448 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlysaveParams
.rc
.bottom
));
1449 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1454 len
+=strlen(keywords
[i
])+1;
1457 s
=(char*)xmalloc(len
);
1459 while (i
<nrofkeywords
) {
1460 strcat(s
,keywords
[i
]);
1462 if (i
<nrofkeywords
) strcat(s
," ");
1464 pU
->saveParams
.lpfilename
=s
;
1465 dwFlags
|= MCI_LOAD_FILE
;
1466 _MCI_CALL_DRIVER( MCI_SAVE
, pU
);
1472 /* prepare device for input/output
1473 * (only applyable to waveform audio)
1476 MCISTR_Cue(_MCISTR_PROTO_
) {
1477 MCI_GENERIC_PARMS
*cueParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1481 while (i
<nrofkeywords
) {
1483 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
1484 FLAG1("input",MCI_WAVE_INPUT
);
1485 FLAG1("output",MCI_WAVE_OUTPUT
);
1490 _MCI_CALL_DRIVER( MCI_CUE
, cueParams
);
1495 /* delete information */
1497 MCISTR_Delete(_MCISTR_PROTO_
) {
1498 int timef
,nrargs
,i
,j
,k
,a
[4],res
;
1500 MCI_WAVE_DELETE_PARMS
*deleteParams
= xmalloc(sizeof(MCI_WAVE_DELETE_PARMS
));
1502 /* only implemented for waveform audio */
1503 if (uDevTyp
!= MCI_DEVTYPE_WAVEFORM_AUDIO
)
1504 return MCIERR_UNSUPPORTED_FUNCTION
; /* well it fits */
1505 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1506 if (res
) return res
;
1508 case MCI_FORMAT_MILLISECONDS
:
1509 case MCI_FORMAT_FRAMES
:
1510 case MCI_FORMAT_BYTES
:
1511 case MCI_FORMAT_SAMPLES
:
1515 case MCI_FORMAT_HMS
:
1516 case MCI_FORMAT_MSF
:
1517 parsestr
="%d:%d:%d";
1520 case MCI_FORMAT_TMSF
:
1521 parsestr
="%d:%d:%d:%d";
1524 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1530 while (i
<nrofkeywords
) {
1531 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1533 a
[0]=a
[1]=a
[2]=a
[3]=0;
1534 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1535 /* add up all integers we got, if we have more
1536 * shift them. (Well I should use the macros in
1537 * mmsystem.h, right).
1539 deleteParams
->dwTo
=0;
1541 deleteParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1545 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1546 dwFlags
|= MCI_FROM
;
1547 a
[0]=a
[1]=a
[2]=a
[3]=0;
1548 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1550 deleteParams
->dwFrom
=0;
1552 deleteParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1558 _MCI_CALL_DRIVER( MCI_DELETE
, deleteParams
);
1563 /* send command to device. only applies to videodisc */
1565 MCISTR_Escape(_MCISTR_PROTO_
)
1567 MCI_VD_ESCAPE_PARMS16
*escapeParams
= xmalloc(sizeof(MCI_VD_ESCAPE_PARMS16
));
1571 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1572 return MCIERR_UNSUPPORTED_FUNCTION
;
1574 while (i
<nrofkeywords
) {
1575 len
+=strlen(keywords
[i
])+1;
1578 s
=(char*)malloc(len
);
1580 while (i
<nrofkeywords
) {
1581 strcat(s
,keywords
[i
]);
1583 if (i
<nrofkeywords
) strcat(s
," ");
1585 escapeParams
->lpstrCommand
= s
;
1586 dwFlags
|= MCI_VD_ESCAPE_STRING
;
1587 _MCI_CALL_DRIVER( MCI_ESCAPE
, escapeParams
);
1593 /* unfreeze [part of] the overlayed video
1594 * only applyable to Overlay devices
1597 MCISTR_Unfreeze(_MCISTR_PROTO_
)
1599 MCI_OVLY_RECT_PARMS16
*unfreezeParams
= xmalloc(sizeof(MCI_OVLY_RECT_PARMS16
));
1602 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1603 return MCIERR_UNSUPPORTED_FUNCTION
;
1604 i
=0;while (i
<nrofkeywords
) {
1605 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1606 sscanf(keywords
[i
+1],"%hd",&(unfreezeParams
->rc
.left
));
1607 sscanf(keywords
[i
+2],"%hd",&(unfreezeParams
->rc
.top
));
1608 sscanf(keywords
[i
+3],"%hd",&(unfreezeParams
->rc
.right
));
1609 sscanf(keywords
[i
+4],"%hd",&(unfreezeParams
->rc
.bottom
));
1610 dwFlags
|= MCI_OVLY_RECT
;
1616 _MCI_CALL_DRIVER( MCI_UNFREEZE
, unfreezeParams
);
1617 free(unfreezeParams
);
1620 /* freeze [part of] the overlayed video
1621 * only applyable to Overlay devices
1624 MCISTR_Freeze(_MCISTR_PROTO_
)
1626 MCI_OVLY_RECT_PARMS16
*freezeParams
= xmalloc(sizeof(MCI_OVLY_RECT_PARMS16
));
1629 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1630 return MCIERR_UNSUPPORTED_FUNCTION
;
1631 i
=0;while (i
<nrofkeywords
) {
1632 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1633 sscanf(keywords
[i
+1],"%hd",&(freezeParams
->rc
.left
));
1634 sscanf(keywords
[i
+2],"%hd",&(freezeParams
->rc
.top
));
1635 sscanf(keywords
[i
+3],"%hd",&(freezeParams
->rc
.right
));
1636 sscanf(keywords
[i
+4],"%hd",&(freezeParams
->rc
.bottom
));
1637 dwFlags
|= MCI_OVLY_RECT
;
1643 _MCI_CALL_DRIVER( MCI_FREEZE
, freezeParams
);
1648 /* copy parts of image to somewhere else
1649 * "source [at <left> <top> <right> <bottom>]" source is framebuffer [or rect]
1650 * "destination [at <left> <top> <right> <bottom>]" destination is framebuffer [or rect]
1652 * "frame [at <left> <top> <right> <bottom>]" frame is framebuffer [or rect]
1653 * where the video input is placed
1654 * "video [at <left> <top> <right> <bottom>]" video is whole video [or rect]
1655 * (defining part of input to
1658 * FIXME: This whole junk is passing multiple rectangles.
1659 * I don't know how to do that with the present interface.
1660 * (Means code below is broken)
1663 MCISTR_Put(_MCISTR_PROTO_
) {
1665 MCI_OVLY_RECT_PARMS16 ovlyputParams
;
1666 MCI_ANIM_RECT_PARMS16 animputParams
;
1668 union U
*pU
= xmalloc(sizeof(union U
));
1670 i
=0;while (i
<nrofkeywords
) {
1672 case MCI_DEVTYPE_ANIMATION
:
1673 FLAG1("source",MCI_ANIM_PUT_SOURCE
);
1674 FLAG1("destination",MCI_ANIM_PUT_DESTINATION
);
1675 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1676 sscanf(keywords
[i
+1],"%hd",&(pU
->animputParams
.rc
.left
));
1677 sscanf(keywords
[i
+2],"%hd",&(pU
->animputParams
.rc
.top
));
1678 sscanf(keywords
[i
+3],"%hd",&(pU
->animputParams
.rc
.right
));
1679 sscanf(keywords
[i
+4],"%hd",&(pU
->animputParams
.rc
.bottom
));
1680 dwFlags
|= MCI_ANIM_RECT
;
1685 case MCI_DEVTYPE_OVERLAY
:
1686 FLAG1("source",MCI_OVLY_PUT_SOURCE
);
1687 FLAG1("destination",MCI_OVLY_PUT_DESTINATION
);
1688 FLAG1("video",MCI_OVLY_PUT_VIDEO
);
1689 FLAG1("frame",MCI_OVLY_PUT_FRAME
);
1690 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1691 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyputParams
.rc
.left
));
1692 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyputParams
.rc
.top
));
1693 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyputParams
.rc
.right
));
1694 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyputParams
.rc
.bottom
));
1695 dwFlags
|= MCI_OVLY_RECT
;
1703 _MCI_CALL_DRIVER( MCI_PUT
, pU
);
1708 /* palette behaviour changing
1710 * "normal" realize the palette normally
1711 * "background" realize the palette as background palette
1714 MCISTR_Realize(_MCISTR_PROTO_
)
1716 MCI_GENERIC_PARMS
*realizeParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1719 if (uDevTyp
!= MCI_DEVTYPE_ANIMATION
)
1720 return MCIERR_UNSUPPORTED_FUNCTION
;
1722 while (i
<nrofkeywords
) {
1723 FLAG1("background",MCI_ANIM_REALIZE_BKGD
);
1724 FLAG1("normal",MCI_ANIM_REALIZE_NORM
);
1727 _MCI_CALL_DRIVER( MCI_REALIZE
, realizeParams
);
1728 free(realizeParams
);
1732 /* videodisc spinning
1737 MCISTR_Spin(_MCISTR_PROTO_
)
1739 MCI_GENERIC_PARMS
*spinParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1742 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1743 return MCIERR_UNSUPPORTED_FUNCTION
;
1745 while (i
<nrofkeywords
) {
1746 FLAG1("up",MCI_VD_SPIN_UP
);
1747 FLAG1("down",MCI_VD_SPIN_UP
);
1750 _MCI_CALL_DRIVER( MCI_SPIN
, spinParams
);
1755 /* step single frames
1756 * "reverse" optional flag
1757 * "by <nr>" for <nr> frames
1760 MCISTR_Step(_MCISTR_PROTO_
) {
1762 MCI_ANIM_STEP_PARMS animstepParams
;
1763 MCI_VD_STEP_PARMS vdstepParams
;
1765 union U
*pU
= xmalloc(sizeof(union U
));
1769 while (i
<nrofkeywords
) {
1771 case MCI_DEVTYPE_ANIMATION
:
1772 FLAG1("reverse",MCI_ANIM_STEP_REVERSE
);
1773 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1774 sscanf(keywords
[i
+1],"%ld",&(pU
->animstepParams
.dwFrames
));
1775 dwFlags
|= MCI_ANIM_STEP_FRAMES
;
1780 case MCI_DEVTYPE_VIDEODISC
:
1781 FLAG1("reverse",MCI_VD_STEP_REVERSE
);
1782 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1783 sscanf(keywords
[i
+1],"%ld",&(pU
->vdstepParams
.dwFrames
));
1784 dwFlags
|= MCI_VD_STEP_FRAMES
;
1792 _MCI_CALL_DRIVER( MCI_STEP
, pU
);
1797 /* update animation window
1799 * "at <left> <top> <right> <bottom>" only in this rectangle
1800 * "hdc" device context
1803 MCISTR_Update(_MCISTR_PROTO_
) {
1805 MCI_ANIM_UPDATE_PARMS16
*updateParams
= xmalloc(sizeof(MCI_ANIM_UPDATE_PARMS16
));
1808 while (i
<nrofkeywords
) {
1809 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1810 sscanf(keywords
[i
+1],"%hd",&(updateParams
->rc
.left
));
1811 sscanf(keywords
[i
+2],"%hd",&(updateParams
->rc
.top
));
1812 sscanf(keywords
[i
+3],"%hd",&(updateParams
->rc
.right
));
1813 sscanf(keywords
[i
+4],"%hd",&(updateParams
->rc
.bottom
));
1814 dwFlags
|= MCI_ANIM_RECT
;
1818 if (!STRCMP(keywords
[i
],"hdc") && (i
+1<nrofkeywords
)) {
1819 dwFlags
|= MCI_ANIM_UPDATE_HDC
;
1820 sscanf(keywords
[i
+1],"%hd",&(updateParams
->hDC
));
1826 _MCI_CALL_DRIVER( MCI_UPDATE
, updateParams
);
1831 /* where command for animation and overlay drivers.
1832 * just returns the specified rectangle as a string
1841 MCISTR_Where(_MCISTR_PROTO_
) {
1843 MCI_ANIM_RECT_PARMS16 animwhereParams
;
1844 MCI_OVLY_RECT_PARMS16 ovlywhereParams
;
1846 union U
*pU
= xmalloc(sizeof(union U
));
1850 while (i
<nrofkeywords
) {
1852 case MCI_DEVTYPE_ANIMATION
:
1853 FLAG1("source",MCI_ANIM_WHERE_SOURCE
);
1854 FLAG1("destination",MCI_ANIM_WHERE_DESTINATION
);
1856 case MCI_DEVTYPE_OVERLAY
:
1857 FLAG1("source",MCI_OVLY_WHERE_SOURCE
);
1858 FLAG1("destination",MCI_OVLY_WHERE_DESTINATION
);
1859 FLAG1("video",MCI_OVLY_WHERE_VIDEO
);
1860 FLAG1("frame",MCI_OVLY_WHERE_FRAME
);
1865 _MCI_CALL_DRIVER( MCI_WHERE
, pU
);
1869 case MCI_DEVTYPE_ANIMATION
:
1870 sprintf(buf
,"%d %d %d %d",
1871 pU
->animwhereParams
.rc
.left
,
1872 pU
->animwhereParams
.rc
.top
,
1873 pU
->animwhereParams
.rc
.right
,
1874 pU
->animwhereParams
.rc
.bottom
1877 case MCI_DEVTYPE_OVERLAY
:
1878 sprintf(buf
,"%d %d %d %d",
1879 pU
->ovlywhereParams
.rc
.left
,
1880 pU
->ovlywhereParams
.rc
.top
,
1881 pU
->ovlywhereParams
.rc
.right
,
1882 pU
->ovlywhereParams
.rc
.bottom
1885 default:strcpy(buf
,"0 0 0 0");break;
1894 MCISTR_Window(_MCISTR_PROTO_
) {
1898 MCI_ANIM_WINDOW_PARMS16 animwindowParams
;
1899 MCI_OVLY_WINDOW_PARMS16 ovlywindowParams
;
1901 union U
*pU
= xmalloc(sizeof(union U
));
1905 while (i
<nrofkeywords
) {
1907 case MCI_DEVTYPE_ANIMATION
:
1908 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1909 dwFlags
|= MCI_ANIM_WINDOW_HWND
;
1910 if (!STRCMP(keywords
[i
+1],"default"))
1911 pU
->animwindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1913 sscanf(keywords
[i
+1],"%hd",&(pU
->animwindowParams
.hWnd
));
1917 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1918 dwFlags
|= MCI_ANIM_WINDOW_STATE
;
1919 if (!STRCMP(keywords
[i
+1],"hide"))
1920 pU
->animwindowParams
.nCmdShow
= SW_HIDE
;
1921 if (!STRCMP(keywords
[i
+1],"iconic"))
1922 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1923 if (!STRCMP(keywords
[i
+1],"minimized"))
1924 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1925 if (!STRCMP(keywords
[i
+1],"maximized"))
1926 pU
->animwindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1927 if (!STRCMP(keywords
[i
+1],"minimize"))
1928 pU
->animwindowParams
.nCmdShow
= SW_MINIMIZE
;
1929 if (!STRCMP(keywords
[i
+1],"normal"))
1930 pU
->animwindowParams
.nCmdShow
= SW_NORMAL
;
1931 if (!STRCMP(keywords
[i
+1],"show"))
1932 pU
->animwindowParams
.nCmdShow
= SW_SHOW
;
1933 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
1934 if (!STRCMP(keywords
[i
+2],"active"))
1935 pU
->animwindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
1936 if (!STRCMP(keywords
[i
+2],"action"))
1937 pU
->animwindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
1943 /* text is enclosed in " ... " as it seems */
1944 if (!STRCMP(keywords
[i
],"text")) {
1948 if (keywords
[i
+1][0]!='"') {
1952 dwFlags
|= MCI_ANIM_WINDOW_TEXT
;
1953 len
= strlen(keywords
[i
+1])+1;
1955 while (j
<nrofkeywords
) {
1956 len
+= strlen(keywords
[j
])+1;
1957 if (strchr(keywords
[j
],'"'))
1961 s
=(char*)xmalloc(len
);
1962 strcpy(s
,keywords
[i
+1]+1);
1966 strcat(s
,keywords
[j
]);
1968 if ((t
=strchr(s
,'"'))) *t
='\0';
1969 /* FIXME: segmented pointer? */
1970 pU
->animwindowParams
.lpstrText
= s
;
1974 FLAG1("stretch",MCI_ANIM_WINDOW_ENABLE_STRETCH
);
1976 case MCI_DEVTYPE_OVERLAY
:
1977 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1978 dwFlags
|= MCI_OVLY_WINDOW_HWND
;
1979 if (!STRCMP(keywords
[i
+1],"default"))
1980 pU
->ovlywindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1982 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlywindowParams
.hWnd
));
1986 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1987 dwFlags
|= MCI_OVLY_WINDOW_STATE
;
1988 if (!STRCMP(keywords
[i
+1],"hide"))
1989 pU
->ovlywindowParams
.nCmdShow
= SW_HIDE
;
1990 if (!STRCMP(keywords
[i
+1],"iconic"))
1991 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1992 if (!STRCMP(keywords
[i
+1],"minimized"))
1993 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1994 if (!STRCMP(keywords
[i
+1],"maximized"))
1995 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1996 if (!STRCMP(keywords
[i
+1],"minimize"))
1997 pU
->ovlywindowParams
.nCmdShow
= SW_MINIMIZE
;
1998 if (!STRCMP(keywords
[i
+1],"normal"))
1999 pU
->ovlywindowParams
.nCmdShow
= SW_NORMAL
;
2000 if (!STRCMP(keywords
[i
+1],"show"))
2001 pU
->ovlywindowParams
.nCmdShow
= SW_SHOW
;
2002 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
2003 if (!STRCMP(keywords
[i
+2],"active"))
2004 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
2005 if (!STRCMP(keywords
[i
+2],"action"))
2006 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
2012 /* text is enclosed in " ... " as it seems */
2013 if (!STRCMP(keywords
[i
],"text")) {
2017 if (keywords
[i
+1][0]!='"') {
2021 dwFlags
|= MCI_OVLY_WINDOW_TEXT
;
2022 len
= strlen(keywords
[i
+1])+1;
2024 while (j
<nrofkeywords
) {
2025 len
+= strlen(keywords
[j
])+1;
2026 if (strchr(keywords
[j
],'"'))
2030 s
=(char*)xmalloc(len
);
2031 strcpy(s
,keywords
[i
+1]+1);
2035 strcat(s
,keywords
[j
]);
2037 if ((t
=strchr(s
,'"'))) *t
='\0';
2038 /* FIXME: segmented pointer? */
2039 pU
->ovlywindowParams
.lpstrText
= s
;
2043 FLAG1("stretch",MCI_OVLY_WINDOW_ENABLE_STRETCH
);
2048 _MCI_CALL_DRIVER( MCI_WINDOW
, pU
);
2054 struct _MCISTR_cmdtable
{
2056 DWORD (*fun
)(_MCISTR_PROTO_
);
2057 } MCISTR_cmdtable
[]={
2058 {"break", MCISTR_Break
},
2059 {"capability", MCISTR_Capability
},
2060 {"close", MCISTR_Close
},
2061 {"cue", MCISTR_Cue
},
2062 {"delete", MCISTR_Delete
},
2063 {"escape", MCISTR_Escape
},
2064 {"freeze", MCISTR_Freeze
},
2065 {"info", MCISTR_Info
},
2066 {"load", MCISTR_Load
},
2067 {"open", MCISTR_Open
},
2068 {"pause", MCISTR_Pause
},
2069 {"play", MCISTR_Play
},
2070 {"put", MCISTR_Put
},
2071 {"realize", MCISTR_Realize
},
2072 {"record", MCISTR_Record
},
2073 {"resume", MCISTR_Resume
},
2074 {"save", MCISTR_Save
},
2075 {"seek", MCISTR_Seek
},
2076 {"set", MCISTR_Set
},
2077 {"spin", MCISTR_Spin
},
2078 {"status", MCISTR_Status
},
2079 {"step", MCISTR_Step
},
2080 {"stop", MCISTR_Stop
},
2081 {"sysinfo", MCISTR_Sysinfo
},
2082 {"unfreeze", MCISTR_Unfreeze
},
2083 {"update", MCISTR_Update
},
2084 {"where", MCISTR_Where
},
2085 {"window", MCISTR_Window
},
2088 /**************************************************************************
2089 * mciSendString [MMSYSTEM.702]
2091 /* The usercode sends a string with a command (and flags) expressed in
2092 * words in it... We do our best to call aprobiate drivers,
2093 * and return a errorcode AND a readable string (if lpstrRS!=NULL)
2094 * Info gathered by watching cool134.exe and from Borland's mcistrwh.hlp
2096 /* FIXME: "all" is a valid devicetype and we should access all devices if
2097 * it is used. (imagine "close all"). Not implemented yet.
2099 DWORD WINAPI
mciSendString (LPCSTR lpstrCommand
, LPSTR lpstrReturnString
,
2100 UINT16 uReturnLength
, HWND16 hwndCallback
)
2102 char *cmd
,*dev
,*args
,**keywords
,*filename
;
2103 WORD uDevTyp
=0,wDevID
=0;
2105 int res
=0,i
,nrofkeywords
;
2107 TRACE(mci
,"('%s', %p, %d, %X)\n", lpstrCommand
,
2108 lpstrReturnString
, uReturnLength
, hwndCallback
2110 /* format is <command> <device> <optargs> */
2111 cmd
=strdup(lpstrCommand
);
2112 dev
=strchr(cmd
,' ');
2115 return MCIERR_MISSING_DEVICE_NAME
;
2118 args
=strchr(dev
,' ');
2119 if (args
!=NULL
) *args
++='\0';
2123 i
=1;/* nrofkeywords = nrofspaces+1 */
2125 while ((s
=strchr(s
,' '))!=NULL
) i
++,s
++;
2126 keywords
=(char**)xmalloc(sizeof(char*)*(i
+2));
2129 while (s
&& i
<nrofkeywords
) {
2137 keywords
=(char**)xmalloc(sizeof(char*));
2139 dwFlags
= 0; /* default flags */
2140 for (i
=0;i
<nrofkeywords
;) {
2141 /* take care, there is also a "device type" capability */
2142 if ((!STRCMP(keywords
[i
],"type")) && (i
<nrofkeywords
-1)) {
2144 dev
= keywords
[i
+1];
2145 memcpy(keywords
+i
,keywords
+(i
+2),(nrofkeywords
-i
-2)*sizeof(char *));
2149 if (!STRCMP(keywords
[i
],"wait")) {
2150 dwFlags
|= MCI_WAIT
;
2151 memcpy(keywords
+i
,keywords
+(i
+1),(nrofkeywords
-i
-1)*sizeof(char *));
2155 if (!STRCMP(keywords
[i
],"notify")) {
2156 dwFlags
|= MCI_NOTIFY
;
2157 memcpy(keywords
+i
,keywords
+(i
+1),(nrofkeywords
-i
-1)*sizeof(char *));
2164 /* determine wDevID and uDevTyp for all commands except "open" */
2165 if (STRCMP(cmd
,"open")!=0) {
2166 wDevID
= MMSYSTEM_FirstDevID();
2170 dname
=mciGetOpenDrv(wDevID
)->lpstrAlias
;
2172 dname
=mciGetOpenDrv(wDevID
)->lpstrDeviceType
;
2173 if (dname
!= NULL
&& !STRCMP(dname
,dev
))
2175 wDevID
= MMSYSTEM_NextDevID(wDevID
);
2176 if (!MMSYSTEM_DevIDValid(wDevID
)) {
2177 TRACE(mci
, "MAXMCIDRIVERS reached!\n");
2178 free(keywords
);free(cmd
);
2179 return MCIERR_INVALID_DEVICE_NAME
;
2182 uDevTyp
=mciGetDrv(wDevID
)->modp
.wType
;
2185 for (i
=0;MCISTR_cmdtable
[i
].cmd
!=NULL
;i
++) {
2186 if (!STRCMP(MCISTR_cmdtable
[i
].cmd
,cmd
)) {
2187 res
=MCISTR_cmdtable
[i
].fun(
2188 wDevID
,uDevTyp
,lpstrReturnString
,
2189 uReturnLength
,dev
,(LPSTR
*)keywords
,nrofkeywords
,
2190 dwFlags
,hwndCallback
2195 if (MCISTR_cmdtable
[i
].cmd
!=NULL
) {
2196 free(keywords
);free(cmd
);
2199 FIXME(mci
,"('%s', %p, %u, %X): unimplemented, please report.\n",
2200 lpstrCommand
, lpstrReturnString
, uReturnLength
, hwndCallback
);
2201 free(keywords
);free(cmd
);
2202 return MCIERR_MISSING_COMMAND_STRING
;