Prepare dlls/{comctl32,gdi,msvideo,setupapi,shell32,twain,winmm} for
[wine/gsoc_dplay.git] / dlls / winmm / mciavi / mciavi.c
blob583c62767ebf80a6194d7749c423aec3ff092b7a
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * Digital video MCI Wine Driver
6 * Copyright 1999, 2000 Eric POUECH
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* TODO list :
24 * - handling of palettes
25 * - recording (which input devices ?), a cam recorder ?
26 * - lots of messages still need to be handled (cf FIXME)
27 * - synchronization between audio and video (especially for interleaved
28 * files)
29 * - synchronization (as in all the Wine MCI drivers (MCI_WAIT) messages)
30 * - robustness when reading file can be enhanced
31 * - better move the AVI handling part to avifile DLL and make use of it
32 * - some files appear to have more than one audio stream (we only play the
33 * first one)
34 * - some files contain an index of audio/video frame. Better use it,
35 * instead of rebuilding it
36 * - mciWindow (for setting the hWnd) is broken with media player
37 * - stopping while playing a file with sound blocks until all buffered
38 * audio is played... still should be stopped ASAP
41 #include <string.h>
42 #include "private_mciavi.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
47 /* ===================================================================
48 * ===================================================================
49 * FIXME: should be using the new mmThreadXXXX functions from WINMM
50 * instead of those
51 * it would require to add a wine internal flag to mmThreadCreate
52 * in order to pass a 32 bit function instead of a 16 bit one
53 * ===================================================================
54 * =================================================================== */
56 struct SCA {
57 UINT wDevID;
58 UINT wMsg;
59 DWORD dwParam1;
60 DWORD dwParam2;
63 /**************************************************************************
64 * MCI_SCAStarter [internal]
66 static DWORD CALLBACK MCI_SCAStarter(LPVOID arg)
68 struct SCA* sca = (struct SCA*)arg;
69 DWORD ret;
71 TRACE("In thread before async command (%08x,%u,%08lx,%08lx)\n",
72 sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);
73 ret = mciSendCommandA(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2);
74 TRACE("In thread after async command (%08x,%u,%08lx,%08lx)\n",
75 sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);
76 HeapFree(GetProcessHeap(), 0, sca);
77 ExitThread(ret);
78 WARN("Should not happen ? what's wrong \n");
79 /* should not go after this point */
80 return ret;
83 /**************************************************************************
84 * MCI_SendCommandAsync [internal]
86 static DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1,
87 DWORD dwParam2, UINT size)
89 struct SCA* sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size);
91 if (sca == 0)
92 return MCIERR_OUT_OF_MEMORY;
94 sca->wDevID = wDevID;
95 sca->wMsg = wMsg;
96 sca->dwParam1 = dwParam1;
98 if (size && dwParam2) {
99 sca->dwParam2 = (DWORD)sca + sizeof(struct SCA);
100 /* copy structure passed by program in dwParam2 to be sure
101 * we can still use it whatever the program does
103 memcpy((LPVOID)sca->dwParam2, (LPVOID)dwParam2, size);
104 } else {
105 sca->dwParam2 = dwParam2;
108 if (CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL) == 0) {
109 WARN("Couldn't allocate thread for async command handling, sending synchronously\n");
110 return MCI_SCAStarter(&sca);
112 return 0;
115 /*======================================================================*
116 * MCI AVI implemantation *
117 *======================================================================*/
119 HINSTANCE MCIAVI_hInstance = 0;
121 BOOL WINAPI MCIAVI_LibMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID fImpLoad)
123 switch (fdwReason) {
124 case DLL_PROCESS_ATTACH:
125 MCIAVI_hInstance = hInstDLL;
126 break;
128 return TRUE;
131 /**************************************************************************
132 * MCIAVI_drvOpen [internal]
134 static DWORD MCIAVI_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
136 WINE_MCIAVI* wma;
137 static WCHAR mciAviWStr[] = {'M','C','I','A','V','I',0};
139 if (!modp) return 0xFFFFFFFF;
141 wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIAVI));
142 if (!wma)
143 return 0;
145 wma->wDevID = modp->wDeviceID;
146 mciSetDriverData(wma->wDevID, (DWORD)wma);
147 wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0);
148 modp->wCustomCommandTable = wma->wCommandTable;
149 modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
150 return modp->wDeviceID;
153 /**************************************************************************
154 * MCIAVI_drvClose [internal]
156 static DWORD MCIAVI_drvClose(DWORD dwDevID)
158 WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
160 if (wma) {
161 mciSetDriverData(dwDevID, 0);
162 mciFreeCommandResource(wma->wCommandTable);
163 HeapFree(GetProcessHeap(), 0, wma);
164 return 1;
166 return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
169 /**************************************************************************
170 * MCIAVI_drvConfigure [internal]
172 static DWORD MCIAVI_drvConfigure(DWORD dwDevID)
174 WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
176 if (wma) {
177 MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK);
178 return 1;
180 return 0;
183 /**************************************************************************
184 * MCIAVI_mciGetOpenDev [internal]
186 WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID)
188 WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);
190 if (wma == NULL || wma->nUseCount == 0) {
191 WARN("Invalid wDevID=%u\n", wDevID);
192 return 0;
194 return wma;
197 static void MCIAVI_CleanUp(WINE_MCIAVI* wma)
199 /* to prevent handling in WindowProc */
200 wma->dwStatus = MCI_MODE_NOT_READY;
201 if (wma->hFile) {
202 mmioClose(wma->hFile, 0);
203 wma->hFile = 0;
204 if (wma->lpVideoIndex) HeapFree(GetProcessHeap(), 0, wma->lpVideoIndex);
205 wma->lpVideoIndex = NULL;
206 if (wma->lpAudioIndex) HeapFree(GetProcessHeap(), 0, wma->lpAudioIndex);
207 wma->lpAudioIndex = NULL;
208 if (wma->hic) ICClose(wma->hic);
209 wma->hic = 0;
210 if (wma->inbih) HeapFree(GetProcessHeap(), 0, wma->inbih);
211 wma->inbih = NULL;
212 if (wma->outbih) HeapFree(GetProcessHeap(), 0, wma->outbih);
213 wma->outbih = NULL;
214 if (wma->indata) HeapFree(GetProcessHeap(), 0, wma->indata);
215 wma->indata = NULL;
216 if (wma->outdata) HeapFree(GetProcessHeap(), 0, wma->outdata);
217 wma->outdata = NULL;
218 if (wma->hbmFrame) DeleteObject(wma->hbmFrame);
219 wma->hbmFrame = 0;
220 if (wma->hWnd) DestroyWindow(wma->hWnd);
221 wma->hWnd = 0;
223 if (wma->lpWaveFormat) HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);
224 wma->lpWaveFormat = 0;
226 memset(&wma->mah, 0, sizeof(wma->mah));
227 memset(&wma->ash_video, 0, sizeof(wma->ash_video));
228 memset(&wma->ash_audio, 0, sizeof(wma->ash_audio));
229 wma->dwCurrVideoFrame = wma->dwCurrAudioBlock = 0;
233 static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
235 /***************************************************************************
236 * MCIAVI_mciOpen [internal]
238 static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,
239 LPMCI_DGV_OPEN_PARMSA lpOpenParms)
241 WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);
242 LRESULT dwRet = 0;
244 TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
246 if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
247 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
249 if (wma->nUseCount > 0) {
250 /* The driver is already open on this channel */
251 /* If the driver was opened shareable before and this open specifies */
252 /* shareable then increment the use count */
253 if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
254 ++wma->nUseCount;
255 else
256 return MCIERR_MUST_USE_SHAREABLE;
257 } else {
258 wma->nUseCount = 1;
259 wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
262 wma->dwStatus = MCI_MODE_NOT_READY;
263 InitializeCriticalSection(&wma->cs);
265 if (dwFlags & MCI_OPEN_ELEMENT) {
266 if (dwFlags & MCI_OPEN_ELEMENT_ID) {
267 /* could it be that (DWORD)lpOpenParms->lpstrElementName
268 * contains the hFile value ?
270 dwRet = MCIERR_UNRECOGNIZED_COMMAND;
271 } else if (strlen(lpOpenParms->lpstrElementName) > 0) {
272 /* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */
273 TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName);
275 if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0)) {
276 wma->hFile = mmioOpenA(lpOpenParms->lpstrElementName, NULL,
277 MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READWRITE);
279 if (wma->hFile == 0) {
280 WARN("can't find file='%s' !\n", lpOpenParms->lpstrElementName);
281 dwRet = MCIERR_FILE_NOT_FOUND;
282 } else {
283 if (!MCIAVI_GetInfo(wma))
284 dwRet = MCIERR_INVALID_FILE;
285 else if (!MCIAVI_OpenVideo(wma))
286 dwRet = MCIERR_CANNOT_LOAD_DRIVER;
287 else if (!MCIAVI_CreateWindow(wma, dwFlags, lpOpenParms))
288 dwRet = MCIERR_CREATEWINDOW;
291 } else {
292 FIXME("Don't record yet\n");
293 dwRet = MCIERR_UNSUPPORTED_FUNCTION;
297 memcpy(&wma->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));
299 if (dwRet == 0) {
300 wma->dwStatus = MCI_MODE_STOP;
301 wma->dwMciTimeFormat = MCI_FORMAT_FRAMES;
302 } else {
303 MCIAVI_CleanUp(wma);
305 return dwRet;
309 /***************************************************************************
310 * MCIAVI_mciClose [internal]
312 static DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
314 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
315 DWORD dwRet = 0;
317 TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
319 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
321 if (wma->nUseCount == 1) {
322 if (wma->dwStatus != MCI_MODE_STOP)
323 dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, lpParms);
324 MCIAVI_CleanUp(wma);
326 if ((dwFlags & MCI_NOTIFY) && lpParms) {
327 mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
328 wma->openParms.wDeviceID,
329 MCI_NOTIFY_SUCCESSFUL);
331 HeapFree(GetProcessHeap(), 0, wma);
332 return dwRet;
334 wma->nUseCount--;
335 return dwRet;
338 /***************************************************************************
339 * MCIAVI_mciPlay [internal]
341 static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
343 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
344 DWORD tc;
345 DWORD frameTime;
346 DWORD delta;
347 DWORD dwRet;
348 LPWAVEHDR waveHdr = NULL;
349 unsigned i, nHdr = 0;
350 DWORD dwFromFrame, dwToFrame;
352 TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
354 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
355 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
357 if (!wma->hFile) return MCIERR_FILE_NOT_FOUND;
358 if (!wma->hWnd) return MCIERR_NO_WINDOW;
360 wma->dwStatus = MCI_MODE_PLAY;
362 if (!(dwFlags & MCI_WAIT)) {
363 return MCI_SendCommandAsync(wma->openParms.wDeviceID, MCI_PLAY, dwFlags,
364 (DWORD)lpParms, sizeof(MCI_PLAY_PARMS));
367 ShowWindow(wma->hWnd, SW_SHOW);
369 dwFromFrame = wma->dwCurrVideoFrame;
370 dwToFrame = wma->dwPlayableVideoFrames - 1;
372 if (lpParms && (dwFlags & MCI_FROM)) {
373 dwFromFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwFrom);
375 if (lpParms && (dwFlags & MCI_TO)) {
376 dwToFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwTo);
378 if (dwToFrame >= wma->dwPlayableVideoFrames)
379 dwToFrame = wma->dwPlayableVideoFrames - 1;
381 TRACE("Playing from frame=%lu to frame=%lu\n", dwFromFrame, dwToFrame);
383 if (dwToFrame <= wma->dwCurrVideoFrame)
384 return TRUE;
385 wma->dwCurrVideoFrame = dwFromFrame;
387 if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_DGV_PLAY_REVERSE|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN))
388 FIXME("Unsupported flag %08lx\n", dwFlags);
390 /* time is in microseconds, we should convert it to milliseconds */
391 frameTime = (wma->mah.dwMicroSecPerFrame + 500) / 1000;
393 if (wma->lpWaveFormat) {
394 if ((dwRet = MCIAVI_OpenAudio(wma, &nHdr, &waveHdr)) != 0)
395 goto cleanUp;
396 /* fill the queue with as many wave headers as possible */
397 MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
400 while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY) {
401 tc = GetTickCount();
403 MCIAVI_DrawFrame(wma);
405 if (wma->lpWaveFormat) {
406 MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
407 delta = GetTickCount() - tc;
408 WaitForSingleObject(wma->hEvent, (delta >= frameTime) ? 0 : frameTime - delta);
411 delta = GetTickCount() - tc;
412 if (delta < frameTime)
413 Sleep(frameTime - delta);
415 if (wma->dwCurrVideoFrame++ >= dwToFrame) {
416 wma->dwCurrVideoFrame--;
417 wma->dwStatus = MCI_MODE_STOP;
421 if (wma->lpWaveFormat) {
422 while (*(volatile DWORD*)&wma->dwEventCount != nHdr - 1) {
423 Sleep(100);
426 /* just to get rid of some race conditions between play, stop and pause */
427 waveOutReset(wma->hWave);
429 for (i = 0; i < nHdr; i++)
430 waveOutUnprepareHeader(wma->hWave, &waveHdr[i], sizeof(WAVEHDR));
433 dwRet = 0;
434 cleanUp:
435 if (wma->lpWaveFormat) {
436 HeapFree(GetProcessHeap(), 0, waveHdr);
438 if (wma->hWave) {
439 waveOutClose(wma->hWave);
440 wma->hWave = 0;
442 CloseHandle(wma->hEvent);
445 if (lpParms && (dwFlags & MCI_NOTIFY)) {
446 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
447 mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
448 wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
451 wma->dwStatus = MCI_MODE_STOP;
453 return dwRet;
456 /***************************************************************************
457 * MCIAVI_mciRecord [internal]
459 static DWORD MCIAVI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECORD_PARMS lpParms)
461 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
463 FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
465 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
466 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
468 wma->dwStatus = MCI_MODE_RECORD;
469 return 0;
472 /***************************************************************************
473 * MCIAVI_mciStop [internal]
475 static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
477 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
478 DWORD dwRet = 0;
480 TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
482 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
483 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
485 switch (wma->dwStatus) {
486 case MCI_MODE_PAUSE:
487 case MCI_MODE_PLAY:
488 case MCI_MODE_RECORD:
490 int oldStat = wma->dwStatus;
491 wma->dwStatus = MCI_MODE_NOT_READY;
492 if (oldStat == MCI_MODE_PAUSE)
493 dwRet = waveOutReset(wma->hWave);
495 while (wma->dwStatus != MCI_MODE_STOP)
496 Sleep(10);
497 break;
498 default:
499 wma->dwStatus = MCI_MODE_STOP;
500 break;
503 if ((dwFlags & MCI_NOTIFY) && lpParms) {
504 mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
505 wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
508 return dwRet;
511 /***************************************************************************
512 * MCIAVI_mciPause [internal]
514 static DWORD MCIAVI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
516 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
518 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
519 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
521 if (wma->dwStatus == MCI_MODE_PLAY)
522 wma->dwStatus = MCI_MODE_PAUSE;
524 return (wma->lpWaveFormat) ? waveOutPause(wma->hWave) : 0;
527 /***************************************************************************
528 * MCIAVI_mciResume [internal]
530 static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
532 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
534 FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
536 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
537 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
539 if (wma->dwStatus == MCI_MODE_PAUSE)
540 wma->dwStatus = MCI_MODE_PLAY;
542 return (wma->lpWaveFormat) ? waveOutRestart(wma->hWave) : 0;
545 /***************************************************************************
546 * MCIAVI_mciSeek [internal]
548 static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
550 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
552 TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
554 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
555 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
557 EnterCriticalSection(&wma->cs);
559 MCIAVI_mciStop(wDevID, MCI_WAIT, 0);
561 if (dwFlags & MCI_SEEK_TO_START) {
562 wma->dwCurrVideoFrame = 0;
563 } else if (dwFlags & MCI_SEEK_TO_END) {
564 wma->dwCurrVideoFrame = wma->dwPlayableVideoFrames - 1;
565 } else if (dwFlags & MCI_TO) {
566 wma->dwCurrVideoFrame = MCIAVI_ConvertTimeFormatToFrame(wma, lpParms->dwTo);
567 } else {
568 WARN("dwFlag doesn't tell where to seek to...\n");
569 return MCIERR_MISSING_PARAMETER;
572 TRACE("Seeking to frame=%lu bytes\n", wma->dwCurrVideoFrame);
574 if (dwFlags & MCI_NOTIFY) {
575 mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
576 wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
579 LeaveCriticalSection(&wma->cs);
581 return 0;
584 /*****************************************************************************
585 * MCIAVI_mciLoad [internal]
587 static DWORD MCIAVI_mciLoad(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSA lpParms)
589 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
591 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
593 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
594 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
596 return 0;
599 /******************************************************************************
600 * MCIAVI_mciSave [internal]
602 static DWORD MCIAVI_mciSave(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SAVE_PARMSA lpParms)
604 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
606 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
608 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
609 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
611 return 0;
614 /******************************************************************************
615 * MCIAVI_mciFreeze [internal]
617 static DWORD MCIAVI_mciFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
619 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
621 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
623 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
624 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
626 return 0;
629 /******************************************************************************
630 * MCIAVI_mciRealize [internal]
632 static DWORD MCIAVI_mciRealize(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
634 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
636 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
638 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
639 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
641 return 0;
644 /******************************************************************************
645 * MCIAVI_mciUnFreeze [internal]
647 static DWORD MCIAVI_mciUnFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
649 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
651 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
653 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
654 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
656 return 0;
659 /******************************************************************************
660 * MCIAVI_mciUpdate [internal]
662 static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms)
664 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
666 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
668 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
669 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
671 return 0;
674 /******************************************************************************
675 * MCIAVI_mciStep [internal]
677 static DWORD MCIAVI_mciStep(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpParms)
679 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
681 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
683 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
684 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
686 return 0;
689 /******************************************************************************
690 * MCIAVI_mciCopy [internal]
692 static DWORD MCIAVI_mciCopy(UINT wDevID, DWORD dwFlags, LPMCI_DGV_COPY_PARMS lpParms)
694 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
696 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
698 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
699 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
701 return 0;
704 /******************************************************************************
705 * MCIAVI_mciCut [internal]
707 static DWORD MCIAVI_mciCut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUT_PARMS lpParms)
709 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
711 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
713 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
714 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
716 return 0;
719 /******************************************************************************
720 * MCIAVI_mciDelete [internal]
722 static DWORD MCIAVI_mciDelete(UINT wDevID, DWORD dwFlags, LPMCI_DGV_DELETE_PARMS lpParms)
724 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
726 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
728 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
729 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
731 return 0;
734 /******************************************************************************
735 * MCIAVI_mciPaste [internal]
737 static DWORD MCIAVI_mciPaste(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PASTE_PARMS lpParms)
739 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
741 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
743 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
744 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
746 return 0;
749 /******************************************************************************
750 * MCIAVI_mciCue [internal]
752 static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpParms)
754 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
756 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
758 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
759 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
761 return 0;
764 /******************************************************************************
765 * MCIAVI_mciCapture [internal]
767 static DWORD MCIAVI_mciCapture(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CAPTURE_PARMSA lpParms)
769 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
771 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
773 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
774 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
776 return 0;
779 /******************************************************************************
780 * MCIAVI_mciMonitor [internal]
782 static DWORD MCIAVI_mciMonitor(UINT wDevID, DWORD dwFlags, LPMCI_DGV_MONITOR_PARMS lpParms)
784 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
786 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
788 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
789 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
791 return 0;
794 /******************************************************************************
795 * MCIAVI_mciReserve [internal]
797 static DWORD MCIAVI_mciReserve(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESERVE_PARMSA lpParms)
799 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
801 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
803 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
804 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
806 return 0;
809 /******************************************************************************
810 * MCIAVI_mciSetAudio [internal]
812 static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSA lpParms)
814 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
816 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
818 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
819 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
821 return 0;
824 /******************************************************************************
825 * MCIAVI_mciSignal [internal]
827 static DWORD MCIAVI_mciSignal(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS lpParms)
829 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
831 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
833 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
834 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
836 return 0;
839 /******************************************************************************
840 * MCIAVI_mciSetVideo [internal]
842 static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_PARMSA lpParms)
844 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
846 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
848 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
849 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
851 return 0;
854 /******************************************************************************
855 * MCIAVI_mciQuality [internal]
857 static DWORD MCIAVI_mciQuality(UINT wDevID, DWORD dwFlags, LPMCI_DGV_QUALITY_PARMSA lpParms)
859 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
861 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
863 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
864 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
866 return 0;
869 /******************************************************************************
870 * MCIAVI_mciList [internal]
872 static DWORD MCIAVI_mciList(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LIST_PARMSA lpParms)
874 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
876 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
878 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
879 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
881 return 0;
884 /******************************************************************************
885 * MCIAVI_mciUndo [internal]
887 static DWORD MCIAVI_mciUndo(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
889 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
891 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
893 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
894 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
896 return 0;
899 /******************************************************************************
900 * MCIAVI_mciConfigure [internal]
902 static DWORD MCIAVI_mciConfigure(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
904 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
906 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
908 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
909 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
911 return 0;
914 /******************************************************************************
915 * MCIAVI_mciRestore [internal]
917 static DWORD MCIAVI_mciRestore(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESTORE_PARMSA lpParms)
919 WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
921 FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
923 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
924 if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
926 return 0;
929 /*======================================================================*
930 * MCI AVI entry points *
931 *======================================================================*/
933 /**************************************************************************
934 * DriverProc (MCIAVI.@)
936 LONG CALLBACK MCIAVI_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
937 DWORD dwParam1, DWORD dwParam2)
939 TRACE("(%08lX, %04X, %08lX, %08lX, %08lX)\n",
940 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
942 switch (wMsg) {
943 case DRV_LOAD: return 1;
944 case DRV_FREE: return 1;
945 case DRV_OPEN: return MCIAVI_drvOpen((LPSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSA)dwParam2);
946 case DRV_CLOSE: return MCIAVI_drvClose(dwDevID);
947 case DRV_ENABLE: return 1;
948 case DRV_DISABLE: return 1;
949 case DRV_QUERYCONFIGURE: return 1;
950 case DRV_CONFIGURE: return MCIAVI_drvConfigure(dwDevID);
951 case DRV_INSTALL: return DRVCNF_RESTART;
952 case DRV_REMOVE: return DRVCNF_RESTART;
955 if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION;
957 switch (wMsg) {
958 case MCI_OPEN_DRIVER: return MCIAVI_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSA) dwParam2);
959 case MCI_CLOSE_DRIVER: return MCIAVI_mciClose (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
960 case MCI_PLAY: return MCIAVI_mciPlay (dwDevID, dwParam1, (LPMCI_PLAY_PARMS) dwParam2);
961 case MCI_RECORD: return MCIAVI_mciRecord (dwDevID, dwParam1, (LPMCI_DGV_RECORD_PARMS) dwParam2);
962 case MCI_STOP: return MCIAVI_mciStop (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
963 case MCI_SET: return MCIAVI_mciSet (dwDevID, dwParam1, (LPMCI_DGV_SET_PARMS) dwParam2);
964 case MCI_PAUSE: return MCIAVI_mciPause (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
965 case MCI_RESUME: return MCIAVI_mciResume (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
966 case MCI_STATUS: return MCIAVI_mciStatus (dwDevID, dwParam1, (LPMCI_DGV_STATUS_PARMSA) dwParam2);
967 case MCI_GETDEVCAPS: return MCIAVI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS) dwParam2);
968 case MCI_INFO: return MCIAVI_mciInfo (dwDevID, dwParam1, (LPMCI_DGV_INFO_PARMSA) dwParam2);
969 case MCI_SEEK: return MCIAVI_mciSeek (dwDevID, dwParam1, (LPMCI_SEEK_PARMS) dwParam2);
970 case MCI_PUT: return MCIAVI_mciPut (dwDevID, dwParam1, (LPMCI_DGV_PUT_PARMS) dwParam2);
971 case MCI_WINDOW: return MCIAVI_mciWindow (dwDevID, dwParam1, (LPMCI_DGV_WINDOW_PARMSA) dwParam2);
972 case MCI_LOAD: return MCIAVI_mciLoad (dwDevID, dwParam1, (LPMCI_DGV_LOAD_PARMSA) dwParam2);
973 case MCI_SAVE: return MCIAVI_mciSave (dwDevID, dwParam1, (LPMCI_DGV_SAVE_PARMSA) dwParam2);
974 case MCI_FREEZE: return MCIAVI_mciFreeze (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2);
975 case MCI_REALIZE: return MCIAVI_mciRealize (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
976 case MCI_UNFREEZE: return MCIAVI_mciUnFreeze (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2);
977 case MCI_UPDATE: return MCIAVI_mciUpdate (dwDevID, dwParam1, (LPMCI_DGV_UPDATE_PARMS) dwParam2);
978 case MCI_WHERE: return MCIAVI_mciWhere (dwDevID, dwParam1, (LPMCI_DGV_RECT_PARMS) dwParam2);
979 case MCI_STEP: return MCIAVI_mciStep (dwDevID, dwParam1, (LPMCI_DGV_STEP_PARMS) dwParam2);
980 case MCI_COPY: return MCIAVI_mciCopy (dwDevID, dwParam1, (LPMCI_DGV_COPY_PARMS) dwParam2);
981 case MCI_CUT: return MCIAVI_mciCut (dwDevID, dwParam1, (LPMCI_DGV_CUT_PARMS) dwParam2);
982 case MCI_DELETE: return MCIAVI_mciDelete (dwDevID, dwParam1, (LPMCI_DGV_DELETE_PARMS) dwParam2);
983 case MCI_PASTE: return MCIAVI_mciPaste (dwDevID, dwParam1, (LPMCI_DGV_PASTE_PARMS) dwParam2);
984 case MCI_CUE: return MCIAVI_mciCue (dwDevID, dwParam1, (LPMCI_DGV_CUE_PARMS) dwParam2);
985 /* Digital Video specific */
986 case MCI_CAPTURE: return MCIAVI_mciCapture (dwDevID, dwParam1, (LPMCI_DGV_CAPTURE_PARMSA) dwParam2);
987 case MCI_MONITOR: return MCIAVI_mciMonitor (dwDevID, dwParam1, (LPMCI_DGV_MONITOR_PARMS) dwParam2);
988 case MCI_RESERVE: return MCIAVI_mciReserve (dwDevID, dwParam1, (LPMCI_DGV_RESERVE_PARMSA) dwParam2);
989 case MCI_SETAUDIO: return MCIAVI_mciSetAudio (dwDevID, dwParam1, (LPMCI_DGV_SETAUDIO_PARMSA) dwParam2);
990 case MCI_SIGNAL: return MCIAVI_mciSignal (dwDevID, dwParam1, (LPMCI_DGV_SIGNAL_PARMS) dwParam2);
991 case MCI_SETVIDEO: return MCIAVI_mciSetVideo (dwDevID, dwParam1, (LPMCI_DGV_SETVIDEO_PARMSA) dwParam2);
992 case MCI_QUALITY: return MCIAVI_mciQuality (dwDevID, dwParam1, (LPMCI_DGV_QUALITY_PARMSA) dwParam2);
993 case MCI_LIST: return MCIAVI_mciList (dwDevID, dwParam1, (LPMCI_DGV_LIST_PARMSA) dwParam2);
994 case MCI_UNDO: return MCIAVI_mciUndo (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
995 case MCI_CONFIGURE: return MCIAVI_mciConfigure (dwDevID, dwParam1, (LPMCI_GENERIC_PARMS) dwParam2);
996 case MCI_RESTORE: return MCIAVI_mciRestore (dwDevID, dwParam1, (LPMCI_DGV_RESTORE_PARMSA) dwParam2);
998 case MCI_SPIN:
999 case MCI_ESCAPE:
1000 WARN("Unsupported command [%lu]\n", wMsg);
1001 break;
1002 case MCI_OPEN:
1003 case MCI_CLOSE:
1004 FIXME("Shouldn't receive a MCI_OPEN or CLOSE message\n");
1005 break;
1006 default:
1007 TRACE("Sending msg [%lu] to default driver proc\n", wMsg);
1008 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1010 return MCIERR_UNRECOGNIZED_COMMAND;