4 * Copyright 1995 Marcus Meissner
6 /* FIXME: special commands of device drivers should be handled by those drivers
16 #include <sys/ioctl.h>
27 extern MCI_OPEN_DRIVER_PARMS mciDrv
[MAXMCIDRIVERS
];
29 /* FIXME: I need to remember the aliasname of a spec. driver.
30 * and this is the easiest way. *sigh*
32 extern MCI_OPEN_PARMS mciOpenDrv
[MAXMCIDRIVERS
];
34 LONG
DrvDefDriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
35 DWORD dwParam1
, DWORD dwParam2
);
37 LONG
WAVE_DriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
38 DWORD dwParam1
, DWORD dwParam2
);
39 LONG
MIDI_DriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
40 DWORD dwParam1
, DWORD dwParam2
);
41 LONG
CDAUDIO_DriverProc(DWORD dwDevID
, HDRVR hDriv
, WORD wMsg
,
42 DWORD dwParam1
, DWORD dwParam2
);
43 LONG
ANIM_DriverProc(DWORD dwDevID
, HDRVR 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,UINT uReturnLength,\
54 LPCSTR dev,LPSTR *keywords,UINT nrofkeywords,DWORD dwFlags
56 /* copy string to return pointer including necessary checks
57 * for use in mciSendString()
59 #define _MCI_STR(s) do {\
60 dprintf_mci(stddeb,"->returns \"%s\"",s);\
61 if (lpstrReturnString) {\
62 lstrcpyn32A(lpstrReturnString,s,uReturnLength);\
63 dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
67 /* calling DriverProc. We need to pass the struct as SEGMENTED POINTER. */
68 #define _MCI_CALL_DRIVER(cmd,params) \
70 case MCI_DEVTYPE_CD_AUDIO:\
71 res=CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags, (DWORD)(params));\
73 case MCI_DEVTYPE_WAVEFORM_AUDIO:\
74 res=WAVE_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
76 case MCI_DEVTYPE_SEQUENCER:\
77 res=MIDI_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
79 case MCI_DEVTYPE_ANIMATION:\
80 res=ANIM_DriverProc(mciDrv[wDevID].wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
82 case MCI_DEVTYPE_DIGITAL_VIDEO:\
83 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //No DIGITAL_VIDEO yet !\n");\
84 res=MCIERR_DEVICE_NOT_INSTALLED;\
87 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //Invalid Device Name '%s' !\n",dev);\
88 res=MCIERR_INVALID_DEVICE_NAME;\
91 /* we need to have strings in 16 bit space for some things
94 #define _MCI_STRDUP_TO_SEG(dest,source) {\
96 x=USER_HEAP_ALLOC(strlen(source));\
97 dest=(LPSTR)MAKELONG(x,USER_HeapSel);\
98 strcpy(PTR_SEG_TO_LIN(dest),source);\
101 /* print a DWORD in the specified timeformat */
103 _MCISTR_printtf(char *buf
,UINT uDevType
,DWORD timef
,DWORD val
) {
106 case MCI_FORMAT_MILLISECONDS
:
107 case MCI_FORMAT_FRAMES
:
108 case MCI_FORMAT_BYTES
:
109 case MCI_FORMAT_SAMPLES
:
110 case MCI_VD_FORMAT_TRACK
:
111 /*case MCI_SEQ_FORMAT_SONGPTR: sameas MCI_VD_FORMAT_TRACK */
112 sprintf(buf
,"%ld",val
);
115 /* well, the macros have the same content*/
118 sprintf(buf
,"%d:%d:%d",
124 case MCI_FORMAT_TMSF
:
125 sprintf(buf
,"%d:%d:%d:%d",
127 MCI_TMSF_MINUTE(val
),
128 MCI_TMSF_SECOND(val
),
133 fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing timeformat for %ld, report.\n",timef
);
134 strcpy(buf
,"0"); /* hmm */
139 /* possible different return types */
140 #define _MCISTR_int 1
141 #define _MCISTR_time 2
142 #define _MCISTR_bool 3
143 #define _MCISTR_tfname 4
144 #define _MCISTR_mode 5
145 #define _MCISTR_divtype 6
146 #define _MCISTR_seqtype 7
147 #define _MCISTR_vdmtype 8
148 #define _MCISTR_devtype 9
151 _MCISTR_convreturn(int type
,DWORD dwReturn
,LPSTR lpstrReturnString
,
152 WORD uReturnLength
,WORD uDevTyp
,int timef
155 case _MCISTR_vdmtype
:
157 case MCI_VD_MEDIA_CLV
:_MCI_STR("CLV");break;
158 case MCI_VD_MEDIA_CAV
:_MCI_STR("CAV");break;
160 case MCI_VD_MEDIA_OTHER
:_MCI_STR("other");break;
163 case _MCISTR_seqtype
:
165 case MCI_SEQ_NONE
:_MCI_STR("none");break;
166 case MCI_SEQ_SMPTE
:_MCI_STR("smpte");break;
167 case MCI_SEQ_FILE
:_MCI_STR("file");break;
168 case MCI_SEQ_MIDI
:_MCI_STR("midi");break;
169 default:fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing sequencer mode %ld\n",dwReturn
);
174 case MCI_MODE_NOT_READY
:_MCI_STR("not ready");break;
175 case MCI_MODE_STOP
:_MCI_STR("stopped");break;
176 case MCI_MODE_PLAY
:_MCI_STR("playing");break;
177 case MCI_MODE_RECORD
:_MCI_STR("recording");break;
178 case MCI_MODE_SEEK
:_MCI_STR("seeking");break;
179 case MCI_MODE_PAUSE
:_MCI_STR("paused");break;
180 case MCI_MODE_OPEN
:_MCI_STR("open");break;
192 sprintf(buf
,"%ld",dwReturn
);
198 _MCISTR_printtf(buf
,uDevTyp
,timef
,dwReturn
);
204 case MCI_FORMAT_MILLISECONDS
:_MCI_STR("milliseconds");break;
205 case MCI_FORMAT_FRAMES
:_MCI_STR("frames");break;
206 case MCI_FORMAT_BYTES
:_MCI_STR("bytes");break;
207 case MCI_FORMAT_SAMPLES
:_MCI_STR("samples");break;
208 case MCI_FORMAT_HMS
:_MCI_STR("hms");break;
209 case MCI_FORMAT_MSF
:_MCI_STR("msf");break;
210 case MCI_FORMAT_TMSF
:_MCI_STR("tmsf");break;
212 fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing timeformat for %d, report.\n",timef
);
216 case _MCISTR_divtype
:
218 case MCI_SEQ_DIV_PPQN
:_MCI_STR("PPQN");break;
219 case MCI_SEQ_DIV_SMPTE_24
:_MCI_STR("SMPTE 24 frame");break;
220 case MCI_SEQ_DIV_SMPTE_25
:_MCI_STR("SMPTE 25 frame");break;
221 case MCI_SEQ_DIV_SMPTE_30
:_MCI_STR("SMPTE 30 frame");break;
222 case MCI_SEQ_DIV_SMPTE_30DROP
:_MCI_STR("SMPTE 30 frame drop");break;
224 case _MCISTR_devtype
:
226 case MCI_DEVTYPE_VCR
:_MCI_STR("vcr");break;
227 case MCI_DEVTYPE_VIDEODISC
:_MCI_STR("videodisc");break;
228 case MCI_DEVTYPE_CD_AUDIO
:_MCI_STR("cd audio");break;
229 case MCI_DEVTYPE_OVERLAY
:_MCI_STR("overlay");break;
230 case MCI_DEVTYPE_DAT
:_MCI_STR("dat");break;
231 case MCI_DEVTYPE_SCANNER
:_MCI_STR("scanner");break;
232 case MCI_DEVTYPE_ANIMATION
:_MCI_STR("animation");break;
233 case MCI_DEVTYPE_DIGITAL_VIDEO
:_MCI_STR("digital video");break;
234 case MCI_DEVTYPE_OTHER
:_MCI_STR("other");break;
235 case MCI_DEVTYPE_WAVEFORM_AUDIO
:_MCI_STR("waveform audio");break;
236 case MCI_DEVTYPE_SEQUENCER
:_MCI_STR("sequencer");break;
237 default:fprintf(stdnimp
,__FILE__
":_MCISTR_convreturn:unknown device type %ld, report.\n",dwReturn
);break;
241 fprintf(stdnimp
,__FILE__
":_MCISTR_convreturn:unknown resulttype %d, report.\n",type
);
246 #define FLAG1(str,flag) \
247 if (!STRCMP(keywords[i],str)) {\
252 #define FLAG2(str1,str2,flag) \
253 if (!STRCMP(keywords[i],str1) && (i+1<nrofkeywords) && !STRCMP(keywords[i+1],str2)) {\
259 /* All known subcommands are implemented in single functions to avoid
260 * bloat and a xxxx lines long mciSendString(). All commands are of the
261 * format MCISTR_Cmd(_MCISTR_PROTO_) where _MCISTR_PROTO_ is the above
262 * defined line of arguments. (This is just for easy enhanceability.)
263 * All functions return the MCIERR_ errorvalue as DWORD. Returnvalues
264 * for the calls are in lpstrReturnString (If I mention return values
265 * in function headers, I mean returnvalues in lpstrReturnString.)
266 * Integers are sprintf("%d")ed integers. Boolean values are
267 * "true" and "false".
268 * timeformat depending values are "%d" "%d:%d" "%d:%d:%d" "%d:%d:%d:%d"
269 * FIXME: is above line correct?
271 * Preceding every function is a list of implemented/known arguments.
272 * Feel free to add missing arguments.
277 * Opens the specified MCI driver.
281 * "alias <aliasname>"
282 * "element <elementname>"
285 * "buffer <nrBytesPerSec>"
287 * "nostatic" increaste nr of nonstatic colours
288 * "parent <windowhandle>"
289 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
290 * "style child" WS_CHILD
291 * "style overlap" WS_OVERLAPPED
292 * "style popup" WS_POPUP
294 * "parent <windowhandle>"
295 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
296 * "style child" WS_CHILD
297 * "style overlap" WS_OVERLAPPED
298 * "style popup" WS_POPUP
302 MCISTR_Open(_MCISTR_PROTO_
) {
306 MCI_OPEN_PARMS openParams
;
307 MCI_WAVE_OPEN_PARMS waveopenParams
;
308 MCI_ANIM_OPEN_PARMS animopenParams
;
309 MCI_OVLY_OPEN_PARMS ovlyopenParams
;
312 U
.openParams
.lpstrElementName
= NULL
;
316 _MCI_STRDUP_TO_SEG(U
.openParams
.lpstrElementName
,s
);
318 if (!STRCMP(dev
,"cdaudio")) {
319 uDevTyp
=MCI_DEVTYPE_CD_AUDIO
;
320 } else if (!STRCMP(dev
,"waveaudio")) {
321 uDevTyp
=MCI_DEVTYPE_WAVEFORM_AUDIO
;
322 } else if (!STRCMP(dev
,"sequencer")) {
323 uDevTyp
=MCI_DEVTYPE_SEQUENCER
;
324 } else if (!STRCMP(dev
,"animation1")) {
325 uDevTyp
=MCI_DEVTYPE_ANIMATION
;
326 } else if (!STRCMP(dev
,"avivideo")) {
327 uDevTyp
=MCI_DEVTYPE_DIGITAL_VIDEO
;
329 return MCIERR_INVALID_DEVICE_NAME
;
332 while(mciDrv
[wDevID
].wType
) {
333 if (++wDevID
>=MAXMCIDRIVERS
) {
334 dprintf_mci(stddeb
, __FILE__
":MCISTR_Open:MAXMCIDRIVERS reached!\n");
335 return MCIERR_INTERNAL
;
338 mciDrv
[wDevID
].wType
= uDevTyp
;
339 mciDrv
[wDevID
].wDeviceID
= wDevID
;
340 U
.openParams
.dwCallback
= 0;
341 U
.openParams
.wDeviceID
= wDevID
;
342 U
.ovlyopenParams
.dwStyle
= 0;
343 U
.animopenParams
.dwStyle
= 0;
345 _MCI_STRDUP_TO_SEG(U
.openParams
.lpstrDeviceType
,dev
);
346 U
.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 _MCI_STRDUP_TO_SEG(U
.openParams
.lpstrAlias
,keywords
[i
]);
357 if (!strcmp(keywords
[i
],"element") && (i
+1<nrofkeywords
)) {
358 dwFlags
|= MCI_OPEN_ELEMENT
;
359 _MCI_STRDUP_TO_SEG(U
.openParams
.lpstrElementName
,keywords
[i
]);
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",&(U
.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 U
.animopenParams
.dwStyle
|= WS_POPUP
;
379 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
380 U
.animopenParams
.dwStyle
|= WS_OVERLAPPED
;
381 } else if (!STRCMP(keywords
[i
+1],"child")) {
382 U
.animopenParams
.dwStyle
|= WS_CHILD
;
383 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
384 U
.animopenParams
.dwStyle
|= st
;
386 fprintf(stdnimp
,__FILE__
":MCISTR_Open: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",&(U
.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",&(U
.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 U
.ovlyopenParams
.dwStyle
|= WS_POPUP
;
411 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
412 U
.ovlyopenParams
.dwStyle
|= WS_OVERLAPPED
;
413 } else if (!STRCMP(keywords
[i
+1],"child")) {
414 U
.ovlyopenParams
.dwStyle
|= WS_CHILD
;
415 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
416 U
.ovlyopenParams
.dwStyle
|= st
;
418 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
424 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown parameter passed %s, please report.\n",keywords
[i
]);
427 _MCI_CALL_DRIVER( MCI_OPEN
, MAKE_SEGPTR(&U
) );
429 memcpy(&mciOpenDrv
[wDevID
],&U
.openParams
,sizeof(MCI_OPEN_PARMS
));
433 /* A help function for a lot of others ...
434 * for instance status/play/record/seek etc.
437 _MCISTR_determine_timeformat(LPCSTR dev
,WORD wDevID
,WORD uDevTyp
,int *timef
) {
438 MCI_STATUS_PARMS statusParams
;
442 dwFlags
= MCI_STATUS_ITEM
;
443 statusParams
.dwItem
= MCI_STATUS_TIME_FORMAT
;
444 statusParams
.dwReturn
= 0;
445 _MCI_CALL_DRIVER( MCI_STATUS
, MAKE_SEGPTR(&statusParams
) );
446 if (res
==0) *timef
=statusParams
.dwReturn
;
450 /* query status of MCI drivers
453 * "mode" - returns "not ready" "paused" "playing" "stopped" "open"
454 * "parked" "recording" "seeking" ....
456 * "current track" - returns current track as integer
457 * "length [track <nr>]" - returns length [of track <nr>] in current
459 * "number of tracks" - returns number of tracks as integer
460 * "position [track <nr>]" - returns position [in track <nr>] in current
462 * "ready" - checks if device is ready to play, -> bool
463 * "start position" - returns start position in timeformat
464 * "time format" - returns timeformat (list of possible values:
465 * "ms" "msf" "milliseconds" "hmsf" "tmsf" "frames"
466 * "bytes" "samples" "hms")
467 * "media present" - returns if media is present as bool
469 * "forward" - returns "true" if device is playing forwards
470 * "speed" - returns speed for device
471 * "palette handle" - returns palette handle
472 * "window handle" - returns window handle
473 * "stretch" - returns stretch bool
475 * "division type" - ? returns "PPQN" "SMPTE 24 frame"
476 * "SMPTE 25 frame" "SMPTE 30 frame" "SMPTE 30 drop frame"
477 * "tempo" - current tempo in (PPQN? speed in frames, SMPTE*? speed in hsmf)
478 * "offset" - offset in dito.
479 * "port" - midi port as integer
480 * "slave" - slave device ("midi","file","none","smpte")
481 * "master" - masterdevice (dito.)
483 * "window handle" - see animation
486 * "speed" - speed as integer
487 * "forward" - returns bool (when playing forward)
488 * "side" - returns 1 or 2
489 * "media type" - returns "CAV" "CLV" "other"
490 * "disc size" - returns "8" or "12"
492 * "input" - base queries on input set
493 * "output" - base queries on output set
494 * "format tag" - return integer format tag
495 * "channels" - return integer nr of channels
496 * "bytespersec" - return average nr of bytes/sec
497 * "samplespersec" - return nr of samples per sec
498 * "bitspersample" - return bitspersample
499 * "alignment" - return block alignment
500 * "level" - return level?
503 #define ITEM1(str,item,xtype) \
504 if (!STRCMP(keywords[i],str)) {\
505 statusParams.dwItem = item;\
510 #define ITEM2(str1,str2,item,xtype) \
511 if ( !STRCMP(keywords[i],str1) &&\
512 (i+1<nrofkeywords) &&\
513 !STRCMP(keywords[i+1],str2)\
515 statusParams.dwItem = item;\
520 #define ITEM3(str1,str2,str3,item,xtype) \
521 if ( !STRCMP(keywords[i],str1) &&\
522 (i+2<nrofkeywords) &&\
523 !STRCMP(keywords[i+1],str2) &&\
524 !STRCMP(keywords[i+2],str3)\
526 statusParams.dwItem = item;\
532 MCISTR_Status(_MCISTR_PROTO_
) {
533 MCI_STATUS_PARMS statusParams
;
534 int type
= 0,i
,res
,timef
;
536 statusParams
.dwCallback
= 0;
537 dwFlags
|= MCI_STATUS_ITEM
;
538 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
541 statusParams
.dwReturn
= 0;
542 statusParams
.dwItem
= 0;
545 while (i
<nrofkeywords
) {
546 if (!STRCMP(keywords
[i
],"track") && (i
+1<nrofkeywords
)) {
547 sscanf(keywords
[i
+1],"%ld",&(statusParams
.dwTrack
));
548 dwFlags
|= MCI_TRACK
;
552 FLAG1("start",MCI_STATUS_START
);
554 ITEM2("current","track",MCI_STATUS_CURRENT_TRACK
,_MCISTR_time
);
555 ITEM2("time","format",MCI_STATUS_TIME_FORMAT
,_MCISTR_tfname
);
556 ITEM1("ready",MCI_STATUS_READY
,_MCISTR_bool
);
557 ITEM1("mode",MCI_STATUS_MODE
,_MCISTR_mode
);
558 ITEM3("number","of","tracks",MCI_STATUS_NUMBER_OF_TRACKS
,_MCISTR_int
);
559 ITEM1("length",MCI_STATUS_LENGTH
,_MCISTR_time
);
560 ITEM1("position",MCI_STATUS_POSITION
,_MCISTR_time
);
561 ITEM2("media","present",MCI_STATUS_MEDIA_PRESENT
,_MCISTR_bool
);
564 case MCI_DEVTYPE_ANIMATION
:
565 case MCI_DEVTYPE_DIGITAL_VIDEO
:
566 ITEM2("palette","handle",MCI_ANIM_STATUS_HPAL
,_MCISTR_int
);
567 ITEM2("window","handle",MCI_ANIM_STATUS_HWND
,_MCISTR_int
);
568 ITEM1("stretch",MCI_ANIM_STATUS_STRETCH
,_MCISTR_bool
);
569 ITEM1("speed",MCI_ANIM_STATUS_SPEED
,_MCISTR_int
);
570 ITEM1("forward",MCI_ANIM_STATUS_FORWARD
,_MCISTR_bool
);
572 case MCI_DEVTYPE_SEQUENCER
:
573 /* just completing the list, not working correctly */
574 ITEM2("division","type",MCI_SEQ_STATUS_DIVTYPE
,_MCISTR_divtype
);
575 /* tempo ... PPQN in frames/second, SMPTE in hmsf */
576 ITEM1("tempo",MCI_SEQ_STATUS_TEMPO
,_MCISTR_int
);
577 ITEM1("port",MCI_SEQ_STATUS_PORT
,_MCISTR_int
);
578 ITEM1("slave",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
579 ITEM1("master",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
580 /* offset ... PPQN in frames/second, SMPTE in hmsf */
581 ITEM1("offset",MCI_SEQ_STATUS_SLAVE
,_MCISTR_time
);
583 case MCI_DEVTYPE_OVERLAY
:
584 ITEM2("window","handle",MCI_OVLY_STATUS_HWND
,_MCISTR_int
);
585 ITEM1("stretch",MCI_OVLY_STATUS_STRETCH
,_MCISTR_bool
);
587 case MCI_DEVTYPE_VIDEODISC
:
588 ITEM1("speed",MCI_VD_STATUS_SPEED
,_MCISTR_int
);
589 ITEM1("forward",MCI_VD_STATUS_FORWARD
,_MCISTR_bool
);
590 ITEM1("side",MCI_VD_STATUS_SIDE
,_MCISTR_int
);
591 ITEM2("media","type",MCI_VD_STATUS_SIDE
,_MCISTR_vdmtype
);
592 /* returns 8 or 12 */
593 ITEM2("disc","size",MCI_VD_STATUS_DISC_SIZE
,_MCISTR_int
);
595 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
596 /* I am not quite sure if foll. 2 lines are right. */
597 FLAG1("input",MCI_WAVE_INPUT
);
598 FLAG1("output",MCI_WAVE_OUTPUT
);
600 ITEM2("format","tag",MCI_WAVE_STATUS_FORMATTAG
,_MCISTR_int
);
601 ITEM1("channels",MCI_WAVE_STATUS_CHANNELS
,_MCISTR_int
);
602 ITEM1("bytespersec",MCI_WAVE_STATUS_AVGBYTESPERSEC
,_MCISTR_int
);
603 ITEM1("samplespersec",MCI_WAVE_STATUS_SAMPLESPERSEC
,_MCISTR_int
);
604 ITEM1("bitspersample",MCI_WAVE_STATUS_BITSPERSAMPLE
,_MCISTR_int
);
605 ITEM1("alignment",MCI_WAVE_STATUS_BLOCKALIGN
,_MCISTR_int
);
606 ITEM1("level",MCI_WAVE_STATUS_LEVEL
,_MCISTR_int
);
609 fprintf(stdnimp
,__FILE__
":MCISTR_Status:unknown keyword '%s'\n",keywords
[i
]);
612 if (!statusParams
.dwItem
)
613 return MCIERR_MISSING_STRING_ARGUMENT
;
615 _MCI_CALL_DRIVER( MCI_STATUS
, MAKE_SEGPTR(&statusParams
) );
617 _MCISTR_convreturn(type
,statusParams
.dwReturn
,lpstrReturnString
,uReturnLength
,uDevTyp
,timef
);
624 /* set specified parameters in respective MCI drivers
626 * "door open" eject media or somesuch
627 * "door close" load media
628 * "time format <timeformatname>" "ms" "milliseconds" "msf" "hmsf"
629 * "tmsf" "SMPTE 24" "SMPTE 25" "SMPTE 30"
631 * "audio [all|left|right] [on|off]" sets specified audiochannel on or off
632 * "video [on|off]" sets video on/off
634 * "formattag pcm" sets format to pcm
635 * "formattag <nr>" sets integer formattag value
636 * "any input" accept input from any known source
637 * "any output" output to any known destination
638 * "input <nr>" input from source <nr>
639 * "output <nr>" output to destination <nr>
640 * "channels <nr>" sets nr of channels
641 * "bytespersec <nr>" sets average bytes per second
642 * "samplespersec <nr>" sets average samples per second (1 sample can
644 * "alignment <nr>" sets the blockalignment to <nr>
645 * "bitspersample <nr>" sets the nr of bits per sample
647 * "master [midi|file|smpte|none]" sets the midi master device
648 * "slave [midi|file|smpte|none]" sets the midi master device
649 * "port mapper" midioutput to portmapper
650 * "port <nr>" midioutput to specified port
651 * "tempo <nr>" tempo of track (depends on timeformat/divtype)
652 * "offset <nr>" start offset?
655 MCISTR_Set(_MCISTR_PROTO_
) {
657 MCI_SET_PARMS setParams
;
658 MCI_WAVE_SET_PARMS wavesetParams
;
659 MCI_SEQ_SET_PARMS seqsetParams
;
663 U
.setParams
.dwCallback
= 0;
665 while (i
<nrofkeywords
) {
666 FLAG2("door","open",MCI_SET_DOOR_OPEN
);
667 FLAG2("door","closed",MCI_SET_DOOR_CLOSED
);
669 if ( !STRCMP(keywords
[i
],"time") &&
670 (i
+2<nrofkeywords
) &&
671 !STRCMP(keywords
[i
+1],"format")
673 dwFlags
|= MCI_SET_TIME_FORMAT
;
675 /* FIXME:is this a shortcut for milliseconds or
676 * minutes:seconds? */
677 if (!STRCMP(keywords
[i
+2],"ms"))
678 U
.setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
680 if (!STRCMP(keywords
[i
+2],"milliseconds"))
681 U
.setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
682 if (!STRCMP(keywords
[i
+2],"msf"))
683 U
.setParams
.dwTimeFormat
= MCI_FORMAT_MSF
;
684 if (!STRCMP(keywords
[i
+2],"hms"))
685 U
.setParams
.dwTimeFormat
= MCI_FORMAT_HMS
;
686 if (!STRCMP(keywords
[i
+2],"frames"))
687 U
.setParams
.dwTimeFormat
= MCI_FORMAT_FRAMES
;
688 if (!STRCMP(keywords
[i
+2],"track"))
689 U
.setParams
.dwTimeFormat
= MCI_VD_FORMAT_TRACK
;
690 if (!STRCMP(keywords
[i
+2],"bytes"))
691 U
.setParams
.dwTimeFormat
= MCI_FORMAT_BYTES
;
692 if (!STRCMP(keywords
[i
+2],"samples"))
693 U
.setParams
.dwTimeFormat
= MCI_FORMAT_SAMPLES
;
694 if (!STRCMP(keywords
[i
+2],"tmsf"))
695 U
.setParams
.dwTimeFormat
= MCI_FORMAT_TMSF
;
696 if ( !STRCMP(keywords
[i
+2],"song") &&
697 (i
+3<nrofkeywords
) &&
698 !STRCMP(keywords
[i
+3],"pointer")
700 U
.setParams
.dwTimeFormat
= MCI_SEQ_FORMAT_SONGPTR
;
701 if (!STRCMP(keywords
[i
+2],"smpte") && (i
+3<nrofkeywords
)) {
702 if (!STRCMP(keywords
[i
+3],"24"))
703 U
.setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_24
;
704 if (!STRCMP(keywords
[i
+3],"25"))
705 U
.setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_25
;
706 if (!STRCMP(keywords
[i
+3],"30"))
707 U
.setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30
;
708 if (!STRCMP(keywords
[i
+3],"drop") && (i
+4<nrofkeywords
) && !STRCMP(keywords
[i
+4],"30")) {
709 U
.setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30DROP
;
718 if (!STRCMP(keywords
[i
],"audio") && (i
+1<nrofkeywords
)) {
719 dwFlags
|= MCI_SET_AUDIO
;
720 if (!STRCMP(keywords
[i
+1],"all"))
721 U
.setParams
.dwAudio
= MCI_SET_AUDIO_ALL
;
722 if (!STRCMP(keywords
[i
+1],"left"))
723 U
.setParams
.dwAudio
= MCI_SET_AUDIO_LEFT
;
724 if (!STRCMP(keywords
[i
+1],"right"))
725 U
.setParams
.dwAudio
= MCI_SET_AUDIO_RIGHT
;
729 FLAG1("video",MCI_SET_VIDEO
);
730 FLAG1("on",MCI_SET_ON
);
731 FLAG1("off",MCI_SET_OFF
);
733 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
734 FLAG2("any","input",MCI_WAVE_SET_ANYINPUT
);
735 FLAG2("any","output",MCI_WAVE_SET_ANYOUTPUT
);
737 if ( !STRCMP(keywords
[i
],"formattag") &&
738 (i
+1<nrofkeywords
) &&
739 !STRCMP(keywords
[i
+1],"pcm")
741 dwFlags
|= MCI_WAVE_SET_FORMATTAG
;
742 U
.wavesetParams
.wFormatTag
= WAVE_FORMAT_PCM
;
747 /* <keyword> <integer> */
748 #define WII(str,flag,fmt,element) \
749 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
750 sscanf(keywords[i+1],fmt,&(U.wavesetParams. element ));\
755 WII("formattag",MCI_WAVE_SET_FORMATTAG
,"%hu",wFormatTag
);
756 WII("channels",MCI_WAVE_SET_CHANNELS
,"%hu",nChannels
);
757 WII("bytespersec",MCI_WAVE_SET_AVGBYTESPERSEC
,"%lu",nAvgBytesPerSec
);
758 WII("samplespersec",MCI_WAVE_SET_SAMPLESPERSEC
,"%lu",nSamplesPerSec
);
759 WII("alignment",MCI_WAVE_SET_BLOCKALIGN
,"%hu",nBlockAlign
);
760 WII("bitspersample",MCI_WAVE_SET_BITSPERSAMPLE
,"%hu",wBitsPerSample
);
761 WII("input",MCI_WAVE_INPUT
,"%hu",wInput
);
762 WII("output",MCI_WAVE_OUTPUT
,"%hu",wOutput
);
765 case MCI_DEVTYPE_SEQUENCER
:
766 if (!STRCMP(keywords
[i
],"master") && (i
+1<nrofkeywords
)) {
767 dwFlags
|= MCI_SEQ_SET_MASTER
;
768 if (!STRCMP(keywords
[i
+1],"midi"))
769 U
.seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
770 if (!STRCMP(keywords
[i
+1],"file"))
771 U
.seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
772 if (!STRCMP(keywords
[i
+1],"smpte"))
773 U
.seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
774 if (!STRCMP(keywords
[i
+1],"none"))
775 U
.seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
779 if (!STRCMP(keywords
[i
],"slave") && (i
+1<nrofkeywords
)) {
780 dwFlags
|= MCI_SEQ_SET_SLAVE
;
781 if (!STRCMP(keywords
[i
+1],"midi"))
782 U
.seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
783 if (!STRCMP(keywords
[i
+1],"file"))
784 U
.seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
785 if (!STRCMP(keywords
[i
+1],"smpte"))
786 U
.seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
787 if (!STRCMP(keywords
[i
+1],"none"))
788 U
.seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
792 if ( !STRCMP(keywords
[i
],"port") &&
793 (i
+1<nrofkeywords
) &&
794 !STRCMP(keywords
[i
+1],"mapper")
796 U
.seqsetParams
.dwPort
=-1;/* FIXME:not sure*/
797 dwFlags
|= MCI_SEQ_SET_PORT
;
801 #define SII(str,flag,element) \
802 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
803 sscanf(keywords[i+1],"%ld",&(U.seqsetParams. element ));\
808 SII("tempo",MCI_SEQ_SET_TEMPO
,dwTempo
);
809 SII("port",MCI_SEQ_SET_PORT
,dwPort
);
810 SII("offset",MCI_SEQ_SET_PORT
,dwOffset
);
815 return MCIERR_MISSING_STRING_ARGUMENT
;
816 _MCI_CALL_DRIVER( MCI_SET
, MAKE_SEGPTR(&U
) );
822 * "off" disable break
823 * "on <keyid>" enable break on key with keyid
824 * (I strongly suspect, that there is another parameter:
826 * but I don't see it mentioned in my documentation.
830 MCISTR_Break(_MCISTR_PROTO_
) {
831 MCI_BREAK_PARMS breakParams
;
834 /*breakParams.hwndBreak ? */
835 i
=0;while (i
<nrofkeywords
) {
836 FLAG1("off",MCI_BREAK_OFF
);
837 if (!strcmp(keywords
[i
],"on") && (nrofkeywords
>i
+1)) {
838 dwFlags
&=~MCI_BREAK_OFF
;
839 dwFlags
|=MCI_BREAK_KEY
;
840 sscanf(keywords
[i
+1],"%d",&(breakParams
.nVirtKey
));
846 _MCI_CALL_DRIVER( MCI_BREAK
, MAKE_SEGPTR(&breakParams
) );
850 #define ITEM1(str,item,xtype) \
851 if (!STRCMP(keywords[i],str)) {\
852 gdcParams.dwItem = item;\
857 #define ITEM2(str1,str2,item,xtype) \
858 if ( !STRCMP(keywords[i],str1) &&\
859 (i+1<nrofkeywords) &&\
860 !STRCMP(keywords[i+1],str2)\
862 gdcParams.dwItem = item;\
867 #define ITEM3(str1,str2,str3,item,xtype) \
868 if ( !STRCMP(keywords[i],str1) &&\
869 (i+2<nrofkeywords) &&\
870 !STRCMP(keywords[i+1],str2) &&\
871 !STRCMP(keywords[i+2],str3)\
873 gdcParams.dwItem = item;\
878 /* get device capabilities of MCI drivers
881 * "device type" returns device name as string
882 * "has audio" returns bool
883 * "has video" returns bool
884 * "uses files" returns bool
885 * "compound device" returns bool
886 * "can record" returns bool
887 * "can play" returns bool
888 * "can eject" returns bool
889 * "can save" returns bool
891 * "palettes" returns nr of available palette entries
892 * "windows" returns nr of available windows
893 * "can reverse" returns bool
894 * "can stretch" returns bool
895 * "slow play rate" returns the slow playrate
896 * "fast play rate" returns the fast playrate
897 * "normal play rate" returns the normal playrate
899 * "windows" returns nr of available windows
900 * "can stretch" returns bool
901 * "can freeze" returns bool
903 * "cav" assume CAV discs (default if no disk inserted)
904 * "clv" assume CLV discs
905 * "can reverse" returns bool
906 * "slow play rate" returns the slow playrate
907 * "fast play rate" returns the fast playrate
908 * "normal play rate" returns the normal playrate
910 * "inputs" returns nr of inputdevices
911 * "outputs" returns nr of outputdevices
914 MCISTR_Capability(_MCISTR_PROTO_
) {
915 MCI_GETDEVCAPS_PARMS gdcParams
;
918 gdcParams
.dwCallback
= 0;
920 return MCIERR_MISSING_STRING_ARGUMENT
;
921 /* well , thats default */
922 dwFlags
|= MCI_GETDEVCAPS_ITEM
;
923 gdcParams
.dwItem
= 0;
925 while (i
<nrofkeywords
) {
926 ITEM2("device","type",MCI_GETDEVCAPS_DEVICE_TYPE
,_MCISTR_devtype
);
927 ITEM2("has","audio",MCI_GETDEVCAPS_HAS_AUDIO
,_MCISTR_bool
);
928 ITEM2("has","video",MCI_GETDEVCAPS_HAS_VIDEO
,_MCISTR_bool
);
929 ITEM2("uses","files",MCI_GETDEVCAPS_USES_FILES
,_MCISTR_bool
);
930 ITEM2("compound","device",MCI_GETDEVCAPS_COMPOUND_DEVICE
,_MCISTR_bool
);
931 ITEM2("can","record",MCI_GETDEVCAPS_CAN_RECORD
,_MCISTR_bool
);
932 ITEM2("can","play",MCI_GETDEVCAPS_CAN_PLAY
,_MCISTR_bool
);
933 ITEM2("can","eject",MCI_GETDEVCAPS_CAN_EJECT
,_MCISTR_bool
);
934 ITEM2("can","save",MCI_GETDEVCAPS_CAN_SAVE
,_MCISTR_bool
);
936 case MCI_DEVTYPE_ANIMATION
:
937 ITEM1("palettes",MCI_ANIM_GETDEVCAPS_PALETTES
,_MCISTR_int
);
938 ITEM1("windows",MCI_ANIM_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
939 ITEM2("can","reverse",MCI_ANIM_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
940 ITEM2("can","stretch",MCI_ANIM_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
941 ITEM3("slow","play","rate",MCI_ANIM_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
942 ITEM3("fast","play","rate",MCI_ANIM_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
943 ITEM3("normal","play","rate",MCI_ANIM_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
945 case MCI_DEVTYPE_OVERLAY
:
946 ITEM1("windows",MCI_OVLY_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
947 ITEM2("can","freeze",MCI_OVLY_GETDEVCAPS_CAN_FREEZE
,_MCISTR_bool
);
948 ITEM2("can","stretch",MCI_OVLY_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
950 case MCI_DEVTYPE_VIDEODISC
:
951 FLAG1("cav",MCI_VD_GETDEVCAPS_CAV
);
952 FLAG1("clv",MCI_VD_GETDEVCAPS_CLV
);
953 ITEM2("can","reverse",MCI_VD_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
954 ITEM3("slow","play","rate",MCI_VD_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
955 ITEM3("fast","play","rate",MCI_VD_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
956 ITEM3("normal","play","rate",MCI_VD_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
958 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
959 ITEM1("inputs",MCI_WAVE_GETDEVCAPS_INPUTS
,_MCISTR_int
);
960 ITEM1("outputs",MCI_WAVE_GETDEVCAPS_OUTPUTS
,_MCISTR_int
);
965 _MCI_CALL_DRIVER( MCI_GETDEVCAPS
, MAKE_SEGPTR(&gdcParams
) );
966 /* no timeformat needed */
968 _MCISTR_convreturn(type
,gdcParams
.dwReturn
,lpstrReturnString
,uReturnLength
,uDevTyp
,0);
974 /* resumes operation of device. no arguments, no return values */
976 MCISTR_Resume(_MCISTR_PROTO_
) {
977 MCI_GENERIC_PARMS genParams
;
980 genParams
.dwCallback
=0;
981 _MCI_CALL_DRIVER( MCI_RESUME
, MAKE_SEGPTR(&genParams
) );
985 /* pauses operation of device. no arguments, no return values */
987 MCISTR_Pause(_MCISTR_PROTO_
) {
988 MCI_GENERIC_PARMS genParams
;
990 genParams
.dwCallback
=0;
991 _MCI_CALL_DRIVER( MCI_PAUSE
, MAKE_SEGPTR(&genParams
) );
995 /* stops operation of device. no arguments, no return values */
997 MCISTR_Stop(_MCISTR_PROTO_
) {
998 MCI_GENERIC_PARMS genParams
;
1000 genParams
.dwCallback
=0;
1001 _MCI_CALL_DRIVER( MCI_STOP
, MAKE_SEGPTR(&genParams
) );
1005 /* starts recording.
1007 * "overwrite" overwrite existing things
1008 * "insert" insert at current position
1009 * "to <time>" record up to <time> (specified in timeformat)
1010 * "from <time>" record from <time> (specified in timeformat)
1013 MCISTR_Record(_MCISTR_PROTO_
) {
1014 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1016 MCI_RECORD_PARMS recordParams
;
1018 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1019 if (res
) return res
;
1022 case MCI_FORMAT_MILLISECONDS
:
1023 case MCI_FORMAT_FRAMES
:
1024 case MCI_FORMAT_BYTES
:
1025 case MCI_FORMAT_SAMPLES
:
1029 case MCI_FORMAT_HMS
:
1030 case MCI_FORMAT_MSF
:
1031 parsestr
="%d:%d:%d";
1034 case MCI_FORMAT_TMSF
:
1035 parsestr
="%d:%d:%d:%d";
1038 default:fprintf(stdnimp
,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef
);
1043 recordParams
.dwCallback
= 0;
1045 while (i
<nrofkeywords
) {
1046 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1048 a
[0]=a
[1]=a
[2]=a
[3]=0;
1049 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1050 /* add up all integers we got, if we have more
1051 * shift them. (Well I should use the macros in
1052 * mmsystem.h, right).
1054 recordParams
.dwTo
=0;
1056 recordParams
.dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1060 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1061 dwFlags
|= MCI_FROM
;
1062 a
[0]=a
[1]=a
[2]=a
[3]=0;
1063 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1065 recordParams
.dwFrom
=0;
1067 recordParams
.dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1071 FLAG1("insert",MCI_RECORD_INSERT
);
1072 FLAG1("overwrite",MCI_RECORD_OVERWRITE
);
1075 _MCI_CALL_DRIVER( MCI_RECORD
, MAKE_SEGPTR(&recordParams
) );
1081 * "to <time>" play up to <time> (specified in set timeformat)
1082 * "from <time>" play from <time> (specified in set timeformat)
1086 * "scan" play as fast as possible (with audio disabled perhaps)
1087 * "reverse" play reverse
1088 * "speed <fps>" play with specified frames per second
1092 * "scan" play as fast as possible (with audio disabled perhaps)
1093 * "reverse" play reverse
1094 * "speed <fps>" play with specified frames per second
1097 MCISTR_Play(_MCISTR_PROTO_
) {
1098 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1101 MCI_PLAY_PARMS playParams
;
1102 MCI_VD_PLAY_PARMS vdplayParams
;
1103 MCI_ANIM_PLAY_PARMS animplayParams
;
1106 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1107 if (res
) return res
;
1109 case MCI_FORMAT_MILLISECONDS
:
1110 case MCI_FORMAT_FRAMES
:
1111 case MCI_FORMAT_BYTES
:
1112 case MCI_FORMAT_SAMPLES
:
1116 case MCI_FORMAT_HMS
:
1117 case MCI_FORMAT_MSF
:
1118 parsestr
="%d:%d:%d";
1121 case MCI_FORMAT_TMSF
:
1122 parsestr
="%d:%d:%d:%d";
1125 default:fprintf(stdnimp
,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef
);
1130 U
.playParams
.dwCallback
=0;
1132 while (i
<nrofkeywords
) {
1133 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1135 a
[0]=a
[1]=a
[2]=a
[3]=0;
1136 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1137 /* add up all integers we got, if we have more
1138 * shift them. (Well I should use the macros in
1139 * mmsystem.h, right).
1141 U
.playParams
.dwTo
=0;
1143 U
.playParams
.dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1147 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1148 dwFlags
|= MCI_FROM
;
1149 a
[0]=a
[1]=a
[2]=a
[3]=0;
1150 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1152 U
.playParams
.dwFrom
=0;
1154 U
.playParams
.dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1159 case MCI_DEVTYPE_VIDEODISC
:
1160 FLAG1("slow",MCI_VD_PLAY_SLOW
);
1161 FLAG1("fast",MCI_VD_PLAY_FAST
);
1162 FLAG1("scan",MCI_VD_PLAY_SCAN
);
1163 FLAG1("reverse",MCI_VD_PLAY_REVERSE
);
1164 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1165 dwFlags
|= MCI_VD_PLAY_SPEED
;
1166 sscanf(keywords
[i
+1],"%ld",&(U
.vdplayParams
.dwSpeed
));
1171 case MCI_DEVTYPE_ANIMATION
:
1172 FLAG1("slow",MCI_ANIM_PLAY_SLOW
);
1173 FLAG1("fast",MCI_ANIM_PLAY_FAST
);
1174 FLAG1("scan",MCI_ANIM_PLAY_SCAN
);
1175 FLAG1("reverse",MCI_ANIM_PLAY_REVERSE
);
1176 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1177 dwFlags
|= MCI_ANIM_PLAY_SPEED
;
1178 sscanf(keywords
[i
+1],"%ld",&(U
.animplayParams
.dwSpeed
));
1186 _MCI_CALL_DRIVER( MCI_PLAY
, MAKE_SEGPTR(&U
) );
1190 /* seek to a specified position
1192 * "to start" seek to start of medium
1193 * "to end" seek to end of medium
1194 * "to <time>" seek to <time> specified in current timeformat
1197 MCISTR_Seek(_MCISTR_PROTO_
) {
1198 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1200 MCI_SEEK_PARMS seekParams
;
1202 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1203 if (res
) return res
;
1205 case MCI_FORMAT_MILLISECONDS
:
1206 case MCI_FORMAT_FRAMES
:
1207 case MCI_FORMAT_BYTES
:
1208 case MCI_FORMAT_SAMPLES
:
1212 case MCI_FORMAT_HMS
:
1213 case MCI_FORMAT_MSF
:
1214 parsestr
="%d:%d:%d";
1217 case MCI_FORMAT_TMSF
:
1218 parsestr
="%d:%d:%d:%d";
1221 default:fprintf(stdnimp
,"mciSendString:SEEK:unknown timeformat %d, please report.\n",timef
);
1226 seekParams
.dwCallback
=0;
1228 while (i
<nrofkeywords
) {
1229 if ( !STRCMP(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1230 if (!STRCMP(keywords
[i
+1],"start")) {
1231 dwFlags
|=MCI_SEEK_TO_START
;
1236 if (!STRCMP(keywords
[i
+1],"end")) {
1237 dwFlags
|=MCI_SEEK_TO_END
;
1244 a
[0]=a
[1]=a
[2]=a
[3]=0;
1245 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1248 seekParams
.dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1252 case MCI_DEVTYPE_VIDEODISC
:
1253 FLAG1("reverse",MCI_VD_SEEK_REVERSE
);
1258 _MCI_CALL_DRIVER( MCI_SEEK
, MAKE_SEGPTR(&seekParams
) );
1262 /* close media/driver */
1264 MCISTR_Close(_MCISTR_PROTO_
) {
1265 MCI_GENERIC_PARMS closeParams
;
1268 _MCI_CALL_DRIVER( MCI_CLOSE
, MAKE_SEGPTR(&closeParams
) );
1272 /* return information.
1274 * "product" return product name (human readable)
1275 * "file" return filename
1277 * "text" returns text?
1279 * "text" returns text?
1282 MCISTR_Info(_MCISTR_PROTO_
) {
1283 MCI_INFO_PARMS infoParams
;
1288 i
=0;while (i
<nrofkeywords
) {
1289 FLAG1("product",MCI_INFO_PRODUCT
);
1290 FLAG1("file",MCI_INFO_FILE
);
1292 case MCI_DEVTYPE_ANIMATION
:
1293 FLAG1("text",MCI_ANIM_INFO_TEXT
);
1295 case MCI_DEVTYPE_OVERLAY
:
1296 FLAG1("text",MCI_OVLY_INFO_TEXT
);
1301 if (dwFlags
== sflags
)
1302 return MCIERR_MISSING_STRING_ARGUMENT
;
1303 /* MCI driver will fill in lpstrReturn, dwRetSize.
1304 * FIXME: I don't know if this is correct behaviour
1306 _MCI_CALL_DRIVER( MCI_INFO
, MAKE_SEGPTR(&infoParams
) );
1308 _MCI_STR(infoParams
.lpstrReturn
);
1312 DWORD
mciSysInfo(DWORD dwFlags
,LPMCI_SYSINFO_PARMS lpParms
);
1314 /* query MCI driver itself for information
1316 * "installname" return install name of <device> (system.ini)
1317 * "quantity" return nr of installed drivers
1318 * "open" open drivers only (additional flag)
1319 * "name <nr>" return nr of devices with <devicetyp>
1320 * "name all" return nr of all devices
1322 * FIXME: mciSysInfo() is broken I think.
1325 MCISTR_Sysinfo(_MCISTR_PROTO_
) {
1326 MCI_SYSINFO_PARMS sysinfoParams
;
1329 sysinfoParams
.lpstrReturn
= lpstrReturnString
;
1330 sysinfoParams
.dwRetSize
= uReturnLength
;
1331 sysinfoParams
.wDeviceType
= uDevTyp
;
1333 while (i
<nrofkeywords
) {
1334 FLAG1("installname",MCI_SYSINFO_INSTALLNAME
);
1335 FLAG1("quantity",MCI_SYSINFO_INSTALLNAME
);
1336 FLAG1("open",MCI_SYSINFO_OPEN
);
1337 if (!strcmp(keywords
[i
],"name") && (i
+1<nrofkeywords
)) {
1338 sscanf(keywords
[i
+1],"%ld",&(sysinfoParams
.dwNumber
));
1339 dwFlags
|= MCI_SYSINFO_NAME
;
1345 res
=mciSysInfo(dwFlags
,&sysinfoParams
);
1346 if (dwFlags
& MCI_SYSINFO_QUANTITY
) {
1349 sprintf(buf
,"%ld",*(long*)PTR_SEG_TO_LIN(lpstrReturnString
));
1352 /* no need to copy anything back, mciSysInfo did it for us */
1357 * Argument: "<filename>"
1358 * Overlay: "at <left> <top> <right> <bottom>" additional
1361 MCISTR_Load(_MCISTR_PROTO_
) {
1363 MCI_LOAD_PARMS loadParams
;
1364 MCI_OVLY_LOAD_PARMS ovlyloadParams
;
1371 while (i
<nrofkeywords
) {
1373 case MCI_DEVTYPE_OVERLAY
:
1374 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1375 dwFlags
|= MCI_OVLY_RECT
;
1376 sscanf(keywords
[i
+1],"%hd",&(U
.ovlyloadParams
.rc
.left
));
1377 sscanf(keywords
[i
+2],"%hd",&(U
.ovlyloadParams
.rc
.top
));
1378 sscanf(keywords
[i
+3],"%hd",&(U
.ovlyloadParams
.rc
.right
));
1379 sscanf(keywords
[i
+4],"%hd",&(U
.ovlyloadParams
.rc
.bottom
));
1380 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1385 len
+=strlen(keywords
[i
])+1;
1388 s
=(char*)xmalloc(len
);
1390 while (i
<nrofkeywords
) {
1391 strcat(s
,keywords
[i
]);
1393 if (i
<nrofkeywords
) strcat(s
," ");
1395 /* FIXME: messy, but I strongly suspect we have to use a
1396 * segmented pointer, so I am doing that
1398 x
=USER_HEAP_ALLOC(len
);
1399 U
.loadParams
.lpfilename
=(LPSTR
)MAKELONG(x
,USER_HeapSel
);
1400 strcpy(PTR_SEG_TO_LIN(U
.loadParams
.lpfilename
),s
);
1402 dwFlags
|= MCI_LOAD_FILE
;
1403 _MCI_CALL_DRIVER( MCI_LOAD
, MAKE_SEGPTR(&U
) );
1409 * Argument: "<filename>"
1410 * Overlay: "at <left> <top> <right> <bottom>" additional
1413 MCISTR_Save(_MCISTR_PROTO_
) {
1415 MCI_SAVE_PARMS saveParams
;
1416 MCI_OVLY_SAVE_PARMS ovlysaveParams
;
1423 while (i
<nrofkeywords
) {
1425 case MCI_DEVTYPE_OVERLAY
:
1426 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1427 dwFlags
|= MCI_OVLY_RECT
;
1428 sscanf(keywords
[i
+1],"%hd",&(U
.ovlysaveParams
.rc
.left
));
1429 sscanf(keywords
[i
+2],"%hd",&(U
.ovlysaveParams
.rc
.top
));
1430 sscanf(keywords
[i
+3],"%hd",&(U
.ovlysaveParams
.rc
.right
));
1431 sscanf(keywords
[i
+4],"%hd",&(U
.ovlysaveParams
.rc
.bottom
));
1432 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1437 len
+=strlen(keywords
[i
])+1;
1440 s
=(char*)xmalloc(len
);
1442 while (i
<nrofkeywords
) {
1443 strcat(s
,keywords
[i
]);
1445 if (i
<nrofkeywords
) strcat(s
," ");
1447 /* FIXME: messy, but I strongly suspect we have to use a
1448 * segmented pointer, so I am doing that
1450 x
=USER_HEAP_ALLOC(len
);
1451 U
.saveParams
.lpfilename
=(LPSTR
)MAKELONG(x
,USER_HeapSel
);
1452 strcpy(PTR_SEG_TO_LIN(U
.saveParams
.lpfilename
),s
);
1454 dwFlags
|= MCI_LOAD_FILE
;
1455 _MCI_CALL_DRIVER( MCI_SAVE
, MAKE_SEGPTR(&U
) );
1460 /* prepare device for input/output
1461 * (only applyable to waveform audio)
1464 MCISTR_Cue(_MCISTR_PROTO_
) {
1465 MCI_GENERIC_PARMS cueParams
;
1469 while (i
<nrofkeywords
) {
1471 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
1472 FLAG1("input",MCI_WAVE_INPUT
);
1473 FLAG1("output",MCI_WAVE_OUTPUT
);
1478 _MCI_CALL_DRIVER( MCI_CUE
, MAKE_SEGPTR(&cueParams
) );
1482 /* delete information */
1484 MCISTR_Delete(_MCISTR_PROTO_
) {
1485 int timef
,nrargs
,i
,j
,k
,a
[4],res
;
1487 MCI_WAVE_DELETE_PARMS deleteParams
;
1489 /* only implemented for waveform audio */
1490 if (uDevTyp
!= MCI_DEVTYPE_WAVEFORM_AUDIO
)
1491 return MCIERR_UNSUPPORTED_FUNCTION
; /* well it fits */
1492 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1493 if (res
) return res
;
1495 case MCI_FORMAT_MILLISECONDS
:
1496 case MCI_FORMAT_FRAMES
:
1497 case MCI_FORMAT_BYTES
:
1498 case MCI_FORMAT_SAMPLES
:
1502 case MCI_FORMAT_HMS
:
1503 case MCI_FORMAT_MSF
:
1504 parsestr
="%d:%d:%d";
1507 case MCI_FORMAT_TMSF
:
1508 parsestr
="%d:%d:%d:%d";
1511 default:fprintf(stdnimp
,"mciSendString:DELETE:unknown timeformat %d, please report.\n",timef
);
1517 while (i
<nrofkeywords
) {
1518 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1520 a
[0]=a
[1]=a
[2]=a
[3]=0;
1521 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1522 /* add up all integers we got, if we have more
1523 * shift them. (Well I should use the macros in
1524 * mmsystem.h, right).
1526 deleteParams
.dwTo
=0;
1528 deleteParams
.dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1532 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1533 dwFlags
|= MCI_FROM
;
1534 a
[0]=a
[1]=a
[2]=a
[3]=0;
1535 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1537 deleteParams
.dwFrom
=0;
1539 deleteParams
.dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1545 _MCI_CALL_DRIVER( MCI_DELETE
, MAKE_SEGPTR(&deleteParams
) );
1549 /* send command to device. only applies to videodisc */
1551 MCISTR_Escape(_MCISTR_PROTO_
) {
1552 MCI_VD_ESCAPE_PARMS escapeParams
;
1557 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1558 return MCIERR_UNSUPPORTED_FUNCTION
;
1560 while (i
<nrofkeywords
) {
1561 len
+=strlen(keywords
[i
])+1;
1564 s
=(char*)xmalloc(len
);
1566 while (i
<nrofkeywords
) {
1567 strcat(s
,keywords
[i
]);
1569 if (i
<nrofkeywords
) strcat(s
," ");
1571 /* FIXME: messy, but I strongly suspect we have to use a
1572 * segmented pointer, so I am doing that
1574 x
=USER_HEAP_ALLOC(len
);
1575 escapeParams
.lpstrCommand
=(LPSTR
)MAKELONG(x
,USER_HeapSel
);
1576 strcpy(PTR_SEG_TO_LIN(escapeParams
.lpstrCommand
),s
);
1578 dwFlags
|= MCI_VD_ESCAPE_STRING
;
1579 _MCI_CALL_DRIVER( MCI_ESCAPE
, MAKE_SEGPTR(&escapeParams
) );
1584 /* unfreeze [part of] the overlayed video
1585 * only applyable to Overlay devices
1588 MCISTR_Unfreeze(_MCISTR_PROTO_
) {
1589 MCI_OVLY_RECT_PARMS unfreezeParams
;
1592 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1593 return MCIERR_UNSUPPORTED_FUNCTION
;
1594 i
=0;while (i
<nrofkeywords
) {
1595 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1596 sscanf(keywords
[i
+1],"%hd",&(unfreezeParams
.rc
.left
));
1597 sscanf(keywords
[i
+2],"%hd",&(unfreezeParams
.rc
.top
));
1598 sscanf(keywords
[i
+3],"%hd",&(unfreezeParams
.rc
.right
));
1599 sscanf(keywords
[i
+4],"%hd",&(unfreezeParams
.rc
.bottom
));
1600 dwFlags
|= MCI_OVLY_RECT
;
1606 _MCI_CALL_DRIVER( MCI_UNFREEZE
, MAKE_SEGPTR(&unfreezeParams
) );
1609 /* freeze [part of] the overlayed video
1610 * only applyable to Overlay devices
1613 MCISTR_Freeze(_MCISTR_PROTO_
) {
1614 MCI_OVLY_RECT_PARMS freezeParams
;
1617 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1618 return MCIERR_UNSUPPORTED_FUNCTION
;
1619 i
=0;while (i
<nrofkeywords
) {
1620 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1621 sscanf(keywords
[i
+1],"%hd",&(freezeParams
.rc
.left
));
1622 sscanf(keywords
[i
+2],"%hd",&(freezeParams
.rc
.top
));
1623 sscanf(keywords
[i
+3],"%hd",&(freezeParams
.rc
.right
));
1624 sscanf(keywords
[i
+4],"%hd",&(freezeParams
.rc
.bottom
));
1625 dwFlags
|= MCI_OVLY_RECT
;
1631 _MCI_CALL_DRIVER( MCI_FREEZE
, MAKE_SEGPTR(&freezeParams
) );
1635 /* copy parts of image to somewhere else
1636 * "source [at <left> <top> <right> <bottom>]" source is framebuffer [or rect]
1637 * "destination [at <left> <top> <right> <bottom>]" destination is framebuffer [or rect]
1639 * "frame [at <left> <top> <right> <bottom>]" frame is framebuffer [or rect]
1640 * where the video input is placed
1641 * "video [at <left> <top> <right> <bottom>]" video is whole video [or rect]
1642 * (defining part of input to
1645 * FIXME: This whole junk is passing multiple rectangles.
1646 * I don't know how to do that with the present interface.
1647 * (Means code below is broken)
1650 MCISTR_Put(_MCISTR_PROTO_
) {
1652 MCI_OVLY_RECT_PARMS ovlyputParams
;
1653 MCI_ANIM_RECT_PARMS animputParams
;
1656 i
=0;while (i
<nrofkeywords
) {
1658 case MCI_DEVTYPE_ANIMATION
:
1659 FLAG1("source",MCI_ANIM_PUT_SOURCE
);
1660 FLAG1("destination",MCI_ANIM_PUT_DESTINATION
);
1661 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1662 sscanf(keywords
[i
+1],"%hd",&(U
.animputParams
.rc
.left
));
1663 sscanf(keywords
[i
+2],"%hd",&(U
.animputParams
.rc
.top
));
1664 sscanf(keywords
[i
+3],"%hd",&(U
.animputParams
.rc
.right
));
1665 sscanf(keywords
[i
+4],"%hd",&(U
.animputParams
.rc
.bottom
));
1666 dwFlags
|= MCI_ANIM_RECT
;
1671 case MCI_DEVTYPE_OVERLAY
:
1672 FLAG1("source",MCI_OVLY_PUT_SOURCE
);
1673 FLAG1("destination",MCI_OVLY_PUT_DESTINATION
);
1674 FLAG1("video",MCI_OVLY_PUT_VIDEO
);
1675 FLAG1("frame",MCI_OVLY_PUT_FRAME
);
1676 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1677 sscanf(keywords
[i
+1],"%hd",&(U
.ovlyputParams
.rc
.left
));
1678 sscanf(keywords
[i
+2],"%hd",&(U
.ovlyputParams
.rc
.top
));
1679 sscanf(keywords
[i
+3],"%hd",&(U
.ovlyputParams
.rc
.right
));
1680 sscanf(keywords
[i
+4],"%hd",&(U
.ovlyputParams
.rc
.bottom
));
1681 dwFlags
|= MCI_OVLY_RECT
;
1689 _MCI_CALL_DRIVER( MCI_PUT
, MAKE_SEGPTR(&U
) );
1693 /* palette behaviour changing
1695 * "normal" realize the palette normally
1696 * "background" realize the palette as background palette
1699 MCISTR_Realize(_MCISTR_PROTO_
) {
1700 MCI_GENERIC_PARMS realizeParams
;
1703 if (uDevTyp
!= MCI_DEVTYPE_ANIMATION
)
1704 return MCIERR_UNSUPPORTED_FUNCTION
;
1706 while (i
<nrofkeywords
) {
1707 FLAG1("background",MCI_ANIM_REALIZE_BKGD
);
1708 FLAG1("normal",MCI_ANIM_REALIZE_NORM
);
1711 _MCI_CALL_DRIVER( MCI_REALIZE
, MAKE_SEGPTR(&realizeParams
) );
1715 /* videodisc spinning
1720 MCISTR_Spin(_MCISTR_PROTO_
) {
1721 MCI_GENERIC_PARMS spinParams
;
1724 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1725 return MCIERR_UNSUPPORTED_FUNCTION
;
1727 while (i
<nrofkeywords
) {
1728 FLAG1("up",MCI_VD_SPIN_UP
);
1729 FLAG1("down",MCI_VD_SPIN_UP
);
1732 _MCI_CALL_DRIVER( MCI_SPIN
, MAKE_SEGPTR(&spinParams
) );
1736 /* step single frames
1737 * "reverse" optional flag
1738 * "by <nr>" for <nr> frames
1741 MCISTR_Step(_MCISTR_PROTO_
) {
1743 MCI_ANIM_STEP_PARMS animstepParams
;
1744 MCI_VD_STEP_PARMS vdstepParams
;
1749 while (i
<nrofkeywords
) {
1751 case MCI_DEVTYPE_ANIMATION
:
1752 FLAG1("reverse",MCI_ANIM_STEP_REVERSE
);
1753 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1754 sscanf(keywords
[i
+1],"%ld",&(U
.animstepParams
.dwFrames
));
1755 dwFlags
|= MCI_ANIM_STEP_FRAMES
;
1760 case MCI_DEVTYPE_VIDEODISC
:
1761 FLAG1("reverse",MCI_VD_STEP_REVERSE
);
1762 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1763 sscanf(keywords
[i
+1],"%ld",&(U
.vdstepParams
.dwFrames
));
1764 dwFlags
|= MCI_VD_STEP_FRAMES
;
1772 _MCI_CALL_DRIVER( MCI_STEP
, MAKE_SEGPTR(&U
) );
1776 /* update animation window
1778 * "at <left> <top> <right> <bottom>" only in this rectangle
1779 * "hdc" device context
1782 MCISTR_Update(_MCISTR_PROTO_
) {
1784 MCI_ANIM_UPDATE_PARMS updateParams
;
1787 while (i
<nrofkeywords
) {
1788 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1789 sscanf(keywords
[i
+1],"%hd",&(updateParams
.rc
.left
));
1790 sscanf(keywords
[i
+2],"%hd",&(updateParams
.rc
.top
));
1791 sscanf(keywords
[i
+3],"%hd",&(updateParams
.rc
.right
));
1792 sscanf(keywords
[i
+4],"%hd",&(updateParams
.rc
.bottom
));
1793 dwFlags
|= MCI_ANIM_RECT
;
1797 if (!STRCMP(keywords
[i
],"hdc") && (i
+1<nrofkeywords
)) {
1798 dwFlags
|= MCI_ANIM_UPDATE_HDC
;
1799 sscanf(keywords
[i
+1],"%hd",&(updateParams
.hDC
));
1805 _MCI_CALL_DRIVER( MCI_UPDATE
, MAKE_SEGPTR(&updateParams
) );
1809 /* where command for animation and overlay drivers.
1810 * just returns the specified rectangle as a string
1819 MCISTR_Where(_MCISTR_PROTO_
) {
1821 MCI_ANIM_RECT_PARMS animwhereParams
;
1822 MCI_OVLY_RECT_PARMS ovlywhereParams
;
1827 while (i
<nrofkeywords
) {
1829 case MCI_DEVTYPE_ANIMATION
:
1830 FLAG1("source",MCI_ANIM_WHERE_SOURCE
);
1831 FLAG1("destination",MCI_ANIM_WHERE_DESTINATION
);
1833 case MCI_DEVTYPE_OVERLAY
:
1834 FLAG1("source",MCI_OVLY_WHERE_SOURCE
);
1835 FLAG1("destination",MCI_OVLY_WHERE_DESTINATION
);
1836 FLAG1("video",MCI_OVLY_WHERE_VIDEO
);
1837 FLAG1("frame",MCI_OVLY_WHERE_FRAME
);
1842 _MCI_CALL_DRIVER( MCI_WHERE
, MAKE_SEGPTR(&U
) );
1846 case MCI_DEVTYPE_ANIMATION
:
1847 sprintf(buf
,"%d %d %d %d",
1848 U
.animwhereParams
.rc
.left
,
1849 U
.animwhereParams
.rc
.top
,
1850 U
.animwhereParams
.rc
.right
,
1851 U
.animwhereParams
.rc
.bottom
1854 case MCI_DEVTYPE_OVERLAY
:
1855 sprintf(buf
,"%d %d %d %d",
1856 U
.ovlywhereParams
.rc
.left
,
1857 U
.ovlywhereParams
.rc
.top
,
1858 U
.ovlywhereParams
.rc
.right
,
1859 U
.ovlywhereParams
.rc
.bottom
1862 default:strcpy(buf
,"0 0 0 0");break;
1870 MCISTR_Window(_MCISTR_PROTO_
) {
1874 MCI_ANIM_WINDOW_PARMS animwindowParams
;
1875 MCI_OVLY_WINDOW_PARMS ovlywindowParams
;
1880 while (i
<nrofkeywords
) {
1882 case MCI_DEVTYPE_ANIMATION
:
1883 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1884 dwFlags
|= MCI_ANIM_WINDOW_HWND
;
1885 if (!STRCMP(keywords
[i
+1],"default"))
1886 U
.animwindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1888 sscanf(keywords
[i
+1],"%hd",&(U
.animwindowParams
.hWnd
));
1892 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1893 dwFlags
|= MCI_ANIM_WINDOW_STATE
;
1894 if (!STRCMP(keywords
[i
+1],"hide"))
1895 U
.animwindowParams
.nCmdShow
= SW_HIDE
;
1896 if (!STRCMP(keywords
[i
+1],"iconic"))
1897 U
.animwindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1898 if (!STRCMP(keywords
[i
+1],"minimized"))
1899 U
.animwindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1900 if (!STRCMP(keywords
[i
+1],"maximized"))
1901 U
.animwindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1902 if (!STRCMP(keywords
[i
+1],"minimize"))
1903 U
.animwindowParams
.nCmdShow
= SW_MINIMIZE
;
1904 if (!STRCMP(keywords
[i
+1],"normal"))
1905 U
.animwindowParams
.nCmdShow
= SW_NORMAL
;
1906 if (!STRCMP(keywords
[i
+1],"show"))
1907 U
.animwindowParams
.nCmdShow
= SW_SHOW
;
1908 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
1909 if (!STRCMP(keywords
[i
+2],"active"))
1910 U
.animwindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
1911 if (!STRCMP(keywords
[i
+2],"action"))
1912 U
.animwindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
1918 /* text is enclosed in " ... " as it seems */
1919 if (!STRCMP(keywords
[i
],"text")) {
1923 if (keywords
[i
+1][0]!='"') {
1927 dwFlags
|= MCI_ANIM_WINDOW_TEXT
;
1928 len
= strlen(keywords
[i
+1])+1;
1930 while (j
<nrofkeywords
) {
1931 len
+= strlen(keywords
[j
])+1;
1932 if (strchr(keywords
[j
],'"'))
1936 s
=(char*)xmalloc(len
);
1937 strcpy(s
,keywords
[i
+1]+1);
1941 strcat(s
,keywords
[j
]);
1943 if ((t
=strchr(s
,'"'))) *t
='\0';
1944 /* FIXME: segmented pointer? */
1945 U
.animwindowParams
.lpstrText
= s
;
1949 FLAG1("stretch",MCI_ANIM_WINDOW_ENABLE_STRETCH
);
1951 case MCI_DEVTYPE_OVERLAY
:
1952 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1953 dwFlags
|= MCI_OVLY_WINDOW_HWND
;
1954 if (!STRCMP(keywords
[i
+1],"default"))
1955 U
.ovlywindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1957 sscanf(keywords
[i
+1],"%hd",&(U
.ovlywindowParams
.hWnd
));
1961 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1962 dwFlags
|= MCI_OVLY_WINDOW_STATE
;
1963 if (!STRCMP(keywords
[i
+1],"hide"))
1964 U
.ovlywindowParams
.nCmdShow
= SW_HIDE
;
1965 if (!STRCMP(keywords
[i
+1],"iconic"))
1966 U
.ovlywindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1967 if (!STRCMP(keywords
[i
+1],"minimized"))
1968 U
.ovlywindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1969 if (!STRCMP(keywords
[i
+1],"maximized"))
1970 U
.ovlywindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1971 if (!STRCMP(keywords
[i
+1],"minimize"))
1972 U
.ovlywindowParams
.nCmdShow
= SW_MINIMIZE
;
1973 if (!STRCMP(keywords
[i
+1],"normal"))
1974 U
.ovlywindowParams
.nCmdShow
= SW_NORMAL
;
1975 if (!STRCMP(keywords
[i
+1],"show"))
1976 U
.ovlywindowParams
.nCmdShow
= SW_SHOW
;
1977 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
1978 if (!STRCMP(keywords
[i
+2],"active"))
1979 U
.ovlywindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
1980 if (!STRCMP(keywords
[i
+2],"action"))
1981 U
.ovlywindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
1987 /* text is enclosed in " ... " as it seems */
1988 if (!STRCMP(keywords
[i
],"text")) {
1992 if (keywords
[i
+1][0]!='"') {
1996 dwFlags
|= MCI_OVLY_WINDOW_TEXT
;
1997 len
= strlen(keywords
[i
+1])+1;
1999 while (j
<nrofkeywords
) {
2000 len
+= strlen(keywords
[j
])+1;
2001 if (strchr(keywords
[j
],'"'))
2005 s
=(char*)xmalloc(len
);
2006 strcpy(s
,keywords
[i
+1]+1);
2010 strcat(s
,keywords
[j
]);
2012 if ((t
=strchr(s
,'"'))) *t
='\0';
2013 /* FIXME: segmented pointer? */
2014 U
.ovlywindowParams
.lpstrText
= s
;
2018 FLAG1("stretch",MCI_OVLY_WINDOW_ENABLE_STRETCH
);
2023 _MCI_CALL_DRIVER( MCI_WINDOW
, MAKE_SEGPTR(&U
) );
2028 struct _MCISTR_cmdtable
{
2030 DWORD (*fun
)(_MCISTR_PROTO_
);
2031 } MCISTR_cmdtable
[]={
2032 {"break", MCISTR_Break
},
2033 {"capability", MCISTR_Capability
},
2034 {"close", MCISTR_Close
},
2035 {"cue", MCISTR_Cue
},
2036 {"delete", MCISTR_Delete
},
2037 {"escape", MCISTR_Escape
},
2038 {"freeze", MCISTR_Freeze
},
2039 {"info", MCISTR_Info
},
2040 {"load", MCISTR_Load
},
2041 {"open", MCISTR_Open
},
2042 {"pause", MCISTR_Pause
},
2043 {"play", MCISTR_Play
},
2044 {"put", MCISTR_Put
},
2045 {"realize", MCISTR_Realize
},
2046 {"record", MCISTR_Record
},
2047 {"resume", MCISTR_Resume
},
2048 {"save", MCISTR_Save
},
2049 {"seek", MCISTR_Seek
},
2050 {"set", MCISTR_Set
},
2051 {"spin", MCISTR_Spin
},
2052 {"status", MCISTR_Status
},
2053 {"step", MCISTR_Step
},
2054 {"stop", MCISTR_Stop
},
2055 {"sysinfo", MCISTR_Sysinfo
},
2056 {"unfreeze", MCISTR_Unfreeze
},
2057 {"update", MCISTR_Update
},
2058 {"where", MCISTR_Where
},
2059 {"window", MCISTR_Window
},
2062 /**************************************************************************
2063 * mciSendString [MMSYSTEM.702]
2065 /* The usercode sends a string with a command (and flags) expressed in
2066 * words in it... We do our best to call aprobiate drivers,
2067 * and return a errorcode AND a readable string (if lpstrRS!=NULL)
2068 * Info gathered by watching cool134.exe and from Borland's mcistrwh.hlp
2070 /* FIXME: "all" is a valid devicetype and we should access all devices if
2071 * it is used. (imagine "close all"). Not implemented yet.
2073 DWORD
mciSendString (LPCSTR lpstrCommand
, LPSTR lpstrReturnString
,
2074 UINT uReturnLength
, HWND hwndCallback
)
2076 char *cmd
,*dev
,*args
,**keywords
;
2077 WORD uDevTyp
=0,wDevID
=0;
2079 int res
=0,i
,nrofkeywords
;
2081 dprintf_mci(stddeb
,"mciSendString('%s', %p, %d, %X)\n", lpstrCommand
,
2082 lpstrReturnString
, uReturnLength
, hwndCallback
2084 /* format is <command> <device> <optargs> */
2085 cmd
=strdup(lpstrCommand
);
2086 dev
=strchr(cmd
,' ');
2089 return MCIERR_MISSING_DEVICE_NAME
;
2092 args
=strchr(dev
,' ');
2093 if (args
!=NULL
) *args
++='\0';
2097 i
=1;/* nrofkeywords = nrofspaces+1 */
2099 while ((s
=strchr(s
,' '))!=NULL
) i
++,s
++;
2100 keywords
=(char**)xmalloc(sizeof(char*)*(i
+2));
2103 while (s
&& i
<nrofkeywords
) {
2111 keywords
=(char**)xmalloc(sizeof(char*));
2113 dwFlags
= 0; /* default flags */
2114 for (i
=0;i
<nrofkeywords
;) {
2115 if (!STRCMP(keywords
[i
],"wait")) {
2116 dwFlags
|= MCI_WAIT
;
2117 memcpy(keywords
+i
,keywords
+(i
+1),nrofkeywords
-i
-1);
2121 if (!STRCMP(keywords
[i
],"notify")) {
2122 /* how should we callback? I don't know. */
2123 /*dwFlags |= MCI_NOTIFY;*/
2124 memcpy(keywords
+i
,keywords
+(i
+1),nrofkeywords
-i
-1);
2131 /* determine wDevID and uDevTyp for all commands except "open" */
2132 if (STRCMP(cmd
,"open")!=0) {
2137 dname
=(SEGPTR
)mciOpenDrv
[wDevID
].lpstrAlias
;
2139 dname
=(SEGPTR
)mciOpenDrv
[wDevID
].lpstrDeviceType
;
2140 if ((dname
!=NULL
)&&(!STRCMP(PTR_SEG_TO_LIN(dname
),dev
)))
2142 if (++wDevID
>= MAXMCIDRIVERS
) {
2143 dprintf_mci(stddeb
, __FILE__
":mciSendString:MAXMCIDRIVERS reached!\n");
2144 free(keywords
);free(cmd
);
2145 return MCIERR_INTERNAL
;
2148 uDevTyp
=mciDrv
[wDevID
].wType
;
2151 for (i
=0;MCISTR_cmdtable
[i
].cmd
!=NULL
;i
++) {
2152 if (!STRCMP(MCISTR_cmdtable
[i
].cmd
,cmd
)) {
2153 res
=MCISTR_cmdtable
[i
].fun(
2154 wDevID
,uDevTyp
,lpstrReturnString
,
2155 uReturnLength
,dev
,(LPSTR
*)keywords
,nrofkeywords
,
2161 if (MCISTR_cmdtable
[i
].cmd
!=NULL
) {
2162 free(keywords
);free(cmd
);
2165 fprintf(stdnimp
,"mciSendString('%s', %p, %u, %X) // unimplemented, please report.\n", lpstrCommand
,
2166 lpstrReturnString
, uReturnLength
, hwndCallback
2168 free(keywords
);free(cmd
);
2169 return MCIERR_MISSING_COMMAND_STRING
;