1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 * Sample MCI ANIMATION Wine Driver for Linux
5 * Copyright 1994 Martin Ayotte
11 #include "debugtools.h"
13 DEFAULT_DEBUG_CHANNEL(mcianim
)
15 #define ANIMFRAMES_PERSEC 30
16 #define ANIMFRAMES_PERMIN 1800
17 #define SECONDS_PERMIN 60
21 int nUseCount
; /* Incremented for each shared open */
22 BOOL16 fShareable
; /* TRUE if first open was shareable */
23 WORD wNotifyDeviceID
; /* MCI device ID with a pending notification */
24 HANDLE16 hCallback
; /* Callback handle for pending notification */
25 MCI_OPEN_PARMSA openParms
;
36 /*-----------------------------------------------------------------------*/
38 /**************************************************************************
39 * ANIM_drvOpen [internal]
41 static DWORD
ANIM_drvOpen(LPSTR str
, LPMCI_OPEN_DRIVER_PARMSA modp
)
43 WINE_MCIANIM
* wma
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(WINE_MCIANIM
));
48 wma
->wDevID
= modp
->wDeviceID
;
49 mciSetDriverData(wma
->wDevID
, (DWORD
)wma
);
50 modp
->wCustomCommandTable
= MCI_NO_COMMAND_TABLE
;
51 modp
->wType
= MCI_DEVTYPE_DIGITAL_VIDEO
;
52 return modp
->wDeviceID
;
55 /**************************************************************************
56 * ANIM_drvClose [internal]
58 static DWORD
ANIM_drvClose(DWORD dwDevID
)
60 WINE_MCIANIM
* wma
= (WINE_MCIANIM
*)mciGetDriverData(dwDevID
);
63 HeapFree(GetProcessHeap(), 0, wma
);
69 /**************************************************************************
70 * ANIM_mciGetOpenDrv [internal]
72 static WINE_MCIANIM
* ANIM_mciGetOpenDrv(UINT16 wDevID
)
74 WINE_MCIANIM
* wma
= (WINE_MCIANIM
*)mciGetDriverData(wDevID
);
76 if (wma
== NULL
|| wma
->nUseCount
== 0) {
77 WARN("Invalid wDevID=%u\n", wDevID
);
83 /**************************************************************************
84 * ANIM_mciOpen [internal]
86 static DWORD
ANIM_mciOpen(UINT16 wDevID
, DWORD dwFlags
, LPMCI_OPEN_PARMSA lpOpenParms
)
89 WINE_MCIANIM
* wma
= (WINE_MCIANIM
*)mciGetDriverData(wDevID
);
91 TRACE("(%04X, %08lX, %p);\n", wDevID
, dwFlags
, lpOpenParms
);
93 if (lpOpenParms
== NULL
) return MCIERR_INTERNAL
;
94 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
96 if (wma
->nUseCount
> 0) {
97 /* The driver already open on this channel */
98 /* If the driver was opened shareable before and this open specifies */
99 /* shareable then increment the use count */
100 if (wma
->fShareable
&& (dwFlags
& MCI_OPEN_SHAREABLE
))
103 return MCIERR_MUST_USE_SHAREABLE
;
106 wma
->fShareable
= dwFlags
& MCI_OPEN_SHAREABLE
;
109 dwDeviceID
= lpOpenParms
->wDeviceID
;
111 TRACE("wDevID=%04X\n", wDevID
);
112 /* FIXME this is not consistent with other implementations */
113 lpOpenParms
->wDeviceID
= wDevID
;
115 /*TRACE("lpParms->wDevID=%04X\n", lpParms->wDeviceID);*/
116 if (dwFlags
& MCI_OPEN_ELEMENT
) {
117 TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms
->lpstrElementName
);
118 if (lpOpenParms
->lpstrElementName
&& strlen(lpOpenParms
->lpstrElementName
) > 0) {
120 FIXME("element is not opened\n");
122 memcpy(&wma
->openParms
, lpOpenParms
, sizeof(MCI_OPEN_PARMSA
));
123 wma
->wNotifyDeviceID
= dwDeviceID
;
125 wma
->dwTimeFormat
= MCI_FORMAT_TMSF
;
129 wma
->lpdwTrackLen
= NULL
;
130 wma
->lpdwTrackPos
= NULL
;
132 Moved to mmsystem.c mciOpen routine
134 if (dwFlags & MCI_NOTIFY) {
135 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n",
136 lpParms->dwCallback);
137 mciDriverNotify((HWND16)LOWORD(lpParms->dwCallback),
138 wma->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
144 /**************************************************************************
145 * ANIM_mciClose [internal]
147 static DWORD
ANIM_mciClose(UINT16 wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
149 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
151 TRACE("(%u, %08lX, %p);\n", wDevID
, dwParam
, lpParms
);
153 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
155 if (--wma
->nUseCount
== 0) {
156 /* do the actual clean-up */
161 /**************************************************************************
162 * ANIM_mciGetDevCaps [internal]
164 static DWORD
ANIM_mciGetDevCaps(UINT16 wDevID
, DWORD dwFlags
,
165 LPMCI_GETDEVCAPS_PARMS lpParms
)
167 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
170 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
172 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
173 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
175 if (dwFlags
& MCI_GETDEVCAPS_ITEM
) {
176 TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08lX;\n", lpParms
->dwItem
);
178 switch(lpParms
->dwItem
) {
179 case MCI_GETDEVCAPS_CAN_RECORD
:
180 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
181 ret
= MCI_RESOURCE_RETURNED
;
183 case MCI_GETDEVCAPS_HAS_AUDIO
:
184 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
185 ret
= MCI_RESOURCE_RETURNED
;
187 case MCI_GETDEVCAPS_HAS_VIDEO
:
188 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
189 ret
= MCI_RESOURCE_RETURNED
;
191 case MCI_GETDEVCAPS_DEVICE_TYPE
:
192 lpParms
->dwReturn
= MAKEMCIRESOURCE(MCI_DEVTYPE_ANIMATION
, MCI_DEVTYPE_ANIMATION
);
193 ret
= MCI_RESOURCE_RETURNED
;
195 case MCI_GETDEVCAPS_USES_FILES
:
196 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
197 ret
= MCI_RESOURCE_RETURNED
;
199 case MCI_GETDEVCAPS_COMPOUND_DEVICE
:
200 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
201 ret
= MCI_RESOURCE_RETURNED
;
203 case MCI_GETDEVCAPS_CAN_EJECT
:
204 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
205 ret
= MCI_RESOURCE_RETURNED
;
207 case MCI_GETDEVCAPS_CAN_PLAY
:
208 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
209 ret
= MCI_RESOURCE_RETURNED
;
211 case MCI_GETDEVCAPS_CAN_SAVE
:
212 lpParms
->dwReturn
= MAKEMCIRESOURCE(FALSE
, MCI_FALSE
);
213 ret
= MCI_RESOURCE_RETURNED
;
216 FIXME("Unknown capability (%08lx) !\n", lpParms
->dwItem
);
217 return MCIERR_UNRECOGNIZED_COMMAND
;
220 WARN("No GETDEVCAPS_ITEM !\n");
221 return MCIERR_UNRECOGNIZED_COMMAND
;
223 TRACE("lpParms->dwReturn=%08lX;\n", lpParms
->dwReturn
);
228 /**************************************************************************
229 * ANIM_CalcTime [internal]
231 static DWORD
ANIM_CalcTime(WINE_MCIANIM
* wma
, DWORD dwFormatType
, DWORD dwFrame
, LPDWORD lpRet
)
239 TRACE("(%p, %08lX, %lu);\n", wma
, dwFormatType
, dwFrame
);
241 switch (dwFormatType
) {
242 case MCI_FORMAT_MILLISECONDS
:
243 dwTime
= dwFrame
/ ANIMFRAMES_PERSEC
* 1000;
245 TRACE("MILLISECONDS %lu\n", dwTime
);
248 wMinutes
= dwFrame
/ ANIMFRAMES_PERMIN
;
249 wSeconds
= (dwFrame
- ANIMFRAMES_PERMIN
* wMinutes
) / ANIMFRAMES_PERSEC
;
250 wFrames
= dwFrame
- ANIMFRAMES_PERMIN
* wMinutes
-
251 ANIMFRAMES_PERSEC
* wSeconds
;
252 dwTime
= MCI_MAKE_MSF(wMinutes
, wSeconds
, wFrames
);
253 TRACE("MSF %02u:%02u:%02u -> dwTime=%lu\n",wMinutes
, wSeconds
, wFrames
, dwTime
);
254 *lpRet
= MCI_COLONIZED3_RETURN
;
257 /* unknown format ! force TMSF ! ... */
258 dwFormatType
= MCI_FORMAT_TMSF
;
259 case MCI_FORMAT_TMSF
:
260 for (wTrack
= 0; wTrack
< wma
->nTracks
; wTrack
++) {
261 /* dwTime += wma->lpdwTrackLen[wTrack - 1];
262 TRACE("Adding trk#%u curpos=%u \n", dwTime);
263 if (dwTime >= dwFrame) break; */
264 if (wma
->lpdwTrackPos
[wTrack
- 1] >= dwFrame
) break;
266 wMinutes
= dwFrame
/ ANIMFRAMES_PERMIN
;
267 wSeconds
= (dwFrame
- ANIMFRAMES_PERMIN
* wMinutes
) / ANIMFRAMES_PERSEC
;
268 wFrames
= dwFrame
- ANIMFRAMES_PERMIN
* wMinutes
-
269 ANIMFRAMES_PERSEC
* wSeconds
;
270 dwTime
= MCI_MAKE_TMSF(wTrack
, wMinutes
, wSeconds
, wFrames
);
271 *lpRet
= MCI_COLONIZED4_RETURN
;
272 TRACE("%02u-%02u:%02u:%02u\n", wTrack
, wMinutes
, wSeconds
, wFrames
);
279 /**************************************************************************
280 * ANIM_CalcFrame [internal]
282 static DWORD
ANIM_CalcFrame(WINE_MCIANIM
* wma
, DWORD dwFormatType
, DWORD dwTime
)
287 TRACE("(%p, %08lX, %lu);\n", wma
, dwFormatType
, dwTime
);
289 switch (dwFormatType
) {
290 case MCI_FORMAT_MILLISECONDS
:
291 dwFrame
= dwTime
* ANIMFRAMES_PERSEC
/ 1000;
292 TRACE("MILLISECONDS %lu\n", dwFrame
);
295 TRACE("MSF %02u:%02u:%02u\n",
296 MCI_MSF_MINUTE(dwTime
), MCI_MSF_SECOND(dwTime
),
297 MCI_MSF_FRAME(dwTime
));
298 dwFrame
+= ANIMFRAMES_PERMIN
* MCI_MSF_MINUTE(dwTime
);
299 dwFrame
+= ANIMFRAMES_PERSEC
* MCI_MSF_SECOND(dwTime
);
300 dwFrame
+= MCI_MSF_FRAME(dwTime
);
303 /* unknown format ! force TMSF ! ... */
304 dwFormatType
= MCI_FORMAT_TMSF
;
305 case MCI_FORMAT_TMSF
:
306 wTrack
= MCI_TMSF_TRACK(dwTime
);
307 TRACE("TMSF %02u-%02u:%02u:%02u\n",
308 MCI_TMSF_TRACK(dwTime
), MCI_TMSF_MINUTE(dwTime
),
309 MCI_TMSF_SECOND(dwTime
), MCI_TMSF_FRAME(dwTime
));
310 TRACE("TMSF trackpos[%u]=%lu\n",
311 wTrack
, wma
->lpdwTrackPos
[wTrack
- 1]);
312 dwFrame
= wma
->lpdwTrackPos
[wTrack
- 1];
313 dwFrame
+= ANIMFRAMES_PERMIN
* MCI_TMSF_MINUTE(dwTime
);
314 dwFrame
+= ANIMFRAMES_PERSEC
* MCI_TMSF_SECOND(dwTime
);
315 dwFrame
+= MCI_TMSF_FRAME(dwTime
);
321 /**************************************************************************
322 * ANIM_mciInfo [internal]
324 static DWORD
ANIM_mciInfo(UINT16 wDevID
, DWORD dwFlags
, LPMCI_INFO_PARMS16 lpParms
)
326 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
330 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
332 if (lpParms
== NULL
|| lpParms
->lpstrReturn
== NULL
)
333 return MCIERR_NULL_PARAMETER_BLOCK
;
336 return MCIERR_INVALID_DEVICE_ID
;
338 TRACE("buf=%p, len=%lu\n", lpParms
->lpstrReturn
, lpParms
->dwRetSize
);
341 case MCI_INFO_PRODUCT
:
342 str
= "Wine's animation";
345 str
= wma
->openParms
.lpstrElementName
;
347 case MCI_ANIM_INFO_TEXT
:
348 str
= "Animation Window";
351 WARN("Don't know this info command (%lu)\n", dwFlags
);
352 return MCIERR_UNRECOGNIZED_COMMAND
;
356 if (lpParms
->dwRetSize
<= strlen(str
)) {
357 lstrcpynA(lpParms
->lpstrReturn
, str
, lpParms
->dwRetSize
- 1);
358 ret
= MCIERR_PARAM_OVERFLOW
;
360 strcpy(lpParms
->lpstrReturn
, str
);
363 *lpParms
->lpstrReturn
= 0;
368 /**************************************************************************
369 * ANIM_mciStatus [internal]
371 static DWORD
ANIM_mciStatus(UINT16 wDevID
, DWORD dwFlags
, LPMCI_STATUS_PARMS lpParms
)
373 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
376 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
378 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
379 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
381 if (dwFlags
& MCI_NOTIFY
) {
382 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
384 mciDriverNotify16((HWND16
)LOWORD(lpParms
->dwCallback
),
385 wma
->wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
387 if (dwFlags
& MCI_STATUS_ITEM
) {
388 switch(lpParms
->dwItem
) {
389 case MCI_STATUS_CURRENT_TRACK
:
390 lpParms
->dwReturn
= wma
->nCurTrack
;
391 TRACE("CURRENT_TRACK=%lu!\n", lpParms
->dwReturn
);
393 case MCI_STATUS_LENGTH
:
394 if (dwFlags
& MCI_TRACK
) {
395 TRACE("MCI_TRACK #%lu LENGTH=??? !\n", lpParms
->dwTrack
);
396 if (lpParms
->dwTrack
> wma
->nTracks
)
397 return MCIERR_OUTOFRANGE
;
398 lpParms
->dwReturn
= wma
->lpdwTrackLen
[lpParms
->dwTrack
];
401 lpParms
->dwReturn
= wma
->dwTotalLen
;
402 lpParms
->dwReturn
= ANIM_CalcTime(wma
, wma
->dwTimeFormat
, lpParms
->dwReturn
, &ret
);
403 TRACE("LENGTH=%lu !\n", lpParms
->dwReturn
);
405 case MCI_STATUS_MODE
:
406 TRACE("MCI_STATUS_MODE=%04X !\n", wma
->mode
);
407 lpParms
->dwReturn
= MAKEMCIRESOURCE(wma
->mode
, wma
->mode
);
408 ret
= MCI_RESOURCE_RETURNED
;
410 case MCI_STATUS_MEDIA_PRESENT
:
411 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
412 ret
= MCI_RESOURCE_RETURNED
;
413 TRACE("MCI_STATUS_MEDIA_PRESENT !\n");
415 case MCI_STATUS_NUMBER_OF_TRACKS
:
416 lpParms
->dwReturn
= 1;
417 TRACE("MCI_STATUS_NUMBER_OF_TRACKS = %lu !\n", lpParms
->dwReturn
);
419 case MCI_STATUS_POSITION
:
420 lpParms
->dwReturn
= wma
->dwCurFrame
;
421 if (dwFlags
& MCI_STATUS_START
) {
422 lpParms
->dwReturn
= 0;
423 TRACE("get MCI_STATUS_START !\n");
425 if (dwFlags
& MCI_TRACK
) {
426 if (lpParms
->dwTrack
> wma
->nTracks
)
427 return MCIERR_OUTOFRANGE
;
428 lpParms
->dwReturn
= wma
->lpdwTrackPos
[lpParms
->dwTrack
- 1];
429 TRACE("get MCI_TRACK #%lu !\n", lpParms
->dwTrack
);
431 lpParms
->dwReturn
= ANIM_CalcTime(wma
, wma
->dwTimeFormat
, lpParms
->dwReturn
, &ret
);
432 TRACE("MCI_STATUS_POSITION=%08lX !\n", lpParms
->dwReturn
);
434 case MCI_STATUS_READY
:
435 TRACE("MCI_STATUS_READY !\n");
436 lpParms
->dwReturn
= MAKEMCIRESOURCE(TRUE
, MCI_TRUE
);
437 ret
= MCI_RESOURCE_RETURNED
;
439 case MCI_STATUS_TIME_FORMAT
:
440 TRACE("MCI_STATUS_TIME_FORMAT !\n");
441 lpParms
->dwReturn
= MAKEMCIRESOURCE(MCI_FORMAT_MILLISECONDS
, MCI_FORMAT_MILLISECONDS
);
442 TRACE("MCI_STATUS_TIME_FORMAT => %u\n", LOWORD(lpParms
->dwReturn
));
443 ret
= MCI_RESOURCE_RETURNED
;
446 FIXME("Unknown command %08lX !\n", lpParms
->dwItem
);
447 return MCIERR_UNRECOGNIZED_COMMAND
;
450 WARN("No MCI_STATUS_ITEM !\n");
451 return MCIERR_UNRECOGNIZED_COMMAND
;
457 /**************************************************************************
458 * ANIM_mciPlay [internal]
460 static DWORD
ANIM_mciPlay(UINT16 wDevID
, DWORD dwFlags
, LPMCI_PLAY_PARMS lpParms
)
462 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
465 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
467 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
468 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
470 start
= 0; end
= wma
->dwTotalLen
;
472 if (dwFlags
& MCI_FROM
) {
473 start
= ANIM_CalcFrame(wma
, wma
->dwTimeFormat
, lpParms
->dwFrom
);
474 TRACE("MCI_FROM=%08lX -> %u \n", lpParms
->dwFrom
, start
);
476 if (dwFlags
& MCI_TO
) {
477 end
= ANIM_CalcFrame(wma
, wma
->dwTimeFormat
, lpParms
->dwTo
);
478 TRACE("MCI_TO=%08lX -> %u \n", lpParms
->dwTo
, end
);
480 wma
->mode
= MCI_MODE_PLAY
;
481 if (dwFlags
& MCI_NOTIFY
) {
482 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n",
483 lpParms
->dwCallback
);
484 mciDriverNotify16((HWND16
)LOWORD(lpParms
->dwCallback
),
485 wma
->wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
490 /**************************************************************************
491 * ANIM_mciStop [internal]
493 static DWORD
ANIM_mciStop(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
495 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
497 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
499 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
500 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
502 wma
->mode
= MCI_MODE_STOP
;
503 if (dwFlags
& MCI_NOTIFY
) {
504 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
506 mciDriverNotify16((HWND16
)LOWORD(lpParms
->dwCallback
),
507 wma
->wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
512 /**************************************************************************
513 * ANIM_mciPause [internal]
515 static DWORD
ANIM_mciPause(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
517 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
519 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
520 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
521 wma
->mode
= MCI_MODE_PAUSE
;
522 if (dwFlags
& MCI_NOTIFY
) {
523 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
525 mciDriverNotify16((HWND16
)LOWORD(lpParms
->dwCallback
),
526 wma
->wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
531 /**************************************************************************
532 * ANIM_mciResume [internal]
534 static DWORD
ANIM_mciResume(UINT16 wDevID
, DWORD dwFlags
, LPMCI_GENERIC_PARMS lpParms
)
536 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
538 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
539 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
540 wma
->mode
= MCI_MODE_STOP
;
541 if (dwFlags
& MCI_NOTIFY
) {
542 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
544 mciDriverNotify16((HWND16
)LOWORD(lpParms
->dwCallback
),
545 wma
->wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
550 /**************************************************************************
551 * ANIM_mciSeek [internal]
553 static DWORD
ANIM_mciSeek(UINT16 wDevID
, DWORD dwFlags
, LPMCI_SEEK_PARMS lpParms
)
555 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
557 MCI_PLAY_PARMS PlayParms
;
559 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
561 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
562 wma
->mode
= MCI_MODE_SEEK
;
564 case MCI_SEEK_TO_START
:
565 PlayParms
.dwFrom
= 0;
567 case MCI_SEEK_TO_END
:
568 PlayParms
.dwFrom
= wma
->dwTotalLen
;
571 PlayParms
.dwFrom
= lpParms
->dwTo
;
574 dwRet
= ANIM_mciPlay(wDevID
, MCI_WAIT
| MCI_FROM
, &PlayParms
);
575 if (dwRet
!= 0) return dwRet
;
576 dwRet
= ANIM_mciStop(wDevID
, MCI_WAIT
, (LPMCI_GENERIC_PARMS
)&PlayParms
);
577 if (dwFlags
& MCI_NOTIFY
) {
578 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
580 mciDriverNotify16((HWND16
)LOWORD(lpParms
->dwCallback
),
581 wma
->wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
587 /**************************************************************************
588 * ANIM_mciSet [internal]
590 static DWORD
ANIM_mciSet(UINT16 wDevID
, DWORD dwFlags
, LPMCI_SET_PARMS lpParms
)
592 WINE_MCIANIM
* wma
= ANIM_mciGetOpenDrv(wDevID
);
594 TRACE("(%u, %08lX, %p);\n", wDevID
, dwFlags
, lpParms
);
596 if (lpParms
== NULL
) return MCIERR_INTERNAL
;
597 if (wma
== NULL
) return MCIERR_INVALID_DEVICE_ID
;
599 TRACE("(dwTimeFormat=%08lX)\n", lpParms->dwTimeFormat);
600 TRACE("(dwAudio=%08lX)\n", lpParms->dwAudio);
602 if (dwFlags
& MCI_SET_TIME_FORMAT
) {
603 switch (lpParms
->dwTimeFormat
) {
604 case MCI_FORMAT_MILLISECONDS
:
605 TRACE("MCI_FORMAT_MILLISECONDS !\n");
608 TRACE("MCI_FORMAT_MSF !\n");
610 case MCI_FORMAT_TMSF
:
611 TRACE("MCI_FORMAT_TMSF !\n");
614 WARN("Bad time format !\n");
615 return MCIERR_BAD_TIME_FORMAT
;
617 wma
->dwTimeFormat
= lpParms
->dwTimeFormat
;
619 if (dwFlags
& MCI_SET_VIDEO
) return MCIERR_UNSUPPORTED_FUNCTION
;
620 if (dwFlags
& MCI_SET_ON
) return MCIERR_UNSUPPORTED_FUNCTION
;
621 if (dwFlags
& MCI_SET_OFF
) return MCIERR_UNSUPPORTED_FUNCTION
;
622 if (dwFlags
& MCI_NOTIFY
) {
623 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms
->dwCallback
);
624 mciDriverNotify16((HWND16
)LOWORD(lpParms
->dwCallback
),
625 wma
->wNotifyDeviceID
, MCI_NOTIFY_SUCCESSFUL
);
630 /**************************************************************************
631 * ANIM_DriverProc [sample driver]
633 LONG CALLBACK
MCIANIM_DriverProc(DWORD dwDevID
, HDRVR hDriv
, DWORD wMsg
,
634 DWORD dwParam1
, DWORD dwParam2
)
637 case DRV_LOAD
: return 1;
638 case DRV_FREE
: return 1;
639 case DRV_OPEN
: return ANIM_drvOpen((LPSTR
)dwParam1
, (LPMCI_OPEN_DRIVER_PARMSA
)dwParam2
);
640 case DRV_CLOSE
: return ANIM_drvClose(dwDevID
);
641 case DRV_ENABLE
: return 1;
642 case DRV_DISABLE
: return 1;
643 case DRV_QUERYCONFIGURE
: return 1;
644 case DRV_CONFIGURE
: MessageBoxA(0, "Sample MultiMedia Driver !", "Wine Driver", MB_OK
); return 1;
645 case DRV_INSTALL
: return DRVCNF_RESTART
;
646 case DRV_REMOVE
: return DRVCNF_RESTART
;
648 case MCI_OPEN_DRIVER
: return ANIM_mciOpen(dwDevID
, dwParam1
, (LPMCI_OPEN_PARMSA
)dwParam2
);
649 case MCI_CLOSE_DRIVER
: return ANIM_mciClose(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
650 case MCI_GETDEVCAPS
: return ANIM_mciGetDevCaps(dwDevID
, dwParam1
, (LPMCI_GETDEVCAPS_PARMS
)dwParam2
);
651 case MCI_INFO
: return ANIM_mciInfo(dwDevID
, dwParam1
, (LPMCI_INFO_PARMS16
)dwParam2
);
652 case MCI_STATUS
: return ANIM_mciStatus(dwDevID
, dwParam1
, (LPMCI_STATUS_PARMS
)dwParam2
);
653 case MCI_SET
: return ANIM_mciSet(dwDevID
, dwParam1
, (LPMCI_SET_PARMS
)dwParam2
);
654 case MCI_PLAY
: return ANIM_mciPlay(dwDevID
, dwParam1
, (LPMCI_PLAY_PARMS
)dwParam2
);
655 case MCI_STOP
: return ANIM_mciStop(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
656 case MCI_PAUSE
: return ANIM_mciPause(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
657 case MCI_RESUME
: return ANIM_mciResume(dwDevID
, dwParam1
, (LPMCI_GENERIC_PARMS
)dwParam2
);
658 case MCI_SEEK
: return ANIM_mciSeek(dwDevID
, dwParam1
, (LPMCI_SEEK_PARMS
)dwParam2
);
675 FIXME("Unsupported message [%lu]\n", wMsg
);
679 ERR("Shouldn't receive a MCI_OPEN or CLOSE message\n");
682 TRACE("Sending msg [%lu] to default driver proc\n", wMsg
);
683 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
685 return MCIERR_UNRECOGNIZED_COMMAND
;
688 /*-----------------------------------------------------------------------*/