xref: /reactos/dll/win32/mciavi32/info.c (revision 69931a4a)
1 /*
2  * Digital video MCI Wine Driver
3  *
4  * Copyright 1999, 2000 Eric POUECH
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <string.h>
22 #include "private_mciavi.h"
23 #include "wine/debug.h"
24 
25 WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
26 
27 /**************************************************************************
28  * 				MCIAVI_ConvertFrameToTimeFormat	[internal]
29  */
30 static DWORD MCIAVI_ConvertFrameToTimeFormat(WINE_MCIAVI* wma, DWORD val, LPDWORD lpRet)
31 {
32     DWORD	   ret = 0;
33 
34     switch (wma->dwMciTimeFormat) {
35     case MCI_FORMAT_MILLISECONDS:
36         ret = (val * wma->mah.dwMicroSecPerFrame) / 1000;
37 	break;
38     case MCI_FORMAT_FRAMES:
39 	ret = val;
40 	break;
41     default:
42 	WARN("Bad time format %u!\n", wma->dwMciTimeFormat);
43     }
44     TRACE("val=%u=0x%08x [tf=%u] => ret=%u\n", val, val, wma->dwMciTimeFormat, ret);
45     *lpRet = 0;
46     return ret;
47 }
48 
49 /**************************************************************************
50  * 				MCIAVI_ConvertTimeFormatToFrame	[internal]
51  */
52 DWORD 	MCIAVI_ConvertTimeFormatToFrame(WINE_MCIAVI* wma, DWORD val)
53 {
54     DWORD	ret = 0;
55 
56     switch (wma->dwMciTimeFormat) {
57     case MCI_FORMAT_MILLISECONDS:
58 	ret = (val * 1000) / wma->mah.dwMicroSecPerFrame;
59 	break;
60     case MCI_FORMAT_FRAMES:
61 	ret = val;
62 	break;
63     default:
64 	WARN("Bad time format %u!\n", wma->dwMciTimeFormat);
65     }
66     TRACE("val=%u=0x%08x [tf=%u] => ret=%u\n", val, val, wma->dwMciTimeFormat, ret);
67     return ret;
68 }
69 
70 /***************************************************************************
71  * 				MCIAVI_mciGetDevCaps		[internal]
72  */
73 DWORD	MCIAVI_mciGetDevCaps(UINT wDevID, DWORD dwFlags,  LPMCI_GETDEVCAPS_PARMS lpParms)
74 {
75     WINE_MCIAVI*	wma = MCIAVI_mciGetOpenDev(wDevID);
76     DWORD		ret = MCIERR_UNSUPPORTED_FUNCTION;
77 
78     TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
79 
80     if (lpParms == NULL) 	return MCIERR_NULL_PARAMETER_BLOCK;
81     if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
82     if (!(dwFlags & MCI_GETDEVCAPS_ITEM)) return MCIERR_MISSING_PARAMETER;
83     if (dwFlags & MCI_TEST)	return 0;
84 
85     EnterCriticalSection(&wma->cs);
86 
87     if (dwFlags & MCI_GETDEVCAPS_ITEM) {
88 	switch (lpParms->dwItem) {
89 	case MCI_GETDEVCAPS_DEVICE_TYPE:
90 	    TRACE("MCI_GETDEVCAPS_DEVICE_TYPE !\n");
91 	    lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_DIGITAL_VIDEO, MCI_DEVTYPE_DIGITAL_VIDEO);
92 	    ret = MCI_RESOURCE_RETURNED;
93 	    break;
94 	case MCI_GETDEVCAPS_HAS_AUDIO:
95 	    TRACE("MCI_GETDEVCAPS_HAS_AUDIO !\n");
96 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
97 	    ret = MCI_RESOURCE_RETURNED;
98 	    break;
99 	case MCI_GETDEVCAPS_HAS_VIDEO:
100 	    TRACE("MCI_GETDEVCAPS_HAS_VIDEO !\n");
101 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
102 	    ret = MCI_RESOURCE_RETURNED;
103 	    break;
104 	case MCI_GETDEVCAPS_USES_FILES:
105 	    TRACE("MCI_GETDEVCAPS_USES_FILES !\n");
106 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
107 	    ret = MCI_RESOURCE_RETURNED;
108 	    break;
109 	case MCI_GETDEVCAPS_COMPOUND_DEVICE:
110 	    TRACE("MCI_GETDEVCAPS_COMPOUND_DEVICE !\n");
111 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
112 	    ret = MCI_RESOURCE_RETURNED;
113 	    break;
114 	case MCI_GETDEVCAPS_CAN_EJECT:
115 	    TRACE("MCI_GETDEVCAPS_CAN_EJECT !\n");
116 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
117 	    ret = MCI_RESOURCE_RETURNED;
118 	    break;
119 	case MCI_GETDEVCAPS_CAN_PLAY:
120 	    TRACE("MCI_GETDEVCAPS_CAN_PLAY !\n");
121 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
122 	    ret = MCI_RESOURCE_RETURNED;
123 	    break;
124 	case MCI_GETDEVCAPS_CAN_RECORD:
125 	    TRACE("MCI_GETDEVCAPS_CAN_RECORD !\n");
126 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
127 	    ret = MCI_RESOURCE_RETURNED;
128 	    break;
129 	case MCI_GETDEVCAPS_CAN_SAVE:
130 	    TRACE("MCI_GETDEVCAPS_CAN_SAVE !\n");
131 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
132 	    ret = MCI_RESOURCE_RETURNED;
133 	    break;
134 	case MCI_DGV_GETDEVCAPS_CAN_REVERSE:
135 	    TRACE("MCI_DGV_GETDEVCAPS_CAN_REVERSE !\n");
136 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */
137 	    ret = MCI_RESOURCE_RETURNED;
138 	    break;
139 	case MCI_DGV_GETDEVCAPS_CAN_STRETCH:
140 	    TRACE("MCI_DGV_GETDEVCAPS_CAN_STRETCH !\n");
141 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */
142 	    ret = MCI_RESOURCE_RETURNED;
143 	    break;
144 	case MCI_DGV_GETDEVCAPS_CAN_LOCK:
145 	    TRACE("MCI_DGV_GETDEVCAPS_CAN_LOCK !\n");
146 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
147 	    ret = MCI_RESOURCE_RETURNED;
148 	    break;
149 	case MCI_DGV_GETDEVCAPS_CAN_FREEZE:
150 	    TRACE("MCI_DGV_GETDEVCAPS_CAN_FREEZE !\n");
151 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
152 	    ret = MCI_RESOURCE_RETURNED;
153 	    break;
154 	case MCI_DGV_GETDEVCAPS_CAN_STR_IN:
155 	    TRACE("MCI_DGV_GETDEVCAPS_CAN_STRETCH_INPUT !\n");
156 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
157 	    ret = MCI_RESOURCE_RETURNED;
158 	    break;
159 	case MCI_DGV_GETDEVCAPS_HAS_STILL:
160 	    TRACE("MCI_DGV_GETDEVCAPS_HAS_STILL !\n");
161 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
162 	    ret = MCI_RESOURCE_RETURNED;
163 	    break;
164 	case MCI_DGV_GETDEVCAPS_CAN_TEST:
165 	    TRACE("MCI_DGV_GETDEVCAPS_CAN_TEST !\n");
166 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
167 	    ret = MCI_RESOURCE_RETURNED;
168 	    break;
169 	case MCI_DGV_GETDEVCAPS_PALETTES:
170 	    TRACE("MCI_DGV_GETDEVCAPS_PALETTES !\n");
171 	    lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE); /* FIXME */
172 	    ret = MCI_RESOURCE_RETURNED;
173 	    break;
174 	/* w2k does not know MAX_WINDOWS or MAX/MINIMUM_RATE */
175 	default:
176             FIXME("Unknown capability (%08x) !\n", lpParms->dwItem);
177             break;
178 	}
179     }
180 
181     LeaveCriticalSection(&wma->cs);
182     return ret;
183 }
184 
185 /***************************************************************************
186  * 				MCIAVI_mciInfo			[internal]
187  */
188 DWORD	MCIAVI_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_INFO_PARMSW lpParms)
189 {
190     LPCWSTR		str = 0;
191     WINE_MCIAVI*	wma = MCIAVI_mciGetOpenDev(wDevID);
192     DWORD		ret = 0;
193     static const WCHAR wszAviPlayer[] = {'W','i','n','e','\'','s',' ','A','V','I',' ','p','l','a','y','e','r',0};
194     static const WCHAR wszVersion[] = {'1','.','1',0};
195 
196     if (lpParms == NULL || lpParms->lpstrReturn == NULL)
197 	return MCIERR_NULL_PARAMETER_BLOCK;
198     if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
199     if (dwFlags & MCI_TEST)	return 0;
200 
201     TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize);
202 
203     EnterCriticalSection(&wma->cs);
204 
205     if (dwFlags & MCI_INFO_PRODUCT)
206 	str = wszAviPlayer;
207     else if (dwFlags & MCI_INFO_VERSION)
208 	str = wszVersion;
209     else if (dwFlags & MCI_INFO_FILE)
210 	str = wma->lpFileName;
211     else {
212 	WARN("Don't know this info command (%u)\n", dwFlags);
213 	ret = MCIERR_UNRECOGNIZED_COMMAND;
214     }
215     if (!ret) {
216 	WCHAR zero = 0;
217 	/* Only mciwave, mciseq and mcicda set dwRetSize (since NT). */
218 	lstrcpynW(lpParms->lpstrReturn, str ? str : &zero, lpParms->dwRetSize);
219     }
220     LeaveCriticalSection(&wma->cs);
221     return ret;
222 }
223 
224 /***************************************************************************
225  * 				MCIAVI_mciSet			[internal]
226  */
227 DWORD	MCIAVI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms)
228 {
229     WINE_MCIAVI*	wma = MCIAVI_mciGetOpenDev(wDevID);
230 
231     if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
232     if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
233     if (dwFlags & MCI_TEST)	return 0;
234 
235     EnterCriticalSection(&wma->cs);
236 
237     if (dwFlags & MCI_SET_TIME_FORMAT) {
238 	switch (lpParms->dwTimeFormat) {
239 	case MCI_FORMAT_MILLISECONDS:
240 	    TRACE("MCI_FORMAT_MILLISECONDS !\n");
241 	    wma->dwMciTimeFormat = MCI_FORMAT_MILLISECONDS;
242 	    break;
243 	case MCI_FORMAT_FRAMES:
244 	    TRACE("MCI_FORMAT_FRAMES !\n");
245 	    wma->dwMciTimeFormat = MCI_FORMAT_FRAMES;
246 	    break;
247 	default:
248             WARN("Bad time format %u!\n", lpParms->dwTimeFormat);
249             LeaveCriticalSection(&wma->cs);
250 	    return MCIERR_BAD_TIME_FORMAT;
251 	}
252     }
253 
254     if (dwFlags & MCI_SET_DOOR_OPEN) {
255 	TRACE("No support for door open !\n");
256         LeaveCriticalSection(&wma->cs);
257 	return MCIERR_UNSUPPORTED_FUNCTION;
258     }
259     if (dwFlags & MCI_SET_DOOR_CLOSED) {
260 	TRACE("No support for door close !\n");
261         LeaveCriticalSection(&wma->cs);
262 	return MCIERR_UNSUPPORTED_FUNCTION;
263     }
264 
265     if (dwFlags & MCI_SET_ON) {
266 	const char *szVideo="";
267 	const char *szAudio="";
268 	const char *szSeek="";
269 
270 	if (dwFlags & MCI_SET_VIDEO) {
271 	    szVideo = " video";
272 	    wma->dwSet |= 4;
273 	}
274 	if (dwFlags & MCI_SET_AUDIO) {
275 	    switch (lpParms->dwAudio) {
276 	    case MCI_SET_AUDIO_ALL:
277 		szAudio = " audio all";
278 		wma->dwSet |= 3;
279 		break;
280 	    case MCI_SET_AUDIO_LEFT:
281 		szAudio = " audio left";
282 		wma->dwSet |= 1;
283 		break;
284 	    case MCI_SET_AUDIO_RIGHT:
285 		szAudio = " audio right";
286 		wma->dwSet |= 2;
287 		break;
288 	    default:
289 		szAudio = " audio unknown";
290 		WARN("Unknown audio channel %u\n", lpParms->dwAudio);
291 		break;
292 	    }
293 	}
294 	if (dwFlags & MCI_DGV_SET_SEEK_EXACTLY) {
295 	    szSeek = " seek_exactly";
296 	}
297 	FIXME("MCI_SET_ON:%s%s%s\n", szVideo, szAudio, szSeek);
298     }
299 
300     if (dwFlags & MCI_SET_OFF) {
301 	const char *szVideo="";
302 	const char *szAudio="";
303 	const char *szSeek="";
304 
305 	if (dwFlags & MCI_SET_VIDEO) {
306 	    szVideo = " video";
307 	    wma->dwSet &= ~4;
308 	}
309 	if (dwFlags & MCI_SET_AUDIO) {
310 	    switch (lpParms->dwAudio) {
311 	    case MCI_SET_AUDIO_ALL:
312 		szAudio = " audio all";
313 		wma->dwSet &= ~3;
314 		break;
315 	    case MCI_SET_AUDIO_LEFT:
316 		szAudio = " audio left";
317 		wma->dwSet &= ~2;
318 		break;
319 	    case MCI_SET_AUDIO_RIGHT:
320 		szAudio = " audio right";
321 		wma->dwSet &= ~2;
322 		break;
323 	    default:
324 		szAudio = " audio unknown";
325 		WARN("Unknown audio channel %u\n", lpParms->dwAudio);
326 		break;
327 	    }
328 	}
329 	if (dwFlags & MCI_DGV_SET_SEEK_EXACTLY) {
330 	    szSeek = " seek_exactly";
331 	}
332 	FIXME("MCI_SET_OFF:%s%s%s\n", szVideo, szAudio, szSeek);
333     }
334     if (dwFlags & MCI_DGV_SET_FILEFORMAT) {
335 	LPCSTR	str = "save";
336 	if (dwFlags & MCI_DGV_SET_STILL)
337 	    str = "capture";
338 
339 	switch (lpParms->dwFileFormat) {
340 	case MCI_DGV_FF_AVI: 	FIXME("Setting file format (%s) to 'AVI'\n", str); 	break;
341 	case MCI_DGV_FF_AVSS: 	FIXME("Setting file format (%s) to 'AVSS'\n", str);	break;
342 	case MCI_DGV_FF_DIB: 	FIXME("Setting file format (%s) to 'DIB'\n", str);	break;
343 	case MCI_DGV_FF_JFIF: 	FIXME("Setting file format (%s) to 'JFIF'\n", str);	break;
344 	case MCI_DGV_FF_JPEG: 	FIXME("Setting file format (%s) to 'JPEG'\n", str);	break;
345 	case MCI_DGV_FF_MPEG: 	FIXME("Setting file format (%s) to 'MPEG'\n", str); 	break;
346 	case MCI_DGV_FF_RDIB:	FIXME("Setting file format (%s) to 'RLE DIB'\n", str);	break;
347 	case MCI_DGV_FF_RJPEG: 	FIXME("Setting file format (%s) to 'RJPEG'\n", str);	break;
348 	default:		FIXME("Setting unknown file format (%s): %d\n", str, lpParms->dwFileFormat);
349 	}
350     }
351 
352     if (dwFlags & MCI_DGV_SET_SPEED) {
353 	FIXME("Setting speed to %d\n", lpParms->dwSpeed);
354     }
355 
356     LeaveCriticalSection(&wma->cs);
357     return 0;
358 }
359 
360 /***************************************************************************
361  * 				MCIAVI_mciStatus			[internal]
362  */
363 DWORD	MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSW lpParms)
364 {
365     WINE_MCIAVI*	wma = MCIAVI_mciGetOpenDev(wDevID);
366     DWORD		ret = 0;
367 
368     if (lpParms == NULL)	return MCIERR_NULL_PARAMETER_BLOCK;
369     if (wma == NULL)		return MCIERR_INVALID_DEVICE_ID;
370     if (!(dwFlags & MCI_STATUS_ITEM))	return MCIERR_MISSING_PARAMETER;
371     if (dwFlags & MCI_TEST)	return 0;
372 
373     EnterCriticalSection(&wma->cs);
374 
375     if (dwFlags & MCI_STATUS_ITEM) {
376 	switch (lpParms->dwItem) {
377 	case MCI_STATUS_CURRENT_TRACK:
378 	    lpParms->dwReturn = 1;
379 	    TRACE("MCI_STATUS_CURRENT_TRACK => %lu\n", lpParms->dwReturn);
380 	    break;
381 	case MCI_STATUS_LENGTH:
382 	    if (!wma->hFile) {
383 		lpParms->dwReturn = 0;
384                 LeaveCriticalSection(&wma->cs);
385 		return MCIERR_UNSUPPORTED_FUNCTION;
386 	    }
387 	    /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
388 	    lpParms->dwReturn = MCIAVI_ConvertFrameToTimeFormat(wma, wma->mah.dwTotalFrames, &ret);
389 	    TRACE("MCI_STATUS_LENGTH => %lu\n", lpParms->dwReturn);
390 	    break;
391 	case MCI_STATUS_MODE:
392  	    lpParms->dwReturn = MAKEMCIRESOURCE(wma->dwStatus, wma->dwStatus);
393 	    ret = MCI_RESOURCE_RETURNED;
394            TRACE("MCI_STATUS_MODE => 0x%04x\n", LOWORD(lpParms->dwReturn));
395 	    break;
396 	case MCI_STATUS_MEDIA_PRESENT:
397 	    TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE\n");
398 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
399 	    ret = MCI_RESOURCE_RETURNED;
400 	    break;
401 	case MCI_STATUS_NUMBER_OF_TRACKS:
402 	    lpParms->dwReturn = 1;
403 	    TRACE("MCI_STATUS_NUMBER_OF_TRACKS => %lu\n", lpParms->dwReturn);
404 	    break;
405 	case MCI_STATUS_POSITION:
406 	    if (!wma->hFile) {
407 		lpParms->dwReturn = 0;
408                 LeaveCriticalSection(&wma->cs);
409 		return MCIERR_UNSUPPORTED_FUNCTION;
410 	    }
411 	    /* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
412 	    lpParms->dwReturn = MCIAVI_ConvertFrameToTimeFormat(wma,
413 							     (dwFlags & MCI_STATUS_START) ? 0 : wma->dwCurrVideoFrame,
414 							     &ret);
415 	    TRACE("MCI_STATUS_POSITION %s => %lu\n",
416 		  (dwFlags & MCI_STATUS_START) ? "start" : "current", lpParms->dwReturn);
417 	    break;
418 	case MCI_STATUS_READY:
419 	    lpParms->dwReturn = (wma->dwStatus == MCI_MODE_NOT_READY) ?
420 		MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE);
421 	    ret = MCI_RESOURCE_RETURNED;
422 	    TRACE("MCI_STATUS_READY = %u\n", LOWORD(lpParms->dwReturn));
423 	    break;
424 	case MCI_STATUS_TIME_FORMAT:
425 	    lpParms->dwReturn = MAKEMCIRESOURCE(wma->dwMciTimeFormat,
426                                 wma->dwMciTimeFormat + MCI_FORMAT_RETURN_BASE);
427 	    TRACE("MCI_STATUS_TIME_FORMAT => %u\n", LOWORD(lpParms->dwReturn));
428 	    ret = MCI_RESOURCE_RETURNED;
429 	    break;
430 	case MCI_DGV_STATUS_AUDIO:
431 	    lpParms->dwReturn = (wma->dwSet & 3) ?
432 		MAKEMCIRESOURCE(MCI_ON, MCI_ON_S) : MAKEMCIRESOURCE(MCI_OFF, MCI_OFF_S);
433 	    ret = MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER;
434 	    TRACE("MCI_STATUS_AUDIO = %u\n", LOWORD(lpParms->dwReturn));
435 	    break;
436 	case MCI_DGV_STATUS_VIDEO:
437 	    lpParms->dwReturn = (wma->dwSet & 4) ?
438 		MAKEMCIRESOURCE(MCI_ON, MCI_ON_S) : MAKEMCIRESOURCE(MCI_OFF, MCI_OFF_S);
439 	    ret = MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER;
440 	    TRACE("MCI_STATUS_VIDEO = %u\n", LOWORD(lpParms->dwReturn));
441 	    break;
442 
443 #if 0
444 	case MCI_AVI_STATUS_AUDIO_BREAKS:
445 	case MCI_AVI_STATUS_FRAMES_SKIPPED:
446 	case MCI_AVI_STATUS_LAST_PLAY_SPEED:
447 	case MCI_DGV_STATUS_AUDIO_INPUT:
448 	case MCI_DGV_STATUS_AUDIO_RECORD:
449 	case MCI_DGV_STATUS_AUDIO_SOURCE:
450 	case MCI_DGV_STATUS_AVGBYTESPERSEC:
451 	case MCI_DGV_STATUS_BASS:
452 	case MCI_DGV_STATUS_BITSPERSAMPLE:
453 	case MCI_DGV_STATUS_BLOCKALIGN:
454 	case MCI_DGV_STATUS_BRIGHTNESS:
455 	case MCI_DGV_STATUS_COLOR:
456 	case MCI_DGV_STATUS_CONTRAST:
457 	case MCI_DGV_STATUS_FILEFORMAT:
458 	case MCI_DGV_STATUS_FILE_MODE:
459 	case MCI_DGV_STATUS_FILE_COMPLETION:
460 	case MCI_DGV_STATUS_GAMMA:
461 #endif
462 	case MCI_DGV_STATUS_BITSPERPEL:
463 	    lpParms->dwReturn = wma->inbih->biBitCount;
464 	    TRACE("MCI_DGV_STATUS_BITSPERPEL => %lu\n", lpParms->dwReturn);
465 	    break;
466 	case MCI_DGV_STATUS_HPAL:
467 	    lpParms->dwReturn = 0;
468 	    TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms->dwReturn);
469 	    break;
470 	case MCI_DGV_STATUS_HWND:
471            lpParms->dwReturn = (DWORD_PTR)wma->hWndPaint;
472            TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWndPaint);
473 	   break;
474 	case MCI_DGV_STATUS_WINDOW_VISIBLE:
475 	    lpParms->dwReturn = IsWindowVisible(wma->hWndPaint) ?
476 		MAKEMCIRESOURCE(TRUE, MCI_TRUE) : MAKEMCIRESOURCE(FALSE, MCI_FALSE);
477 	    ret = MCI_RESOURCE_RETURNED;
478 	    TRACE("MCI_STATUS_WINDOW_VISIBLE = %u\n", LOWORD(lpParms->dwReturn));
479 	    break;
480 	case MCI_DGV_STATUS_WINDOW_MINIMIZED:
481 	    lpParms->dwReturn = IsIconic(wma->hWndPaint) ?
482 		MAKEMCIRESOURCE(TRUE, MCI_TRUE) : MAKEMCIRESOURCE(FALSE, MCI_FALSE);
483 	    ret = MCI_RESOURCE_RETURNED;
484 	    TRACE("MCI_STATUS_WINDOW_MINIMIZED = %u\n", LOWORD(lpParms->dwReturn));
485 	    break;
486 	case MCI_DGV_STATUS_WINDOW_MAXIMIZED:
487 	    lpParms->dwReturn = IsZoomed(wma->hWndPaint) ?
488 		MAKEMCIRESOURCE(TRUE, MCI_TRUE) : MAKEMCIRESOURCE(FALSE, MCI_FALSE);
489 	    ret = MCI_RESOURCE_RETURNED;
490 	    TRACE("MCI_STATUS_WINDOW_MMAXIMIZED = %u\n", LOWORD(lpParms->dwReturn));
491 	    break;
492 	case MCI_DGV_STATUS_SPEED:
493 	    lpParms->dwReturn = 1000;
494 	    TRACE("MCI_DGV_STATUS_SPEED = %lu\n", lpParms->dwReturn);
495 	    break;
496 	case MCI_DGV_STATUS_FRAME_RATE:
497 	    /* FIXME: 1000 is a settable speed multiplier */
498 	    lpParms->dwReturn = MulDiv(1000000,1000,wma->mah.dwMicroSecPerFrame);
499 	    TRACE("MCI_DGV_STATUS_FRAME_RATE = %lu\n", lpParms->dwReturn);
500 	    break;
501 	case MCI_DGV_STATUS_FORWARD:
502 	    lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
503 	    ret = MCI_RESOURCE_RETURNED;
504 	    TRACE("MCI_DGV_STATUS_FORWARD = %u\n", LOWORD(lpParms->dwReturn));
505 	    break;
506 	case MCI_DGV_STATUS_PAUSE_MODE:
507 	    if (wma->dwStatus != MCI_MODE_PAUSE) {
508 		LeaveCriticalSection(&wma->cs);
509 		return MCIERR_NONAPPLICABLE_FUNCTION;
510 	    }
511 	    lpParms->dwReturn = MAKEMCIRESOURCE(MCI_MODE_PLAY, MCI_MODE_PLAY);
512 	    ret = MCI_RESOURCE_RETURNED;
513 	    TRACE("MCI_STATUS_MODE => 0x%04x\n", LOWORD(lpParms->dwReturn));
514 	    break;
515 	case MCI_DGV_STATUS_AUDIO_STREAM:
516 	   lpParms->dwReturn = wma->audio_stream_n;
517 	   TRACE("MCI_DGV_STATUS_AUDIO_STREAM => %lu\n", lpParms->dwReturn);
518 	   break;
519 #if 0
520 	case MCI_DGV_STATUS_KEY_COLOR:
521 	case MCI_DGV_STATUS_KEY_INDEX:
522 	case MCI_DGV_STATUS_MONITOR:
523 	case MCI_DGV_MONITOR_FILE:
524 	case MCI_DGV_MONITOR_INPUT:
525 	case MCI_DGV_STATUS_MONITOR_METHOD:
526 	case MCI_DGV_STATUS_SAMPLESPERSECOND:
527 	case MCI_DGV_STATUS_SEEK_EXACTLY:
528 	case MCI_DGV_STATUS_SHARPNESS:
529 	case MCI_DGV_STATUS_SIZE:
530 	case MCI_DGV_STATUS_SMPTE:
531 	case MCI_DGV_STATUS_STILL_FILEFORMAT:
532 	case MCI_DGV_STATUS_TINT:
533 	case MCI_DGV_STATUS_TREBLE:
534 	case MCI_DGV_STATUS_UNSAVED:
535 	case MCI_DGV_STATUS_VIDEO_RECORD:
536 	case MCI_DGV_STATUS_VIDEO_SOURCE:
537 	case MCI_DGV_STATUS_VIDEO_SRC_NUM:
538 	case MCI_DGV_STATUS_VIDEO_STREAM:
539 	case MCI_DGV_STATUS_VOLUME:
540 #endif
541 	default:
542             FIXME("Unknown command %08X !\n", lpParms->dwItem);
543             TRACE("(%04x, %08X, %p)\n", wDevID, dwFlags, lpParms);
544             LeaveCriticalSection(&wma->cs);
545 	    return MCIERR_UNSUPPORTED_FUNCTION;
546 	}
547     }
548 
549     if (dwFlags & MCI_NOTIFY) {
550 	TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
551 	mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
552                        wDevID, MCI_NOTIFY_SUCCESSFUL);
553     }
554     LeaveCriticalSection(&wma->cs);
555     return ret;
556 }
557