1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1995 Marcus Meissner
8 /* FIXME: special commands of device drivers should be handled by those drivers
11 /* FIXME: this current implementation does not allow commands like
12 * capability <filename> can play
13 * which is allowed by the MCI standard.
20 #include <sys/ioctl.h>
21 #include "multimedia.h"
30 /* The reason why I just don't lowercase the keywords array in
31 * mciSendString is left as an exercise to the reader.
33 #define STRCMP(x,y) lstrcmpiA(x,y)
35 /* standard function parameters for all functions */
36 #define _MCISTR_PROTO_ \
37 WORD wDevID, WORD uDevTyp, LPSTR lpstrReturnString, \
38 UINT16 uReturnLength, LPCSTR dev, LPSTR *keywords, \
39 UINT16 nrofkeywords, DWORD dwFlags, HWND16 hwndCallback
41 /* copy string to return pointer including necessary checks
42 * for use in mciSendString()
46 TRACE(mci, "->returns '%s'\n", s); \
47 if (lpstrReturnString) { \
48 lstrcpynA(lpstrReturnString, s, uReturnLength); \
49 TRACE(mci, "-->'%s'\n", lpstrReturnString); \
53 /* print a DWORD in the specified timeformat */
55 _MCISTR_printtf(char *buf
, UINT16 uDevType
, DWORD timef
, DWORD val
)
59 case MCI_FORMAT_MILLISECONDS
:
60 case MCI_FORMAT_FRAMES
:
61 case MCI_FORMAT_BYTES
:
62 case MCI_FORMAT_SAMPLES
:
63 case MCI_VD_FORMAT_TRACK
:
64 /*case MCI_SEQ_FORMAT_SONGPTR: sameas MCI_VD_FORMAT_TRACK */
65 sprintf(buf
, "%ld",val
);
68 /* well, the macros have the same content*/
71 sprintf(buf
, "%d:%d:%d",
77 sprintf(buf
, "%d:%d:%d:%d",
81 MCI_TMSF_FRAME(val
) );
84 FIXME(mci
, "missing timeformat for %ld, report.\n",timef
);
85 strcpy(buf
,"0"); /* hmm */
90 /* possible different return types */
92 #define _MCISTR_time 2
93 #define _MCISTR_bool 3
94 #define _MCISTR_tfname 4
95 #define _MCISTR_mode 5
96 #define _MCISTR_divtype 6
97 #define _MCISTR_seqtype 7
98 #define _MCISTR_vdmtype 8
99 #define _MCISTR_devtype 9
102 _MCISTR_convreturn(int type
, DWORD dwReturn
, LPSTR lpstrReturnString
,
103 WORD uReturnLength
, WORD uDevTyp
, int timef
)
106 case _MCISTR_vdmtype
:
108 case MCI_VD_MEDIA_CLV
: _MCI_STR("CLV"); break;
109 case MCI_VD_MEDIA_CAV
: _MCI_STR("CAV"); break;
111 case MCI_VD_MEDIA_OTHER
:_MCI_STR("other"); break;
114 case _MCISTR_seqtype
:
116 case MCI_SEQ_NONE
: _MCI_STR("none"); break;
117 case MCI_SEQ_SMPTE
: _MCI_STR("smpte"); break;
118 case MCI_SEQ_FILE
: _MCI_STR("file"); break;
119 case MCI_SEQ_MIDI
: _MCI_STR("midi"); break;
120 default:FIXME(mci
,"missing sequencer mode %ld\n",dwReturn
);
125 case MCI_MODE_NOT_READY
:_MCI_STR("not ready"); break;
126 case MCI_MODE_STOP
: _MCI_STR("stopped"); break;
127 case MCI_MODE_PLAY
: _MCI_STR("playing"); break;
128 case MCI_MODE_RECORD
: _MCI_STR("recording"); break;
129 case MCI_MODE_SEEK
: _MCI_STR("seeking"); break;
130 case MCI_MODE_PAUSE
: _MCI_STR("paused"); break;
131 case MCI_MODE_OPEN
: _MCI_STR("open"); break;
143 sprintf(buf
,"%ld",dwReturn
);
149 _MCISTR_printtf(buf
,uDevTyp
,timef
,dwReturn
);
155 case MCI_FORMAT_MILLISECONDS
: _MCI_STR("milliseconds"); break;
156 case MCI_FORMAT_FRAMES
: _MCI_STR("frames"); break;
157 case MCI_FORMAT_BYTES
: _MCI_STR("bytes"); break;
158 case MCI_FORMAT_SAMPLES
: _MCI_STR("samples"); break;
159 case MCI_FORMAT_HMS
: _MCI_STR("hms"); break;
160 case MCI_FORMAT_MSF
: _MCI_STR("msf"); break;
161 case MCI_FORMAT_TMSF
: _MCI_STR("tmsf"); break;
163 FIXME(mci
,"missing timefmt for %d, report.\n",timef
);
167 case _MCISTR_divtype
:
169 case MCI_SEQ_DIV_PPQN
: _MCI_STR("PPQN"); break;
170 case MCI_SEQ_DIV_SMPTE_24
: _MCI_STR("SMPTE 24 frame"); break;
171 case MCI_SEQ_DIV_SMPTE_25
: _MCI_STR("SMPTE 25 frame"); break;
172 case MCI_SEQ_DIV_SMPTE_30
: _MCI_STR("SMPTE 30 frame"); break;
173 case MCI_SEQ_DIV_SMPTE_30DROP
: _MCI_STR("SMPTE 30 frame drop");break;
175 case _MCISTR_devtype
:
177 case MCI_DEVTYPE_VCR
: _MCI_STR("vcr"); break;
178 case MCI_DEVTYPE_VIDEODISC
: _MCI_STR("videodisc"); break;
179 case MCI_DEVTYPE_CD_AUDIO
: _MCI_STR("cd audio"); break;
180 case MCI_DEVTYPE_OVERLAY
: _MCI_STR("overlay"); break;
181 case MCI_DEVTYPE_DAT
: _MCI_STR("dat"); break;
182 case MCI_DEVTYPE_SCANNER
: _MCI_STR("scanner"); break;
183 case MCI_DEVTYPE_ANIMATION
: _MCI_STR("animation"); break;
184 case MCI_DEVTYPE_DIGITAL_VIDEO
: _MCI_STR("digital video"); break;
185 case MCI_DEVTYPE_OTHER
: _MCI_STR("other"); break;
186 case MCI_DEVTYPE_WAVEFORM_AUDIO
:_MCI_STR("waveform audio"); break;
187 case MCI_DEVTYPE_SEQUENCER
: _MCI_STR("sequencer"); break;
188 default:FIXME(mci
,"unknown device type %ld, report.\n",
193 FIXME(mci
,"unknown resulttype %d, report.\n",type
);
198 #define FLAG1(str,flag) \
199 if (!STRCMP(keywords[i],str)) { \
205 #define FLAG2(str1,str2,flag) \
206 if (!STRCMP(keywords[i],str1) && \
207 (i+1<nrofkeywords) && \
208 !STRCMP(keywords[i+1],str2)) { \
214 /* All known subcommands are implemented in single functions to avoid
215 * bloat and a xxxx lines long mciSendString(). All commands are of the
216 * format MCISTR_Cmd(_MCISTR_PROTO_) where _MCISTR_PROTO_ is the above
217 * defined line of arguments. (This is just for easy enhanceability.)
218 * All functions return the MCIERR_ errorvalue as DWORD. Returnvalues
219 * for the calls are in lpstrReturnString (If I mention return values
220 * in function headers, I mean returnvalues in lpstrReturnString.)
221 * Integers are sprintf("%d")ed integers. Boolean values are
222 * "true" and "false".
223 * timeformat depending values are "%d" "%d:%d" "%d:%d:%d" "%d:%d:%d:%d"
224 * FIXME: is above line correct?
226 * Preceding every function is a list of implemented/known arguments.
227 * Feel free to add missing arguments.
232 * Opens the specified MCI driver.
236 * "alias <aliasname>"
237 * "element <elementname>"
240 * "buffer <nrBytesPerSec>"
242 * "nostatic" increaste nr of nonstatic colours
243 * "parent <windowhandle>"
244 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
245 * "style child" WS_CHILD
246 * "style overlap" WS_OVERLAPPED
247 * "style popup" WS_POPUP
249 * "parent <windowhandle>"
250 * "style <mask>" bitmask of WS_xxxxx (see windows.h)
251 * "style child" WS_CHILD
252 * "style overlap" WS_OVERLAPPED
253 * "style popup" WS_POPUP
257 MCISTR_Open(_MCISTR_PROTO_
)
262 MCI_OPEN_PARMS16 openParams
;
263 MCI_WAVE_OPEN_PARMS16 waveopenParams
;
264 MCI_ANIM_OPEN_PARMS16 animopenParams
;
265 MCI_OVLY_OPEN_PARMS16 ovlyopenParams
;
267 union U
*pU
= xmalloc(sizeof(union U
));
269 pU
->openParams
.lpstrElementName
= NULL
;
273 pU
->openParams
.lpstrElementName
= strdup(s
);
274 dwFlags
|= MCI_OPEN_ELEMENT
;
276 uDevTyp
= MCI_GetDevType(dev
);
278 free(pU
->openParams
.lpstrElementName
);
280 return MCIERR_INVALID_DEVICE_NAME
;
283 pU
->openParams
.dwCallback
= hwndCallback
;
284 pU
->openParams
.wDeviceID
= wDevID
;
285 pU
->openParams
.wReserved0
= 0;
286 pU
->ovlyopenParams
.dwStyle
= 0;
287 pU
->animopenParams
.dwStyle
= 0;
288 pU
->openParams
.lpstrDeviceType
= strdup(dev
);
289 pU
->openParams
.lpstrAlias
= NULL
;
290 dwFlags
|= MCI_OPEN_TYPE
;
292 while (i
< nrofkeywords
) {
293 FLAG1("shareable",MCI_OPEN_SHAREABLE
);
294 if (!STRCMP(keywords
[i
],"alias") && (i
+1 < nrofkeywords
)) {
295 dwFlags
|= MCI_OPEN_ALIAS
;
296 pU
->openParams
.lpstrAlias
= strdup(keywords
[i
+1]);
300 if (!STRCMP(keywords
[i
],"element") && (i
+1<nrofkeywords
)) {
301 dwFlags
|= MCI_OPEN_ELEMENT
;
302 pU
->openParams
.lpstrElementName
= strdup(keywords
[i
+1]);
307 case MCI_DEVTYPE_ANIMATION
:
308 case MCI_DEVTYPE_DIGITAL_VIDEO
:
309 FLAG1("nostatic",MCI_ANIM_OPEN_NOSTATIC
);
310 if (!STRCMP(keywords
[i
],"parent") && (i
+1 < nrofkeywords
)) {
311 dwFlags
|= MCI_ANIM_OPEN_PARENT
;
312 sscanf(keywords
[i
+1], "%hu", &(pU
->animopenParams
.hWndParent
));
316 if (!STRCMP(keywords
[i
], "style") && (i
+1 < nrofkeywords
)) {
319 dwFlags
|= MCI_ANIM_OPEN_WS
;
320 if (!STRCMP(keywords
[i
+1],"popup")) {
321 pU
->animopenParams
.dwStyle
|= WS_POPUP
;
322 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
323 pU
->animopenParams
.dwStyle
|= WS_OVERLAPPED
;
324 } else if (!STRCMP(keywords
[i
+1],"child")) {
325 pU
->animopenParams
.dwStyle
|= WS_CHILD
;
326 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
327 pU
->animopenParams
.dwStyle
|= st
;
329 FIXME(mci
, "unknown 'style' keyword %s, please report.\n", keywords
[i
+1]);
334 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
335 if (!STRCMP(keywords
[i
],"buffer") && (i
+1 < nrofkeywords
)) {
336 dwFlags
|= MCI_WAVE_OPEN_BUFFER
;
337 sscanf(keywords
[i
+1], "%ld", &(pU
->waveopenParams
.dwBufferSeconds
));
340 case MCI_DEVTYPE_OVERLAY
:
341 /* looks just like anim, but without NOSTATIC */
342 if (!STRCMP(keywords
[i
], "parent") && (i
+1 < nrofkeywords
)) {
343 dwFlags
|= MCI_OVLY_OPEN_PARENT
;
344 sscanf(keywords
[i
+1], "%hd", &(pU
->ovlyopenParams
.hWndParent
));
348 if (!STRCMP(keywords
[i
],"style") && (i
+1 < nrofkeywords
)) {
351 dwFlags
|= MCI_OVLY_OPEN_WS
;
352 if (!STRCMP(keywords
[i
+1],"popup")) {
353 pU
->ovlyopenParams
.dwStyle
|= WS_POPUP
;
354 } else if (!STRCMP(keywords
[i
+1],"overlap")) {
355 pU
->ovlyopenParams
.dwStyle
|= WS_OVERLAPPED
;
356 } else if (!STRCMP(keywords
[i
+1],"child")) {
357 pU
->ovlyopenParams
.dwStyle
|= WS_CHILD
;
358 } else if (sscanf(keywords
[i
+1],"%ld",&st
)) {
359 pU
->ovlyopenParams
.dwStyle
|= st
;
361 FIXME(mci
,"unknown 'style' keyword %s, please report.\n",keywords
[i
+1]);
367 FIXME(mci
,"unknown parameter passed %s, please report.\n",
371 res
= mciSendCommandA(0, MCI_OPEN
, dwFlags
, (DWORD
)pU
);
373 free(pU
->openParams
.lpstrElementName
);
374 free(pU
->openParams
.lpstrDeviceType
);
375 free(pU
->openParams
.lpstrAlias
);
380 /* A help function for a lot of others ...
381 * for instance status/play/record/seek etc.
384 _MCISTR_determine_timeformat(LPCSTR dev
,WORD wDevID
,WORD uDevTyp
,int *timef
)
387 DWORD dwFlags
= MCI_STATUS_ITEM
;
388 MCI_STATUS_PARMS
*statusParams
= xmalloc(sizeof(MCI_STATUS_PARMS
));
390 if (!statusParams
) return 0;
391 statusParams
->dwItem
= MCI_STATUS_TIME_FORMAT
;
392 statusParams
->dwReturn
= 0;
393 res
= mciSendCommandA(wDevID
, MCI_STATUS
, dwFlags
, (DWORD
)statusParams
);
395 if (res
==0) *timef
= statusParams
->dwReturn
;
400 /* query status of MCI drivers
403 * "mode" - returns "not ready" "paused" "playing" "stopped" "open"
404 * "parked" "recording" "seeking" ....
406 * "current track" - returns current track as integer
407 * "length [track <nr>]" - returns length [of track <nr>] in current
409 * "number of tracks" - returns number of tracks as integer
410 * "position [track <nr>]" - returns position [in track <nr>] in current
412 * "ready" - checks if device is ready to play, -> bool
413 * "start position" - returns start position in timeformat
414 * "time format" - returns timeformat (list of possible values:
415 * "ms" "msf" "milliseconds" "hmsf" "tmsf" "frames"
416 * "bytes" "samples" "hms")
417 * "media present" - returns if media is present as bool
419 * "forward" - returns "true" if device is playing forwards
420 * "speed" - returns speed for device
421 * "palette handle" - returns palette handle
422 * "window handle" - returns window handle
423 * "stretch" - returns stretch bool
425 * "division type" - ? returns "PPQN" "SMPTE 24 frame"
426 * "SMPTE 25 frame" "SMPTE 30 frame" "SMPTE 30 drop frame"
427 * "tempo" - current tempo in (PPQN? speed in frames, SMPTE*? speed in hsmf)
428 * "offset" - offset in dito.
429 * "port" - midi port as integer
430 * "slave" - slave device ("midi","file","none","smpte")
431 * "master" - masterdevice (dito.)
433 * "window handle" - see animation
436 * "speed" - speed as integer
437 * "forward" - returns bool (when playing forward)
438 * "side" - returns 1 or 2
439 * "media type" - returns "CAV" "CLV" "other"
440 * "disc size" - returns "8" or "12"
442 * "input" - base queries on input set
443 * "output" - base queries on output set
444 * "format tag" - return integer format tag
445 * "channels" - return integer nr of channels
446 * "bytespersec" - return average nr of bytes/sec
447 * "samplespersec" - return nr of samples per sec
448 * "bitspersample" - return bitspersample
449 * "alignment" - return block alignment
450 * "level" - return level?
453 #define ITEM1(str,item,xtype) \
454 if (!STRCMP(keywords[i],str)) { \
455 statusParams->dwItem = item; \
460 #define ITEM2(str1,str2,item,xtype) \
461 if ( !STRCMP(keywords[i],str1) && \
462 (i+1 < nrofkeywords) && \
463 !STRCMP(keywords[i+1],str2)) { \
464 statusParams->dwItem = item; \
469 #define ITEM3(str1,str2,str3,item,xtype) \
470 if ( !STRCMP(keywords[i],str1) && \
471 (i+2 < nrofkeywords) && \
472 !STRCMP(keywords[i+1],str2) && \
473 !STRCMP(keywords[i+2],str3)) { \
474 statusParams->dwItem = item; \
481 MCISTR_Status(_MCISTR_PROTO_
) {
482 MCI_STATUS_PARMS
*statusParams
= xmalloc(sizeof(MCI_STATUS_PARMS
));
483 int type
= 0,i
,res
,timef
;
485 statusParams
->dwCallback
= hwndCallback
;
486 dwFlags
|= MCI_STATUS_ITEM
;
487 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
490 statusParams
->dwReturn
= 0;
491 statusParams
->dwItem
= 0;
494 while (i
< nrofkeywords
) {
495 if (!STRCMP(keywords
[i
],"track") && (i
+1 < nrofkeywords
)) {
496 sscanf(keywords
[i
+1],"%ld",&(statusParams
->dwTrack
));
497 dwFlags
|= MCI_TRACK
;
501 FLAG1("start",MCI_STATUS_START
);
503 ITEM2("current","track",MCI_STATUS_CURRENT_TRACK
,_MCISTR_time
);
504 ITEM2("time","format",MCI_STATUS_TIME_FORMAT
,_MCISTR_tfname
);
505 ITEM1("ready",MCI_STATUS_READY
,_MCISTR_bool
);
506 ITEM1("mode",MCI_STATUS_MODE
,_MCISTR_mode
);
507 ITEM3("number","of","tracks",MCI_STATUS_NUMBER_OF_TRACKS
,_MCISTR_int
);
508 ITEM1("length",MCI_STATUS_LENGTH
,_MCISTR_time
);
509 ITEM1("position",MCI_STATUS_POSITION
,_MCISTR_time
);
510 ITEM2("media","present",MCI_STATUS_MEDIA_PRESENT
,_MCISTR_bool
);
513 case MCI_DEVTYPE_ANIMATION
:
514 case MCI_DEVTYPE_DIGITAL_VIDEO
:
515 ITEM2("palette","handle",MCI_ANIM_STATUS_HPAL
,_MCISTR_int
);
516 ITEM2("window","handle",MCI_ANIM_STATUS_HWND
,_MCISTR_int
);
517 ITEM1("stretch",MCI_ANIM_STATUS_STRETCH
,_MCISTR_bool
);
518 ITEM1("speed",MCI_ANIM_STATUS_SPEED
,_MCISTR_int
);
519 ITEM1("forward",MCI_ANIM_STATUS_FORWARD
,_MCISTR_bool
);
521 case MCI_DEVTYPE_SEQUENCER
:
522 /* just completing the list, not working correctly */
523 ITEM2("division","type",MCI_SEQ_STATUS_DIVTYPE
,_MCISTR_divtype
);
524 /* tempo ... PPQN in frames/second, SMPTE in hmsf */
525 ITEM1("tempo",MCI_SEQ_STATUS_TEMPO
,_MCISTR_int
);
526 ITEM1("port",MCI_SEQ_STATUS_PORT
,_MCISTR_int
);
527 ITEM1("slave",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
528 ITEM1("master",MCI_SEQ_STATUS_SLAVE
,_MCISTR_seqtype
);
529 /* offset ... PPQN in frames/second, SMPTE in hmsf */
530 ITEM1("offset",MCI_SEQ_STATUS_SLAVE
,_MCISTR_time
);
532 case MCI_DEVTYPE_OVERLAY
:
533 ITEM2("window","handle",MCI_OVLY_STATUS_HWND
,_MCISTR_int
);
534 ITEM1("stretch",MCI_OVLY_STATUS_STRETCH
,_MCISTR_bool
);
536 case MCI_DEVTYPE_VIDEODISC
:
537 ITEM1("speed",MCI_VD_STATUS_SPEED
,_MCISTR_int
);
538 ITEM1("forward",MCI_VD_STATUS_FORWARD
,_MCISTR_bool
);
539 ITEM1("side",MCI_VD_STATUS_SIDE
,_MCISTR_int
);
540 ITEM2("media","type",MCI_VD_STATUS_SIDE
,_MCISTR_vdmtype
);
541 /* returns 8 or 12 */
542 ITEM2("disc","size",MCI_VD_STATUS_DISC_SIZE
,_MCISTR_int
);
544 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
545 /* I am not quite sure if foll. 2 lines are right. */
546 FLAG1("input",MCI_WAVE_INPUT
);
547 FLAG1("output",MCI_WAVE_OUTPUT
);
549 ITEM2("format","tag",MCI_WAVE_STATUS_FORMATTAG
,_MCISTR_int
);
550 ITEM1("channels",MCI_WAVE_STATUS_CHANNELS
,_MCISTR_int
);
551 ITEM1("bytespersec",MCI_WAVE_STATUS_AVGBYTESPERSEC
,_MCISTR_int
);
552 ITEM1("samplespersec",MCI_WAVE_STATUS_SAMPLESPERSEC
,_MCISTR_int
);
553 ITEM1("bitspersample",MCI_WAVE_STATUS_BITSPERSAMPLE
,_MCISTR_int
);
554 ITEM1("alignment",MCI_WAVE_STATUS_BLOCKALIGN
,_MCISTR_int
);
555 ITEM1("level",MCI_WAVE_STATUS_LEVEL
,_MCISTR_int
);
558 FIXME(mci
,"unknown keyword '%s'\n",keywords
[i
]);
561 if (!statusParams
->dwItem
)
562 return MCIERR_MISSING_STRING_ARGUMENT
;
564 res
= mciSendCommandA(wDevID
, MCI_STATUS
, dwFlags
, (DWORD
)statusParams
);
567 _MCISTR_convreturn(type
,statusParams
->dwReturn
,lpstrReturnString
,uReturnLength
,uDevTyp
,timef
);
575 /* set specified parameters in respective MCI drivers
577 * "door open" eject media or somesuch
578 * "door close" load media
579 * "time format <timeformatname>" "ms" "milliseconds" "msf" "hmsf"
580 * "tmsf" "SMPTE 24" "SMPTE 25" "SMPTE 30"
582 * "audio [all|left|right] [on|off]" sets specified audiochannel on or off
583 * "video [on|off]" sets video on/off
585 * "formattag pcm" sets format to pcm
586 * "formattag <nr>" sets integer formattag value
587 * "any input" accept input from any known source
588 * "any output" output to any known destination
589 * "input <nr>" input from source <nr>
590 * "output <nr>" output to destination <nr>
591 * "channels <nr>" sets nr of channels
592 * "bytespersec <nr>" sets average bytes per second
593 * "samplespersec <nr>" sets average samples per second (1 sample can
595 * "alignment <nr>" sets the blockalignment to <nr>
596 * "bitspersample <nr>" sets the nr of bits per sample
598 * "master [midi|file|smpte|none]" sets the midi master device
599 * "slave [midi|file|smpte|none]" sets the midi master device
600 * "port mapper" midioutput to portmapper
601 * "port <nr>" midioutput to specified port
602 * "tempo <nr>" tempo of track (depends on timeformat/divtype)
603 * "offset <nr>" start offset?
606 MCISTR_Set(_MCISTR_PROTO_
) {
608 MCI_SET_PARMS setParams
;
609 MCI_WAVE_SET_PARMS16 wavesetParams
;
610 MCI_SEQ_SET_PARMS seqsetParams
;
612 union U
*pU
= xmalloc(sizeof(union U
));
615 pU
->setParams
.dwCallback
= hwndCallback
;
617 while (i
< nrofkeywords
) {
618 FLAG2("door","open",MCI_SET_DOOR_OPEN
);
619 FLAG2("door","closed",MCI_SET_DOOR_CLOSED
);
621 if ( !STRCMP(keywords
[i
],"time") &&
622 (i
+2 < nrofkeywords
) &&
623 !STRCMP(keywords
[i
+1],"format")
625 dwFlags
|= MCI_SET_TIME_FORMAT
;
627 /* FIXME:is this a shortcut for milliseconds or
628 * minutes:seconds? */
629 if (!STRCMP(keywords
[i
+2],"ms"))
630 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
632 if (!STRCMP(keywords
[i
+2],"milliseconds"))
633 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MILLISECONDS
;
634 if (!STRCMP(keywords
[i
+2],"msf"))
635 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_MSF
;
636 if (!STRCMP(keywords
[i
+2],"hms"))
637 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_HMS
;
638 if (!STRCMP(keywords
[i
+2],"frames"))
639 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_FRAMES
;
640 if (!STRCMP(keywords
[i
+2],"track"))
641 pU
->setParams
.dwTimeFormat
= MCI_VD_FORMAT_TRACK
;
642 if (!STRCMP(keywords
[i
+2],"bytes"))
643 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_BYTES
;
644 if (!STRCMP(keywords
[i
+2],"samples"))
645 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SAMPLES
;
646 if (!STRCMP(keywords
[i
+2],"tmsf"))
647 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_TMSF
;
648 if ( !STRCMP(keywords
[i
+2],"song") &&
649 (i
+3 < nrofkeywords
) &&
650 !STRCMP(keywords
[i
+3],"pointer")
652 pU
->setParams
.dwTimeFormat
= MCI_SEQ_FORMAT_SONGPTR
;
653 if (!STRCMP(keywords
[i
+2],"smpte") && (i
+3 < nrofkeywords
)) {
654 if (!STRCMP(keywords
[i
+3],"24"))
655 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_24
;
656 if (!STRCMP(keywords
[i
+3],"25"))
657 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_25
;
658 if (!STRCMP(keywords
[i
+3],"30"))
659 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30
;
660 if (!STRCMP(keywords
[i
+3],"drop") && (i
+4 < nrofkeywords
) && !STRCMP(keywords
[i
+4],"30")) {
661 pU
->setParams
.dwTimeFormat
= MCI_FORMAT_SMPTE_30DROP
;
670 if (!STRCMP(keywords
[i
],"audio") && (i
+1 < nrofkeywords
)) {
671 dwFlags
|= MCI_SET_AUDIO
;
672 if (!STRCMP(keywords
[i
+1],"all"))
673 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_ALL
;
674 if (!STRCMP(keywords
[i
+1],"left"))
675 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_LEFT
;
676 if (!STRCMP(keywords
[i
+1],"right"))
677 pU
->setParams
.dwAudio
= MCI_SET_AUDIO_RIGHT
;
681 FLAG1("video",MCI_SET_VIDEO
);
682 FLAG1("on",MCI_SET_ON
);
683 FLAG1("off",MCI_SET_OFF
);
685 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
686 FLAG2("any","input",MCI_WAVE_SET_ANYINPUT
);
687 FLAG2("any","output",MCI_WAVE_SET_ANYOUTPUT
);
689 if ( !STRCMP(keywords
[i
],"formattag") &&
690 (i
+1 < nrofkeywords
) &&
691 !STRCMP(keywords
[i
+1],"pcm")
693 dwFlags
|= MCI_WAVE_SET_FORMATTAG
;
694 pU
->wavesetParams
.wFormatTag
= WAVE_FORMAT_PCM
;
699 /* <keyword> <integer> */
700 #define WII(str,flag,fmt,element) \
701 if (!STRCMP(keywords[i],str) && \
702 (i+1 < nrofkeywords)) { \
703 sscanf(keywords[i+1], fmt, \
704 &(pU->wavesetParams. element)); \
709 WII("formattag",MCI_WAVE_SET_FORMATTAG
,"%hu",wFormatTag
);
710 WII("channels",MCI_WAVE_SET_CHANNELS
,"%hu",nChannels
);
711 WII("bytespersec",MCI_WAVE_SET_AVGBYTESPERSEC
,"%lu",nAvgBytesPerSec
);
712 WII("samplespersec",MCI_WAVE_SET_SAMPLESPERSEC
,"%lu",nSamplesPerSec
);
713 WII("alignment",MCI_WAVE_SET_BLOCKALIGN
,"%hu",nBlockAlign
);
714 WII("bitspersample",MCI_WAVE_SET_BITSPERSAMPLE
,"%hu",wBitsPerSample
);
715 WII("input",MCI_WAVE_INPUT
,"%hu",wInput
);
716 WII("output",MCI_WAVE_OUTPUT
,"%hu",wOutput
);
719 case MCI_DEVTYPE_SEQUENCER
:
720 if (!STRCMP(keywords
[i
],"master") && (i
+1 < nrofkeywords
)) {
721 dwFlags
|= MCI_SEQ_SET_MASTER
;
722 if (!STRCMP(keywords
[i
+1],"midi"))
723 pU
->seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
724 if (!STRCMP(keywords
[i
+1],"file"))
725 pU
->seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
726 if (!STRCMP(keywords
[i
+1],"smpte"))
727 pU
->seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
728 if (!STRCMP(keywords
[i
+1],"none"))
729 pU
->seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
733 if (!STRCMP(keywords
[i
],"slave") && (i
+1 < nrofkeywords
)) {
734 dwFlags
|= MCI_SEQ_SET_SLAVE
;
735 if (!STRCMP(keywords
[i
+1],"midi"))
736 pU
->seqsetParams
.dwMaster
= MCI_SEQ_MIDI
;
737 if (!STRCMP(keywords
[i
+1],"file"))
738 pU
->seqsetParams
.dwMaster
= MCI_SEQ_FILE
;
739 if (!STRCMP(keywords
[i
+1],"smpte"))
740 pU
->seqsetParams
.dwMaster
= MCI_SEQ_SMPTE
;
741 if (!STRCMP(keywords
[i
+1],"none"))
742 pU
->seqsetParams
.dwMaster
= MCI_SEQ_NONE
;
746 if ( !STRCMP(keywords
[i
],"port") &&
747 (i
+1 < nrofkeywords
) &&
748 !STRCMP(keywords
[i
+1],"mapper")
750 pU
->seqsetParams
.dwPort
=-1;/* FIXME:not sure*/
751 dwFlags
|= MCI_SEQ_SET_PORT
;
755 #define SII(str,flag,element) \
756 if (!STRCMP(keywords[i],str) && (i+1 < nrofkeywords)) {\
757 sscanf(keywords[i+1],"%ld",&(pU->seqsetParams. element));\
762 SII("tempo",MCI_SEQ_SET_TEMPO
,dwTempo
);
763 SII("port",MCI_SEQ_SET_PORT
,dwPort
);
764 SII("offset",MCI_SEQ_SET_PORT
,dwOffset
);
769 return MCIERR_MISSING_STRING_ARGUMENT
;
770 res
= mciSendCommandA(wDevID
, MCI_SET
, dwFlags
, (DWORD
)pU
);
777 * "off" disable break
778 * "on <keyid>" enable break on key with keyid
779 * (I strongly suspect, that there is another parameter:
781 * but I don't see it mentioned in my documentation.
785 MCISTR_Break(_MCISTR_PROTO_
)
787 MCI_BREAK_PARMS16
*breakParams
= xmalloc(sizeof(MCI_BREAK_PARMS16
));
790 if (!breakParams
) return 0;
791 /*breakParams.hwndBreak ? */
792 for (i
= 0; i
< nrofkeywords
; i
++) {
793 FLAG1("off",MCI_BREAK_OFF
);
794 if (!strcmp(keywords
[i
],"on") && (nrofkeywords
>i
+1)) {
795 dwFlags
&=~MCI_BREAK_OFF
;
796 dwFlags
|=MCI_BREAK_KEY
;
797 sscanf(keywords
[i
+1],"%hd",&(breakParams
->nVirtKey
));
802 res
= mciSendCommandA(wDevID
, MCI_BREAK
, dwFlags
, (DWORD
)breakParams
);
807 #define ITEM1(str,item,xtype) \
808 if (!STRCMP(keywords[i],str)) { \
809 gdcParams->dwItem = item; \
814 #define ITEM2(str1,str2,item,xtype) \
815 if ( !STRCMP(keywords[i],str1) && \
816 (i+1 < nrofkeywords) && \
817 !STRCMP(keywords[i+1],str2)) { \
818 gdcParams->dwItem = item; \
823 #define ITEM3(str1,str2,str3,item,xtype) \
824 if ( !STRCMP(keywords[i],str1) && \
825 (i+2 < nrofkeywords) && \
826 !STRCMP(keywords[i+1],str2) && \
827 !STRCMP(keywords[i+2],str3)) { \
828 gdcParams->dwItem = item; \
834 /* get device capabilities of MCI drivers
837 * "device type" returns device name as string
838 * "has audio" returns bool
839 * "has video" returns bool
840 * "uses files" returns bool
841 * "compound device" returns bool
842 * "can record" returns bool
843 * "can play" returns bool
844 * "can eject" returns bool
845 * "can save" returns bool
847 * "palettes" returns nr of available palette entries
848 * "windows" returns nr of available windows
849 * "can reverse" returns bool
850 * "can stretch" returns bool
851 * "slow play rate" returns the slow playrate
852 * "fast play rate" returns the fast playrate
853 * "normal play rate" returns the normal playrate
855 * "windows" returns nr of available windows
856 * "can stretch" returns bool
857 * "can freeze" returns bool
859 * "cav" assume CAV discs (default if no disk inserted)
860 * "clv" assume CLV discs
861 * "can reverse" returns bool
862 * "slow play rate" returns the slow playrate
863 * "fast play rate" returns the fast playrate
864 * "normal play rate" returns the normal playrate
866 * "inputs" returns nr of inputdevices
867 * "outputs" returns nr of outputdevices
870 MCISTR_Capability(_MCISTR_PROTO_
) {
871 MCI_GETDEVCAPS_PARMS
*gdcParams
= xmalloc(sizeof(MCI_GETDEVCAPS_PARMS
));
874 gdcParams
->dwCallback
= hwndCallback
;
876 return MCIERR_MISSING_STRING_ARGUMENT
;
877 /* well , thats default */
878 dwFlags
|= MCI_GETDEVCAPS_ITEM
;
879 gdcParams
->dwItem
= 0;
881 while (i
< nrofkeywords
) {
882 ITEM2("device","type",MCI_GETDEVCAPS_DEVICE_TYPE
,_MCISTR_devtype
);
883 ITEM2("has","audio",MCI_GETDEVCAPS_HAS_AUDIO
,_MCISTR_bool
);
884 ITEM2("has","video",MCI_GETDEVCAPS_HAS_VIDEO
,_MCISTR_bool
);
885 ITEM2("uses","files",MCI_GETDEVCAPS_USES_FILES
,_MCISTR_bool
);
886 ITEM2("compound","device",MCI_GETDEVCAPS_COMPOUND_DEVICE
,_MCISTR_bool
);
887 ITEM2("can","record",MCI_GETDEVCAPS_CAN_RECORD
,_MCISTR_bool
);
888 ITEM2("can","play",MCI_GETDEVCAPS_CAN_PLAY
,_MCISTR_bool
);
889 ITEM2("can","eject",MCI_GETDEVCAPS_CAN_EJECT
,_MCISTR_bool
);
890 ITEM2("can","save",MCI_GETDEVCAPS_CAN_SAVE
,_MCISTR_bool
);
892 case MCI_DEVTYPE_ANIMATION
:
893 ITEM1("palettes",MCI_ANIM_GETDEVCAPS_PALETTES
,_MCISTR_int
);
894 ITEM1("windows",MCI_ANIM_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
895 ITEM2("can","reverse",MCI_ANIM_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
896 ITEM2("can","stretch",MCI_ANIM_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
897 ITEM3("slow","play","rate",MCI_ANIM_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
898 ITEM3("fast","play","rate",MCI_ANIM_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
899 ITEM3("normal","play","rate",MCI_ANIM_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
901 case MCI_DEVTYPE_OVERLAY
:
902 ITEM1("windows",MCI_OVLY_GETDEVCAPS_MAX_WINDOWS
,_MCISTR_int
);
903 ITEM2("can","freeze",MCI_OVLY_GETDEVCAPS_CAN_FREEZE
,_MCISTR_bool
);
904 ITEM2("can","stretch",MCI_OVLY_GETDEVCAPS_CAN_STRETCH
,_MCISTR_bool
);
906 case MCI_DEVTYPE_VIDEODISC
:
907 FLAG1("cav",MCI_VD_GETDEVCAPS_CAV
);
908 FLAG1("clv",MCI_VD_GETDEVCAPS_CLV
);
909 ITEM2("can","reverse",MCI_VD_GETDEVCAPS_CAN_REVERSE
,_MCISTR_bool
);
910 ITEM3("slow","play","rate",MCI_VD_GETDEVCAPS_SLOW_RATE
,_MCISTR_int
);
911 ITEM3("fast","play","rate",MCI_VD_GETDEVCAPS_FAST_RATE
,_MCISTR_int
);
912 ITEM3("normal","play","rate",MCI_VD_GETDEVCAPS_NORMAL_RATE
,_MCISTR_int
);
914 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
915 ITEM1("inputs",MCI_WAVE_GETDEVCAPS_INPUTS
,_MCISTR_int
);
916 ITEM1("outputs",MCI_WAVE_GETDEVCAPS_OUTPUTS
,_MCISTR_int
);
921 res
= mciSendCommandA(wDevID
, MCI_GETDEVCAPS
, dwFlags
, (DWORD
)gdcParams
);
923 /* no timeformat needed */
925 _MCISTR_convreturn(type
, gdcParams
->dwReturn
, lpstrReturnString
,
926 uReturnLength
, uDevTyp
, 0);
933 /* resumes operation of device. no arguments, no return values */
935 MCISTR_Resume(_MCISTR_PROTO_
)
937 MCI_GENERIC_PARMS
*genParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
939 genParams
->dwCallback
= hwndCallback
;
940 res
= mciSendCommandA(wDevID
, MCI_RESUME
, dwFlags
, (DWORD
)genParams
);
945 /* pauses operation of device. no arguments, no return values */
947 MCISTR_Pause(_MCISTR_PROTO_
)
949 MCI_GENERIC_PARMS
*genParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
951 genParams
->dwCallback
= hwndCallback
;
952 res
= mciSendCommandA(wDevID
, MCI_PAUSE
, dwFlags
, (DWORD
)genParams
);
957 /* stops operation of device. no arguments, no return values */
959 MCISTR_Stop(_MCISTR_PROTO_
)
961 MCI_GENERIC_PARMS
*genParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
963 genParams
->dwCallback
= hwndCallback
;
964 res
= mciSendCommandA(wDevID
, MCI_STOP
, dwFlags
, (DWORD
)genParams
);
971 * "overwrite" overwrite existing things
972 * "insert" insert at current position
973 * "to <time>" record up to <time> (specified in timeformat)
974 * "from <time>" record from <time> (specified in timeformat)
977 MCISTR_Record(_MCISTR_PROTO_
) {
978 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
980 MCI_RECORD_PARMS
*recordParams
= xmalloc(sizeof(MCI_RECORD_PARMS
));
982 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
986 case MCI_FORMAT_MILLISECONDS
:
987 case MCI_FORMAT_FRAMES
:
988 case MCI_FORMAT_BYTES
:
989 case MCI_FORMAT_SAMPLES
:
998 case MCI_FORMAT_TMSF
:
999 parsestr
="%d:%d:%d:%d";
1002 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1007 recordParams
->dwCallback
= hwndCallback
;
1009 while (i
< nrofkeywords
) {
1010 if (!strcmp(keywords
[i
],"to") && (i
+1 < nrofkeywords
)) {
1012 a
[0]=a
[1]=a
[2]=a
[3]=0;
1013 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1014 /* add up all integers we got, if we have more
1015 * shift them. (Well I should use the macros in
1016 * mmsystem.h, right).
1018 recordParams
->dwTo
=0;
1020 recordParams
->dwTo
+=a
[k
] << (8*(nrargs
-k
));
1024 if (!strcmp(keywords
[i
],"from") && (i
+1 < nrofkeywords
)) {
1025 dwFlags
|= MCI_FROM
;
1026 a
[0]=a
[1]=a
[2]=a
[3]=0;
1027 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1029 recordParams
->dwFrom
=0;
1031 recordParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1035 FLAG1("insert",MCI_RECORD_INSERT
);
1036 FLAG1("overwrite",MCI_RECORD_OVERWRITE
);
1039 res
= mciSendCommandA(wDevID
, MCI_RECORD
, dwFlags
, (DWORD
)recordParams
);
1046 * "to <time>" play up to <time> (specified in set timeformat)
1047 * "from <time>" play from <time> (specified in set timeformat)
1051 * "scan" play as fast as possible (with audio disabled perhaps)
1052 * "reverse" play reverse
1053 * "speed <fps>" play with specified frames per second
1057 * "scan" play as fast as possible (with audio disabled perhaps)
1058 * "reverse" play reverse
1059 * "speed <fps>" play with specified frames per second
1062 MCISTR_Play(_MCISTR_PROTO_
) {
1063 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1066 MCI_PLAY_PARMS playParams
;
1067 MCI_VD_PLAY_PARMS vdplayParams
;
1068 MCI_ANIM_PLAY_PARMS animplayParams
;
1070 union U
*pU
= xmalloc(sizeof(union U
));
1072 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1073 if (res
) return res
;
1075 case MCI_FORMAT_MILLISECONDS
:
1076 case MCI_FORMAT_FRAMES
:
1077 case MCI_FORMAT_BYTES
:
1078 case MCI_FORMAT_SAMPLES
:
1082 case MCI_FORMAT_HMS
:
1083 case MCI_FORMAT_MSF
:
1084 parsestr
="%d:%d:%d";
1087 case MCI_FORMAT_TMSF
:
1088 parsestr
="%d:%d:%d:%d";
1091 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1096 pU
->playParams
.dwCallback
=hwndCallback
;
1098 while (i
< nrofkeywords
) {
1099 if (!strcmp(keywords
[i
],"to") && (i
+1 < nrofkeywords
)) {
1101 a
[0]=a
[1]=a
[2]=a
[3]=0;
1102 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1103 /* add up all integers we got, if we have more
1104 * shift them. (Well I should use the macros in
1105 * mmsystem.h, right).
1107 pU
->playParams
.dwTo
=0;
1109 pU
->playParams
.dwTo
+=a
[k
] << (8*(nrargs
-k
));
1113 if (!strcmp(keywords
[i
],"from") && (i
+1 < nrofkeywords
)) {
1114 dwFlags
|= MCI_FROM
;
1115 a
[0]=a
[1]=a
[2]=a
[3]=0;
1116 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1118 pU
->playParams
.dwFrom
=0;
1120 pU
->playParams
.dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1125 case MCI_DEVTYPE_VIDEODISC
:
1126 FLAG1("slow",MCI_VD_PLAY_SLOW
);
1127 FLAG1("fast",MCI_VD_PLAY_FAST
);
1128 FLAG1("scan",MCI_VD_PLAY_SCAN
);
1129 FLAG1("reverse",MCI_VD_PLAY_REVERSE
);
1130 if (!STRCMP(keywords
[i
],"speed") && (i
+1 < nrofkeywords
)) {
1131 dwFlags
|= MCI_VD_PLAY_SPEED
;
1132 sscanf(keywords
[i
+1],"%ld",&(pU
->vdplayParams
.dwSpeed
));
1137 case MCI_DEVTYPE_ANIMATION
:
1138 FLAG1("slow",MCI_ANIM_PLAY_SLOW
);
1139 FLAG1("fast",MCI_ANIM_PLAY_FAST
);
1140 FLAG1("scan",MCI_ANIM_PLAY_SCAN
);
1141 FLAG1("reverse",MCI_ANIM_PLAY_REVERSE
);
1142 if (!STRCMP(keywords
[i
],"speed") && (i
+1 < nrofkeywords
)) {
1143 dwFlags
|= MCI_ANIM_PLAY_SPEED
;
1144 sscanf(keywords
[i
+1],"%ld",&(pU
->animplayParams
.dwSpeed
));
1152 res
= mciSendCommandA(wDevID
, MCI_PLAY
, dwFlags
, (DWORD
)pU
);
1157 /* seek to a specified position
1159 * "to start" seek to start of medium
1160 * "to end" seek to end of medium
1161 * "to <time>" seek to <time> specified in current timeformat
1164 MCISTR_Seek(_MCISTR_PROTO_
) {
1165 int i
,res
,timef
,nrargs
,j
,k
,a
[4];
1167 MCI_SEEK_PARMS
*seekParams
= xmalloc(sizeof(MCI_SEEK_PARMS
));
1169 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1170 if (res
) return res
;
1172 case MCI_FORMAT_MILLISECONDS
:
1173 case MCI_FORMAT_FRAMES
:
1174 case MCI_FORMAT_BYTES
:
1175 case MCI_FORMAT_SAMPLES
:
1179 case MCI_FORMAT_HMS
:
1180 case MCI_FORMAT_MSF
:
1181 parsestr
="%d:%d:%d";
1184 case MCI_FORMAT_TMSF
:
1185 parsestr
="%d:%d:%d:%d";
1188 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1193 seekParams
->dwCallback
=hwndCallback
;
1195 while (i
< nrofkeywords
) {
1196 if ( !STRCMP(keywords
[i
],"to") && (i
+1 < nrofkeywords
)) {
1197 if (!STRCMP(keywords
[i
+1],"start")) {
1198 dwFlags
|=MCI_SEEK_TO_START
;
1203 if (!STRCMP(keywords
[i
+1],"end")) {
1204 dwFlags
|=MCI_SEEK_TO_END
;
1211 a
[0]=a
[1]=a
[2]=a
[3]=0;
1212 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1215 seekParams
->dwTo
+=a
[k
] << (8*(nrargs
-k
));
1219 case MCI_DEVTYPE_VIDEODISC
:
1220 FLAG1("reverse",MCI_VD_SEEK_REVERSE
);
1225 res
= mciSendCommandA(wDevID
, MCI_SEEK
, dwFlags
, (DWORD
)seekParams
);
1230 /* close media/driver */
1232 MCISTR_Close(_MCISTR_PROTO_
)
1234 MCI_GENERIC_PARMS
* closeParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1237 res
= mciSendCommandA(wDevID
, MCI_CLOSE
, dwFlags
, (DWORD
)closeParams
);
1242 /* return information.
1244 * "product" return product name (human readable)
1245 * "file" return filename
1247 * "text" returns text?
1249 * "text" returns text?
1252 MCISTR_Info(_MCISTR_PROTO_
)
1254 MCI_INFO_PARMS16
* infoParams
= xmalloc(sizeof(MCI_INFO_PARMS16
));
1260 while (i
< nrofkeywords
) {
1261 FLAG1("product",MCI_INFO_PRODUCT
);
1262 FLAG1("file",MCI_INFO_FILE
);
1264 case MCI_DEVTYPE_ANIMATION
:
1265 FLAG1("text",MCI_ANIM_INFO_TEXT
);
1267 case MCI_DEVTYPE_OVERLAY
:
1268 FLAG1("text",MCI_OVLY_INFO_TEXT
);
1273 if (dwFlags
== sflags
)
1274 return MCIERR_MISSING_STRING_ARGUMENT
;
1275 /* MCI driver will fill in lpstrReturn, dwRetSize.
1276 * FIXME: I don't know if this is correct behaviour
1278 res
= mciSendCommandA(wDevID
, MCI_INFO
, dwFlags
, (DWORD
)infoParams
);
1280 _MCI_STR(infoParams
->lpstrReturn
);
1285 /* query MCI driver itself for information
1287 * "installname" return install name of <device> (system.ini)
1288 * "quantity" return nr of installed drivers
1289 * "open" open drivers only (additional flag)
1290 * "name <nr>" return nr of devices with <devicetyp>
1291 * "name all" return nr of all devices
1293 * FIXME: mciSysInfo16() is broken I think.
1296 MCISTR_Sysinfo(_MCISTR_PROTO_
) {
1297 MCI_SYSINFO_PARMS16 sysinfoParams
;
1300 sysinfoParams
.lpstrReturn
= lpstrReturnString
;
1301 sysinfoParams
.dwRetSize
= uReturnLength
;
1302 sysinfoParams
.wDeviceType
= uDevTyp
;
1304 for (i
= 0; i
< nrofkeywords
; i
++) {
1305 FLAG1("installname",MCI_SYSINFO_INSTALLNAME
);
1306 FLAG1("quantity",MCI_SYSINFO_INSTALLNAME
);
1307 FLAG1("open",MCI_SYSINFO_OPEN
);
1308 if (!strcmp(keywords
[i
],"name") && (i
+1 < nrofkeywords
)) {
1309 sscanf(keywords
[i
+1],"%ld",&(sysinfoParams
.dwNumber
));
1310 dwFlags
|= MCI_SYSINFO_NAME
;
1314 res
= mciSendCommand16(0, MCI_SYSINFO
, dwFlags
, (DWORD
)&sysinfoParams
);
1316 if (dwFlags
& MCI_SYSINFO_QUANTITY
) {
1319 sprintf(buf
,"%ld",*(long*)lpstrReturnString
);
1322 /* no need to copy anything back, mciSysInfo did it for us */
1327 * Argument: "<filename>"
1328 * Overlay: "at <left> <top> <right> <bottom>" additional
1331 MCISTR_Load(_MCISTR_PROTO_
) {
1333 MCI_LOAD_PARMS16 loadParams
;
1334 MCI_OVLY_LOAD_PARMS16 ovlyloadParams
;
1336 union U
*pU
= xmalloc(sizeof(union U
));
1341 while (i
< nrofkeywords
) {
1343 case MCI_DEVTYPE_OVERLAY
:
1344 if (!STRCMP(keywords
[i
],"at") && (i
+4 < nrofkeywords
)) {
1345 dwFlags
|= MCI_OVLY_RECT
;
1346 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyloadParams
.rc
.left
));
1347 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyloadParams
.rc
.top
));
1348 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyloadParams
.rc
.right
));
1349 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyloadParams
.rc
.bottom
));
1350 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1355 len
+=strlen(keywords
[i
])+1;
1358 s
=(char*)xmalloc(len
);
1360 while (i
< nrofkeywords
) {
1361 strcat(s
,keywords
[i
]);
1363 if (i
< nrofkeywords
) strcat(s
," ");
1365 pU
->loadParams
.lpfilename
=s
;
1366 dwFlags
|= MCI_LOAD_FILE
;
1367 res
= mciSendCommandA(wDevID
, MCI_LOAD
, dwFlags
, (DWORD
)pU
);
1374 * Argument: "<filename>"
1375 * Overlay: "at <left> <top> <right> <bottom>" additional
1378 MCISTR_Save(_MCISTR_PROTO_
) {
1380 MCI_SAVE_PARMS saveParams
;
1381 MCI_OVLY_SAVE_PARMS16 ovlysaveParams
;
1383 union U
*pU
= xmalloc(sizeof(union U
));
1388 while (i
< nrofkeywords
) {
1390 case MCI_DEVTYPE_OVERLAY
:
1391 if (!STRCMP(keywords
[i
],"at") && (i
+4 < nrofkeywords
)) {
1392 dwFlags
|= MCI_OVLY_RECT
;
1393 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlysaveParams
.rc
.left
));
1394 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlysaveParams
.rc
.top
));
1395 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlysaveParams
.rc
.right
));
1396 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlysaveParams
.rc
.bottom
));
1397 memcpy(keywords
+i
,keywords
+(i
+5),nrofkeywords
-(i
+5));
1402 len
+=strlen(keywords
[i
])+1;
1405 s
=(char*)xmalloc(len
);
1407 while (i
< nrofkeywords
) {
1408 strcat(s
,keywords
[i
]);
1410 if (i
< nrofkeywords
) strcat(s
," ");
1412 pU
->saveParams
.lpfilename
=s
;
1413 dwFlags
|= MCI_LOAD_FILE
;
1414 res
= mciSendCommandA(wDevID
, MCI_SAVE
, dwFlags
, (DWORD
)pU
);
1420 /* prepare device for input/output
1421 * (only applyable to waveform audio)
1424 MCISTR_Cue(_MCISTR_PROTO_
) {
1425 MCI_GENERIC_PARMS
*cueParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1428 for (i
= 0; i
< nrofkeywords
; i
++) {
1430 case MCI_DEVTYPE_WAVEFORM_AUDIO
:
1431 FLAG1("input", MCI_WAVE_INPUT
);
1432 FLAG1("output", MCI_WAVE_OUTPUT
);
1436 res
= mciSendCommandA(wDevID
, MCI_CUE
, dwFlags
, (DWORD
)cueParams
);
1441 /* delete information */
1443 MCISTR_Delete(_MCISTR_PROTO_
) {
1444 int timef
,nrargs
,i
,j
,k
,a
[4],res
;
1446 MCI_WAVE_DELETE_PARMS
*deleteParams
= xmalloc(sizeof(MCI_WAVE_DELETE_PARMS
));
1448 /* only implemented for waveform audio */
1449 if (uDevTyp
!= MCI_DEVTYPE_WAVEFORM_AUDIO
)
1450 return MCIERR_UNSUPPORTED_FUNCTION
; /* well it fits */
1451 res
= _MCISTR_determine_timeformat(dev
,wDevID
,uDevTyp
,&timef
);
1452 if (res
) return res
;
1454 case MCI_FORMAT_MILLISECONDS
:
1455 case MCI_FORMAT_FRAMES
:
1456 case MCI_FORMAT_BYTES
:
1457 case MCI_FORMAT_SAMPLES
:
1461 case MCI_FORMAT_HMS
:
1462 case MCI_FORMAT_MSF
:
1463 parsestr
="%d:%d:%d";
1466 case MCI_FORMAT_TMSF
:
1467 parsestr
="%d:%d:%d:%d";
1470 default:FIXME(mci
,"unknown timeformat %d, please report.\n",timef
);
1476 while (i
< nrofkeywords
) {
1477 if (!strcmp(keywords
[i
],"to") && (i
+1 < nrofkeywords
)) {
1479 a
[0]=a
[1]=a
[2]=a
[3]=0;
1480 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1481 /* add up all integers we got, if we have more
1482 * shift them. (Well I should use the macros in
1483 * mmsystem.h, right).
1485 deleteParams
->dwTo
=0;
1487 deleteParams
->dwTo
+=a
[k
]<<(8*(nrargs
-k
));
1491 if (!strcmp(keywords
[i
],"from") && (i
+1 < nrofkeywords
)) {
1492 dwFlags
|= MCI_FROM
;
1493 a
[0]=a
[1]=a
[2]=a
[3]=0;
1494 j
=sscanf(keywords
[i
+1],parsestr
,&a
[0],&a
[1],&a
[2],&a
[3]);
1496 deleteParams
->dwFrom
=0;
1498 deleteParams
->dwFrom
+=a
[k
]<<(8*(nrargs
-k
));
1504 res
= mciSendCommandA(wDevID
, MCI_DELETE
, dwFlags
, (DWORD
)deleteParams
);
1509 /* send command to device. only applies to videodisc */
1511 MCISTR_Escape(_MCISTR_PROTO_
)
1513 MCI_VD_ESCAPE_PARMS16
*escapeParams
= xmalloc(sizeof(MCI_VD_ESCAPE_PARMS16
));
1517 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1518 return MCIERR_UNSUPPORTED_FUNCTION
;
1520 while (i
< nrofkeywords
) {
1521 len
+=strlen(keywords
[i
])+1;
1524 s
=(char*)malloc(len
);
1526 while (i
< nrofkeywords
) {
1527 strcat(s
,keywords
[i
]);
1529 if (i
< nrofkeywords
) strcat(s
," ");
1531 escapeParams
->lpstrCommand
= s
;
1532 dwFlags
|= MCI_VD_ESCAPE_STRING
;
1533 res
= mciSendCommandA(wDevID
, MCI_ESCAPE
, dwFlags
, (DWORD
)escapeParams
);
1539 /* unfreeze [part of] the overlayed video
1540 * only applyable to Overlay devices
1543 MCISTR_Unfreeze(_MCISTR_PROTO_
)
1545 MCI_OVLY_RECT_PARMS16
*unfreezeParams
= xmalloc(sizeof(MCI_OVLY_RECT_PARMS16
));
1548 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1549 return MCIERR_UNSUPPORTED_FUNCTION
;
1550 i
=0;while (i
< nrofkeywords
) {
1551 if (!STRCMP(keywords
[i
],"at") && (i
+4 < nrofkeywords
)) {
1552 sscanf(keywords
[i
+1],"%hd",&(unfreezeParams
->rc
.left
));
1553 sscanf(keywords
[i
+2],"%hd",&(unfreezeParams
->rc
.top
));
1554 sscanf(keywords
[i
+3],"%hd",&(unfreezeParams
->rc
.right
));
1555 sscanf(keywords
[i
+4],"%hd",&(unfreezeParams
->rc
.bottom
));
1556 dwFlags
|= MCI_OVLY_RECT
;
1562 res
= mciSendCommandA(wDevID
, MCI_UNFREEZE
, dwFlags
, (DWORD
)unfreezeParams
);
1563 free(unfreezeParams
);
1566 /* freeze [part of] the overlayed video
1567 * only applyable to Overlay devices
1570 MCISTR_Freeze(_MCISTR_PROTO_
)
1572 MCI_OVLY_RECT_PARMS16
*freezeParams
= xmalloc(sizeof(MCI_OVLY_RECT_PARMS16
));
1575 if (uDevTyp
!= MCI_DEVTYPE_OVERLAY
)
1576 return MCIERR_UNSUPPORTED_FUNCTION
;
1577 i
=0;while (i
< nrofkeywords
) {
1578 if (!STRCMP(keywords
[i
],"at") && (i
+4 < nrofkeywords
)) {
1579 sscanf(keywords
[i
+1],"%hd",&(freezeParams
->rc
.left
));
1580 sscanf(keywords
[i
+2],"%hd",&(freezeParams
->rc
.top
));
1581 sscanf(keywords
[i
+3],"%hd",&(freezeParams
->rc
.right
));
1582 sscanf(keywords
[i
+4],"%hd",&(freezeParams
->rc
.bottom
));
1583 dwFlags
|= MCI_OVLY_RECT
;
1589 res
= mciSendCommandA(wDevID
, MCI_FREEZE
, dwFlags
, (DWORD
)freezeParams
);
1594 /* copy parts of image to somewhere else
1595 * "source [at <left> <top> <right> <bottom>]" source is framebuffer [or rect]
1596 * "destination [at <left> <top> <right> <bottom>]" destination is framebuffer [or rect]
1598 * "frame [at <left> <top> <right> <bottom>]" frame is framebuffer [or rect]
1599 * where the video input is placed
1600 * "video [at <left> <top> <right> <bottom>]" video is whole video [or rect]
1601 * (defining part of input to
1604 * FIXME: This whole junk is passing multiple rectangles.
1605 * I don't know how to do that with the present interface.
1606 * (Means code below is broken)
1609 MCISTR_Put(_MCISTR_PROTO_
) {
1611 MCI_OVLY_RECT_PARMS16 ovlyputParams
;
1612 MCI_ANIM_RECT_PARMS16 animputParams
;
1614 union U
*pU
= xmalloc(sizeof(union U
));
1616 i
=0;while (i
< nrofkeywords
) {
1618 case MCI_DEVTYPE_ANIMATION
:
1619 FLAG1("source",MCI_ANIM_PUT_SOURCE
);
1620 FLAG1("destination",MCI_ANIM_PUT_DESTINATION
);
1621 if (!STRCMP(keywords
[i
],"at") && (i
+4 < nrofkeywords
)) {
1622 sscanf(keywords
[i
+1],"%hd",&(pU
->animputParams
.rc
.left
));
1623 sscanf(keywords
[i
+2],"%hd",&(pU
->animputParams
.rc
.top
));
1624 sscanf(keywords
[i
+3],"%hd",&(pU
->animputParams
.rc
.right
));
1625 sscanf(keywords
[i
+4],"%hd",&(pU
->animputParams
.rc
.bottom
));
1626 dwFlags
|= MCI_ANIM_RECT
;
1631 case MCI_DEVTYPE_OVERLAY
:
1632 FLAG1("source",MCI_OVLY_PUT_SOURCE
);
1633 FLAG1("destination",MCI_OVLY_PUT_DESTINATION
);
1634 FLAG1("video",MCI_OVLY_PUT_VIDEO
);
1635 FLAG1("frame",MCI_OVLY_PUT_FRAME
);
1636 if (!STRCMP(keywords
[i
],"at") && (i
+4 < nrofkeywords
)) {
1637 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlyputParams
.rc
.left
));
1638 sscanf(keywords
[i
+2],"%hd",&(pU
->ovlyputParams
.rc
.top
));
1639 sscanf(keywords
[i
+3],"%hd",&(pU
->ovlyputParams
.rc
.right
));
1640 sscanf(keywords
[i
+4],"%hd",&(pU
->ovlyputParams
.rc
.bottom
));
1641 dwFlags
|= MCI_OVLY_RECT
;
1649 res
= mciSendCommandA(wDevID
, MCI_PUT
, dwFlags
, (DWORD
)pU
);
1654 /* palette behaviour changing
1656 * "normal" realize the palette normally
1657 * "background" realize the palette as background palette
1660 MCISTR_Realize(_MCISTR_PROTO_
)
1662 MCI_GENERIC_PARMS
*realizeParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1665 if (uDevTyp
!= MCI_DEVTYPE_ANIMATION
)
1666 return MCIERR_UNSUPPORTED_FUNCTION
;
1668 while (i
< nrofkeywords
) {
1669 FLAG1("background",MCI_ANIM_REALIZE_BKGD
);
1670 FLAG1("normal",MCI_ANIM_REALIZE_NORM
);
1673 res
= mciSendCommandA(wDevID
, MCI_REALIZE
, dwFlags
, (DWORD
)realizeParams
);
1674 free(realizeParams
);
1678 /* videodisc spinning
1683 MCISTR_Spin(_MCISTR_PROTO_
)
1685 MCI_GENERIC_PARMS
*spinParams
= xmalloc(sizeof(MCI_GENERIC_PARMS
));
1688 if (uDevTyp
!= MCI_DEVTYPE_VIDEODISC
)
1689 return MCIERR_UNSUPPORTED_FUNCTION
;
1691 while (i
< nrofkeywords
) {
1692 FLAG1("up",MCI_VD_SPIN_UP
);
1693 FLAG1("down",MCI_VD_SPIN_UP
);
1696 res
= mciSendCommandA(wDevID
, MCI_SPIN
, dwFlags
, (DWORD
)spinParams
);
1701 /* step single frames
1702 * "reverse" optional flag
1703 * "by <nr>" for <nr> frames
1706 MCISTR_Step(_MCISTR_PROTO_
) {
1708 MCI_ANIM_STEP_PARMS animstepParams
;
1709 MCI_VD_STEP_PARMS vdstepParams
;
1711 union U
*pU
= xmalloc(sizeof(union U
));
1715 while (i
< nrofkeywords
) {
1717 case MCI_DEVTYPE_ANIMATION
:
1718 FLAG1("reverse",MCI_ANIM_STEP_REVERSE
);
1719 if (!STRCMP(keywords
[i
],"by") && (i
+1 < nrofkeywords
)) {
1720 sscanf(keywords
[i
+1],"%ld",&(pU
->animstepParams
.dwFrames
));
1721 dwFlags
|= MCI_ANIM_STEP_FRAMES
;
1726 case MCI_DEVTYPE_VIDEODISC
:
1727 FLAG1("reverse",MCI_VD_STEP_REVERSE
);
1728 if (!STRCMP(keywords
[i
],"by") && (i
+1 < nrofkeywords
)) {
1729 sscanf(keywords
[i
+1],"%ld",&(pU
->vdstepParams
.dwFrames
));
1730 dwFlags
|= MCI_VD_STEP_FRAMES
;
1738 res
= mciSendCommandA(wDevID
, MCI_STEP
, dwFlags
, (DWORD
)pU
);
1743 /* update animation window
1745 * "at <left> <top> <right> <bottom>" only in this rectangle
1746 * "hdc" device context
1749 MCISTR_Update(_MCISTR_PROTO_
) {
1751 MCI_ANIM_UPDATE_PARMS16
*updateParams
= xmalloc(sizeof(MCI_ANIM_UPDATE_PARMS16
));
1754 while (i
<nrofkeywords
) {
1755 if (!STRCMP(keywords
[i
],"at") && (i
+4 < nrofkeywords
)) {
1756 sscanf(keywords
[i
+1],"%hd",&(updateParams
->rc
.left
));
1757 sscanf(keywords
[i
+2],"%hd",&(updateParams
->rc
.top
));
1758 sscanf(keywords
[i
+3],"%hd",&(updateParams
->rc
.right
));
1759 sscanf(keywords
[i
+4],"%hd",&(updateParams
->rc
.bottom
));
1760 dwFlags
|= MCI_ANIM_RECT
;
1764 if (!STRCMP(keywords
[i
],"hdc") && (i
+1 < nrofkeywords
)) {
1765 dwFlags
|= MCI_ANIM_UPDATE_HDC
;
1766 sscanf(keywords
[i
+1],"%hd",&(updateParams
->hDC
));
1772 res
= mciSendCommandA(wDevID
, MCI_UPDATE
, dwFlags
, (DWORD
)updateParams
);
1777 /* where command for animation and overlay drivers.
1778 * just returns the specified rectangle as a string
1787 MCISTR_Where(_MCISTR_PROTO_
) {
1789 MCI_ANIM_RECT_PARMS16 animwhereParams
;
1790 MCI_OVLY_RECT_PARMS16 ovlywhereParams
;
1792 union U
*pU
= xmalloc(sizeof(union U
));
1796 while (i
< nrofkeywords
) {
1798 case MCI_DEVTYPE_ANIMATION
:
1799 FLAG1("source",MCI_ANIM_WHERE_SOURCE
);
1800 FLAG1("destination",MCI_ANIM_WHERE_DESTINATION
);
1802 case MCI_DEVTYPE_OVERLAY
:
1803 FLAG1("source",MCI_OVLY_WHERE_SOURCE
);
1804 FLAG1("destination",MCI_OVLY_WHERE_DESTINATION
);
1805 FLAG1("video",MCI_OVLY_WHERE_VIDEO
);
1806 FLAG1("frame",MCI_OVLY_WHERE_FRAME
);
1811 res
= mciSendCommandA(wDevID
, MCI_WHERE
, dwFlags
, (DWORD
)pU
);
1815 case MCI_DEVTYPE_ANIMATION
:
1816 sprintf(buf
,"%d %d %d %d",
1817 pU
->animwhereParams
.rc
.left
,
1818 pU
->animwhereParams
.rc
.top
,
1819 pU
->animwhereParams
.rc
.right
,
1820 pU
->animwhereParams
.rc
.bottom
1823 case MCI_DEVTYPE_OVERLAY
:
1824 sprintf(buf
,"%d %d %d %d",
1825 pU
->ovlywhereParams
.rc
.left
,
1826 pU
->ovlywhereParams
.rc
.top
,
1827 pU
->ovlywhereParams
.rc
.right
,
1828 pU
->ovlywhereParams
.rc
.bottom
1831 default:strcpy(buf
,"0 0 0 0");break;
1840 MCISTR_Window(_MCISTR_PROTO_
) {
1844 MCI_ANIM_WINDOW_PARMS16 animwindowParams
;
1845 MCI_OVLY_WINDOW_PARMS16 ovlywindowParams
;
1847 union U
*pU
= xmalloc(sizeof(union U
));
1851 while (i
< nrofkeywords
) {
1853 case MCI_DEVTYPE_ANIMATION
:
1854 if (!STRCMP(keywords
[i
],"handle") && (i
+1 < nrofkeywords
)) {
1855 dwFlags
|= MCI_ANIM_WINDOW_HWND
;
1856 if (!STRCMP(keywords
[i
+1],"default"))
1857 pU
->animwindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1859 sscanf(keywords
[i
+1],"%hd",&(pU
->animwindowParams
.hWnd
));
1863 if (!STRCMP(keywords
[i
],"state") && (i
+1 < nrofkeywords
)) {
1864 dwFlags
|= MCI_ANIM_WINDOW_STATE
;
1865 if (!STRCMP(keywords
[i
+1],"hide"))
1866 pU
->animwindowParams
.nCmdShow
= SW_HIDE
;
1867 if (!STRCMP(keywords
[i
+1],"iconic"))
1868 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1869 if (!STRCMP(keywords
[i
+1],"minimized"))
1870 pU
->animwindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1871 if (!STRCMP(keywords
[i
+1],"maximized"))
1872 pU
->animwindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1873 if (!STRCMP(keywords
[i
+1],"minimize"))
1874 pU
->animwindowParams
.nCmdShow
= SW_MINIMIZE
;
1875 if (!STRCMP(keywords
[i
+1],"normal"))
1876 pU
->animwindowParams
.nCmdShow
= SW_NORMAL
;
1877 if (!STRCMP(keywords
[i
+1],"show"))
1878 pU
->animwindowParams
.nCmdShow
= SW_SHOW
;
1879 if (!STRCMP(keywords
[i
+1],"no") && (i
+2 < nrofkeywords
)) {
1880 if (!STRCMP(keywords
[i
+2],"active"))
1881 pU
->animwindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
1882 if (!STRCMP(keywords
[i
+2],"action"))
1883 pU
->animwindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
1889 /* text is enclosed in " ... " as it seems */
1890 if (!STRCMP(keywords
[i
],"text")) {
1894 if (keywords
[i
+1][0]!='"') {
1898 dwFlags
|= MCI_ANIM_WINDOW_TEXT
;
1899 len
= strlen(keywords
[i
+1])+1;
1901 while (j
< nrofkeywords
) {
1902 len
+= strlen(keywords
[j
])+1;
1903 if (strchr(keywords
[j
],'"'))
1907 s
=(char*)xmalloc(len
);
1908 strcpy(s
,keywords
[i
+1]+1);
1912 strcat(s
,keywords
[j
]);
1914 if ((t
=strchr(s
,'"'))) *t
='\0';
1915 /* FIXME: segmented pointer? */
1916 pU
->animwindowParams
.lpstrText
= s
;
1920 FLAG1("stretch",MCI_ANIM_WINDOW_ENABLE_STRETCH
);
1922 case MCI_DEVTYPE_OVERLAY
:
1923 if (!STRCMP(keywords
[i
],"handle") && (i
+1 < nrofkeywords
)) {
1924 dwFlags
|= MCI_OVLY_WINDOW_HWND
;
1925 if (!STRCMP(keywords
[i
+1],"default"))
1926 pU
->ovlywindowParams
.hWnd
= MCI_OVLY_WINDOW_DEFAULT
;
1928 sscanf(keywords
[i
+1],"%hd",&(pU
->ovlywindowParams
.hWnd
));
1932 if (!STRCMP(keywords
[i
],"state") && (i
+1 < nrofkeywords
)) {
1933 dwFlags
|= MCI_OVLY_WINDOW_STATE
;
1934 if (!STRCMP(keywords
[i
+1],"hide"))
1935 pU
->ovlywindowParams
.nCmdShow
= SW_HIDE
;
1936 if (!STRCMP(keywords
[i
+1],"iconic"))
1937 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINNOACTIVE
; /* correct? */
1938 if (!STRCMP(keywords
[i
+1],"minimized"))
1939 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMINIMIZED
;
1940 if (!STRCMP(keywords
[i
+1],"maximized"))
1941 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWMAXIMIZED
;
1942 if (!STRCMP(keywords
[i
+1],"minimize"))
1943 pU
->ovlywindowParams
.nCmdShow
= SW_MINIMIZE
;
1944 if (!STRCMP(keywords
[i
+1],"normal"))
1945 pU
->ovlywindowParams
.nCmdShow
= SW_NORMAL
;
1946 if (!STRCMP(keywords
[i
+1],"show"))
1947 pU
->ovlywindowParams
.nCmdShow
= SW_SHOW
;
1948 if (!STRCMP(keywords
[i
+1],"no") && (i
+2 < nrofkeywords
)) {
1949 if (!STRCMP(keywords
[i
+2],"active"))
1950 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNOACTIVATE
;
1951 if (!STRCMP(keywords
[i
+2],"action"))
1952 pU
->ovlywindowParams
.nCmdShow
= SW_SHOWNA
;/* correct?*/
1958 /* text is enclosed in " ... " as it seems */
1959 if (!STRCMP(keywords
[i
],"text")) {
1963 if (keywords
[i
+1][0]!='"') {
1967 dwFlags
|= MCI_OVLY_WINDOW_TEXT
;
1968 len
= strlen(keywords
[i
+1])+1;
1970 while (j
< nrofkeywords
) {
1971 len
+= strlen(keywords
[j
])+1;
1972 if (strchr(keywords
[j
],'"'))
1976 s
=(char*)xmalloc(len
);
1977 strcpy(s
,keywords
[i
+1]+1);
1981 strcat(s
,keywords
[j
]);
1983 if ((t
=strchr(s
,'"'))) *t
='\0';
1984 /* FIXME: segmented pointer? */
1985 pU
->ovlywindowParams
.lpstrText
= s
;
1989 FLAG1("stretch",MCI_OVLY_WINDOW_ENABLE_STRETCH
);
1994 res
= mciSendCommandA(wDevID
, MCI_WINDOW
, dwFlags
, (DWORD
)pU
);
2000 struct _MCISTR_cmdtable
{
2002 DWORD (*fun
)(_MCISTR_PROTO_
);
2003 } MCISTR_cmdtable
[]={
2004 {"break", MCISTR_Break
},
2005 {"capability", MCISTR_Capability
},
2006 {"close", MCISTR_Close
},
2007 {"cue", MCISTR_Cue
},
2008 {"delete", MCISTR_Delete
},
2009 {"escape", MCISTR_Escape
},
2010 {"freeze", MCISTR_Freeze
},
2011 {"info", MCISTR_Info
},
2012 {"load", MCISTR_Load
},
2013 {"open", MCISTR_Open
},
2014 {"pause", MCISTR_Pause
},
2015 {"play", MCISTR_Play
},
2016 {"put", MCISTR_Put
},
2017 {"realize", MCISTR_Realize
},
2018 {"record", MCISTR_Record
},
2019 {"resume", MCISTR_Resume
},
2020 {"save", MCISTR_Save
},
2021 {"seek", MCISTR_Seek
},
2022 {"set", MCISTR_Set
},
2023 {"spin", MCISTR_Spin
},
2024 {"status", MCISTR_Status
},
2025 {"step", MCISTR_Step
},
2026 {"stop", MCISTR_Stop
},
2027 {"sysinfo", MCISTR_Sysinfo
},
2028 {"unfreeze", MCISTR_Unfreeze
},
2029 {"update", MCISTR_Update
},
2030 {"where", MCISTR_Where
},
2031 {"window", MCISTR_Window
},
2035 /**************************************************************************
2036 * mciSendString16 [MMSYSTEM.702]
2038 /* The usercode sends a string with a command (and flags) expressed in
2039 * words in it... We do our best to call aprobiate drivers,
2040 * and return a errorcode AND a readable string (if lpstrRS!=NULL)
2041 * Info gathered by watching cool134.exe and from Borland's mcistrwh.hlp
2043 /* FIXME: "all" is a valid devicetype and we should access all devices if
2044 * it is used. (imagine "close all"). Not implemented yet.
2046 DWORD WINAPI
mciSendString16(LPCSTR lpstrCommand
, LPSTR lpstrReturnString
,
2047 UINT16 uReturnLength
, HWND16 hwndCallback
)
2049 char *cmd
,*dev
,*args
,**keywords
,*filename
;
2050 WORD uDevTyp
=0,wDevID
=0;
2052 int res
=0,i
,nrofkeywords
;
2054 TRACE(mci
,"('%s', %p, %d, %X)\n",
2055 lpstrCommand
, lpstrReturnString
, uReturnLength
, hwndCallback
);
2057 /* format is <command> <device> <optargs> */
2058 cmd
=strdup(lpstrCommand
);
2059 dev
=strchr(cmd
,' ');
2062 return MCIERR_MISSING_DEVICE_NAME
;
2065 args
=strchr(dev
,' ');
2066 if (args
!=NULL
) *args
++='\0';
2070 i
=1;/* nrofkeywords = nrofspaces+1 */
2072 while ((s
=strchr(s
,' '))!=NULL
) i
++,s
++;
2073 keywords
=(char**)xmalloc(sizeof(char*)*(i
+2));
2076 while (s
&& i
< nrofkeywords
) {
2084 keywords
=(char**)xmalloc(sizeof(char*));
2086 dwFlags
= 0; /* default flags */
2087 for (i
=0;i
< nrofkeywords
;) {
2088 /* take care, there is also a "device type" capability */
2089 if ((!STRCMP(keywords
[i
],"type")) && (i
< nrofkeywords
-1)) {
2091 dev
= keywords
[i
+1];
2092 memcpy(keywords
+i
,keywords
+(i
+2),(nrofkeywords
-i
-2)*sizeof(char *));
2096 if (!STRCMP(keywords
[i
],"wait")) {
2097 dwFlags
|= MCI_WAIT
;
2098 memcpy(keywords
+i
,keywords
+(i
+1),(nrofkeywords
-i
-1)*sizeof(char *));
2102 if (!STRCMP(keywords
[i
],"notify")) {
2103 dwFlags
|= MCI_NOTIFY
;
2104 memcpy(keywords
+i
,keywords
+(i
+1),(nrofkeywords
-i
-1)*sizeof(char *));
2111 /* FIXME: this code should be moved to mmsystem.c */
2112 /* determine wDevID and uDevTyp for all commands except "open" */
2113 if (STRCMP(cmd
,"open")!=0) {
2114 wDevID
= MCI_FirstDevID();
2118 dname
=MCI_GetOpenDrv(wDevID
)->lpstrAlias
;
2120 dname
=MCI_GetOpenDrv(wDevID
)->lpstrDeviceType
;
2121 if (dname
!= NULL
&& !STRCMP(dname
,dev
))
2123 wDevID
= MCI_NextDevID(wDevID
);
2124 if (!MCI_DevIDValid(wDevID
)) {
2125 TRACE(mci
, "MAXMCIDRIVERS reached!\n");
2126 free(keywords
);free(cmd
);
2127 return MCIERR_INVALID_DEVICE_NAME
;
2130 uDevTyp
=MCI_GetDrv(wDevID
)->modp
.wType
;
2134 for (i
=0;MCISTR_cmdtable
[i
].cmd
!=NULL
;i
++) {
2135 if (!STRCMP(MCISTR_cmdtable
[i
].cmd
,cmd
)) {
2136 res
=MCISTR_cmdtable
[i
].fun(
2137 wDevID
,uDevTyp
,lpstrReturnString
,
2138 uReturnLength
,dev
,(LPSTR
*)keywords
,nrofkeywords
,
2139 dwFlags
,hwndCallback
2144 if (MCISTR_cmdtable
[i
].cmd
!=NULL
) {
2145 free(keywords
);free(cmd
);
2148 FIXME(mci
,"('%s', %p, %u, %X): unimplemented, please report.\n",
2149 lpstrCommand
, lpstrReturnString
, uReturnLength
, hwndCallback
);
2150 free(keywords
);free(cmd
);
2151 return MCIERR_MISSING_COMMAND_STRING
;
2154 /**************************************************************************
2155 * mciSendStringA [MMSYSTEM.702][WINMM.51]
2157 DWORD WINAPI
mciSendStringA(LPCSTR lpstrCommand
, LPSTR lpstrReturnString
,
2158 UINT uReturnLength
, HWND hwndCallback
)
2160 return mciSendString16(lpstrCommand
, lpstrReturnString
, uReturnLength
, hwndCallback
);
2163 /**************************************************************************
2164 * mciSendStringW [WINMM.52]
2166 DWORD WINAPI
mciSendStringW(LPCWSTR lpwstrCommand
, LPSTR lpstrReturnString
,
2167 UINT uReturnLength
, HWND hwndCallback
)
2172 /* FIXME: is there something to do with lpstrReturnString ? */
2173 lpstrCommand
= HEAP_strdupWtoA(GetProcessHeap(), 0, lpwstrCommand
);
2174 ret
= mciSendString16(lpstrCommand
, lpstrReturnString
, uReturnLength
, hwndCallback
);
2175 HeapFree(GetProcessHeap(), 0, lpstrCommand
);