4 * Copyright 1995 Marcus Meissner
6 /* FIXME: special commands of device drivers should be handled by those drivers
16 #include <sys/ioctl.h>
28 extern MCI_OPEN_DRIVER_PARMS mciDrv
[MAXMCIDRIVERS
];
30 /* FIXME: I need to remember the aliasname of a spec. driver.
31 * and this is the easiest way. *sigh*
33 extern MCI_OPEN_PARMS mciOpenDrv
[MAXMCIDRIVERS
];
35 LONG
DrvDefDriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
36 DWORD dwParam1
, DWORD dwParam2
);
38 LONG
WAVE_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
39 DWORD dwParam1
, DWORD dwParam2
);
40 LONG
MIDI_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
41 DWORD dwParam1
, DWORD dwParam2
);
42 LONG
CDAUDIO_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
43 DWORD dwParam1
, DWORD dwParam2
);
44 LONG
ANIM_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
45 DWORD dwParam1
, DWORD dwParam2
);
47 /* The reason why I just don't lowercase the keywords array in
48 * mciSendString is left as an exercise to the reader.
50 #define STRCMP(x,y) lstrcmpi32A(x,y)
52 /* standard functionparameters for all functions */
53 #define _MCISTR_PROTO_ \
54 WORD wDevID,WORD uDevTyp,LPSTR lpstrReturnString,UINT uReturnLength,\
55 LPCSTR dev,LPSTR *keywords,UINT nrofkeywords,DWORD dwFlags
57 /* copy string to return pointer including necessary checks
58 * for use in mciSendString()
60 #define _MCI_STR(s) do {\
61 dprintf_mci(stddeb,"->returns \"%s\"",s);\
62 if (lpstrReturnString) {\
63 lstrcpyn32A(lpstrReturnString,s,uReturnLength);\
64 dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
68 /* calling DriverProc. We need to pass the struct as SEGMENTED POINTER. */
69 #define _MCI_CALL_DRIVER(cmd,params) \
71 case MCI_DEVTYPE_CD_AUDIO:\
72 res=CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags, (DWORD)(params));\
74 case MCI_DEVTYPE_WAVEFORM_AUDIO:\
75 res=WAVE_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
77 case MCI_DEVTYPE_SEQUENCER:\
78 res=MIDI_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
80 case MCI_DEVTYPE_ANIMATION:\
81 res=ANIM_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
83 case MCI_DEVTYPE_DIGITAL_VIDEO:\
84 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //No DIGITAL_VIDEO yet !\n");\
85 res=MCIERR_DEVICE_NOT_INSTALLED;\
88 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //Invalid Device Name '%s' !\n",dev);\
89 res=MCIERR_INVALID_DEVICE_NAME;\
92 /* print a DWORD in the specified timeformat */
94 _MCISTR_printtf(char *buf
,UINT uDevType
,DWORD timef
,DWORD val
) {
97 case MCI_FORMAT_MILLISECONDS
:
98 case MCI_FORMAT_FRAMES
:
99 case MCI_FORMAT_BYTES
:
100 case MCI_FORMAT_SAMPLES
:
101 case MCI_VD_FORMAT_TRACK
:
102 /*case MCI_SEQ_FORMAT_SONGPTR: sameas MCI_VD_FORMAT_TRACK */
103 sprintf(buf
,"%ld",val
);
106 /* well, the macros have the same content*/
109 sprintf(buf
,"%d:%d:%d",
115 case MCI_FORMAT_TMSF
:
116 sprintf(buf
,"%d:%d:%d:%d",
118 MCI_TMSF_MINUTE(val
),
119 MCI_TMSF_SECOND(val
),
124 fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing timeformat for %ld, report.\n",timef
);
125 strcpy(buf
,"0"); /* hmm */
130 /* possible different return types */
131 #define _MCISTR_int 1
132 #define _MCISTR_time 2
133 #define _MCISTR_bool 3
134 #define _MCISTR_tfname 4
135 #define _MCISTR_mode 5
136 #define _MCISTR_divtype 6
137 #define _MCISTR_seqtype 7
138 #define _MCISTR_vdmtype 8
139 #define _MCISTR_devtype 9
142 _MCISTR_convreturn(int type
,DWORD dwReturn
,LPSTR lpstrReturnString
,
143 WORD uReturnLength
,WORD uDevTyp
,int timef
146 case _MCISTR_vdmtype
:
148 case MCI_VD_MEDIA_CLV
:_MCI_STR("CLV");break;
149 case MCI_VD_MEDIA_CAV
:_MCI_STR("CAV");break;
151 case MCI_VD_MEDIA_OTHER
:_MCI_STR("other");break;
154 case _MCISTR_seqtype
:
156 case MCI_SEQ_NONE
:_MCI_STR("none");break;
157 case MCI_SEQ_SMPTE
:_MCI_STR("smpte");break;
158 case MCI_SEQ_FILE
:_MCI_STR("file");break;
159 case MCI_SEQ_MIDI
:_MCI_STR("midi");break;
160 default:fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing sequencer mode %ld\n",dwReturn
);
165 case MCI_MODE_NOT_READY
:_MCI_STR("not ready");break;
166 case MCI_MODE_STOP
:_MCI_STR("stopped");break;
167 case MCI_MODE_PLAY
:_MCI_STR("playing");break;
168 case MCI_MODE_RECORD
:_MCI_STR("recording");break;
169 case MCI_MODE_SEEK
:_MCI_STR("seeking");break;
170 case MCI_MODE_PAUSE
:_MCI_STR("paused");break;
171 case MCI_MODE_OPEN
:_MCI_STR("open");break;
183 sprintf(buf
,"%ld",dwReturn
);
189 _MCISTR_printtf(buf
,uDevTyp
,timef
,dwReturn
);
195 case MCI_FORMAT_MILLISECONDS
:_MCI_STR("milliseconds");break;
196 case MCI_FORMAT_FRAMES
:_MCI_STR("frames");break;
197 case MCI_FORMAT_BYTES
:_MCI_STR("bytes");break;
198 case MCI_FORMAT_SAMPLES
:_MCI_STR("samples");break;
199 case MCI_FORMAT_HMS
:_MCI_STR("hms");break;
200 case MCI_FORMAT_MSF
:_MCI_STR("msf");break;
201 case MCI_FORMAT_TMSF
:_MCI_STR("tmsf");break;
203 fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing timeformat for %d, report.\n",timef
);
207 case _MCISTR_divtype
:
209 case MCI_SEQ_DIV_PPQN
:_MCI_STR("PPQN");break;
210 case MCI_SEQ_DIV_SMPTE_24
:_MCI_STR("SMPTE 24 frame");break;
211 case MCI_SEQ_DIV_SMPTE_25
:_MCI_STR("SMPTE 25 frame");break;
212 case MCI_SEQ_DIV_SMPTE_30
:_MCI_STR("SMPTE 30 frame");break;
213 case MCI_SEQ_DIV_SMPTE_30DROP
:_MCI_STR("SMPTE 30 frame drop");break;
215 case _MCISTR_devtype
:
217 case MCI_DEVTYPE_VCR
:_MCI_STR("vcr");break;
218 case MCI_DEVTYPE_VIDEODISC
:_MCI_STR("videodisc");break;
219 case MCI_DEVTYPE_CD_AUDIO
:_MCI_STR("cd audio");break;
220 case MCI_DEVTYPE_OVERLAY
:_MCI_STR("overlay");break;
221 case MCI_DEVTYPE_DAT
:_MCI_STR("dat");break;
222 case MCI_DEVTYPE_SCANNER
:_MCI_STR("scanner");break;
223 case MCI_DEVTYPE_ANIMATION
:_MCI_STR("animation");break;
224 case MCI_DEVTYPE_DIGITAL_VIDEO
:_MCI_STR("digital video");break;
225 case MCI_DEVTYPE_OTHER
:_MCI_STR("other");break;
226 case MCI_DEVTYPE_WAVEFORM_AUDIO
:_MCI_STR("waveform audio");break;
227 case MCI_DEVTYPE_SEQUENCER
:_MCI_STR("sequencer");break;
228 default:fprintf(stdnimp
,__FILE__
":_MCISTR_convreturn:unknown device type %ld, report.\n",dwReturn
);break;
232 fprintf(stdnimp
,__FILE__
":_MCISTR_convreturn:unknown resulttype %d, report.\n",type
);
237 #define FLAG1(str,flag) \
238 if (!STRCMP(keywords[i],str)) {\
243 #define FLAG2(str1,str2,flag) \
244 if (!STRCMP(keywords[i],str1) && (i+1<nrofkeywords) && !STRCMP(keywords[i+1],str2)) {\
250 /* All known subcommands are implemented in single functions to avoid
251 * bloat and a xxxx lines long mciSendString(). All commands are of the
252 * format MCISTR_Cmd(_MCISTR_PROTO_) where _MCISTR_PROTO_ is the above
253 * defined line of arguments. (This is just for easy enhanceability.)
254 * All functions return the MCIERR_ errorvalue as DWORD. Returnvalues
255 * for the calls are in lpstrReturnString (If I mention return values
256 * in function headers, I mean returnvalues in lpstrReturnString.)
257 * Integers are sprintf("%d")ed integers. Boolean values are
258 * "true" and "false".
259 * timeformat depending values are "%d" "%d:%d" "%d:%d:%d" "%d:%d:%d:%d"
260 * FIXME: is above line correct?
262 * Preceding every function is a list of implemented/known arguments.
263 * Feel free to add missing arguments.
268 * Opens the specified MCI driver.
272 * "alias <aliasname>"
273 * "element <elementname>"
276 * "buffer <nrBytesPerSec>"
278 * "nostatic" increaste nr of nonstatic colours
279 * "parent <windowhandle>"
280 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
281 * "style child" WS_CHILD
282 * "style overlap" WS_OVERLAPPED
283 * "style popup" WS_POPUP
285 * "parent <windowhandle>"
286 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
287 * "style child" WS_CHILD
288 * "style overlap" WS_OVERLAPPED
289 * "style popup" WS_POPUP
293 MCISTR_Open(_MCISTR_PROTO_
) {
297 MCI_OPEN_PARMS openParams
;
298 MCI_WAVE_OPEN_PARMS waveopenParams
;
299 MCI_ANIM_OPEN_PARMS animopenParams
;
300 MCI_OVLY_OPEN_PARMS ovlyopenParams
;
302 union U
*pU
= SEGPTR_NEW(union U
);
304 pU
->openParams
.lpstrElementName
= NULL
;
308 pU
->openParams
.lpstrElementName
=SEGPTR_GET(SEGPTR_STRDUP(s
));
310 if (!STRCMP(dev
,"cdaudio")) {
311 uDevTyp
=MCI_DEVTYPE_CD_AUDIO
;
312 } else if (!STRCMP(dev
,"waveaudio")) {
313 uDevTyp
=MCI_DEVTYPE_WAVEFORM_AUDIO
;
314 } else if (!STRCMP(dev
,"sequencer")) {
315 uDevTyp
=MCI_DEVTYPE_SEQUENCER
;
316 } else if (!STRCMP(dev
,"animation1")) {
317 uDevTyp
=MCI_DEVTYPE_ANIMATION
;
318 } else if (!STRCMP(dev
,"avivideo")) {
319 uDevTyp
=MCI_DEVTYPE_DIGITAL_VIDEO
;
321 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrElementName
));
323 return MCIERR_INVALID_DEVICE_NAME
;
326 while(mciDrv
[wDevID
].wType
) {
327 if (++wDevID
>=MAXMCIDRIVERS
) {
328 dprintf_mci(stddeb
, __FILE__
":MCISTR_Open:MAXMCIDRIVERS reached!\n");
329 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrElementName
));
331 return MCIERR_INTERNAL
;
334 mciDrv
[wDevID
].wType
= uDevTyp
;
335 mciDrv
[wDevID
].wDeviceID
= wDevID
;
336 pU
->openParams
.dwCallback
= 0;
337 pU
->openParams
.wDeviceID
= wDevID
;
338 pU
->ovlyopenParams
.dwStyle
= 0;
339 pU
->animopenParams
.dwStyle
= 0;
340 pU
->openParams
.lpstrDeviceType
= SEGPTR_GET(SEGPTR_STRDUP(dev
));
341 pU
->openParams
.lpstrAlias
= NULL
;
342 dwFlags
|= MCI_OPEN_TYPE
;
344 while (i
<nrofkeywords
) {
345 FLAG1("shareable",MCI_OPEN_SHAREABLE
);
346 if (!strcmp(keywords
[i
],"alias") && (i
+1<nrofkeywords
)) {
347 dwFlags
|= MCI_OPEN_ALIAS
;
348 pU
->openParams
.lpstrAlias
=SEGPTR_GET(SEGPTR_STRDUP(keywords
[i
+1]));
352 if (!strcmp(keywords
[i
],"element") && (i
+1<nrofkeywords
)) {
353 dwFlags
|= MCI_OPEN_ELEMENT
;
354 pU
->openParams
.lpstrElementName
=SEGPTR_GET(SEGPTR_STRDUP(keywords
[i
]));
359 case MCI_DEVTYPE_ANIMATION
:
360 case MCI_DEVTYPE_DIGITAL_VIDEO
:
361 FLAG1("nostatic",MCI_ANIM_OPEN_NOSTATIC
);
362 if (!STRCMP(keywords
[i
],"parent") && (i
+1<nrofkeywords
)) {
363 dwFlags
|= MCI_ANIM_OPEN_PARENT
;
364 sscanf(keywords
[i
+1],"%hu",&(pU
->animopenParams
.hWndParent
));
368 if (!STRCMP(keywords
[i
],"style") && (i
+1<nrofkeywords
)) {
371 dwFlags
|= MCI_ANIM_OPEN_WS
;
372 if (!STRCMP(keywords
[i
+1],"popup")) {
373 pU
->animopenParams
.dwStyle
|= WS_POPUP
;
374 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
375 pU
->animopenParams
.dwStyle
|= WS_OVERLAPPED
;
376 } else if (!STRCMP(keywords
[i
+1],"child")) {
377 pU
->animopenParams
.dwStyle
|= WS_CHILD
;
378 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
379 pU
->animopenParams
.dwStyle
|= st
;
381 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
386 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
387 if (!STRCMP(keywords
[i
],"buffer") && (i
+1<nrofkeywords
)) {
388 dwFlags
|= MCI_WAVE_OPEN_BUFFER
;
389 sscanf(keywords
[i
+1],"%ld",&(pU
->waveopenParams
.dwBufferSeconds
));
392 case MCI_DEVTYPE_OVERLAY
:
393 /* looks just like anim, but without NOSTATIC */
394 if (!STRCMP(keywords
[i
],"parent") && (i
+1<nrofkeywords
)) {
395 dwFlags
|= MCI_OVLY_OPEN_PARENT
;
396 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyopenParams
.hWndParent
));
400 if (!STRCMP(keywords
[i
],"style") && (i
+1<nrofkeywords
)) {
403 dwFlags
|= MCI_OVLY_OPEN_WS
;
404 if (!STRCMP(keywords
[i
+1],"popup")) {
405 pU
->ovlyopenParams
.dwStyle
|= WS_POPUP
;
406 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
407 pU
->ovlyopenParams
.dwStyle
|= WS_OVERLAPPED
;
408 } else if (!STRCMP(keywords
[i
+1],"child")) {
409 pU
->ovlyopenParams
.dwStyle
|= WS_CHILD
;
410 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
411 pU
->ovlyopenParams
.dwStyle
|= st
;
413 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
419 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown parameter passed %s, please report.\n",keywords
[i
]);
422 _MCI_CALL_DRIVER( MCI_OPEN
, SEGPTR_GET(pU
) );
424 memcpy(&mciOpenDrv
[wDevID
],&pU
->openParams
,sizeof(MCI_OPEN_PARMS
));
426 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrElementName
));
427 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrDeviceType
));
428 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrAlias
));
434 /* A help function for a lot of others ...
435 * for instance status/play/record/seek etc.
438 _MCISTR_determine_timeformat(LPCSTR dev
,WORD wDevID
,WORD uDevTyp
,int *timef
)
441 DWORD dwFlags
= MCI_STATUS_ITEM
;
442 MCI_STATUS_PARMS
*statusParams
= SEGPTR_NEW(MCI_STATUS_PARMS
);
444 if (!statusParams
) return 0;
445 statusParams
->dwItem
= MCI_STATUS_TIME_FORMAT
;
446 statusParams
->dwReturn
= 0;
447 _MCI_CALL_DRIVER( MCI_STATUS
, SEGPTR_GET(statusParams
) );
448 if (res
==0) *timef
= statusParams
->dwReturn
;
449 SEGPTR_FREE(statusParams
);
453 /* query status of MCI drivers
456 * "mode" - returns "not ready" "paused" "playing" "stopped" "open"
457 * "parked" "recording" "seeking" ....
459 * "current track" - returns current track as integer
460 * "length [track <nr>]" - returns length [of track <nr>] in current
462 * "number of tracks" - returns number of tracks as integer
463 * "position [track <nr>]" - returns position [in track <nr>] in current
465 * "ready" - checks if device is ready to play, -> bool
466 * "start position" - returns start position in timeformat
467 * "time format" - returns timeformat (list of possible values:
468 * "ms" "msf" "milliseconds" "hmsf" "tmsf" "frames"
469 * "bytes" "samples" "hms")
470 * "media present" - returns if media is present as bool
472 * "forward" - returns "true" if device is playing forwards
473 * "speed" - returns speed for device
474 * "palette handle" - returns palette handle
475 * "window handle" - returns window handle
476 * "stretch" - returns stretch bool
478 * "division type" - ? returns "PPQN" "SMPTE 24 frame"
479 * "SMPTE 25 frame" "SMPTE 30 frame" "SMPTE 30 drop frame"
480 * "tempo" - current tempo in (PPQN? speed in frames, SMPTE*? speed in hsmf)
481 * "offset" - offset in dito.
482 * "port" - midi port as integer
483 * "slave" - slave device ("midi","file","none","smpte")
484 * "master" - masterdevice (dito.)
486 * "window handle" - see animation
489 * "speed" - speed as integer
490 * "forward" - returns bool (when playing forward)
491 * "side" - returns 1 or 2
492 * "media type" - returns "CAV" "CLV" "other"
493 * "disc size" - returns "8" or "12"
495 * "input" - base queries on input set
496 * "output" - base queries on output set
497 * "format tag" - return integer format tag
498 * "channels" - return integer nr of channels
499 * "bytespersec" - return average nr of bytes/sec
500 * "samplespersec" - return nr of samples per sec
501 * "bitspersample" - return bitspersample
502 * "alignment" - return block alignment
503 * "level" - return level?
506 #define ITEM1(str,item,xtype) \
507 if (!STRCMP(keywords[i],str)) {\
508 statusParams->dwItem = item;\
513 #define ITEM2(str1,str2,item,xtype) \
514 if ( !STRCMP(keywords[i],str1) &&\
515 (i+1<nrofkeywords) &&\
516 !STRCMP(keywords[i+1],str2)\
518 statusParams->dwItem = item;\
523 #define ITEM3(str1,str2,str3,item,xtype) \
524 if ( !STRCMP(keywords[i],str1) &&\
525 (i+2<nrofkeywords) &&\
526 !STRCMP(keywords[i+1],str2) &&\
527 !STRCMP(keywords[i+2],str3)\
529 statusParams->dwItem = item;\
535 MCISTR_Status(_MCISTR_PROTO_
) {
536 MCI_STATUS_PARMS
*statusParams
= SEGPTR_NEW(MCI_STATUS_PARMS
);
537 int type
= 0,i
,res
,timef
;
539 statusParams
->dwCallback
= 0;
540 dwFlags
|= MCI_STATUS_ITEM
;
541 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
544 statusParams
->dwReturn
= 0;
545 statusParams
->dwItem
= 0;
548 while (i
<nrofkeywords
) {
549 if (!STRCMP(keywords
[i
],"track") && (i
+1<nrofkeywords
)) {
550 sscanf(keywords
[i
+1],"%ld",&(statusParams
->dwTrack
));
551 dwFlags
|= MCI_TRACK
;
555 FLAG1("start",MCI_STATUS_START
);
557 ITEM2("current","track",MCI_STATUS_CURRENT_TRACK
,_MCISTR_time
);
558 ITEM2("time","format",MCI_STATUS_TIME_FORMAT
,_MCISTR_tfname
);
559 ITEM1("ready",MCI_STATUS_READY
,_MCISTR_bool
);
560 ITEM1("mode",MCI_STATUS_MODE
,_MCISTR_mode
);
561 ITEM3("number","of","tracks",MCI_STATUS_NUMBER_OF_TRACKS
,_MCISTR_int
);
562 ITEM1("length",MCI_STATUS_LENGTH
,_MCISTR_time
);
563 ITEM1("position",MCI_STATUS_POSITION
,_MCISTR_time
);
564 ITEM2("media","present",MCI_STATUS_MEDIA_PRESENT
,_MCISTR_bool
);
567 case MCI_DEVTYPE_ANIMATION
:
568 case MCI_DEVTYPE_DIGITAL_VIDEO
:
569 ITEM2("palette","handle",MCI_ANIM_STATUS_HPAL
,_MCISTR_int
);
570 ITEM2("window","handle",MCI_ANIM_STATUS_HWND
,_MCISTR_int
);
571 ITEM1("stretch",MCI_ANIM_STATUS_STRETCH
,_MCISTR_bool
);
572 ITEM1("speed",MCI_ANIM_STATUS_SPEED
,_MCISTR_int
);
573 ITEM1("forward",MCI_ANIM_STATUS_FORWARD
,_MCISTR_bool
);
575 case MCI_DEVTYPE_SEQUENCER
:
576 /* just completing the list, not working correctly */
577 ITEM2("division","type",MCI_SEQ_STATUS_DIVTYPE
,_MCISTR_divtype
);
578 /* tempo ... PPQN in frames/second, SMPTE in hmsf */
579 ITEM1("tempo",MCI_SEQ_STATUS_TEMPO
,_MCISTR_int
);
580 ITEM1("port",MCI_SEQ_STATUS_PORT
,_MCISTR_int
);
581 ITEM1("slave",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
582 ITEM1("master",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
583 /* offset ... PPQN in frames/second, SMPTE in hmsf */
584 ITEM1("offset",MCI_SEQ_STATUS_SLAVE
,_MCISTR_time
);
586 case MCI_DEVTYPE_OVERLAY
:
587 ITEM2("window","handle",MCI_OVLY_STATUS_HWND
,_MCISTR_int
);
588 ITEM1("stretch",MCI_OVLY_STATUS_STRETCH
,_MCISTR_bool
);
590 case MCI_DEVTYPE_VIDEODISC
:
591 ITEM1("speed",MCI_VD_STATUS_SPEED
,_MCISTR_int
);
592 ITEM1("forward",MCI_VD_STATUS_FORWARD
,_MCISTR_bool
);
593 ITEM1("side",MCI_VD_STATUS_SIDE
,_MCISTR_int
);
594 ITEM2("media","type",MCI_VD_STATUS_SIDE
,_MCISTR_vdmtype
);
595 /* returns 8 or 12 */
596 ITEM2("disc","size",MCI_VD_STATUS_DISC_SIZE
,_MCISTR_int
);
598 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
599 /* I am not quite sure if foll. 2 lines are right. */
600 FLAG1("input",MCI_WAVE_INPUT
);
601 FLAG1("output",MCI_WAVE_OUTPUT
);
603 ITEM2("format","tag",MCI_WAVE_STATUS_FORMATTAG
,_MCISTR_int
);
604 ITEM1("channels",MCI_WAVE_STATUS_CHANNELS
,_MCISTR_int
);
605 ITEM1("bytespersec",MCI_WAVE_STATUS_AVGBYTESPERSEC
,_MCISTR_int
);
606 ITEM1("samplespersec",MCI_WAVE_STATUS_SAMPLESPERSEC
,_MCISTR_int
);
607 ITEM1("bitspersample",MCI_WAVE_STATUS_BITSPERSAMPLE
,_MCISTR_int
);
608 ITEM1("alignment",MCI_WAVE_STATUS_BLOCKALIGN
,_MCISTR_int
);
609 ITEM1("level",MCI_WAVE_STATUS_LEVEL
,_MCISTR_int
);
612 fprintf(stdnimp
,__FILE__
":MCISTR_Status:unknown keyword '%s'\n",keywords
[i
]);
615 if (!statusParams
->dwItem
)
616 return MCIERR_MISSING_STRING_ARGUMENT
;
618 _MCI_CALL_DRIVER( MCI_STATUS
, SEGPTR_GET(statusParams
) );
620 _MCISTR_convreturn(type
,statusParams
->dwReturn
,lpstrReturnString
,uReturnLength
,uDevTyp
,timef
);
621 SEGPTR_FREE(statusParams
);
628 /* set specified parameters in respective MCI drivers
630 * "door open" eject media or somesuch
631 * "door close" load media
632 * "time format <timeformatname>" "ms" "milliseconds" "msf" "hmsf"
633 * "tmsf" "SMPTE 24" "SMPTE 25" "SMPTE 30"
635 * "audio [all|left|right] [on|off]" sets specified audiochannel on or off
636 * "video [on|off]" sets video on/off
638 * "formattag pcm" sets format to pcm
639 * "formattag <nr>" sets integer formattag value
640 * "any input" accept input from any known source
641 * "any output" output to any known destination
642 * "input <nr>" input from source <nr>
643 * "output <nr>" output to destination <nr>
644 * "channels <nr>" sets nr of channels
645 * "bytespersec <nr>" sets average bytes per second
646 * "samplespersec <nr>" sets average samples per second (1 sample can
648 * "alignment <nr>" sets the blockalignment to <nr>
649 * "bitspersample <nr>" sets the nr of bits per sample
651 * "master [midi|file|smpte|none]" sets the midi master device
652 * "slave [midi|file|smpte|none]" sets the midi master device
653 * "port mapper" midioutput to portmapper
654 * "port <nr>" midioutput to specified port
655 * "tempo <nr>" tempo of track (depends on timeformat/divtype)
656 * "offset <nr>" start offset?
659 MCISTR_Set(_MCISTR_PROTO_
) {
661 MCI_SET_PARMS setParams
;
662 MCI_WAVE_SET_PARMS wavesetParams
;
663 MCI_SEQ_SET_PARMS seqsetParams
;
665 union U
*pU
= SEGPTR_NEW(union U
);
668 pU
->setParams
.dwCallback
= 0;
670 while (i
<nrofkeywords
) {
671 FLAG2("door","open",MCI_SET_DOOR_OPEN
);
672 FLAG2("door","closed",MCI_SET_DOOR_CLOSED
);
674 if ( !STRCMP(keywords
[i
],"time") &&
675 (i
+2<nrofkeywords
) &&
676 !STRCMP(keywords
[i
+1],"format")
678 dwFlags
|= MCI_SET_TIME_FORMAT
;
680 /* FIXME:is this a shortcut for milliseconds or
681 * minutes:seconds? */
682 if (!STRCMP(keywords
[i
+2],"ms"))
683 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
685 if (!STRCMP(keywords
[i
+2],"milliseconds"))
686 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
687 if (!STRCMP(keywords
[i
+2],"msf"))
688 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MSF
;
689 if (!STRCMP(keywords
[i
+2],"hms"))
690 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_HMS
;
691 if (!STRCMP(keywords
[i
+2],"frames"))
692 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_FRAMES
;
693 if (!STRCMP(keywords
[i
+2],"track"))
694 pU
->setParams
.dwTimeFormat
= MCI_VD_FORMAT_TRACK
;
695 if (!STRCMP(keywords
[i
+2],"bytes"))
696 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_BYTES
;
697 if (!STRCMP(keywords
[i
+2],"samples"))
698 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SAMPLES
;
699 if (!STRCMP(keywords
[i
+2],"tmsf"))
700 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_TMSF
;
701 if ( !STRCMP(keywords
[i
+2],"song") &&
702 (i
+3<nrofkeywords
) &&
703 !STRCMP(keywords
[i
+3],"pointer")
705 pU
->setParams
.dwTimeFormat
= MCI_SEQ_FORMAT_SONGPTR
;
706 if (!STRCMP(keywords
[i
+2],"smpte") && (i
+3<nrofkeywords
)) {
707 if (!STRCMP(keywords
[i
+3],"24"))
708 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_24
;
709 if (!STRCMP(keywords
[i
+3],"25"))
710 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_25
;
711 if (!STRCMP(keywords
[i
+3],"30"))
712 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30
;
713 if (!STRCMP(keywords
[i
+3],"drop") && (i
+4<nrofkeywords
) && !STRCMP(keywords
[i
+4],"30")) {
714 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30DROP
;
723 if (!STRCMP(keywords
[i
],"audio") && (i
+1<nrofkeywords
)) {
724 dwFlags
|= MCI_SET_AUDIO
;
725 if (!STRCMP(keywords
[i
+1],"all"))
726 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_ALL
;
727 if (!STRCMP(keywords
[i
+1],"left"))
728 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_LEFT
;
729 if (!STRCMP(keywords
[i
+1],"right"))
730 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_RIGHT
;
734 FLAG1("video",MCI_SET_VIDEO
);
735 FLAG1("on",MCI_SET_ON
);
736 FLAG1("off",MCI_SET_OFF
);
738 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
739 FLAG2("any","input",MCI_WAVE_SET_ANYINPUT
);
740 FLAG2("any","output",MCI_WAVE_SET_ANYOUTPUT
);
742 if ( !STRCMP(keywords
[i
],"formattag") &&
743 (i
+1<nrofkeywords
) &&
744 !STRCMP(keywords
[i
+1],"pcm")
746 dwFlags
|= MCI_WAVE_SET_FORMATTAG
;
747 pU
->wavesetParams
.wFormatTag
= WAVE_FORMAT_PCM
;
752 /* <keyword> <integer> */
753 #define WII(str,flag,fmt,element) \
754 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
755 sscanf(keywords[i+1],fmt,&(pU->wavesetParams. element ));\
760 WII("formattag",MCI_WAVE_SET_FORMATTAG
,"%hu",wFormatTag
);
761 WII("channels",MCI_WAVE_SET_CHANNELS
,"%hu",nChannels
);
762 WII("bytespersec",MCI_WAVE_SET_AVGBYTESPERSEC
,"%lu",nAvgBytesPerSec
);
763 WII("samplespersec",MCI_WAVE_SET_SAMPLESPERSEC
,"%lu",nSamplesPerSec
);
764 WII("alignment",MCI_WAVE_SET_BLOCKALIGN
,"%hu",nBlockAlign
);
765 WII("bitspersample",MCI_WAVE_SET_BITSPERSAMPLE
,"%hu",wBitsPerSample
);
766 WII("input",MCI_WAVE_INPUT
,"%hu",wInput
);
767 WII("output",MCI_WAVE_OUTPUT
,"%hu",wOutput
);
770 case MCI_DEVTYPE_SEQUENCER
:
771 if (!STRCMP(keywords
[i
],"master") && (i
+1<nrofkeywords
)) {
772 dwFlags
|= MCI_SEQ_SET_MASTER
;
773 if (!STRCMP(keywords
[i
+1],"midi"))
774 pU
->seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
775 if (!STRCMP(keywords
[i
+1],"file"))
776 pU
->seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
777 if (!STRCMP(keywords
[i
+1],"smpte"))
778 pU
->seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
779 if (!STRCMP(keywords
[i
+1],"none"))
780 pU
->seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
784 if (!STRCMP(keywords
[i
],"slave") && (i
+1<nrofkeywords
)) {
785 dwFlags
|= MCI_SEQ_SET_SLAVE
;
786 if (!STRCMP(keywords
[i
+1],"midi"))
787 pU
->seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
788 if (!STRCMP(keywords
[i
+1],"file"))
789 pU
->seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
790 if (!STRCMP(keywords
[i
+1],"smpte"))
791 pU
->seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
792 if (!STRCMP(keywords
[i
+1],"none"))
793 pU
->seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
797 if ( !STRCMP(keywords
[i
],"port") &&
798 (i
+1<nrofkeywords
) &&
799 !STRCMP(keywords
[i
+1],"mapper")
801 pU
->seqsetParams
.dwPort
=-1;/* FIXME:not sure*/
802 dwFlags
|= MCI_SEQ_SET_PORT
;
806 #define SII(str,flag,element) \
807 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
808 sscanf(keywords[i+1],"%ld",&(pU->seqsetParams. element ));\
813 SII("tempo",MCI_SEQ_SET_TEMPO
,dwTempo
);
814 SII("port",MCI_SEQ_SET_PORT
,dwPort
);
815 SII("offset",MCI_SEQ_SET_PORT
,dwOffset
);
820 return MCIERR_MISSING_STRING_ARGUMENT
;
821 _MCI_CALL_DRIVER( MCI_SET
, SEGPTR_GET(pU
) );
828 * "off" disable break
829 * "on <keyid>" enable break on key with keyid
830 * (I strongly suspect, that there is another parameter:
832 * but I don't see it mentioned in my documentation.
836 MCISTR_Break(_MCISTR_PROTO_
)
838 MCI_BREAK_PARMS
*breakParams
= SEGPTR_NEW(MCI_BREAK_PARMS
);
841 if (!breakParams
) return 0;
842 /*breakParams.hwndBreak ? */
843 for (i
= 0; i
< nrofkeywords
; i
++)
845 FLAG1("off",MCI_BREAK_OFF
);
846 if (!strcmp(keywords
[i
],"on") && (nrofkeywords
>i
+1)) {
847 dwFlags
&=~MCI_BREAK_OFF
;
848 dwFlags
|=MCI_BREAK_KEY
;
849 sscanf(keywords
[i
+1],"%d",&(breakParams
->nVirtKey
));
854 _MCI_CALL_DRIVER( MCI_BREAK
, SEGPTR_GET(breakParams
) );
855 SEGPTR_FREE(breakParams
);
859 #define ITEM1(str,item,xtype) \
860 if (!STRCMP(keywords[i],str)) {\
861 gdcParams->dwItem = item;\
866 #define ITEM2(str1,str2,item,xtype) \
867 if ( !STRCMP(keywords[i],str1) &&\
868 (i+1<nrofkeywords) &&\
869 !STRCMP(keywords[i+1],str2)\
871 gdcParams->dwItem = item;\
876 #define ITEM3(str1,str2,str3,item,xtype) \
877 if ( !STRCMP(keywords[i],str1) &&\
878 (i+2<nrofkeywords) &&\
879 !STRCMP(keywords[i+1],str2) &&\
880 !STRCMP(keywords[i+2],str3)\
882 gdcParams->dwItem = item;\
887 /* get device capabilities of MCI drivers
890 * "device type" returns device name as string
891 * "has audio" returns bool
892 * "has video" returns bool
893 * "uses files" returns bool
894 * "compound device" returns bool
895 * "can record" returns bool
896 * "can play" returns bool
897 * "can eject" returns bool
898 * "can save" returns bool
900 * "palettes" returns nr of available palette entries
901 * "windows" returns nr of available windows
902 * "can reverse" returns bool
903 * "can stretch" returns bool
904 * "slow play rate" returns the slow playrate
905 * "fast play rate" returns the fast playrate
906 * "normal play rate" returns the normal playrate
908 * "windows" returns nr of available windows
909 * "can stretch" returns bool
910 * "can freeze" returns bool
912 * "cav" assume CAV discs (default if no disk inserted)
913 * "clv" assume CLV discs
914 * "can reverse" returns bool
915 * "slow play rate" returns the slow playrate
916 * "fast play rate" returns the fast playrate
917 * "normal play rate" returns the normal playrate
919 * "inputs" returns nr of inputdevices
920 * "outputs" returns nr of outputdevices
923 MCISTR_Capability(_MCISTR_PROTO_
) {
924 MCI_GETDEVCAPS_PARMS
*gdcParams
= SEGPTR_NEW(MCI_GETDEVCAPS_PARMS
);
927 gdcParams
->dwCallback
= 0;
929 return MCIERR_MISSING_STRING_ARGUMENT
;
930 /* well , thats default */
931 dwFlags
|= MCI_GETDEVCAPS_ITEM
;
932 gdcParams
->dwItem
= 0;
934 while (i
<nrofkeywords
) {
935 ITEM2("device","type",MCI_GETDEVCAPS_DEVICE_TYPE
,_MCISTR_devtype
);
936 ITEM2("has","audio",MCI_GETDEVCAPS_HAS_AUDIO
,_MCISTR_bool
);
937 ITEM2("has","video",MCI_GETDEVCAPS_HAS_VIDEO
,_MCISTR_bool
);
938 ITEM2("uses","files",MCI_GETDEVCAPS_USES_FILES
,_MCISTR_bool
);
939 ITEM2("compound","device",MCI_GETDEVCAPS_COMPOUND_DEVICE
,_MCISTR_bool
);
940 ITEM2("can","record",MCI_GETDEVCAPS_CAN_RECORD
,_MCISTR_bool
);
941 ITEM2("can","play",MCI_GETDEVCAPS_CAN_PLAY
,_MCISTR_bool
);
942 ITEM2("can","eject",MCI_GETDEVCAPS_CAN_EJECT
,_MCISTR_bool
);
943 ITEM2("can","save",MCI_GETDEVCAPS_CAN_SAVE
,_MCISTR_bool
);
945 case MCI_DEVTYPE_ANIMATION
:
946 ITEM1("palettes",MCI_ANIM_GETDEVCAPS_PALETTES
,_MCISTR_int
);
947 ITEM1("windows",MCI_ANIM_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
948 ITEM2("can","reverse",MCI_ANIM_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
949 ITEM2("can","stretch",MCI_ANIM_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
950 ITEM3("slow","play","rate",MCI_ANIM_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
951 ITEM3("fast","play","rate",MCI_ANIM_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
952 ITEM3("normal","play","rate",MCI_ANIM_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
954 case MCI_DEVTYPE_OVERLAY
:
955 ITEM1("windows",MCI_OVLY_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
956 ITEM2("can","freeze",MCI_OVLY_GETDEVCAPS_CAN_FREEZE
,_MCISTR_bool
);
957 ITEM2("can","stretch",MCI_OVLY_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
959 case MCI_DEVTYPE_VIDEODISC
:
960 FLAG1("cav",MCI_VD_GETDEVCAPS_CAV
);
961 FLAG1("clv",MCI_VD_GETDEVCAPS_CLV
);
962 ITEM2("can","reverse",MCI_VD_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
963 ITEM3("slow","play","rate",MCI_VD_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
964 ITEM3("fast","play","rate",MCI_VD_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
965 ITEM3("normal","play","rate",MCI_VD_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
967 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
968 ITEM1("inputs",MCI_WAVE_GETDEVCAPS_INPUTS
,_MCISTR_int
);
969 ITEM1("outputs",MCI_WAVE_GETDEVCAPS_OUTPUTS
,_MCISTR_int
);
974 _MCI_CALL_DRIVER( MCI_GETDEVCAPS
, SEGPTR_GET(gdcParams
) );
975 /* no timeformat needed */
977 _MCISTR_convreturn( type
, gdcParams
->dwReturn
, lpstrReturnString
,
978 uReturnLength
, uDevTyp
, 0 );
979 SEGPTR_FREE(gdcParams
);
985 /* resumes operation of device. no arguments, no return values */
987 MCISTR_Resume(_MCISTR_PROTO_
)
989 MCI_GENERIC_PARMS
*genParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
991 genParams
->dwCallback
= 0;
992 _MCI_CALL_DRIVER( MCI_RESUME
, SEGPTR_GET(genParams
) );
996 /* pauses operation of device. no arguments, no return values */
998 MCISTR_Pause(_MCISTR_PROTO_
)
1000 MCI_GENERIC_PARMS
*genParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1002 genParams
->dwCallback
= 0;
1003 _MCI_CALL_DRIVER( MCI_PAUSE
, SEGPTR_GET(genParams
) );
1007 /* stops operation of device. no arguments, no return values */
1009 MCISTR_Stop(_MCISTR_PROTO_
)
1011 MCI_GENERIC_PARMS
*genParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1013 genParams
->dwCallback
= 0;
1014 _MCI_CALL_DRIVER( MCI_STOP
, SEGPTR_GET(genParams
) );
1018 /* starts recording.
1020 * "overwrite" overwrite existing things
1021 * "insert" insert at current position
1022 * "to <time>" record up to <time> (specified in timeformat)
1023 * "from <time>" record from <time> (specified in timeformat)
1026 MCISTR_Record(_MCISTR_PROTO_
) {
1027 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1029 MCI_RECORD_PARMS
*recordParams
= SEGPTR_NEW(MCI_RECORD_PARMS
);
1031 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1032 if (res
) return res
;
1035 case MCI_FORMAT_MILLISECONDS
:
1036 case MCI_FORMAT_FRAMES
:
1037 case MCI_FORMAT_BYTES
:
1038 case MCI_FORMAT_SAMPLES
:
1042 case MCI_FORMAT_HMS
:
1043 case MCI_FORMAT_MSF
:
1044 parsestr
="%d:%d:%d";
1047 case MCI_FORMAT_TMSF
:
1048 parsestr
="%d:%d:%d:%d";
1051 default:fprintf(stdnimp
,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef
);
1056 recordParams
->dwCallback
= 0;
1058 while (i
<nrofkeywords
) {
1059 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1061 a
[0]=a
[1]=a
[2]=a
[3]=0;
1062 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1063 /* add up all integers we got, if we have more
1064 * shift them. (Well I should use the macros in
1065 * mmsystem.h, right).
1067 recordParams
->dwTo
=0;
1069 recordParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1073 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1074 dwFlags
|= MCI_FROM
;
1075 a
[0]=a
[1]=a
[2]=a
[3]=0;
1076 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1078 recordParams
->dwFrom
=0;
1080 recordParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1084 FLAG1("insert",MCI_RECORD_INSERT
);
1085 FLAG1("overwrite",MCI_RECORD_OVERWRITE
);
1088 _MCI_CALL_DRIVER( MCI_RECORD
, SEGPTR_GET(recordParams
) );
1089 SEGPTR_FREE(recordParams
);
1095 * "to <time>" play up to <time> (specified in set timeformat)
1096 * "from <time>" play from <time> (specified in set timeformat)
1100 * "scan" play as fast as possible (with audio disabled perhaps)
1101 * "reverse" play reverse
1102 * "speed <fps>" play with specified frames per second
1106 * "scan" play as fast as possible (with audio disabled perhaps)
1107 * "reverse" play reverse
1108 * "speed <fps>" play with specified frames per second
1111 MCISTR_Play(_MCISTR_PROTO_
) {
1112 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1115 MCI_PLAY_PARMS playParams
;
1116 MCI_VD_PLAY_PARMS vdplayParams
;
1117 MCI_ANIM_PLAY_PARMS animplayParams
;
1119 union U
*pU
= SEGPTR_NEW(union U
);
1121 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1122 if (res
) return res
;
1124 case MCI_FORMAT_MILLISECONDS
:
1125 case MCI_FORMAT_FRAMES
:
1126 case MCI_FORMAT_BYTES
:
1127 case MCI_FORMAT_SAMPLES
:
1131 case MCI_FORMAT_HMS
:
1132 case MCI_FORMAT_MSF
:
1133 parsestr
="%d:%d:%d";
1136 case MCI_FORMAT_TMSF
:
1137 parsestr
="%d:%d:%d:%d";
1140 default:fprintf(stdnimp
,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef
);
1145 pU
->playParams
.dwCallback
=0;
1147 while (i
<nrofkeywords
) {
1148 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1150 a
[0]=a
[1]=a
[2]=a
[3]=0;
1151 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1152 /* add up all integers we got, if we have more
1153 * shift them. (Well I should use the macros in
1154 * mmsystem.h, right).
1156 pU
->playParams
.dwTo
=0;
1158 pU
->playParams
.dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1162 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1163 dwFlags
|= MCI_FROM
;
1164 a
[0]=a
[1]=a
[2]=a
[3]=0;
1165 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1167 pU
->playParams
.dwFrom
=0;
1169 pU
->playParams
.dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1174 case MCI_DEVTYPE_VIDEODISC
:
1175 FLAG1("slow",MCI_VD_PLAY_SLOW
);
1176 FLAG1("fast",MCI_VD_PLAY_FAST
);
1177 FLAG1("scan",MCI_VD_PLAY_SCAN
);
1178 FLAG1("reverse",MCI_VD_PLAY_REVERSE
);
1179 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1180 dwFlags
|= MCI_VD_PLAY_SPEED
;
1181 sscanf(keywords
[i
+1],"%ld",&(pU
->vdplayParams
.dwSpeed
));
1186 case MCI_DEVTYPE_ANIMATION
:
1187 FLAG1("slow",MCI_ANIM_PLAY_SLOW
);
1188 FLAG1("fast",MCI_ANIM_PLAY_FAST
);
1189 FLAG1("scan",MCI_ANIM_PLAY_SCAN
);
1190 FLAG1("reverse",MCI_ANIM_PLAY_REVERSE
);
1191 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1192 dwFlags
|= MCI_ANIM_PLAY_SPEED
;
1193 sscanf(keywords
[i
+1],"%ld",&(pU
->animplayParams
.dwSpeed
));
1201 _MCI_CALL_DRIVER( MCI_PLAY
, SEGPTR_GET(pU
) );
1206 /* seek to a specified position
1208 * "to start" seek to start of medium
1209 * "to end" seek to end of medium
1210 * "to <time>" seek to <time> specified in current timeformat
1213 MCISTR_Seek(_MCISTR_PROTO_
) {
1214 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1216 MCI_SEEK_PARMS
*seekParams
= SEGPTR_NEW(MCI_SEEK_PARMS
);
1218 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1219 if (res
) return res
;
1221 case MCI_FORMAT_MILLISECONDS
:
1222 case MCI_FORMAT_FRAMES
:
1223 case MCI_FORMAT_BYTES
:
1224 case MCI_FORMAT_SAMPLES
:
1228 case MCI_FORMAT_HMS
:
1229 case MCI_FORMAT_MSF
:
1230 parsestr
="%d:%d:%d";
1233 case MCI_FORMAT_TMSF
:
1234 parsestr
="%d:%d:%d:%d";
1237 default:fprintf(stdnimp
,"mciSendString:SEEK:unknown timeformat %d, please report.\n",timef
);
1242 seekParams
->dwCallback
=0;
1244 while (i
<nrofkeywords
) {
1245 if ( !STRCMP(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1246 if (!STRCMP(keywords
[i
+1],"start")) {
1247 dwFlags
|=MCI_SEEK_TO_START
;
1252 if (!STRCMP(keywords
[i
+1],"end")) {
1253 dwFlags
|=MCI_SEEK_TO_END
;
1260 a
[0]=a
[1]=a
[2]=a
[3]=0;
1261 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1264 seekParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1268 case MCI_DEVTYPE_VIDEODISC
:
1269 FLAG1("reverse",MCI_VD_SEEK_REVERSE
);
1274 _MCI_CALL_DRIVER( MCI_SEEK
, SEGPTR_GET(seekParams
) );
1275 SEGPTR_FREE(seekParams
);
1279 /* close media/driver */
1281 MCISTR_Close(_MCISTR_PROTO_
)
1283 MCI_GENERIC_PARMS
*closeParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1285 _MCI_CALL_DRIVER( MCI_CLOSE
, SEGPTR_GET(closeParams
) );
1286 SEGPTR_FREE(closeParams
);
1290 /* return information.
1292 * "product" return product name (human readable)
1293 * "file" return filename
1295 * "text" returns text?
1297 * "text" returns text?
1300 MCISTR_Info(_MCISTR_PROTO_
)
1302 MCI_INFO_PARMS
*infoParams
= SEGPTR_NEW(MCI_INFO_PARMS
);
1307 i
=0;while (i
<nrofkeywords
) {
1308 FLAG1("product",MCI_INFO_PRODUCT
);
1309 FLAG1("file",MCI_INFO_FILE
);
1311 case MCI_DEVTYPE_ANIMATION
:
1312 FLAG1("text",MCI_ANIM_INFO_TEXT
);
1314 case MCI_DEVTYPE_OVERLAY
:
1315 FLAG1("text",MCI_OVLY_INFO_TEXT
);
1320 if (dwFlags
== sflags
)
1321 return MCIERR_MISSING_STRING_ARGUMENT
;
1322 /* MCI driver will fill in lpstrReturn, dwRetSize.
1323 * FIXME: I don't know if this is correct behaviour
1325 _MCI_CALL_DRIVER( MCI_INFO
, SEGPTR_GET(infoParams
) );
1327 _MCI_STR(infoParams
->lpstrReturn
);
1328 SEGPTR_FREE(infoParams
);
1332 DWORD
mciSysInfo(DWORD dwFlags
,LPMCI_SYSINFO_PARMS lpParms
);
1334 /* query MCI driver itself for information
1336 * "installname" return install name of <device> (system.ini)
1337 * "quantity" return nr of installed drivers
1338 * "open" open drivers only (additional flag)
1339 * "name <nr>" return nr of devices with <devicetyp>
1340 * "name all" return nr of all devices
1342 * FIXME: mciSysInfo() is broken I think.
1345 MCISTR_Sysinfo(_MCISTR_PROTO_
) {
1346 MCI_SYSINFO_PARMS sysinfoParams
;
1349 sysinfoParams
.lpstrReturn
= lpstrReturnString
;
1350 sysinfoParams
.dwRetSize
= uReturnLength
;
1351 sysinfoParams
.wDeviceType
= uDevTyp
;
1353 while (i
<nrofkeywords
) {
1354 FLAG1("installname",MCI_SYSINFO_INSTALLNAME
);
1355 FLAG1("quantity",MCI_SYSINFO_INSTALLNAME
);
1356 FLAG1("open",MCI_SYSINFO_OPEN
);
1357 if (!strcmp(keywords
[i
],"name") && (i
+1<nrofkeywords
)) {
1358 sscanf(keywords
[i
+1],"%ld",&(sysinfoParams
.dwNumber
));
1359 dwFlags
|= MCI_SYSINFO_NAME
;
1365 res
=mciSysInfo(dwFlags
,&sysinfoParams
);
1366 if (dwFlags
& MCI_SYSINFO_QUANTITY
) {
1369 sprintf(buf
,"%ld",*(long*)PTR_SEG_TO_LIN(lpstrReturnString
));
1372 /* no need to copy anything back, mciSysInfo did it for us */
1377 * Argument: "<filename>"
1378 * Overlay: "at <left> <top> <right> <bottom>" additional
1381 MCISTR_Load(_MCISTR_PROTO_
) {
1383 MCI_LOAD_PARMS loadParams
;
1384 MCI_OVLY_LOAD_PARMS ovlyloadParams
;
1386 union U
*pU
= SEGPTR_NEW(union U
);
1391 while (i
<nrofkeywords
) {
1393 case MCI_DEVTYPE_OVERLAY
:
1394 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1395 dwFlags
|= MCI_OVLY_RECT
;
1396 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyloadParams
.rc
.left
));
1397 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyloadParams
.rc
.top
));
1398 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyloadParams
.rc
.right
));
1399 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyloadParams
.rc
.bottom
));
1400 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1405 len
+=strlen(keywords
[i
])+1;
1408 s
=(char*)SEGPTR_ALLOC(len
);
1410 while (i
<nrofkeywords
) {
1411 strcat(s
,keywords
[i
]);
1413 if (i
<nrofkeywords
) strcat(s
," ");
1415 pU
->loadParams
.lpfilename
=(LPSTR
)SEGPTR_GET(s
);
1416 dwFlags
|= MCI_LOAD_FILE
;
1417 _MCI_CALL_DRIVER( MCI_LOAD
, SEGPTR_GET(pU
) );
1424 * Argument: "<filename>"
1425 * Overlay: "at <left> <top> <right> <bottom>" additional
1428 MCISTR_Save(_MCISTR_PROTO_
) {
1430 MCI_SAVE_PARMS saveParams
;
1431 MCI_OVLY_SAVE_PARMS ovlysaveParams
;
1433 union U
*pU
= SEGPTR_NEW(union U
);
1438 while (i
<nrofkeywords
) {
1440 case MCI_DEVTYPE_OVERLAY
:
1441 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1442 dwFlags
|= MCI_OVLY_RECT
;
1443 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlysaveParams
.rc
.left
));
1444 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlysaveParams
.rc
.top
));
1445 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlysaveParams
.rc
.right
));
1446 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlysaveParams
.rc
.bottom
));
1447 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1452 len
+=strlen(keywords
[i
])+1;
1455 s
=(char*)SEGPTR_ALLOC(len
);
1457 while (i
<nrofkeywords
) {
1458 strcat(s
,keywords
[i
]);
1460 if (i
<nrofkeywords
) strcat(s
," ");
1462 pU
->saveParams
.lpfilename
=(LPSTR
)SEGPTR_GET(s
);
1463 dwFlags
|= MCI_LOAD_FILE
;
1464 _MCI_CALL_DRIVER( MCI_SAVE
, SEGPTR_GET(pU
) );
1470 /* prepare device for input/output
1471 * (only applyable to waveform audio)
1474 MCISTR_Cue(_MCISTR_PROTO_
) {
1475 MCI_GENERIC_PARMS
*cueParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1479 while (i
<nrofkeywords
) {
1481 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
1482 FLAG1("input",MCI_WAVE_INPUT
);
1483 FLAG1("output",MCI_WAVE_OUTPUT
);
1488 _MCI_CALL_DRIVER( MCI_CUE
, SEGPTR_GET(cueParams
) );
1489 SEGPTR_FREE(cueParams
);
1493 /* delete information */
1495 MCISTR_Delete(_MCISTR_PROTO_
) {
1496 int timef
,nrargs
,i
,j
,k
,a
[4],res
;
1498 MCI_WAVE_DELETE_PARMS
*deleteParams
= SEGPTR_NEW(MCI_WAVE_DELETE_PARMS
);
1500 /* only implemented for waveform audio */
1501 if (uDevTyp
!= MCI_DEVTYPE_WAVEFORM_AUDIO
)
1502 return MCIERR_UNSUPPORTED_FUNCTION
; /* well it fits */
1503 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1504 if (res
) return res
;
1506 case MCI_FORMAT_MILLISECONDS
:
1507 case MCI_FORMAT_FRAMES
:
1508 case MCI_FORMAT_BYTES
:
1509 case MCI_FORMAT_SAMPLES
:
1513 case MCI_FORMAT_HMS
:
1514 case MCI_FORMAT_MSF
:
1515 parsestr
="%d:%d:%d";
1518 case MCI_FORMAT_TMSF
:
1519 parsestr
="%d:%d:%d:%d";
1522 default:fprintf(stdnimp
,"mciSendString:DELETE:unknown timeformat %d, please report.\n",timef
);
1528 while (i
<nrofkeywords
) {
1529 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1531 a
[0]=a
[1]=a
[2]=a
[3]=0;
1532 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1533 /* add up all integers we got, if we have more
1534 * shift them. (Well I should use the macros in
1535 * mmsystem.h, right).
1537 deleteParams
->dwTo
=0;
1539 deleteParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1543 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1544 dwFlags
|= MCI_FROM
;
1545 a
[0]=a
[1]=a
[2]=a
[3]=0;
1546 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1548 deleteParams
->dwFrom
=0;
1550 deleteParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1556 _MCI_CALL_DRIVER( MCI_DELETE
, SEGPTR_GET(deleteParams
) );
1557 SEGPTR_FREE(deleteParams
);
1561 /* send command to device. only applies to videodisc */
1563 MCISTR_Escape(_MCISTR_PROTO_
)
1565 MCI_VD_ESCAPE_PARMS
*escapeParams
= SEGPTR_NEW(MCI_VD_ESCAPE_PARMS
);
1569 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1570 return MCIERR_UNSUPPORTED_FUNCTION
;
1572 while (i
<nrofkeywords
) {
1573 len
+=strlen(keywords
[i
])+1;
1576 s
=(char*)SEGPTR_ALLOC(len
);
1578 while (i
<nrofkeywords
) {
1579 strcat(s
,keywords
[i
]);
1581 if (i
<nrofkeywords
) strcat(s
," ");
1583 escapeParams
->lpstrCommand
= (LPSTR
)SEGPTR_GET(s
);
1584 dwFlags
|= MCI_VD_ESCAPE_STRING
;
1585 _MCI_CALL_DRIVER( MCI_ESCAPE
, SEGPTR_GET(escapeParams
) );
1587 SEGPTR_FREE(escapeParams
);
1591 /* unfreeze [part of] the overlayed video
1592 * only applyable to Overlay devices
1595 MCISTR_Unfreeze(_MCISTR_PROTO_
)
1597 MCI_OVLY_RECT_PARMS
*unfreezeParams
= SEGPTR_NEW(MCI_OVLY_RECT_PARMS
);
1600 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1601 return MCIERR_UNSUPPORTED_FUNCTION
;
1602 i
=0;while (i
<nrofkeywords
) {
1603 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1604 sscanf(keywords
[i
+1],"%hd",&(unfreezeParams
->rc
.left
));
1605 sscanf(keywords
[i
+2],"%hd",&(unfreezeParams
->rc
.top
));
1606 sscanf(keywords
[i
+3],"%hd",&(unfreezeParams
->rc
.right
));
1607 sscanf(keywords
[i
+4],"%hd",&(unfreezeParams
->rc
.bottom
));
1608 dwFlags
|= MCI_OVLY_RECT
;
1614 _MCI_CALL_DRIVER( MCI_UNFREEZE
, SEGPTR_GET(unfreezeParams
) );
1615 SEGPTR_FREE(unfreezeParams
);
1618 /* freeze [part of] the overlayed video
1619 * only applyable to Overlay devices
1622 MCISTR_Freeze(_MCISTR_PROTO_
)
1624 MCI_OVLY_RECT_PARMS
*freezeParams
= SEGPTR_NEW(MCI_OVLY_RECT_PARMS
);
1627 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1628 return MCIERR_UNSUPPORTED_FUNCTION
;
1629 i
=0;while (i
<nrofkeywords
) {
1630 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1631 sscanf(keywords
[i
+1],"%hd",&(freezeParams
->rc
.left
));
1632 sscanf(keywords
[i
+2],"%hd",&(freezeParams
->rc
.top
));
1633 sscanf(keywords
[i
+3],"%hd",&(freezeParams
->rc
.right
));
1634 sscanf(keywords
[i
+4],"%hd",&(freezeParams
->rc
.bottom
));
1635 dwFlags
|= MCI_OVLY_RECT
;
1641 _MCI_CALL_DRIVER( MCI_FREEZE
, SEGPTR_GET(freezeParams
) );
1642 SEGPTR_FREE(freezeParams
);
1646 /* copy parts of image to somewhere else
1647 * "source [at <left> <top> <right> <bottom>]" source is framebuffer [or rect]
1648 * "destination [at <left> <top> <right> <bottom>]" destination is framebuffer [or rect]
1650 * "frame [at <left> <top> <right> <bottom>]" frame is framebuffer [or rect]
1651 * where the video input is placed
1652 * "video [at <left> <top> <right> <bottom>]" video is whole video [or rect]
1653 * (defining part of input to
1656 * FIXME: This whole junk is passing multiple rectangles.
1657 * I don't know how to do that with the present interface.
1658 * (Means code below is broken)
1661 MCISTR_Put(_MCISTR_PROTO_
) {
1663 MCI_OVLY_RECT_PARMS ovlyputParams
;
1664 MCI_ANIM_RECT_PARMS animputParams
;
1666 union U
*pU
= SEGPTR_NEW(union U
);
1668 i
=0;while (i
<nrofkeywords
) {
1670 case MCI_DEVTYPE_ANIMATION
:
1671 FLAG1("source",MCI_ANIM_PUT_SOURCE
);
1672 FLAG1("destination",MCI_ANIM_PUT_DESTINATION
);
1673 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1674 sscanf(keywords
[i
+1],"%hd",&(pU
->animputParams
.rc
.left
));
1675 sscanf(keywords
[i
+2],"%hd",&(pU
->animputParams
.rc
.top
));
1676 sscanf(keywords
[i
+3],"%hd",&(pU
->animputParams
.rc
.right
));
1677 sscanf(keywords
[i
+4],"%hd",&(pU
->animputParams
.rc
.bottom
));
1678 dwFlags
|= MCI_ANIM_RECT
;
1683 case MCI_DEVTYPE_OVERLAY
:
1684 FLAG1("source",MCI_OVLY_PUT_SOURCE
);
1685 FLAG1("destination",MCI_OVLY_PUT_DESTINATION
);
1686 FLAG1("video",MCI_OVLY_PUT_VIDEO
);
1687 FLAG1("frame",MCI_OVLY_PUT_FRAME
);
1688 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1689 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyputParams
.rc
.left
));
1690 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyputParams
.rc
.top
));
1691 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyputParams
.rc
.right
));
1692 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyputParams
.rc
.bottom
));
1693 dwFlags
|= MCI_OVLY_RECT
;
1701 _MCI_CALL_DRIVER( MCI_PUT
, SEGPTR_GET(pU
) );
1706 /* palette behaviour changing
1708 * "normal" realize the palette normally
1709 * "background" realize the palette as background palette
1712 MCISTR_Realize(_MCISTR_PROTO_
)
1714 MCI_GENERIC_PARMS
*realizeParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1717 if (uDevTyp
!= MCI_DEVTYPE_ANIMATION
)
1718 return MCIERR_UNSUPPORTED_FUNCTION
;
1720 while (i
<nrofkeywords
) {
1721 FLAG1("background",MCI_ANIM_REALIZE_BKGD
);
1722 FLAG1("normal",MCI_ANIM_REALIZE_NORM
);
1725 _MCI_CALL_DRIVER( MCI_REALIZE
, SEGPTR_GET(realizeParams
) );
1726 SEGPTR_FREE(realizeParams
);
1730 /* videodisc spinning
1735 MCISTR_Spin(_MCISTR_PROTO_
)
1737 MCI_GENERIC_PARMS
*spinParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1740 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1741 return MCIERR_UNSUPPORTED_FUNCTION
;
1743 while (i
<nrofkeywords
) {
1744 FLAG1("up",MCI_VD_SPIN_UP
);
1745 FLAG1("down",MCI_VD_SPIN_UP
);
1748 _MCI_CALL_DRIVER( MCI_SPIN
, SEGPTR_GET(spinParams
) );
1749 SEGPTR_FREE(spinParams
);
1753 /* step single frames
1754 * "reverse" optional flag
1755 * "by <nr>" for <nr> frames
1758 MCISTR_Step(_MCISTR_PROTO_
) {
1760 MCI_ANIM_STEP_PARMS animstepParams
;
1761 MCI_VD_STEP_PARMS vdstepParams
;
1763 union U
*pU
= SEGPTR_NEW(union U
);
1767 while (i
<nrofkeywords
) {
1769 case MCI_DEVTYPE_ANIMATION
:
1770 FLAG1("reverse",MCI_ANIM_STEP_REVERSE
);
1771 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1772 sscanf(keywords
[i
+1],"%ld",&(pU
->animstepParams
.dwFrames
));
1773 dwFlags
|= MCI_ANIM_STEP_FRAMES
;
1778 case MCI_DEVTYPE_VIDEODISC
:
1779 FLAG1("reverse",MCI_VD_STEP_REVERSE
);
1780 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1781 sscanf(keywords
[i
+1],"%ld",&(pU
->vdstepParams
.dwFrames
));
1782 dwFlags
|= MCI_VD_STEP_FRAMES
;
1790 _MCI_CALL_DRIVER( MCI_STEP
, SEGPTR_GET(pU
) );
1795 /* update animation window
1797 * "at <left> <top> <right> <bottom>" only in this rectangle
1798 * "hdc" device context
1801 MCISTR_Update(_MCISTR_PROTO_
) {
1803 MCI_ANIM_UPDATE_PARMS
*updateParams
= SEGPTR_NEW(MCI_ANIM_UPDATE_PARMS
);
1806 while (i
<nrofkeywords
) {
1807 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1808 sscanf(keywords
[i
+1],"%hd",&(updateParams
->rc
.left
));
1809 sscanf(keywords
[i
+2],"%hd",&(updateParams
->rc
.top
));
1810 sscanf(keywords
[i
+3],"%hd",&(updateParams
->rc
.right
));
1811 sscanf(keywords
[i
+4],"%hd",&(updateParams
->rc
.bottom
));
1812 dwFlags
|= MCI_ANIM_RECT
;
1816 if (!STRCMP(keywords
[i
],"hdc") && (i
+1<nrofkeywords
)) {
1817 dwFlags
|= MCI_ANIM_UPDATE_HDC
;
1818 sscanf(keywords
[i
+1],"%hd",&(updateParams
->hDC
));
1824 _MCI_CALL_DRIVER( MCI_UPDATE
, SEGPTR_GET(updateParams
) );
1825 SEGPTR_FREE(updateParams
);
1829 /* where command for animation and overlay drivers.
1830 * just returns the specified rectangle as a string
1839 MCISTR_Where(_MCISTR_PROTO_
) {
1841 MCI_ANIM_RECT_PARMS animwhereParams
;
1842 MCI_OVLY_RECT_PARMS ovlywhereParams
;
1844 union U
*pU
= SEGPTR_NEW(union U
);
1848 while (i
<nrofkeywords
) {
1850 case MCI_DEVTYPE_ANIMATION
:
1851 FLAG1("source",MCI_ANIM_WHERE_SOURCE
);
1852 FLAG1("destination",MCI_ANIM_WHERE_DESTINATION
);
1854 case MCI_DEVTYPE_OVERLAY
:
1855 FLAG1("source",MCI_OVLY_WHERE_SOURCE
);
1856 FLAG1("destination",MCI_OVLY_WHERE_DESTINATION
);
1857 FLAG1("video",MCI_OVLY_WHERE_VIDEO
);
1858 FLAG1("frame",MCI_OVLY_WHERE_FRAME
);
1863 _MCI_CALL_DRIVER( MCI_WHERE
, SEGPTR_GET(pU
) );
1867 case MCI_DEVTYPE_ANIMATION
:
1868 sprintf(buf
,"%d %d %d %d",
1869 pU
->animwhereParams
.rc
.left
,
1870 pU
->animwhereParams
.rc
.top
,
1871 pU
->animwhereParams
.rc
.right
,
1872 pU
->animwhereParams
.rc
.bottom
1875 case MCI_DEVTYPE_OVERLAY
:
1876 sprintf(buf
,"%d %d %d %d",
1877 pU
->ovlywhereParams
.rc
.left
,
1878 pU
->ovlywhereParams
.rc
.top
,
1879 pU
->ovlywhereParams
.rc
.right
,
1880 pU
->ovlywhereParams
.rc
.bottom
1883 default:strcpy(buf
,"0 0 0 0");break;
1892 MCISTR_Window(_MCISTR_PROTO_
) {
1896 MCI_ANIM_WINDOW_PARMS animwindowParams
;
1897 MCI_OVLY_WINDOW_PARMS ovlywindowParams
;
1899 union U
*pU
= SEGPTR_NEW(union U
);
1903 while (i
<nrofkeywords
) {
1905 case MCI_DEVTYPE_ANIMATION
:
1906 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1907 dwFlags
|= MCI_ANIM_WINDOW_HWND
;
1908 if (!STRCMP(keywords
[i
+1],"default"))
1909 pU
->animwindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1911 sscanf(keywords
[i
+1],"%hd",&(pU
->animwindowParams
.hWnd
));
1915 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1916 dwFlags
|= MCI_ANIM_WINDOW_STATE
;
1917 if (!STRCMP(keywords
[i
+1],"hide"))
1918 pU
->animwindowParams
.nCmdShow
= SW_HIDE
;
1919 if (!STRCMP(keywords
[i
+1],"iconic"))
1920 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1921 if (!STRCMP(keywords
[i
+1],"minimized"))
1922 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1923 if (!STRCMP(keywords
[i
+1],"maximized"))
1924 pU
->animwindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1925 if (!STRCMP(keywords
[i
+1],"minimize"))
1926 pU
->animwindowParams
.nCmdShow
= SW_MINIMIZE
;
1927 if (!STRCMP(keywords
[i
+1],"normal"))
1928 pU
->animwindowParams
.nCmdShow
= SW_NORMAL
;
1929 if (!STRCMP(keywords
[i
+1],"show"))
1930 pU
->animwindowParams
.nCmdShow
= SW_SHOW
;
1931 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
1932 if (!STRCMP(keywords
[i
+2],"active"))
1933 pU
->animwindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
1934 if (!STRCMP(keywords
[i
+2],"action"))
1935 pU
->animwindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
1941 /* text is enclosed in " ... " as it seems */
1942 if (!STRCMP(keywords
[i
],"text")) {
1946 if (keywords
[i
+1][0]!='"') {
1950 dwFlags
|= MCI_ANIM_WINDOW_TEXT
;
1951 len
= strlen(keywords
[i
+1])+1;
1953 while (j
<nrofkeywords
) {
1954 len
+= strlen(keywords
[j
])+1;
1955 if (strchr(keywords
[j
],'"'))
1959 s
=(char*)xmalloc(len
);
1960 strcpy(s
,keywords
[i
+1]+1);
1964 strcat(s
,keywords
[j
]);
1966 if ((t
=strchr(s
,'"'))) *t
='\0';
1967 /* FIXME: segmented pointer? */
1968 pU
->animwindowParams
.lpstrText
= s
;
1972 FLAG1("stretch",MCI_ANIM_WINDOW_ENABLE_STRETCH
);
1974 case MCI_DEVTYPE_OVERLAY
:
1975 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1976 dwFlags
|= MCI_OVLY_WINDOW_HWND
;
1977 if (!STRCMP(keywords
[i
+1],"default"))
1978 pU
->ovlywindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1980 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlywindowParams
.hWnd
));
1984 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1985 dwFlags
|= MCI_OVLY_WINDOW_STATE
;
1986 if (!STRCMP(keywords
[i
+1],"hide"))
1987 pU
->ovlywindowParams
.nCmdShow
= SW_HIDE
;
1988 if (!STRCMP(keywords
[i
+1],"iconic"))
1989 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1990 if (!STRCMP(keywords
[i
+1],"minimized"))
1991 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1992 if (!STRCMP(keywords
[i
+1],"maximized"))
1993 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1994 if (!STRCMP(keywords
[i
+1],"minimize"))
1995 pU
->ovlywindowParams
.nCmdShow
= SW_MINIMIZE
;
1996 if (!STRCMP(keywords
[i
+1],"normal"))
1997 pU
->ovlywindowParams
.nCmdShow
= SW_NORMAL
;
1998 if (!STRCMP(keywords
[i
+1],"show"))
1999 pU
->ovlywindowParams
.nCmdShow
= SW_SHOW
;
2000 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
2001 if (!STRCMP(keywords
[i
+2],"active"))
2002 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
2003 if (!STRCMP(keywords
[i
+2],"action"))
2004 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
2010 /* text is enclosed in " ... " as it seems */
2011 if (!STRCMP(keywords
[i
],"text")) {
2015 if (keywords
[i
+1][0]!='"') {
2019 dwFlags
|= MCI_OVLY_WINDOW_TEXT
;
2020 len
= strlen(keywords
[i
+1])+1;
2022 while (j
<nrofkeywords
) {
2023 len
+= strlen(keywords
[j
])+1;
2024 if (strchr(keywords
[j
],'"'))
2028 s
=(char*)xmalloc(len
);
2029 strcpy(s
,keywords
[i
+1]+1);
2033 strcat(s
,keywords
[j
]);
2035 if ((t
=strchr(s
,'"'))) *t
='\0';
2036 /* FIXME: segmented pointer? */
2037 pU
->ovlywindowParams
.lpstrText
= s
;
2041 FLAG1("stretch",MCI_OVLY_WINDOW_ENABLE_STRETCH
);
2046 _MCI_CALL_DRIVER( MCI_WINDOW
, SEGPTR_GET(pU
) );
2052 struct _MCISTR_cmdtable
{
2054 DWORD (*fun
)(_MCISTR_PROTO_
);
2055 } MCISTR_cmdtable
[]={
2056 {"break", MCISTR_Break
},
2057 {"capability", MCISTR_Capability
},
2058 {"close", MCISTR_Close
},
2059 {"cue", MCISTR_Cue
},
2060 {"delete", MCISTR_Delete
},
2061 {"escape", MCISTR_Escape
},
2062 {"freeze", MCISTR_Freeze
},
2063 {"info", MCISTR_Info
},
2064 {"load", MCISTR_Load
},
2065 {"open", MCISTR_Open
},
2066 {"pause", MCISTR_Pause
},
2067 {"play", MCISTR_Play
},
2068 {"put", MCISTR_Put
},
2069 {"realize", MCISTR_Realize
},
2070 {"record", MCISTR_Record
},
2071 {"resume", MCISTR_Resume
},
2072 {"save", MCISTR_Save
},
2073 {"seek", MCISTR_Seek
},
2074 {"set", MCISTR_Set
},
2075 {"spin", MCISTR_Spin
},
2076 {"status", MCISTR_Status
},
2077 {"step", MCISTR_Step
},
2078 {"stop", MCISTR_Stop
},
2079 {"sysinfo", MCISTR_Sysinfo
},
2080 {"unfreeze", MCISTR_Unfreeze
},
2081 {"update", MCISTR_Update
},
2082 {"where", MCISTR_Where
},
2083 {"window", MCISTR_Window
},
2086 /**************************************************************************
2087 * mciSendString [MMSYSTEM.702]
2089 /* The usercode sends a string with a command (and flags) expressed in
2090 * words in it... We do our best to call aprobiate drivers,
2091 * and return a errorcode AND a readable string (if lpstrRS!=NULL)
2092 * Info gathered by watching cool134.exe and from Borland's mcistrwh.hlp
2094 /* FIXME: "all" is a valid devicetype and we should access all devices if
2095 * it is used. (imagine "close all"). Not implemented yet.
2097 DWORD
mciSendString (LPCSTR lpstrCommand
, LPSTR lpstrReturnString
,
2098 UINT uReturnLength
, HWND hwndCallback
)
2100 char *cmd
,*dev
,*args
,**keywords
;
2101 WORD uDevTyp
=0,wDevID
=0;
2103 int res
=0,i
,nrofkeywords
;
2105 dprintf_mci(stddeb
,"mciSendString('%s', %p, %d, %X)\n", lpstrCommand
,
2106 lpstrReturnString
, uReturnLength
, hwndCallback
2108 /* format is <command> <device> <optargs> */
2109 cmd
=strdup(lpstrCommand
);
2110 dev
=strchr(cmd
,' ');
2113 return MCIERR_MISSING_DEVICE_NAME
;
2116 args
=strchr(dev
,' ');
2117 if (args
!=NULL
) *args
++='\0';
2121 i
=1;/* nrofkeywords = nrofspaces+1 */
2123 while ((s
=strchr(s
,' '))!=NULL
) i
++,s
++;
2124 keywords
=(char**)xmalloc(sizeof(char*)*(i
+2));
2127 while (s
&& i
<nrofkeywords
) {
2135 keywords
=(char**)xmalloc(sizeof(char*));
2137 dwFlags
= 0; /* default flags */
2138 for (i
=0;i
<nrofkeywords
;) {
2139 if (!STRCMP(keywords
[i
],"wait")) {
2140 dwFlags
|= MCI_WAIT
;
2141 memcpy(keywords
+i
,keywords
+(i
+1),nrofkeywords
-i
-1);
2145 if (!STRCMP(keywords
[i
],"notify")) {
2146 /* how should we callback? I don't know. */
2147 /*dwFlags |= MCI_NOTIFY;*/
2148 memcpy(keywords
+i
,keywords
+(i
+1),nrofkeywords
-i
-1);
2155 /* determine wDevID and uDevTyp for all commands except "open" */
2156 if (STRCMP(cmd
,"open")!=0) {
2161 dname
=(SEGPTR
)mciOpenDrv
[wDevID
].lpstrAlias
;
2163 dname
=(SEGPTR
)mciOpenDrv
[wDevID
].lpstrDeviceType
;
2164 if ((dname
!=NULL
)&&(!STRCMP(PTR_SEG_TO_LIN(dname
),dev
)))
2166 if (++wDevID
>= MAXMCIDRIVERS
) {
2167 dprintf_mci(stddeb
, __FILE__
":mciSendString:MAXMCIDRIVERS reached!\n");
2168 free(keywords
);free(cmd
);
2169 return MCIERR_INTERNAL
;
2172 uDevTyp
=mciDrv
[wDevID
].wType
;
2175 for (i
=0;MCISTR_cmdtable
[i
].cmd
!=NULL
;i
++) {
2176 if (!STRCMP(MCISTR_cmdtable
[i
].cmd
,cmd
)) {
2177 res
=MCISTR_cmdtable
[i
].fun(
2178 wDevID
,uDevTyp
,lpstrReturnString
,
2179 uReturnLength
,dev
,(LPSTR
*)keywords
,nrofkeywords
,
2185 if (MCISTR_cmdtable
[i
].cmd
!=NULL
) {
2186 free(keywords
);free(cmd
);
2189 fprintf(stdnimp
,"mciSendString('%s', %p, %u, %X) // unimplemented, please report.\n", lpstrCommand
,
2190 lpstrReturnString
, uReturnLength
, hwndCallback
2192 free(keywords
);free(cmd
);
2193 return MCIERR_MISSING_COMMAND_STRING
;