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