4 * Copyright 1995 Marcus Meissner
6 /* FIXME: special commands of device drivers should be handled by those drivers
9 /* FIXME: this current implementation does not allow commands like
10 * capability <filename> can play
11 * which is allowed by the MCI standard.
19 #include <sys/ioctl.h>
31 extern MCI_OPEN_DRIVER_PARMS mciDrv
[MAXMCIDRIVERS
];
33 /* FIXME: I need to remember the aliasname of a spec. driver.
34 * and this is the easiest way. *sigh*
36 extern MCI_OPEN_PARMS mciOpenDrv
[MAXMCIDRIVERS
];
38 #define GetDrv(wDevID) (&mciDrv[MMSYSTEM_DevIDToIndex(wDevID)])
39 #define GetOpenDrv(wDevID) (&mciOpenDrv[MMSYSTEM_DevIDToIndex(wDevID)])
40 extern int MMSYSTEM_DevIDToIndex(UINT16 wDevID
);
41 extern UINT16
MMSYSTEM_FirstDevID(void);
42 extern UINT16
MMSYSTEM_NextDevID(UINT16 wDevID
);
43 extern BOOL32
MMSYSTEM_DevIDValid(UINT16 wDevID
);
45 LONG
DrvDefDriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
46 DWORD dwParam1
, DWORD dwParam2
);
48 LONG
WAVE_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
49 DWORD dwParam1
, DWORD dwParam2
);
50 LONG
MIDI_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
51 DWORD dwParam1
, DWORD dwParam2
);
52 LONG
CDAUDIO_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
53 DWORD dwParam1
, DWORD dwParam2
);
54 LONG
ANIM_DriverProc(DWORD dwDevID
, HDRVR16 hDriv
, WORD wMsg
,
55 DWORD dwParam1
, DWORD dwParam2
);
57 /* The reason why I just don't lowercase the keywords array in
58 * mciSendString is left as an exercise to the reader.
60 #define STRCMP(x,y) lstrcmpi32A(x,y)
62 /* standard functionparameters for all functions */
63 #define _MCISTR_PROTO_ \
64 WORD wDevID,WORD uDevTyp,LPSTR lpstrReturnString,UINT16 uReturnLength,\
65 LPCSTR dev,LPSTR *keywords,UINT16 nrofkeywords,DWORD dwFlags,\
68 /* copy string to return pointer including necessary checks
69 * for use in mciSendString()
71 #define _MCI_STR(s) do {\
72 dprintf_mci(stddeb,"->returns \"%s\"",s);\
73 if (lpstrReturnString) {\
74 lstrcpyn32A(lpstrReturnString,s,uReturnLength);\
75 dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\
79 /* calling DriverProc. We need to pass the struct as SEGMENTED POINTER. */
80 #define _MCI_CALL_DRIVER(cmd,params) \
82 case MCI_DEVTYPE_CD_AUDIO:\
83 res=CDAUDIO_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags, (DWORD)(params));\
85 case MCI_DEVTYPE_WAVEFORM_AUDIO:\
86 res=WAVE_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
88 case MCI_DEVTYPE_SEQUENCER:\
89 res=MIDI_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
91 case MCI_DEVTYPE_ANIMATION:\
92 res=ANIM_DriverProc(GetDrv(wDevID)->wDeviceID,0,cmd,dwFlags,(DWORD)(params));\
94 case MCI_DEVTYPE_DIGITAL_VIDEO:\
95 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //No DIGITAL_VIDEO yet !\n");\
96 res=MCIERR_DEVICE_NOT_INSTALLED;\
99 dprintf_mci(stddeb,"_MCI_CALL_DRIVER //Invalid Device Name '%s' !\n",dev);\
100 res=MCIERR_INVALID_DEVICE_NAME;\
103 /* print a DWORD in the specified timeformat */
105 _MCISTR_printtf(char *buf
,UINT16 uDevType
,DWORD timef
,DWORD val
) {
108 case MCI_FORMAT_MILLISECONDS
:
109 case MCI_FORMAT_FRAMES
:
110 case MCI_FORMAT_BYTES
:
111 case MCI_FORMAT_SAMPLES
:
112 case MCI_VD_FORMAT_TRACK
:
113 /*case MCI_SEQ_FORMAT_SONGPTR: sameas MCI_VD_FORMAT_TRACK */
114 sprintf(buf
,"%ld",val
);
117 /* well, the macros have the same content*/
120 sprintf(buf
,"%d:%d:%d",
126 case MCI_FORMAT_TMSF
:
127 sprintf(buf
,"%d:%d:%d:%d",
129 MCI_TMSF_MINUTE(val
),
130 MCI_TMSF_SECOND(val
),
135 fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing timeformat for %ld, report.\n",timef
);
136 strcpy(buf
,"0"); /* hmm */
141 /* possible different return types */
142 #define _MCISTR_int 1
143 #define _MCISTR_time 2
144 #define _MCISTR_bool 3
145 #define _MCISTR_tfname 4
146 #define _MCISTR_mode 5
147 #define _MCISTR_divtype 6
148 #define _MCISTR_seqtype 7
149 #define _MCISTR_vdmtype 8
150 #define _MCISTR_devtype 9
153 _MCISTR_convreturn(int type
,DWORD dwReturn
,LPSTR lpstrReturnString
,
154 WORD uReturnLength
,WORD uDevTyp
,int timef
157 case _MCISTR_vdmtype
:
159 case MCI_VD_MEDIA_CLV
:_MCI_STR("CLV");break;
160 case MCI_VD_MEDIA_CAV
:_MCI_STR("CAV");break;
162 case MCI_VD_MEDIA_OTHER
:_MCI_STR("other");break;
165 case _MCISTR_seqtype
:
167 case MCI_SEQ_NONE
:_MCI_STR("none");break;
168 case MCI_SEQ_SMPTE
:_MCI_STR("smpte");break;
169 case MCI_SEQ_FILE
:_MCI_STR("file");break;
170 case MCI_SEQ_MIDI
:_MCI_STR("midi");break;
171 default:fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing sequencer mode %ld\n",dwReturn
);
176 case MCI_MODE_NOT_READY
:_MCI_STR("not ready");break;
177 case MCI_MODE_STOP
:_MCI_STR("stopped");break;
178 case MCI_MODE_PLAY
:_MCI_STR("playing");break;
179 case MCI_MODE_RECORD
:_MCI_STR("recording");break;
180 case MCI_MODE_SEEK
:_MCI_STR("seeking");break;
181 case MCI_MODE_PAUSE
:_MCI_STR("paused");break;
182 case MCI_MODE_OPEN
:_MCI_STR("open");break;
194 sprintf(buf
,"%ld",dwReturn
);
200 _MCISTR_printtf(buf
,uDevTyp
,timef
,dwReturn
);
206 case MCI_FORMAT_MILLISECONDS
:_MCI_STR("milliseconds");break;
207 case MCI_FORMAT_FRAMES
:_MCI_STR("frames");break;
208 case MCI_FORMAT_BYTES
:_MCI_STR("bytes");break;
209 case MCI_FORMAT_SAMPLES
:_MCI_STR("samples");break;
210 case MCI_FORMAT_HMS
:_MCI_STR("hms");break;
211 case MCI_FORMAT_MSF
:_MCI_STR("msf");break;
212 case MCI_FORMAT_TMSF
:_MCI_STR("tmsf");break;
214 fprintf(stdnimp
,__FILE__
":MCISTR_Status:missing timeformat for %d, report.\n",timef
);
218 case _MCISTR_divtype
:
220 case MCI_SEQ_DIV_PPQN
:_MCI_STR("PPQN");break;
221 case MCI_SEQ_DIV_SMPTE_24
:_MCI_STR("SMPTE 24 frame");break;
222 case MCI_SEQ_DIV_SMPTE_25
:_MCI_STR("SMPTE 25 frame");break;
223 case MCI_SEQ_DIV_SMPTE_30
:_MCI_STR("SMPTE 30 frame");break;
224 case MCI_SEQ_DIV_SMPTE_30DROP
:_MCI_STR("SMPTE 30 frame drop");break;
226 case _MCISTR_devtype
:
228 case MCI_DEVTYPE_VCR
:_MCI_STR("vcr");break;
229 case MCI_DEVTYPE_VIDEODISC
:_MCI_STR("videodisc");break;
230 case MCI_DEVTYPE_CD_AUDIO
:_MCI_STR("cd audio");break;
231 case MCI_DEVTYPE_OVERLAY
:_MCI_STR("overlay");break;
232 case MCI_DEVTYPE_DAT
:_MCI_STR("dat");break;
233 case MCI_DEVTYPE_SCANNER
:_MCI_STR("scanner");break;
234 case MCI_DEVTYPE_ANIMATION
:_MCI_STR("animation");break;
235 case MCI_DEVTYPE_DIGITAL_VIDEO
:_MCI_STR("digital video");break;
236 case MCI_DEVTYPE_OTHER
:_MCI_STR("other");break;
237 case MCI_DEVTYPE_WAVEFORM_AUDIO
:_MCI_STR("waveform audio");break;
238 case MCI_DEVTYPE_SEQUENCER
:_MCI_STR("sequencer");break;
239 default:fprintf(stdnimp
,__FILE__
":_MCISTR_convreturn:unknown device type %ld, report.\n",dwReturn
);break;
243 fprintf(stdnimp
,__FILE__
":_MCISTR_convreturn:unknown resulttype %d, report.\n",type
);
248 #define FLAG1(str,flag) \
249 if (!STRCMP(keywords[i],str)) {\
254 #define FLAG2(str1,str2,flag) \
255 if (!STRCMP(keywords[i],str1) && (i+1<nrofkeywords) && !STRCMP(keywords[i+1],str2)) {\
261 /* All known subcommands are implemented in single functions to avoid
262 * bloat and a xxxx lines long mciSendString(). All commands are of the
263 * format MCISTR_Cmd(_MCISTR_PROTO_) where _MCISTR_PROTO_ is the above
264 * defined line of arguments. (This is just for easy enhanceability.)
265 * All functions return the MCIERR_ errorvalue as DWORD. Returnvalues
266 * for the calls are in lpstrReturnString (If I mention return values
267 * in function headers, I mean returnvalues in lpstrReturnString.)
268 * Integers are sprintf("%d")ed integers. Boolean values are
269 * "true" and "false".
270 * timeformat depending values are "%d" "%d:%d" "%d:%d:%d" "%d:%d:%d:%d"
271 * FIXME: is above line correct?
273 * Preceding every function is a list of implemented/known arguments.
274 * Feel free to add missing arguments.
279 * Opens the specified MCI driver.
283 * "alias <aliasname>"
284 * "element <elementname>"
287 * "buffer <nrBytesPerSec>"
289 * "nostatic" increaste nr of nonstatic colours
290 * "parent <windowhandle>"
291 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
292 * "style child" WS_CHILD
293 * "style overlap" WS_OVERLAPPED
294 * "style popup" WS_POPUP
296 * "parent <windowhandle>"
297 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
298 * "style child" WS_CHILD
299 * "style overlap" WS_OVERLAPPED
300 * "style popup" WS_POPUP
304 MCISTR_Open(_MCISTR_PROTO_
) {
308 MCI_OPEN_PARMS openParams
;
309 MCI_WAVE_OPEN_PARMS waveopenParams
;
310 MCI_ANIM_OPEN_PARMS animopenParams
;
311 MCI_OVLY_OPEN_PARMS ovlyopenParams
;
313 union U
*pU
= SEGPTR_NEW(union U
);
315 pU
->openParams
.lpstrElementName
= NULL
;
319 pU
->openParams
.lpstrElementName
=SEGPTR_GET(SEGPTR_STRDUP(s
));
320 dwFlags
|= MCI_OPEN_ELEMENT
;
322 if (!STRCMP(dev
,"cdaudio")) {
323 uDevTyp
=MCI_DEVTYPE_CD_AUDIO
;
324 } else if (!STRCMP(dev
,"waveaudio")) {
325 uDevTyp
=MCI_DEVTYPE_WAVEFORM_AUDIO
;
326 } else if (!STRCMP(dev
,"sequencer")) {
327 uDevTyp
=MCI_DEVTYPE_SEQUENCER
;
328 } else if (!STRCMP(dev
,"animation1")) {
329 uDevTyp
=MCI_DEVTYPE_ANIMATION
;
330 } else if (!STRCMP(dev
,"avivideo")) {
331 uDevTyp
=MCI_DEVTYPE_DIGITAL_VIDEO
;
333 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrElementName
));
335 return MCIERR_INVALID_DEVICE_NAME
;
337 wDevID
=MMSYSTEM_FirstDevID();
338 while(GetDrv(wDevID
)->wType
) {
339 wDevID
= MMSYSTEM_NextDevID(wDevID
);
340 if (!MMSYSTEM_DevIDValid(wDevID
)) {
341 dprintf_mci(stddeb
, __FILE__
":MCISTR_Open:MAXMCIDRIVERS reached!\n");
342 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrElementName
));
344 return MCIERR_INTERNAL
;
347 GetDrv(wDevID
)->wType
= uDevTyp
;
348 GetDrv(wDevID
)->wDeviceID
= 0; /* FIXME? for multiple devices */
349 pU
->openParams
.dwCallback
= hwndCallback
;
350 pU
->openParams
.wDeviceID
= wDevID
;
351 pU
->ovlyopenParams
.dwStyle
= 0;
352 pU
->animopenParams
.dwStyle
= 0;
353 pU
->openParams
.lpstrDeviceType
= SEGPTR_GET(SEGPTR_STRDUP(dev
));
354 pU
->openParams
.lpstrAlias
= NULL
;
355 dwFlags
|= MCI_OPEN_TYPE
;
357 while (i
<nrofkeywords
) {
358 FLAG1("shareable",MCI_OPEN_SHAREABLE
);
359 if (!STRCMP(keywords
[i
],"alias") && (i
+1<nrofkeywords
)) {
360 dwFlags
|= MCI_OPEN_ALIAS
;
361 pU
->openParams
.lpstrAlias
=SEGPTR_GET(SEGPTR_STRDUP(keywords
[i
+1]));
365 if (!STRCMP(keywords
[i
],"element") && (i
+1<nrofkeywords
)) {
366 dwFlags
|= MCI_OPEN_ELEMENT
;
367 pU
->openParams
.lpstrElementName
=SEGPTR_GET(SEGPTR_STRDUP(keywords
[i
+1]));
372 case MCI_DEVTYPE_ANIMATION
:
373 case MCI_DEVTYPE_DIGITAL_VIDEO
:
374 FLAG1("nostatic",MCI_ANIM_OPEN_NOSTATIC
);
375 if (!STRCMP(keywords
[i
],"parent") && (i
+1<nrofkeywords
)) {
376 dwFlags
|= MCI_ANIM_OPEN_PARENT
;
377 sscanf(keywords
[i
+1],"%hu",&(pU
->animopenParams
.hWndParent
));
381 if (!STRCMP(keywords
[i
],"style") && (i
+1<nrofkeywords
)) {
384 dwFlags
|= MCI_ANIM_OPEN_WS
;
385 if (!STRCMP(keywords
[i
+1],"popup")) {
386 pU
->animopenParams
.dwStyle
|= WS_POPUP
;
387 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
388 pU
->animopenParams
.dwStyle
|= WS_OVERLAPPED
;
389 } else if (!STRCMP(keywords
[i
+1],"child")) {
390 pU
->animopenParams
.dwStyle
|= WS_CHILD
;
391 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
392 pU
->animopenParams
.dwStyle
|= st
;
394 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
399 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
400 if (!STRCMP(keywords
[i
],"buffer") && (i
+1<nrofkeywords
)) {
401 dwFlags
|= MCI_WAVE_OPEN_BUFFER
;
402 sscanf(keywords
[i
+1],"%ld",&(pU
->waveopenParams
.dwBufferSeconds
));
405 case MCI_DEVTYPE_OVERLAY
:
406 /* looks just like anim, but without NOSTATIC */
407 if (!STRCMP(keywords
[i
],"parent") && (i
+1<nrofkeywords
)) {
408 dwFlags
|= MCI_OVLY_OPEN_PARENT
;
409 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyopenParams
.hWndParent
));
413 if (!STRCMP(keywords
[i
],"style") && (i
+1<nrofkeywords
)) {
416 dwFlags
|= MCI_OVLY_OPEN_WS
;
417 if (!STRCMP(keywords
[i
+1],"popup")) {
418 pU
->ovlyopenParams
.dwStyle
|= WS_POPUP
;
419 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
420 pU
->ovlyopenParams
.dwStyle
|= WS_OVERLAPPED
;
421 } else if (!STRCMP(keywords
[i
+1],"child")) {
422 pU
->ovlyopenParams
.dwStyle
|= WS_CHILD
;
423 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
424 pU
->ovlyopenParams
.dwStyle
|= st
;
426 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
432 fprintf(stdnimp
,__FILE__
":MCISTR_Open:unknown parameter passed %s, please report.\n",keywords
[i
]);
435 _MCI_CALL_DRIVER( MCI_OPEN
, SEGPTR_GET(pU
) );
437 memcpy(GetOpenDrv(wDevID
),&pU
->openParams
,sizeof(MCI_OPEN_PARMS
));
439 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrElementName
));
440 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrDeviceType
));
441 SEGPTR_FREE(PTR_SEG_TO_LIN(pU
->openParams
.lpstrAlias
));
447 /* A help function for a lot of others ...
448 * for instance status/play/record/seek etc.
451 _MCISTR_determine_timeformat(LPCSTR dev
,WORD wDevID
,WORD uDevTyp
,int *timef
)
454 DWORD dwFlags
= MCI_STATUS_ITEM
;
455 MCI_STATUS_PARMS
*statusParams
= SEGPTR_NEW(MCI_STATUS_PARMS
);
457 if (!statusParams
) return 0;
458 statusParams
->dwItem
= MCI_STATUS_TIME_FORMAT
;
459 statusParams
->dwReturn
= 0;
460 _MCI_CALL_DRIVER( MCI_STATUS
, SEGPTR_GET(statusParams
) );
461 if (res
==0) *timef
= statusParams
->dwReturn
;
462 SEGPTR_FREE(statusParams
);
466 /* query status of MCI drivers
469 * "mode" - returns "not ready" "paused" "playing" "stopped" "open"
470 * "parked" "recording" "seeking" ....
472 * "current track" - returns current track as integer
473 * "length [track <nr>]" - returns length [of track <nr>] in current
475 * "number of tracks" - returns number of tracks as integer
476 * "position [track <nr>]" - returns position [in track <nr>] in current
478 * "ready" - checks if device is ready to play, -> bool
479 * "start position" - returns start position in timeformat
480 * "time format" - returns timeformat (list of possible values:
481 * "ms" "msf" "milliseconds" "hmsf" "tmsf" "frames"
482 * "bytes" "samples" "hms")
483 * "media present" - returns if media is present as bool
485 * "forward" - returns "true" if device is playing forwards
486 * "speed" - returns speed for device
487 * "palette handle" - returns palette handle
488 * "window handle" - returns window handle
489 * "stretch" - returns stretch bool
491 * "division type" - ? returns "PPQN" "SMPTE 24 frame"
492 * "SMPTE 25 frame" "SMPTE 30 frame" "SMPTE 30 drop frame"
493 * "tempo" - current tempo in (PPQN? speed in frames, SMPTE*? speed in hsmf)
494 * "offset" - offset in dito.
495 * "port" - midi port as integer
496 * "slave" - slave device ("midi","file","none","smpte")
497 * "master" - masterdevice (dito.)
499 * "window handle" - see animation
502 * "speed" - speed as integer
503 * "forward" - returns bool (when playing forward)
504 * "side" - returns 1 or 2
505 * "media type" - returns "CAV" "CLV" "other"
506 * "disc size" - returns "8" or "12"
508 * "input" - base queries on input set
509 * "output" - base queries on output set
510 * "format tag" - return integer format tag
511 * "channels" - return integer nr of channels
512 * "bytespersec" - return average nr of bytes/sec
513 * "samplespersec" - return nr of samples per sec
514 * "bitspersample" - return bitspersample
515 * "alignment" - return block alignment
516 * "level" - return level?
519 #define ITEM1(str,item,xtype) \
520 if (!STRCMP(keywords[i],str)) {\
521 statusParams->dwItem = item;\
526 #define ITEM2(str1,str2,item,xtype) \
527 if ( !STRCMP(keywords[i],str1) &&\
528 (i+1<nrofkeywords) &&\
529 !STRCMP(keywords[i+1],str2)\
531 statusParams->dwItem = item;\
536 #define ITEM3(str1,str2,str3,item,xtype) \
537 if ( !STRCMP(keywords[i],str1) &&\
538 (i+2<nrofkeywords) &&\
539 !STRCMP(keywords[i+1],str2) &&\
540 !STRCMP(keywords[i+2],str3)\
542 statusParams->dwItem = item;\
548 MCISTR_Status(_MCISTR_PROTO_
) {
549 MCI_STATUS_PARMS
*statusParams
= SEGPTR_NEW(MCI_STATUS_PARMS
);
550 int type
= 0,i
,res
,timef
;
552 statusParams
->dwCallback
= hwndCallback
;
553 dwFlags
|= MCI_STATUS_ITEM
;
554 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
557 statusParams
->dwReturn
= 0;
558 statusParams
->dwItem
= 0;
561 while (i
<nrofkeywords
) {
562 if (!STRCMP(keywords
[i
],"track") && (i
+1<nrofkeywords
)) {
563 sscanf(keywords
[i
+1],"%ld",&(statusParams
->dwTrack
));
564 dwFlags
|= MCI_TRACK
;
568 FLAG1("start",MCI_STATUS_START
);
570 ITEM2("current","track",MCI_STATUS_CURRENT_TRACK
,_MCISTR_time
);
571 ITEM2("time","format",MCI_STATUS_TIME_FORMAT
,_MCISTR_tfname
);
572 ITEM1("ready",MCI_STATUS_READY
,_MCISTR_bool
);
573 ITEM1("mode",MCI_STATUS_MODE
,_MCISTR_mode
);
574 ITEM3("number","of","tracks",MCI_STATUS_NUMBER_OF_TRACKS
,_MCISTR_int
);
575 ITEM1("length",MCI_STATUS_LENGTH
,_MCISTR_time
);
576 ITEM1("position",MCI_STATUS_POSITION
,_MCISTR_time
);
577 ITEM2("media","present",MCI_STATUS_MEDIA_PRESENT
,_MCISTR_bool
);
580 case MCI_DEVTYPE_ANIMATION
:
581 case MCI_DEVTYPE_DIGITAL_VIDEO
:
582 ITEM2("palette","handle",MCI_ANIM_STATUS_HPAL
,_MCISTR_int
);
583 ITEM2("window","handle",MCI_ANIM_STATUS_HWND
,_MCISTR_int
);
584 ITEM1("stretch",MCI_ANIM_STATUS_STRETCH
,_MCISTR_bool
);
585 ITEM1("speed",MCI_ANIM_STATUS_SPEED
,_MCISTR_int
);
586 ITEM1("forward",MCI_ANIM_STATUS_FORWARD
,_MCISTR_bool
);
588 case MCI_DEVTYPE_SEQUENCER
:
589 /* just completing the list, not working correctly */
590 ITEM2("division","type",MCI_SEQ_STATUS_DIVTYPE
,_MCISTR_divtype
);
591 /* tempo ... PPQN in frames/second, SMPTE in hmsf */
592 ITEM1("tempo",MCI_SEQ_STATUS_TEMPO
,_MCISTR_int
);
593 ITEM1("port",MCI_SEQ_STATUS_PORT
,_MCISTR_int
);
594 ITEM1("slave",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
595 ITEM1("master",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
596 /* offset ... PPQN in frames/second, SMPTE in hmsf */
597 ITEM1("offset",MCI_SEQ_STATUS_SLAVE
,_MCISTR_time
);
599 case MCI_DEVTYPE_OVERLAY
:
600 ITEM2("window","handle",MCI_OVLY_STATUS_HWND
,_MCISTR_int
);
601 ITEM1("stretch",MCI_OVLY_STATUS_STRETCH
,_MCISTR_bool
);
603 case MCI_DEVTYPE_VIDEODISC
:
604 ITEM1("speed",MCI_VD_STATUS_SPEED
,_MCISTR_int
);
605 ITEM1("forward",MCI_VD_STATUS_FORWARD
,_MCISTR_bool
);
606 ITEM1("side",MCI_VD_STATUS_SIDE
,_MCISTR_int
);
607 ITEM2("media","type",MCI_VD_STATUS_SIDE
,_MCISTR_vdmtype
);
608 /* returns 8 or 12 */
609 ITEM2("disc","size",MCI_VD_STATUS_DISC_SIZE
,_MCISTR_int
);
611 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
612 /* I am not quite sure if foll. 2 lines are right. */
613 FLAG1("input",MCI_WAVE_INPUT
);
614 FLAG1("output",MCI_WAVE_OUTPUT
);
616 ITEM2("format","tag",MCI_WAVE_STATUS_FORMATTAG
,_MCISTR_int
);
617 ITEM1("channels",MCI_WAVE_STATUS_CHANNELS
,_MCISTR_int
);
618 ITEM1("bytespersec",MCI_WAVE_STATUS_AVGBYTESPERSEC
,_MCISTR_int
);
619 ITEM1("samplespersec",MCI_WAVE_STATUS_SAMPLESPERSEC
,_MCISTR_int
);
620 ITEM1("bitspersample",MCI_WAVE_STATUS_BITSPERSAMPLE
,_MCISTR_int
);
621 ITEM1("alignment",MCI_WAVE_STATUS_BLOCKALIGN
,_MCISTR_int
);
622 ITEM1("level",MCI_WAVE_STATUS_LEVEL
,_MCISTR_int
);
625 fprintf(stdnimp
,__FILE__
":MCISTR_Status:unknown keyword '%s'\n",keywords
[i
]);
628 if (!statusParams
->dwItem
)
629 return MCIERR_MISSING_STRING_ARGUMENT
;
631 _MCI_CALL_DRIVER( MCI_STATUS
, SEGPTR_GET(statusParams
) );
633 _MCISTR_convreturn(type
,statusParams
->dwReturn
,lpstrReturnString
,uReturnLength
,uDevTyp
,timef
);
634 SEGPTR_FREE(statusParams
);
641 /* set specified parameters in respective MCI drivers
643 * "door open" eject media or somesuch
644 * "door close" load media
645 * "time format <timeformatname>" "ms" "milliseconds" "msf" "hmsf"
646 * "tmsf" "SMPTE 24" "SMPTE 25" "SMPTE 30"
648 * "audio [all|left|right] [on|off]" sets specified audiochannel on or off
649 * "video [on|off]" sets video on/off
651 * "formattag pcm" sets format to pcm
652 * "formattag <nr>" sets integer formattag value
653 * "any input" accept input from any known source
654 * "any output" output to any known destination
655 * "input <nr>" input from source <nr>
656 * "output <nr>" output to destination <nr>
657 * "channels <nr>" sets nr of channels
658 * "bytespersec <nr>" sets average bytes per second
659 * "samplespersec <nr>" sets average samples per second (1 sample can
661 * "alignment <nr>" sets the blockalignment to <nr>
662 * "bitspersample <nr>" sets the nr of bits per sample
664 * "master [midi|file|smpte|none]" sets the midi master device
665 * "slave [midi|file|smpte|none]" sets the midi master device
666 * "port mapper" midioutput to portmapper
667 * "port <nr>" midioutput to specified port
668 * "tempo <nr>" tempo of track (depends on timeformat/divtype)
669 * "offset <nr>" start offset?
672 MCISTR_Set(_MCISTR_PROTO_
) {
674 MCI_SET_PARMS setParams
;
675 MCI_WAVE_SET_PARMS wavesetParams
;
676 MCI_SEQ_SET_PARMS seqsetParams
;
678 union U
*pU
= SEGPTR_NEW(union U
);
681 pU
->setParams
.dwCallback
= hwndCallback
;
683 while (i
<nrofkeywords
) {
684 FLAG2("door","open",MCI_SET_DOOR_OPEN
);
685 FLAG2("door","closed",MCI_SET_DOOR_CLOSED
);
687 if ( !STRCMP(keywords
[i
],"time") &&
688 (i
+2<nrofkeywords
) &&
689 !STRCMP(keywords
[i
+1],"format")
691 dwFlags
|= MCI_SET_TIME_FORMAT
;
693 /* FIXME:is this a shortcut for milliseconds or
694 * minutes:seconds? */
695 if (!STRCMP(keywords
[i
+2],"ms"))
696 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
698 if (!STRCMP(keywords
[i
+2],"milliseconds"))
699 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
700 if (!STRCMP(keywords
[i
+2],"msf"))
701 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MSF
;
702 if (!STRCMP(keywords
[i
+2],"hms"))
703 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_HMS
;
704 if (!STRCMP(keywords
[i
+2],"frames"))
705 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_FRAMES
;
706 if (!STRCMP(keywords
[i
+2],"track"))
707 pU
->setParams
.dwTimeFormat
= MCI_VD_FORMAT_TRACK
;
708 if (!STRCMP(keywords
[i
+2],"bytes"))
709 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_BYTES
;
710 if (!STRCMP(keywords
[i
+2],"samples"))
711 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SAMPLES
;
712 if (!STRCMP(keywords
[i
+2],"tmsf"))
713 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_TMSF
;
714 if ( !STRCMP(keywords
[i
+2],"song") &&
715 (i
+3<nrofkeywords
) &&
716 !STRCMP(keywords
[i
+3],"pointer")
718 pU
->setParams
.dwTimeFormat
= MCI_SEQ_FORMAT_SONGPTR
;
719 if (!STRCMP(keywords
[i
+2],"smpte") && (i
+3<nrofkeywords
)) {
720 if (!STRCMP(keywords
[i
+3],"24"))
721 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_24
;
722 if (!STRCMP(keywords
[i
+3],"25"))
723 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_25
;
724 if (!STRCMP(keywords
[i
+3],"30"))
725 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30
;
726 if (!STRCMP(keywords
[i
+3],"drop") && (i
+4<nrofkeywords
) && !STRCMP(keywords
[i
+4],"30")) {
727 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30DROP
;
736 if (!STRCMP(keywords
[i
],"audio") && (i
+1<nrofkeywords
)) {
737 dwFlags
|= MCI_SET_AUDIO
;
738 if (!STRCMP(keywords
[i
+1],"all"))
739 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_ALL
;
740 if (!STRCMP(keywords
[i
+1],"left"))
741 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_LEFT
;
742 if (!STRCMP(keywords
[i
+1],"right"))
743 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_RIGHT
;
747 FLAG1("video",MCI_SET_VIDEO
);
748 FLAG1("on",MCI_SET_ON
);
749 FLAG1("off",MCI_SET_OFF
);
751 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
752 FLAG2("any","input",MCI_WAVE_SET_ANYINPUT
);
753 FLAG2("any","output",MCI_WAVE_SET_ANYOUTPUT
);
755 if ( !STRCMP(keywords
[i
],"formattag") &&
756 (i
+1<nrofkeywords
) &&
757 !STRCMP(keywords
[i
+1],"pcm")
759 dwFlags
|= MCI_WAVE_SET_FORMATTAG
;
760 pU
->wavesetParams
.wFormatTag
= WAVE_FORMAT_PCM
;
765 /* <keyword> <integer> */
766 #define WII(str,flag,fmt,element) \
767 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
768 sscanf(keywords[i+1],fmt,&(pU->wavesetParams. element ));\
773 WII("formattag",MCI_WAVE_SET_FORMATTAG
,"%hu",wFormatTag
);
774 WII("channels",MCI_WAVE_SET_CHANNELS
,"%hu",nChannels
);
775 WII("bytespersec",MCI_WAVE_SET_AVGBYTESPERSEC
,"%lu",nAvgBytesPerSec
);
776 WII("samplespersec",MCI_WAVE_SET_SAMPLESPERSEC
,"%lu",nSamplesPerSec
);
777 WII("alignment",MCI_WAVE_SET_BLOCKALIGN
,"%hu",nBlockAlign
);
778 WII("bitspersample",MCI_WAVE_SET_BITSPERSAMPLE
,"%hu",wBitsPerSample
);
779 WII("input",MCI_WAVE_INPUT
,"%hu",wInput
);
780 WII("output",MCI_WAVE_OUTPUT
,"%hu",wOutput
);
783 case MCI_DEVTYPE_SEQUENCER
:
784 if (!STRCMP(keywords
[i
],"master") && (i
+1<nrofkeywords
)) {
785 dwFlags
|= MCI_SEQ_SET_MASTER
;
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
],"slave") && (i
+1<nrofkeywords
)) {
798 dwFlags
|= MCI_SEQ_SET_SLAVE
;
799 if (!STRCMP(keywords
[i
+1],"midi"))
800 pU
->seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
801 if (!STRCMP(keywords
[i
+1],"file"))
802 pU
->seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
803 if (!STRCMP(keywords
[i
+1],"smpte"))
804 pU
->seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
805 if (!STRCMP(keywords
[i
+1],"none"))
806 pU
->seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
810 if ( !STRCMP(keywords
[i
],"port") &&
811 (i
+1<nrofkeywords
) &&
812 !STRCMP(keywords
[i
+1],"mapper")
814 pU
->seqsetParams
.dwPort
=-1;/* FIXME:not sure*/
815 dwFlags
|= MCI_SEQ_SET_PORT
;
819 #define SII(str,flag,element) \
820 if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
821 sscanf(keywords[i+1],"%ld",&(pU->seqsetParams. element ));\
826 SII("tempo",MCI_SEQ_SET_TEMPO
,dwTempo
);
827 SII("port",MCI_SEQ_SET_PORT
,dwPort
);
828 SII("offset",MCI_SEQ_SET_PORT
,dwOffset
);
833 return MCIERR_MISSING_STRING_ARGUMENT
;
834 _MCI_CALL_DRIVER( MCI_SET
, SEGPTR_GET(pU
) );
841 * "off" disable break
842 * "on <keyid>" enable break on key with keyid
843 * (I strongly suspect, that there is another parameter:
845 * but I don't see it mentioned in my documentation.
849 MCISTR_Break(_MCISTR_PROTO_
)
851 MCI_BREAK_PARMS
*breakParams
= SEGPTR_NEW(MCI_BREAK_PARMS
);
854 if (!breakParams
) return 0;
855 /*breakParams.hwndBreak ? */
856 for (i
= 0; i
< nrofkeywords
; i
++)
858 FLAG1("off",MCI_BREAK_OFF
);
859 if (!strcmp(keywords
[i
],"on") && (nrofkeywords
>i
+1)) {
860 dwFlags
&=~MCI_BREAK_OFF
;
861 dwFlags
|=MCI_BREAK_KEY
;
862 sscanf(keywords
[i
+1],"%d",&(breakParams
->nVirtKey
));
867 _MCI_CALL_DRIVER( MCI_BREAK
, SEGPTR_GET(breakParams
) );
868 SEGPTR_FREE(breakParams
);
872 #define ITEM1(str,item,xtype) \
873 if (!STRCMP(keywords[i],str)) {\
874 gdcParams->dwItem = item;\
879 #define ITEM2(str1,str2,item,xtype) \
880 if ( !STRCMP(keywords[i],str1) &&\
881 (i+1<nrofkeywords) &&\
882 !STRCMP(keywords[i+1],str2)\
884 gdcParams->dwItem = item;\
889 #define ITEM3(str1,str2,str3,item,xtype) \
890 if ( !STRCMP(keywords[i],str1) &&\
891 (i+2<nrofkeywords) &&\
892 !STRCMP(keywords[i+1],str2) &&\
893 !STRCMP(keywords[i+2],str3)\
895 gdcParams->dwItem = item;\
900 /* get device capabilities of MCI drivers
903 * "device type" returns device name as string
904 * "has audio" returns bool
905 * "has video" returns bool
906 * "uses files" returns bool
907 * "compound device" returns bool
908 * "can record" returns bool
909 * "can play" returns bool
910 * "can eject" returns bool
911 * "can save" returns bool
913 * "palettes" returns nr of available palette entries
914 * "windows" returns nr of available windows
915 * "can reverse" returns bool
916 * "can stretch" returns bool
917 * "slow play rate" returns the slow playrate
918 * "fast play rate" returns the fast playrate
919 * "normal play rate" returns the normal playrate
921 * "windows" returns nr of available windows
922 * "can stretch" returns bool
923 * "can freeze" returns bool
925 * "cav" assume CAV discs (default if no disk inserted)
926 * "clv" assume CLV discs
927 * "can reverse" returns bool
928 * "slow play rate" returns the slow playrate
929 * "fast play rate" returns the fast playrate
930 * "normal play rate" returns the normal playrate
932 * "inputs" returns nr of inputdevices
933 * "outputs" returns nr of outputdevices
936 MCISTR_Capability(_MCISTR_PROTO_
) {
937 MCI_GETDEVCAPS_PARMS
*gdcParams
= SEGPTR_NEW(MCI_GETDEVCAPS_PARMS
);
940 gdcParams
->dwCallback
= hwndCallback
;
942 return MCIERR_MISSING_STRING_ARGUMENT
;
943 /* well , thats default */
944 dwFlags
|= MCI_GETDEVCAPS_ITEM
;
945 gdcParams
->dwItem
= 0;
947 while (i
<nrofkeywords
) {
948 ITEM2("device","type",MCI_GETDEVCAPS_DEVICE_TYPE
,_MCISTR_devtype
);
949 ITEM2("has","audio",MCI_GETDEVCAPS_HAS_AUDIO
,_MCISTR_bool
);
950 ITEM2("has","video",MCI_GETDEVCAPS_HAS_VIDEO
,_MCISTR_bool
);
951 ITEM2("uses","files",MCI_GETDEVCAPS_USES_FILES
,_MCISTR_bool
);
952 ITEM2("compound","device",MCI_GETDEVCAPS_COMPOUND_DEVICE
,_MCISTR_bool
);
953 ITEM2("can","record",MCI_GETDEVCAPS_CAN_RECORD
,_MCISTR_bool
);
954 ITEM2("can","play",MCI_GETDEVCAPS_CAN_PLAY
,_MCISTR_bool
);
955 ITEM2("can","eject",MCI_GETDEVCAPS_CAN_EJECT
,_MCISTR_bool
);
956 ITEM2("can","save",MCI_GETDEVCAPS_CAN_SAVE
,_MCISTR_bool
);
958 case MCI_DEVTYPE_ANIMATION
:
959 ITEM1("palettes",MCI_ANIM_GETDEVCAPS_PALETTES
,_MCISTR_int
);
960 ITEM1("windows",MCI_ANIM_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
961 ITEM2("can","reverse",MCI_ANIM_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
962 ITEM2("can","stretch",MCI_ANIM_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
963 ITEM3("slow","play","rate",MCI_ANIM_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
964 ITEM3("fast","play","rate",MCI_ANIM_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
965 ITEM3("normal","play","rate",MCI_ANIM_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
967 case MCI_DEVTYPE_OVERLAY
:
968 ITEM1("windows",MCI_OVLY_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
969 ITEM2("can","freeze",MCI_OVLY_GETDEVCAPS_CAN_FREEZE
,_MCISTR_bool
);
970 ITEM2("can","stretch",MCI_OVLY_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
972 case MCI_DEVTYPE_VIDEODISC
:
973 FLAG1("cav",MCI_VD_GETDEVCAPS_CAV
);
974 FLAG1("clv",MCI_VD_GETDEVCAPS_CLV
);
975 ITEM2("can","reverse",MCI_VD_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
976 ITEM3("slow","play","rate",MCI_VD_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
977 ITEM3("fast","play","rate",MCI_VD_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
978 ITEM3("normal","play","rate",MCI_VD_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
980 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
981 ITEM1("inputs",MCI_WAVE_GETDEVCAPS_INPUTS
,_MCISTR_int
);
982 ITEM1("outputs",MCI_WAVE_GETDEVCAPS_OUTPUTS
,_MCISTR_int
);
987 _MCI_CALL_DRIVER( MCI_GETDEVCAPS
, SEGPTR_GET(gdcParams
) );
988 /* no timeformat needed */
990 _MCISTR_convreturn( type
, gdcParams
->dwReturn
, lpstrReturnString
,
991 uReturnLength
, uDevTyp
, 0 );
992 SEGPTR_FREE(gdcParams
);
998 /* resumes operation of device. no arguments, no return values */
1000 MCISTR_Resume(_MCISTR_PROTO_
)
1002 MCI_GENERIC_PARMS
*genParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1004 genParams
->dwCallback
= hwndCallback
;
1005 _MCI_CALL_DRIVER( MCI_RESUME
, SEGPTR_GET(genParams
) );
1009 /* pauses operation of device. no arguments, no return values */
1011 MCISTR_Pause(_MCISTR_PROTO_
)
1013 MCI_GENERIC_PARMS
*genParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1015 genParams
->dwCallback
= hwndCallback
;
1016 _MCI_CALL_DRIVER( MCI_PAUSE
, SEGPTR_GET(genParams
) );
1020 /* stops operation of device. no arguments, no return values */
1022 MCISTR_Stop(_MCISTR_PROTO_
)
1024 MCI_GENERIC_PARMS
*genParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1026 genParams
->dwCallback
= hwndCallback
;
1027 _MCI_CALL_DRIVER( MCI_STOP
, SEGPTR_GET(genParams
) );
1031 /* starts recording.
1033 * "overwrite" overwrite existing things
1034 * "insert" insert at current position
1035 * "to <time>" record up to <time> (specified in timeformat)
1036 * "from <time>" record from <time> (specified in timeformat)
1039 MCISTR_Record(_MCISTR_PROTO_
) {
1040 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1042 MCI_RECORD_PARMS
*recordParams
= SEGPTR_NEW(MCI_RECORD_PARMS
);
1044 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1045 if (res
) return res
;
1048 case MCI_FORMAT_MILLISECONDS
:
1049 case MCI_FORMAT_FRAMES
:
1050 case MCI_FORMAT_BYTES
:
1051 case MCI_FORMAT_SAMPLES
:
1055 case MCI_FORMAT_HMS
:
1056 case MCI_FORMAT_MSF
:
1057 parsestr
="%d:%d:%d";
1060 case MCI_FORMAT_TMSF
:
1061 parsestr
="%d:%d:%d:%d";
1064 default:fprintf(stdnimp
,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef
);
1069 recordParams
->dwCallback
= hwndCallback
;
1071 while (i
<nrofkeywords
) {
1072 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1074 a
[0]=a
[1]=a
[2]=a
[3]=0;
1075 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1076 /* add up all integers we got, if we have more
1077 * shift them. (Well I should use the macros in
1078 * mmsystem.h, right).
1080 recordParams
->dwTo
=0;
1082 recordParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1086 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1087 dwFlags
|= MCI_FROM
;
1088 a
[0]=a
[1]=a
[2]=a
[3]=0;
1089 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1091 recordParams
->dwFrom
=0;
1093 recordParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1097 FLAG1("insert",MCI_RECORD_INSERT
);
1098 FLAG1("overwrite",MCI_RECORD_OVERWRITE
);
1101 _MCI_CALL_DRIVER( MCI_RECORD
, SEGPTR_GET(recordParams
) );
1102 SEGPTR_FREE(recordParams
);
1108 * "to <time>" play up to <time> (specified in set timeformat)
1109 * "from <time>" play from <time> (specified in set timeformat)
1113 * "scan" play as fast as possible (with audio disabled perhaps)
1114 * "reverse" play reverse
1115 * "speed <fps>" play with specified frames per second
1119 * "scan" play as fast as possible (with audio disabled perhaps)
1120 * "reverse" play reverse
1121 * "speed <fps>" play with specified frames per second
1124 MCISTR_Play(_MCISTR_PROTO_
) {
1125 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1128 MCI_PLAY_PARMS playParams
;
1129 MCI_VD_PLAY_PARMS vdplayParams
;
1130 MCI_ANIM_PLAY_PARMS animplayParams
;
1132 union U
*pU
= SEGPTR_NEW(union U
);
1134 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1135 if (res
) return res
;
1137 case MCI_FORMAT_MILLISECONDS
:
1138 case MCI_FORMAT_FRAMES
:
1139 case MCI_FORMAT_BYTES
:
1140 case MCI_FORMAT_SAMPLES
:
1144 case MCI_FORMAT_HMS
:
1145 case MCI_FORMAT_MSF
:
1146 parsestr
="%d:%d:%d";
1149 case MCI_FORMAT_TMSF
:
1150 parsestr
="%d:%d:%d:%d";
1153 default:fprintf(stdnimp
,"mciSendString:PLAY:unknown timeformat %d, please report.\n",timef
);
1158 pU
->playParams
.dwCallback
=hwndCallback
;
1160 while (i
<nrofkeywords
) {
1161 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1163 a
[0]=a
[1]=a
[2]=a
[3]=0;
1164 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1165 /* add up all integers we got, if we have more
1166 * shift them. (Well I should use the macros in
1167 * mmsystem.h, right).
1169 pU
->playParams
.dwTo
=0;
1171 pU
->playParams
.dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1175 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1176 dwFlags
|= MCI_FROM
;
1177 a
[0]=a
[1]=a
[2]=a
[3]=0;
1178 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1180 pU
->playParams
.dwFrom
=0;
1182 pU
->playParams
.dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1187 case MCI_DEVTYPE_VIDEODISC
:
1188 FLAG1("slow",MCI_VD_PLAY_SLOW
);
1189 FLAG1("fast",MCI_VD_PLAY_FAST
);
1190 FLAG1("scan",MCI_VD_PLAY_SCAN
);
1191 FLAG1("reverse",MCI_VD_PLAY_REVERSE
);
1192 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1193 dwFlags
|= MCI_VD_PLAY_SPEED
;
1194 sscanf(keywords
[i
+1],"%ld",&(pU
->vdplayParams
.dwSpeed
));
1199 case MCI_DEVTYPE_ANIMATION
:
1200 FLAG1("slow",MCI_ANIM_PLAY_SLOW
);
1201 FLAG1("fast",MCI_ANIM_PLAY_FAST
);
1202 FLAG1("scan",MCI_ANIM_PLAY_SCAN
);
1203 FLAG1("reverse",MCI_ANIM_PLAY_REVERSE
);
1204 if (!STRCMP(keywords
[i
],"speed") && (i
+1<nrofkeywords
)) {
1205 dwFlags
|= MCI_ANIM_PLAY_SPEED
;
1206 sscanf(keywords
[i
+1],"%ld",&(pU
->animplayParams
.dwSpeed
));
1214 _MCI_CALL_DRIVER( MCI_PLAY
, SEGPTR_GET(pU
) );
1219 /* seek to a specified position
1221 * "to start" seek to start of medium
1222 * "to end" seek to end of medium
1223 * "to <time>" seek to <time> specified in current timeformat
1226 MCISTR_Seek(_MCISTR_PROTO_
) {
1227 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1229 MCI_SEEK_PARMS
*seekParams
= SEGPTR_NEW(MCI_SEEK_PARMS
);
1231 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1232 if (res
) return res
;
1234 case MCI_FORMAT_MILLISECONDS
:
1235 case MCI_FORMAT_FRAMES
:
1236 case MCI_FORMAT_BYTES
:
1237 case MCI_FORMAT_SAMPLES
:
1241 case MCI_FORMAT_HMS
:
1242 case MCI_FORMAT_MSF
:
1243 parsestr
="%d:%d:%d";
1246 case MCI_FORMAT_TMSF
:
1247 parsestr
="%d:%d:%d:%d";
1250 default:fprintf(stdnimp
,"mciSendString:SEEK:unknown timeformat %d, please report.\n",timef
);
1255 seekParams
->dwCallback
=hwndCallback
;
1257 while (i
<nrofkeywords
) {
1258 if ( !STRCMP(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1259 if (!STRCMP(keywords
[i
+1],"start")) {
1260 dwFlags
|=MCI_SEEK_TO_START
;
1265 if (!STRCMP(keywords
[i
+1],"end")) {
1266 dwFlags
|=MCI_SEEK_TO_END
;
1273 a
[0]=a
[1]=a
[2]=a
[3]=0;
1274 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1277 seekParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1281 case MCI_DEVTYPE_VIDEODISC
:
1282 FLAG1("reverse",MCI_VD_SEEK_REVERSE
);
1287 _MCI_CALL_DRIVER( MCI_SEEK
, SEGPTR_GET(seekParams
) );
1288 SEGPTR_FREE(seekParams
);
1292 /* close media/driver */
1294 MCISTR_Close(_MCISTR_PROTO_
)
1296 MCI_GENERIC_PARMS
*closeParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1298 _MCI_CALL_DRIVER( MCI_CLOSE
, SEGPTR_GET(closeParams
) );
1299 SEGPTR_FREE(closeParams
);
1303 /* return information.
1305 * "product" return product name (human readable)
1306 * "file" return filename
1308 * "text" returns text?
1310 * "text" returns text?
1313 MCISTR_Info(_MCISTR_PROTO_
)
1315 MCI_INFO_PARMS
*infoParams
= SEGPTR_NEW(MCI_INFO_PARMS
);
1320 i
=0;while (i
<nrofkeywords
) {
1321 FLAG1("product",MCI_INFO_PRODUCT
);
1322 FLAG1("file",MCI_INFO_FILE
);
1324 case MCI_DEVTYPE_ANIMATION
:
1325 FLAG1("text",MCI_ANIM_INFO_TEXT
);
1327 case MCI_DEVTYPE_OVERLAY
:
1328 FLAG1("text",MCI_OVLY_INFO_TEXT
);
1333 if (dwFlags
== sflags
)
1334 return MCIERR_MISSING_STRING_ARGUMENT
;
1335 /* MCI driver will fill in lpstrReturn, dwRetSize.
1336 * FIXME: I don't know if this is correct behaviour
1338 _MCI_CALL_DRIVER( MCI_INFO
, SEGPTR_GET(infoParams
) );
1340 _MCI_STR(infoParams
->lpstrReturn
);
1341 SEGPTR_FREE(infoParams
);
1345 DWORD
mciSysInfo(DWORD dwFlags
,LPMCI_SYSINFO_PARMS lpParms
);
1347 /* query MCI driver itself for information
1349 * "installname" return install name of <device> (system.ini)
1350 * "quantity" return nr of installed drivers
1351 * "open" open drivers only (additional flag)
1352 * "name <nr>" return nr of devices with <devicetyp>
1353 * "name all" return nr of all devices
1355 * FIXME: mciSysInfo() is broken I think.
1358 MCISTR_Sysinfo(_MCISTR_PROTO_
) {
1359 MCI_SYSINFO_PARMS sysinfoParams
;
1362 sysinfoParams
.lpstrReturn
= lpstrReturnString
;
1363 sysinfoParams
.dwRetSize
= uReturnLength
;
1364 sysinfoParams
.wDeviceType
= uDevTyp
;
1366 while (i
<nrofkeywords
) {
1367 FLAG1("installname",MCI_SYSINFO_INSTALLNAME
);
1368 FLAG1("quantity",MCI_SYSINFO_INSTALLNAME
);
1369 FLAG1("open",MCI_SYSINFO_OPEN
);
1370 if (!strcmp(keywords
[i
],"name") && (i
+1<nrofkeywords
)) {
1371 sscanf(keywords
[i
+1],"%ld",&(sysinfoParams
.dwNumber
));
1372 dwFlags
|= MCI_SYSINFO_NAME
;
1378 res
=mciSysInfo(dwFlags
,&sysinfoParams
);
1379 if (dwFlags
& MCI_SYSINFO_QUANTITY
) {
1382 sprintf(buf
,"%ld",*(long*)PTR_SEG_TO_LIN(lpstrReturnString
));
1385 /* no need to copy anything back, mciSysInfo did it for us */
1390 * Argument: "<filename>"
1391 * Overlay: "at <left> <top> <right> <bottom>" additional
1394 MCISTR_Load(_MCISTR_PROTO_
) {
1396 MCI_LOAD_PARMS loadParams
;
1397 MCI_OVLY_LOAD_PARMS ovlyloadParams
;
1399 union U
*pU
= SEGPTR_NEW(union U
);
1404 while (i
<nrofkeywords
) {
1406 case MCI_DEVTYPE_OVERLAY
:
1407 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1408 dwFlags
|= MCI_OVLY_RECT
;
1409 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyloadParams
.rc
.left
));
1410 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyloadParams
.rc
.top
));
1411 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyloadParams
.rc
.right
));
1412 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyloadParams
.rc
.bottom
));
1413 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1418 len
+=strlen(keywords
[i
])+1;
1421 s
=(char*)SEGPTR_ALLOC(len
);
1423 while (i
<nrofkeywords
) {
1424 strcat(s
,keywords
[i
]);
1426 if (i
<nrofkeywords
) strcat(s
," ");
1428 pU
->loadParams
.lpfilename
=(LPSTR
)SEGPTR_GET(s
);
1429 dwFlags
|= MCI_LOAD_FILE
;
1430 _MCI_CALL_DRIVER( MCI_LOAD
, SEGPTR_GET(pU
) );
1437 * Argument: "<filename>"
1438 * Overlay: "at <left> <top> <right> <bottom>" additional
1441 MCISTR_Save(_MCISTR_PROTO_
) {
1443 MCI_SAVE_PARMS saveParams
;
1444 MCI_OVLY_SAVE_PARMS ovlysaveParams
;
1446 union U
*pU
= SEGPTR_NEW(union U
);
1451 while (i
<nrofkeywords
) {
1453 case MCI_DEVTYPE_OVERLAY
:
1454 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1455 dwFlags
|= MCI_OVLY_RECT
;
1456 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlysaveParams
.rc
.left
));
1457 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlysaveParams
.rc
.top
));
1458 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlysaveParams
.rc
.right
));
1459 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlysaveParams
.rc
.bottom
));
1460 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1465 len
+=strlen(keywords
[i
])+1;
1468 s
=(char*)SEGPTR_ALLOC(len
);
1470 while (i
<nrofkeywords
) {
1471 strcat(s
,keywords
[i
]);
1473 if (i
<nrofkeywords
) strcat(s
," ");
1475 pU
->saveParams
.lpfilename
=(LPSTR
)SEGPTR_GET(s
);
1476 dwFlags
|= MCI_LOAD_FILE
;
1477 _MCI_CALL_DRIVER( MCI_SAVE
, SEGPTR_GET(pU
) );
1483 /* prepare device for input/output
1484 * (only applyable to waveform audio)
1487 MCISTR_Cue(_MCISTR_PROTO_
) {
1488 MCI_GENERIC_PARMS
*cueParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1492 while (i
<nrofkeywords
) {
1494 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
1495 FLAG1("input",MCI_WAVE_INPUT
);
1496 FLAG1("output",MCI_WAVE_OUTPUT
);
1501 _MCI_CALL_DRIVER( MCI_CUE
, SEGPTR_GET(cueParams
) );
1502 SEGPTR_FREE(cueParams
);
1506 /* delete information */
1508 MCISTR_Delete(_MCISTR_PROTO_
) {
1509 int timef
,nrargs
,i
,j
,k
,a
[4],res
;
1511 MCI_WAVE_DELETE_PARMS
*deleteParams
= SEGPTR_NEW(MCI_WAVE_DELETE_PARMS
);
1513 /* only implemented for waveform audio */
1514 if (uDevTyp
!= MCI_DEVTYPE_WAVEFORM_AUDIO
)
1515 return MCIERR_UNSUPPORTED_FUNCTION
; /* well it fits */
1516 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1517 if (res
) return res
;
1519 case MCI_FORMAT_MILLISECONDS
:
1520 case MCI_FORMAT_FRAMES
:
1521 case MCI_FORMAT_BYTES
:
1522 case MCI_FORMAT_SAMPLES
:
1526 case MCI_FORMAT_HMS
:
1527 case MCI_FORMAT_MSF
:
1528 parsestr
="%d:%d:%d";
1531 case MCI_FORMAT_TMSF
:
1532 parsestr
="%d:%d:%d:%d";
1535 default:fprintf(stdnimp
,"mciSendString:DELETE:unknown timeformat %d, please report.\n",timef
);
1541 while (i
<nrofkeywords
) {
1542 if (!strcmp(keywords
[i
],"to") && (i
+1<nrofkeywords
)) {
1544 a
[0]=a
[1]=a
[2]=a
[3]=0;
1545 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1546 /* add up all integers we got, if we have more
1547 * shift them. (Well I should use the macros in
1548 * mmsystem.h, right).
1550 deleteParams
->dwTo
=0;
1552 deleteParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1556 if (!strcmp(keywords
[i
],"from") && (i
+1<nrofkeywords
)) {
1557 dwFlags
|= MCI_FROM
;
1558 a
[0]=a
[1]=a
[2]=a
[3]=0;
1559 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1561 deleteParams
->dwFrom
=0;
1563 deleteParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1569 _MCI_CALL_DRIVER( MCI_DELETE
, SEGPTR_GET(deleteParams
) );
1570 SEGPTR_FREE(deleteParams
);
1574 /* send command to device. only applies to videodisc */
1576 MCISTR_Escape(_MCISTR_PROTO_
)
1578 MCI_VD_ESCAPE_PARMS
*escapeParams
= SEGPTR_NEW(MCI_VD_ESCAPE_PARMS
);
1582 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1583 return MCIERR_UNSUPPORTED_FUNCTION
;
1585 while (i
<nrofkeywords
) {
1586 len
+=strlen(keywords
[i
])+1;
1589 s
=(char*)SEGPTR_ALLOC(len
);
1591 while (i
<nrofkeywords
) {
1592 strcat(s
,keywords
[i
]);
1594 if (i
<nrofkeywords
) strcat(s
," ");
1596 escapeParams
->lpstrCommand
= (LPSTR
)SEGPTR_GET(s
);
1597 dwFlags
|= MCI_VD_ESCAPE_STRING
;
1598 _MCI_CALL_DRIVER( MCI_ESCAPE
, SEGPTR_GET(escapeParams
) );
1600 SEGPTR_FREE(escapeParams
);
1604 /* unfreeze [part of] the overlayed video
1605 * only applyable to Overlay devices
1608 MCISTR_Unfreeze(_MCISTR_PROTO_
)
1610 MCI_OVLY_RECT_PARMS
*unfreezeParams
= SEGPTR_NEW(MCI_OVLY_RECT_PARMS
);
1613 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1614 return MCIERR_UNSUPPORTED_FUNCTION
;
1615 i
=0;while (i
<nrofkeywords
) {
1616 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1617 sscanf(keywords
[i
+1],"%hd",&(unfreezeParams
->rc
.left
));
1618 sscanf(keywords
[i
+2],"%hd",&(unfreezeParams
->rc
.top
));
1619 sscanf(keywords
[i
+3],"%hd",&(unfreezeParams
->rc
.right
));
1620 sscanf(keywords
[i
+4],"%hd",&(unfreezeParams
->rc
.bottom
));
1621 dwFlags
|= MCI_OVLY_RECT
;
1627 _MCI_CALL_DRIVER( MCI_UNFREEZE
, SEGPTR_GET(unfreezeParams
) );
1628 SEGPTR_FREE(unfreezeParams
);
1631 /* freeze [part of] the overlayed video
1632 * only applyable to Overlay devices
1635 MCISTR_Freeze(_MCISTR_PROTO_
)
1637 MCI_OVLY_RECT_PARMS
*freezeParams
= SEGPTR_NEW(MCI_OVLY_RECT_PARMS
);
1640 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1641 return MCIERR_UNSUPPORTED_FUNCTION
;
1642 i
=0;while (i
<nrofkeywords
) {
1643 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1644 sscanf(keywords
[i
+1],"%hd",&(freezeParams
->rc
.left
));
1645 sscanf(keywords
[i
+2],"%hd",&(freezeParams
->rc
.top
));
1646 sscanf(keywords
[i
+3],"%hd",&(freezeParams
->rc
.right
));
1647 sscanf(keywords
[i
+4],"%hd",&(freezeParams
->rc
.bottom
));
1648 dwFlags
|= MCI_OVLY_RECT
;
1654 _MCI_CALL_DRIVER( MCI_FREEZE
, SEGPTR_GET(freezeParams
) );
1655 SEGPTR_FREE(freezeParams
);
1659 /* copy parts of image to somewhere else
1660 * "source [at <left> <top> <right> <bottom>]" source is framebuffer [or rect]
1661 * "destination [at <left> <top> <right> <bottom>]" destination is framebuffer [or rect]
1663 * "frame [at <left> <top> <right> <bottom>]" frame is framebuffer [or rect]
1664 * where the video input is placed
1665 * "video [at <left> <top> <right> <bottom>]" video is whole video [or rect]
1666 * (defining part of input to
1669 * FIXME: This whole junk is passing multiple rectangles.
1670 * I don't know how to do that with the present interface.
1671 * (Means code below is broken)
1674 MCISTR_Put(_MCISTR_PROTO_
) {
1676 MCI_OVLY_RECT_PARMS ovlyputParams
;
1677 MCI_ANIM_RECT_PARMS animputParams
;
1679 union U
*pU
= SEGPTR_NEW(union U
);
1681 i
=0;while (i
<nrofkeywords
) {
1683 case MCI_DEVTYPE_ANIMATION
:
1684 FLAG1("source",MCI_ANIM_PUT_SOURCE
);
1685 FLAG1("destination",MCI_ANIM_PUT_DESTINATION
);
1686 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1687 sscanf(keywords
[i
+1],"%hd",&(pU
->animputParams
.rc
.left
));
1688 sscanf(keywords
[i
+2],"%hd",&(pU
->animputParams
.rc
.top
));
1689 sscanf(keywords
[i
+3],"%hd",&(pU
->animputParams
.rc
.right
));
1690 sscanf(keywords
[i
+4],"%hd",&(pU
->animputParams
.rc
.bottom
));
1691 dwFlags
|= MCI_ANIM_RECT
;
1696 case MCI_DEVTYPE_OVERLAY
:
1697 FLAG1("source",MCI_OVLY_PUT_SOURCE
);
1698 FLAG1("destination",MCI_OVLY_PUT_DESTINATION
);
1699 FLAG1("video",MCI_OVLY_PUT_VIDEO
);
1700 FLAG1("frame",MCI_OVLY_PUT_FRAME
);
1701 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1702 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyputParams
.rc
.left
));
1703 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyputParams
.rc
.top
));
1704 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyputParams
.rc
.right
));
1705 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyputParams
.rc
.bottom
));
1706 dwFlags
|= MCI_OVLY_RECT
;
1714 _MCI_CALL_DRIVER( MCI_PUT
, SEGPTR_GET(pU
) );
1719 /* palette behaviour changing
1721 * "normal" realize the palette normally
1722 * "background" realize the palette as background palette
1725 MCISTR_Realize(_MCISTR_PROTO_
)
1727 MCI_GENERIC_PARMS
*realizeParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1730 if (uDevTyp
!= MCI_DEVTYPE_ANIMATION
)
1731 return MCIERR_UNSUPPORTED_FUNCTION
;
1733 while (i
<nrofkeywords
) {
1734 FLAG1("background",MCI_ANIM_REALIZE_BKGD
);
1735 FLAG1("normal",MCI_ANIM_REALIZE_NORM
);
1738 _MCI_CALL_DRIVER( MCI_REALIZE
, SEGPTR_GET(realizeParams
) );
1739 SEGPTR_FREE(realizeParams
);
1743 /* videodisc spinning
1748 MCISTR_Spin(_MCISTR_PROTO_
)
1750 MCI_GENERIC_PARMS
*spinParams
= SEGPTR_NEW(MCI_GENERIC_PARMS
);
1753 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1754 return MCIERR_UNSUPPORTED_FUNCTION
;
1756 while (i
<nrofkeywords
) {
1757 FLAG1("up",MCI_VD_SPIN_UP
);
1758 FLAG1("down",MCI_VD_SPIN_UP
);
1761 _MCI_CALL_DRIVER( MCI_SPIN
, SEGPTR_GET(spinParams
) );
1762 SEGPTR_FREE(spinParams
);
1766 /* step single frames
1767 * "reverse" optional flag
1768 * "by <nr>" for <nr> frames
1771 MCISTR_Step(_MCISTR_PROTO_
) {
1773 MCI_ANIM_STEP_PARMS animstepParams
;
1774 MCI_VD_STEP_PARMS vdstepParams
;
1776 union U
*pU
= SEGPTR_NEW(union U
);
1780 while (i
<nrofkeywords
) {
1782 case MCI_DEVTYPE_ANIMATION
:
1783 FLAG1("reverse",MCI_ANIM_STEP_REVERSE
);
1784 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1785 sscanf(keywords
[i
+1],"%ld",&(pU
->animstepParams
.dwFrames
));
1786 dwFlags
|= MCI_ANIM_STEP_FRAMES
;
1791 case MCI_DEVTYPE_VIDEODISC
:
1792 FLAG1("reverse",MCI_VD_STEP_REVERSE
);
1793 if (!STRCMP(keywords
[i
],"by") && (i
+1<nrofkeywords
)) {
1794 sscanf(keywords
[i
+1],"%ld",&(pU
->vdstepParams
.dwFrames
));
1795 dwFlags
|= MCI_VD_STEP_FRAMES
;
1803 _MCI_CALL_DRIVER( MCI_STEP
, SEGPTR_GET(pU
) );
1808 /* update animation window
1810 * "at <left> <top> <right> <bottom>" only in this rectangle
1811 * "hdc" device context
1814 MCISTR_Update(_MCISTR_PROTO_
) {
1816 MCI_ANIM_UPDATE_PARMS
*updateParams
= SEGPTR_NEW(MCI_ANIM_UPDATE_PARMS
);
1819 while (i
<nrofkeywords
) {
1820 if (!STRCMP(keywords
[i
],"at") && (i
+4<nrofkeywords
)) {
1821 sscanf(keywords
[i
+1],"%hd",&(updateParams
->rc
.left
));
1822 sscanf(keywords
[i
+2],"%hd",&(updateParams
->rc
.top
));
1823 sscanf(keywords
[i
+3],"%hd",&(updateParams
->rc
.right
));
1824 sscanf(keywords
[i
+4],"%hd",&(updateParams
->rc
.bottom
));
1825 dwFlags
|= MCI_ANIM_RECT
;
1829 if (!STRCMP(keywords
[i
],"hdc") && (i
+1<nrofkeywords
)) {
1830 dwFlags
|= MCI_ANIM_UPDATE_HDC
;
1831 sscanf(keywords
[i
+1],"%hd",&(updateParams
->hDC
));
1837 _MCI_CALL_DRIVER( MCI_UPDATE
, SEGPTR_GET(updateParams
) );
1838 SEGPTR_FREE(updateParams
);
1842 /* where command for animation and overlay drivers.
1843 * just returns the specified rectangle as a string
1852 MCISTR_Where(_MCISTR_PROTO_
) {
1854 MCI_ANIM_RECT_PARMS animwhereParams
;
1855 MCI_OVLY_RECT_PARMS ovlywhereParams
;
1857 union U
*pU
= SEGPTR_NEW(union U
);
1861 while (i
<nrofkeywords
) {
1863 case MCI_DEVTYPE_ANIMATION
:
1864 FLAG1("source",MCI_ANIM_WHERE_SOURCE
);
1865 FLAG1("destination",MCI_ANIM_WHERE_DESTINATION
);
1867 case MCI_DEVTYPE_OVERLAY
:
1868 FLAG1("source",MCI_OVLY_WHERE_SOURCE
);
1869 FLAG1("destination",MCI_OVLY_WHERE_DESTINATION
);
1870 FLAG1("video",MCI_OVLY_WHERE_VIDEO
);
1871 FLAG1("frame",MCI_OVLY_WHERE_FRAME
);
1876 _MCI_CALL_DRIVER( MCI_WHERE
, SEGPTR_GET(pU
) );
1880 case MCI_DEVTYPE_ANIMATION
:
1881 sprintf(buf
,"%d %d %d %d",
1882 pU
->animwhereParams
.rc
.left
,
1883 pU
->animwhereParams
.rc
.top
,
1884 pU
->animwhereParams
.rc
.right
,
1885 pU
->animwhereParams
.rc
.bottom
1888 case MCI_DEVTYPE_OVERLAY
:
1889 sprintf(buf
,"%d %d %d %d",
1890 pU
->ovlywhereParams
.rc
.left
,
1891 pU
->ovlywhereParams
.rc
.top
,
1892 pU
->ovlywhereParams
.rc
.right
,
1893 pU
->ovlywhereParams
.rc
.bottom
1896 default:strcpy(buf
,"0 0 0 0");break;
1905 MCISTR_Window(_MCISTR_PROTO_
) {
1909 MCI_ANIM_WINDOW_PARMS animwindowParams
;
1910 MCI_OVLY_WINDOW_PARMS ovlywindowParams
;
1912 union U
*pU
= SEGPTR_NEW(union U
);
1916 while (i
<nrofkeywords
) {
1918 case MCI_DEVTYPE_ANIMATION
:
1919 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1920 dwFlags
|= MCI_ANIM_WINDOW_HWND
;
1921 if (!STRCMP(keywords
[i
+1],"default"))
1922 pU
->animwindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1924 sscanf(keywords
[i
+1],"%hd",&(pU
->animwindowParams
.hWnd
));
1928 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1929 dwFlags
|= MCI_ANIM_WINDOW_STATE
;
1930 if (!STRCMP(keywords
[i
+1],"hide"))
1931 pU
->animwindowParams
.nCmdShow
= SW_HIDE
;
1932 if (!STRCMP(keywords
[i
+1],"iconic"))
1933 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1934 if (!STRCMP(keywords
[i
+1],"minimized"))
1935 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1936 if (!STRCMP(keywords
[i
+1],"maximized"))
1937 pU
->animwindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1938 if (!STRCMP(keywords
[i
+1],"minimize"))
1939 pU
->animwindowParams
.nCmdShow
= SW_MINIMIZE
;
1940 if (!STRCMP(keywords
[i
+1],"normal"))
1941 pU
->animwindowParams
.nCmdShow
= SW_NORMAL
;
1942 if (!STRCMP(keywords
[i
+1],"show"))
1943 pU
->animwindowParams
.nCmdShow
= SW_SHOW
;
1944 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
1945 if (!STRCMP(keywords
[i
+2],"active"))
1946 pU
->animwindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
1947 if (!STRCMP(keywords
[i
+2],"action"))
1948 pU
->animwindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
1954 /* text is enclosed in " ... " as it seems */
1955 if (!STRCMP(keywords
[i
],"text")) {
1959 if (keywords
[i
+1][0]!='"') {
1963 dwFlags
|= MCI_ANIM_WINDOW_TEXT
;
1964 len
= strlen(keywords
[i
+1])+1;
1966 while (j
<nrofkeywords
) {
1967 len
+= strlen(keywords
[j
])+1;
1968 if (strchr(keywords
[j
],'"'))
1972 s
=(char*)xmalloc(len
);
1973 strcpy(s
,keywords
[i
+1]+1);
1977 strcat(s
,keywords
[j
]);
1979 if ((t
=strchr(s
,'"'))) *t
='\0';
1980 /* FIXME: segmented pointer? */
1981 pU
->animwindowParams
.lpstrText
= s
;
1985 FLAG1("stretch",MCI_ANIM_WINDOW_ENABLE_STRETCH
);
1987 case MCI_DEVTYPE_OVERLAY
:
1988 if (!STRCMP(keywords
[i
],"handle") && (i
+1<nrofkeywords
)) {
1989 dwFlags
|= MCI_OVLY_WINDOW_HWND
;
1990 if (!STRCMP(keywords
[i
+1],"default"))
1991 pU
->ovlywindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1993 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlywindowParams
.hWnd
));
1997 if (!STRCMP(keywords
[i
],"state") && (i
+1<nrofkeywords
)) {
1998 dwFlags
|= MCI_OVLY_WINDOW_STATE
;
1999 if (!STRCMP(keywords
[i
+1],"hide"))
2000 pU
->ovlywindowParams
.nCmdShow
= SW_HIDE
;
2001 if (!STRCMP(keywords
[i
+1],"iconic"))
2002 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
2003 if (!STRCMP(keywords
[i
+1],"minimized"))
2004 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
2005 if (!STRCMP(keywords
[i
+1],"maximized"))
2006 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
2007 if (!STRCMP(keywords
[i
+1],"minimize"))
2008 pU
->ovlywindowParams
.nCmdShow
= SW_MINIMIZE
;
2009 if (!STRCMP(keywords
[i
+1],"normal"))
2010 pU
->ovlywindowParams
.nCmdShow
= SW_NORMAL
;
2011 if (!STRCMP(keywords
[i
+1],"show"))
2012 pU
->ovlywindowParams
.nCmdShow
= SW_SHOW
;
2013 if (!STRCMP(keywords
[i
+1],"no") && (i
+2<nrofkeywords
)) {
2014 if (!STRCMP(keywords
[i
+2],"active"))
2015 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
2016 if (!STRCMP(keywords
[i
+2],"action"))
2017 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
2023 /* text is enclosed in " ... " as it seems */
2024 if (!STRCMP(keywords
[i
],"text")) {
2028 if (keywords
[i
+1][0]!='"') {
2032 dwFlags
|= MCI_OVLY_WINDOW_TEXT
;
2033 len
= strlen(keywords
[i
+1])+1;
2035 while (j
<nrofkeywords
) {
2036 len
+= strlen(keywords
[j
])+1;
2037 if (strchr(keywords
[j
],'"'))
2041 s
=(char*)xmalloc(len
);
2042 strcpy(s
,keywords
[i
+1]+1);
2046 strcat(s
,keywords
[j
]);
2048 if ((t
=strchr(s
,'"'))) *t
='\0';
2049 /* FIXME: segmented pointer? */
2050 pU
->ovlywindowParams
.lpstrText
= s
;
2054 FLAG1("stretch",MCI_OVLY_WINDOW_ENABLE_STRETCH
);
2059 _MCI_CALL_DRIVER( MCI_WINDOW
, SEGPTR_GET(pU
) );
2065 struct _MCISTR_cmdtable
{
2067 DWORD (*fun
)(_MCISTR_PROTO_
);
2068 } MCISTR_cmdtable
[]={
2069 {"break", MCISTR_Break
},
2070 {"capability", MCISTR_Capability
},
2071 {"close", MCISTR_Close
},
2072 {"cue", MCISTR_Cue
},
2073 {"delete", MCISTR_Delete
},
2074 {"escape", MCISTR_Escape
},
2075 {"freeze", MCISTR_Freeze
},
2076 {"info", MCISTR_Info
},
2077 {"load", MCISTR_Load
},
2078 {"open", MCISTR_Open
},
2079 {"pause", MCISTR_Pause
},
2080 {"play", MCISTR_Play
},
2081 {"put", MCISTR_Put
},
2082 {"realize", MCISTR_Realize
},
2083 {"record", MCISTR_Record
},
2084 {"resume", MCISTR_Resume
},
2085 {"save", MCISTR_Save
},
2086 {"seek", MCISTR_Seek
},
2087 {"set", MCISTR_Set
},
2088 {"spin", MCISTR_Spin
},
2089 {"status", MCISTR_Status
},
2090 {"step", MCISTR_Step
},
2091 {"stop", MCISTR_Stop
},
2092 {"sysinfo", MCISTR_Sysinfo
},
2093 {"unfreeze", MCISTR_Unfreeze
},
2094 {"update", MCISTR_Update
},
2095 {"where", MCISTR_Where
},
2096 {"window", MCISTR_Window
},
2099 /**************************************************************************
2100 * mciSendString [MMSYSTEM.702]
2102 /* The usercode sends a string with a command (and flags) expressed in
2103 * words in it... We do our best to call aprobiate drivers,
2104 * and return a errorcode AND a readable string (if lpstrRS!=NULL)
2105 * Info gathered by watching cool134.exe and from Borland's mcistrwh.hlp
2107 /* FIXME: "all" is a valid devicetype and we should access all devices if
2108 * it is used. (imagine "close all"). Not implemented yet.
2110 DWORD
mciSendString (LPCSTR lpstrCommand
, LPSTR lpstrReturnString
,
2111 UINT16 uReturnLength
, HWND16 hwndCallback
)
2113 char *cmd
,*dev
,*args
,**keywords
,*filename
;
2114 WORD uDevTyp
=0,wDevID
=0;
2116 int res
=0,i
,nrofkeywords
;
2118 dprintf_mci(stddeb
,"mciSendString('%s', %p, %d, %X)\n", lpstrCommand
,
2119 lpstrReturnString
, uReturnLength
, hwndCallback
2121 /* format is <command> <device> <optargs> */
2122 cmd
=strdup(lpstrCommand
);
2123 dev
=strchr(cmd
,' ');
2126 return MCIERR_MISSING_DEVICE_NAME
;
2129 args
=strchr(dev
,' ');
2130 if (args
!=NULL
) *args
++='\0';
2134 i
=1;/* nrofkeywords = nrofspaces+1 */
2136 while ((s
=strchr(s
,' '))!=NULL
) i
++,s
++;
2137 keywords
=(char**)xmalloc(sizeof(char*)*(i
+2));
2140 while (s
&& i
<nrofkeywords
) {
2148 keywords
=(char**)xmalloc(sizeof(char*));
2150 dwFlags
= 0; /* default flags */
2151 for (i
=0;i
<nrofkeywords
;) {
2152 if (!STRCMP(keywords
[i
],"type")) {
2154 dev
= keywords
[i
+1];
2155 memcpy(keywords
+i
,keywords
+(i
+2),(nrofkeywords
-i
-2)*sizeof(char *));
2159 if (!STRCMP(keywords
[i
],"wait")) {
2160 dwFlags
|= MCI_WAIT
;
2161 memcpy(keywords
+i
,keywords
+(i
+1),(nrofkeywords
-i
-1)*sizeof(char *));
2165 if (!STRCMP(keywords
[i
],"notify")) {
2166 dwFlags
|= MCI_NOTIFY
;
2167 memcpy(keywords
+i
,keywords
+(i
+1),(nrofkeywords
-i
-1)*sizeof(char *));
2174 /* determine wDevID and uDevTyp for all commands except "open" */
2175 if (STRCMP(cmd
,"open")!=0) {
2176 wDevID
= MMSYSTEM_FirstDevID();
2180 dname
=(SEGPTR
)GetOpenDrv(wDevID
)->lpstrAlias
;
2182 dname
=(SEGPTR
)GetOpenDrv(wDevID
)->lpstrDeviceType
;
2183 if ((dname
!=NULL
)&&(!STRCMP(PTR_SEG_TO_LIN(dname
),dev
)))
2185 wDevID
= MMSYSTEM_NextDevID(wDevID
);
2186 if (!MMSYSTEM_DevIDValid(wDevID
)) {
2187 dprintf_mci(stddeb
, __FILE__
":mciSendString:MAXMCIDRIVERS reached!\n");
2188 free(keywords
);free(cmd
);
2189 return MCIERR_INVALID_DEVICE_NAME
;
2192 uDevTyp
=GetDrv(wDevID
)->wType
;
2195 for (i
=0;MCISTR_cmdtable
[i
].cmd
!=NULL
;i
++) {
2196 if (!STRCMP(MCISTR_cmdtable
[i
].cmd
,cmd
)) {
2197 res
=MCISTR_cmdtable
[i
].fun(
2198 wDevID
,uDevTyp
,lpstrReturnString
,
2199 uReturnLength
,dev
,(LPSTR
*)keywords
,nrofkeywords
,
2200 dwFlags
,hwndCallback
2205 if (MCISTR_cmdtable
[i
].cmd
!=NULL
) {
2206 free(keywords
);free(cmd
);
2209 fprintf(stdnimp
,"mciSendString('%s', %p, %u, %X) // unimplemented, please report.\n", lpstrCommand
,
2210 lpstrReturnString
, uReturnLength
, hwndCallback
2212 free(keywords
);free(cmd
);
2213 return MCIERR_MISSING_COMMAND_STRING
;