MCI #5: Much improved mciavi driver
Dmitry Timoshkov
dmitry at baikal.ru
Tue Dec 30 10:48:19 CST 2003
Hello,
Please apply after MCI #4.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Much improved mciavi driver. Fixed synchronization, RIFF file
with many streams parsing, added support for some MCI_PUT and
MCI_WHERE cases.
diff -u cvs/hq/wine/dlls/winmm/mciavi/info.c wine/dlls/winmm/mciavi/info.c
--- cvs/hq/wine/dlls/winmm/mciavi/info.c 2003-12-30 22:44:20.000000000 +0800
+++ wine/dlls/winmm/mciavi/info.c 2003-12-30 23:28:23.000000000 +0800
@@ -82,6 +82,8 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID,
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (dwFlags & MCI_GETDEVCAPS_ITEM) {
switch (lpParms->dwItem) {
case MCI_GETDEVCAPS_DEVICE_TYPE:
@@ -131,12 +133,15 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID,
break;
default:
FIXME("Unknown capability (%08lx) !\n", lpParms->dwItem);
- return MCIERR_UNRECOGNIZED_COMMAND;
+ ret = MCIERR_UNRECOGNIZED_COMMAND;
+ break;
}
} else {
WARN("No GetDevCaps-Item !\n");
- return MCIERR_UNRECOGNIZED_COMMAND;
+ ret = MCIERR_UNRECOGNIZED_COMMAND;
}
+
+ LeaveCriticalSection(&wma->cs);
return ret;
}
@@ -155,15 +160,18 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD
TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
+ EnterCriticalSection(&wma->cs);
+
switch (dwFlags) {
case MCI_INFO_PRODUCT:
str = "Wine's AVI player";
break;
case MCI_INFO_FILE:
- str = wma->openParms.lpstrElementName;
+ str = wma->lpFileName;
break;
default:
WARN("Don't know this info command (%lu)\n", dwFlags);
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (str) {
@@ -175,6 +183,8 @@ DWORD MCIAVI_mciInfo(UINT wDevID, DWORD
} else {
lpParms->lpstrReturn[0] = 0;
}
+
+ LeaveCriticalSection(&wma->cs);
return ret;
}
@@ -188,6 +198,8 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD d
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (dwFlags & MCI_SET_TIME_FORMAT) {
switch (lpParms->dwTimeFormat) {
case MCI_FORMAT_MILLISECONDS:
@@ -200,18 +212,22 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD d
break;
default:
WARN("Bad time format %lu!\n", lpParms->dwTimeFormat);
+ LeaveCriticalSection(&wma->cs);
return MCIERR_BAD_TIME_FORMAT;
}
}
if (dwFlags & MCI_SET_DOOR_OPEN) {
TRACE("No support for door open !\n");
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
if (dwFlags & MCI_SET_DOOR_CLOSED) {
TRACE("No support for door close !\n");
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
+
if (dwFlags & MCI_SET_ON) {
char buffer[256];
@@ -302,6 +318,7 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD d
FIXME("Setting speed to %ld\n", lpParms->dwSpeed);
}
+ LeaveCriticalSection(&wma->cs);
return 0;
}
@@ -316,6 +333,8 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (dwFlags & MCI_STATUS_ITEM) {
switch (lpParms->dwItem) {
case MCI_STATUS_CURRENT_TRACK:
@@ -325,6 +344,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR
case MCI_STATUS_LENGTH:
if (!wma->hFile) {
lpParms->dwReturn = 0;
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
/* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
@@ -334,7 +354,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR
case MCI_STATUS_MODE:
lpParms->dwReturn = MAKEMCIRESOURCE(wma->dwStatus, wma->dwStatus);
ret = MCI_RESOURCE_RETURNED;
- TRACE("MCI_STATUS_MODE => %u\n", LOWORD(lpParms->dwReturn));
+ TRACE("MCI_STATUS_MODE => 0x%04x\n", LOWORD(lpParms->dwReturn));
break;
case MCI_STATUS_MEDIA_PRESENT:
TRACE("MCI_STATUS_MEDIA_PRESENT => TRUE\n");
@@ -348,6 +368,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR
case MCI_STATUS_POSITION:
if (!wma->hFile) {
lpParms->dwReturn = 0;
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNSUPPORTED_FUNCTION;
}
/* only one track in file is currently handled, so don't take care of MCI_TRACK flag */
@@ -401,7 +422,7 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR
TRACE("MCI_DGV_STATUS_HPAL => %lx\n", lpParms->dwReturn);
break;
case MCI_DGV_STATUS_HWND:
- lpParms->dwReturn = (DWORD)wma->hWndPaint;
+ lpParms->dwReturn = (DWORD_PTR)wma->hWndPaint;
TRACE("MCI_DGV_STATUS_HWND => %p\n", wma->hWndPaint);
break;
#if 0
@@ -436,17 +457,20 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWOR
default:
FIXME("Unknowm command %08lX !\n", lpParms->dwItem);
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
} else {
WARN("No Status-Item!\n");
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
+
if (dwFlags & MCI_NOTIFY) {
TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
- wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ wDevID, MCI_NOTIFY_SUCCESSFUL);
}
-
+ LeaveCriticalSection(&wma->cs);
return ret;
}
diff -u cvs/hq/wine/dlls/winmm/mciavi/mciavi.c wine/dlls/winmm/mciavi/mciavi.c
--- cvs/hq/wine/dlls/winmm/mciavi/mciavi.c 2003-12-30 22:44:20.000000000 +0800
+++ wine/dlls/winmm/mciavi/mciavi.c 2003-12-30 23:28:23.000000000 +0800
@@ -4,6 +4,7 @@
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
+ * Copyright 2003 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,24 +27,25 @@
* - lots of messages still need to be handled (cf FIXME)
* - synchronization between audio and video (especially for interleaved
* files)
- * - synchronization (as in all the Wine MCI drivers (MCI_WAIT) messages)
* - robustness when reading file can be enhanced
* - better move the AVI handling part to avifile DLL and make use of it
* - some files appear to have more than one audio stream (we only play the
* first one)
* - some files contain an index of audio/video frame. Better use it,
* instead of rebuilding it
- * - mciWindow (for setting the hWnd) is broken with media player
* - stopping while playing a file with sound blocks until all buffered
* audio is played... still should be stopped ASAP
*/
+#include <assert.h>
#include <string.h>
#include "private_mciavi.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
+static DWORD MCIAVI_mciStop(UINT, DWORD, LPMCI_GENERIC_PARMS);
+
/* ===================================================================
* ===================================================================
* FIXME: should be using the new mmThreadXXXX functions from WINMM
@@ -54,10 +56,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
* =================================================================== */
struct SCA {
- UINT wDevID;
- UINT wMsg;
- DWORD dwParam1;
- DWORD dwParam2;
+ MCIDEVICEID wDevID;
+ UINT wMsg;
+ DWORD_PTR dwParam1;
+ DWORD_PTR dwParam2;
};
/**************************************************************************
@@ -68,15 +70,15 @@ static DWORD CALLBACK MCI_SCAStarter(LPV
struct SCA* sca = (struct SCA*)arg;
DWORD ret;
- TRACE("In thread before async command (%08x,%u,%08lx,%08lx)\n",
+ TRACE("In thread before async command (%08x,%04x,%08lx,%08lx)\n",
sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);
ret = mciSendCommandA(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2);
- TRACE("In thread after async command (%08x,%u,%08lx,%08lx)\n",
+ TRACE("In thread after async command (%08x,%04x,%08lx,%08lx)\n",
sca->wDevID, sca->wMsg, sca->dwParam1, sca->dwParam2);
HeapFree(GetProcessHeap(), 0, sca);
ExitThread(ret);
- WARN("Should not happen ? what's wrong \n");
/* should not go after this point */
+ assert(0);
return ret;
}
@@ -84,7 +86,7 @@ static DWORD CALLBACK MCI_SCAStarter(LPV
* MCI_SendCommandAsync [internal]
*/
static DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1,
- DWORD dwParam2, UINT size)
+ DWORD_PTR dwParam2, UINT size)
{
struct SCA* sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA) + size);
@@ -96,7 +98,7 @@ static DWORD MCI_SendCommandAsync(UINT w
sca->dwParam1 = dwParam1;
if (size && dwParam2) {
- sca->dwParam2 = (DWORD)sca + sizeof(struct SCA);
+ sca->dwParam2 = (DWORD_PTR)sca + sizeof(struct SCA);
/* copy structure passed by program in dwParam2 to be sure
* we can still use it whatever the program does
*/
@@ -137,17 +139,22 @@ static DWORD MCIAVI_drvOpen(LPSTR str, L
WINE_MCIAVI* wma;
static const WCHAR mciAviWStr[] = {'M','C','I','A','V','I',0};
+ TRACE("%s, %p\n", debugstr_a(str), modp);
+
+ /* session instance */
if (!modp) return 0xFFFFFFFF;
wma = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCIAVI));
if (!wma)
return 0;
+ InitializeCriticalSection(&wma->cs);
wma->wDevID = modp->wDeviceID;
- mciSetDriverData(wma->wDevID, (DWORD)wma);
wma->wCommandTable = mciLoadCommandResource(MCIAVI_hInstance, mciAviWStr, 0);
modp->wCustomCommandTable = wma->wCommandTable;
modp->wType = MCI_DEVTYPE_DIGITAL_VIDEO;
+ mciSetDriverData(wma->wDevID, (DWORD)wma);
+
return modp->wDeviceID;
}
@@ -156,11 +163,24 @@ static DWORD MCIAVI_drvOpen(LPSTR str, L
*/
static DWORD MCIAVI_drvClose(DWORD dwDevID)
{
- WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
+ WINE_MCIAVI *wma;
+
+ TRACE("%04lx\n", dwDevID);
+
+ /* finish all outstanding things */
+ MCIAVI_mciClose(dwDevID, MCI_WAIT, NULL);
+
+ wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
if (wma) {
+ EnterCriticalSection(&wma->cs);
+
mciSetDriverData(dwDevID, 0);
mciFreeCommandResource(wma->wCommandTable);
+
+ LeaveCriticalSection(&wma->cs);
+ DeleteCriticalSection(&wma->cs);
+
HeapFree(GetProcessHeap(), 0, wma);
return 1;
}
@@ -172,7 +192,13 @@ static DWORD MCIAVI_drvClose(DWORD dwDev
*/
static DWORD MCIAVI_drvConfigure(DWORD dwDevID)
{
- WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
+ WINE_MCIAVI *wma;
+
+ TRACE("%04lx\n", dwDevID);
+
+ MCIAVI_mciStop(dwDevID, MCI_WAIT, NULL);
+
+ wma = (WINE_MCIAVI*)mciGetDriverData(dwDevID);
if (wma) {
MessageBoxA(0, "Sample AVI Wine Driver !", "MM-Wine Driver", MB_OK);
@@ -202,6 +228,10 @@ static void MCIAVI_CleanUp(WINE_MCIAVI*
if (wma->hFile) {
mmioClose(wma->hFile, 0);
wma->hFile = 0;
+
+ if (wma->lpFileName) HeapFree(GetProcessHeap(), 0, wma->lpFileName);
+ wma->lpFileName = NULL;
+
if (wma->lpVideoIndex) HeapFree(GetProcessHeap(), 0, wma->lpVideoIndex);
wma->lpVideoIndex = NULL;
if (wma->lpAudioIndex) HeapFree(GetProcessHeap(), 0, wma->lpAudioIndex);
@@ -231,22 +261,26 @@ static void MCIAVI_CleanUp(WINE_MCIAVI*
}
}
-static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
-
/***************************************************************************
* MCIAVI_mciOpen [internal]
*/
static DWORD MCIAVI_mciOpen(UINT wDevID, DWORD dwFlags,
LPMCI_DGV_OPEN_PARMSA lpOpenParms)
{
- WINE_MCIAVI* wma = (WINE_MCIAVI*)mciGetDriverData(wDevID);
+ WINE_MCIAVI *wma;
LRESULT dwRet = 0;
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpOpenParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = (WINE_MCIAVI *)mciGetDriverData(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (wma->nUseCount > 0) {
/* The driver is already open on this channel */
/* If the driver was opened shareable before and this open specifies */
@@ -254,14 +288,16 @@ static DWORD MCIAVI_mciOpen(UINT wDevID,
if (wma->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
++wma->nUseCount;
else
+ {
+ LeaveCriticalSection(&wma->cs);
return MCIERR_MUST_USE_SHAREABLE;
+ }
} else {
wma->nUseCount = 1;
wma->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
}
wma->dwStatus = MCI_MODE_NOT_READY;
- InitializeCriticalSection(&wma->cs);
if (dwFlags & MCI_OPEN_ELEMENT) {
if (dwFlags & MCI_OPEN_ELEMENT_ID) {
@@ -273,7 +309,11 @@ static DWORD MCIAVI_mciOpen(UINT wDevID,
/* FIXME : what should be done id wma->hFile is already != 0, or the driver is playin' */
TRACE("MCI_OPEN_ELEMENT '%s' !\n", lpOpenParms->lpstrElementName);
- if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0)) {
+ if (lpOpenParms->lpstrElementName && (strlen(lpOpenParms->lpstrElementName) > 0))
+ {
+ wma->lpFileName = HeapAlloc(GetProcessHeap(), 0, strlen(lpOpenParms->lpstrElementName) + 1);
+ strcpy(wma->lpFileName, lpOpenParms->lpstrElementName);
+
wma->hFile = mmioOpenA(lpOpenParms->lpstrElementName, NULL,
MMIO_ALLOCBUF | MMIO_DENYWRITE | MMIO_READWRITE);
@@ -295,44 +335,52 @@ static DWORD MCIAVI_mciOpen(UINT wDevID,
}
}
- memcpy(&wma->openParms, lpOpenParms, sizeof(MCI_WAVE_OPEN_PARMSA));
-
if (dwRet == 0) {
+ TRACE("lpOpenParms->wDeviceID = %04x\n", lpOpenParms->wDeviceID);
+
wma->dwStatus = MCI_MODE_STOP;
wma->dwMciTimeFormat = MCI_FORMAT_FRAMES;
} else {
MCIAVI_CleanUp(wma);
}
- return dwRet;
+ LeaveCriticalSection(&wma->cs);
+ return dwRet;
}
/***************************************************************************
* MCIAVI_mciClose [internal]
*/
-static DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
+DWORD MCIAVI_mciClose(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
DWORD dwRet = 0;
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
+ wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (wma->nUseCount == 1) {
if (wma->dwStatus != MCI_MODE_STOP)
- dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, lpParms);
+ dwRet = MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
MCIAVI_CleanUp(wma);
if ((dwFlags & MCI_NOTIFY) && lpParms) {
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
- wma->openParms.wDeviceID,
+ wDevID,
MCI_NOTIFY_SUCCESSFUL);
}
- HeapFree(GetProcessHeap(), 0, wma);
+ LeaveCriticalSection(&wma->cs);
return dwRet;
}
wma->nUseCount--;
+
+ LeaveCriticalSection(&wma->cs);
return dwRet;
}
@@ -341,7 +389,7 @@ static DWORD MCIAVI_mciClose(UINT wDevID
*/
static DWORD MCIAVI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
DWORD tc;
DWORD frameTime;
DWORD delta;
@@ -353,19 +401,34 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
- if (!wma->hFile) return MCIERR_FILE_NOT_FOUND;
- if (!wma->hWndPaint) return MCIERR_NO_WINDOW;
+ EnterCriticalSection(&wma->cs);
+
+ if (!wma->hFile)
+ {
+ LeaveCriticalSection(&wma->cs);
+ return MCIERR_FILE_NOT_FOUND;
+ }
+ if (!wma->hWndPaint)
+ {
+ LeaveCriticalSection(&wma->cs);
+ return MCIERR_NO_WINDOW;
+ }
wma->dwStatus = MCI_MODE_PLAY;
+ LeaveCriticalSection(&wma->cs);
if (!(dwFlags & MCI_WAIT)) {
- return MCI_SendCommandAsync(wma->openParms.wDeviceID, MCI_PLAY, dwFlags,
- (DWORD)lpParms, sizeof(MCI_PLAY_PARMS));
+ return MCI_SendCommandAsync(wDevID, MCI_PLAY, dwFlags,
+ (DWORD_PTR)lpParms, sizeof(MCI_PLAY_PARMS));
}
- ShowWindow(wma->hWndPaint, SW_SHOW);
+ ShowWindow(wma->hWndPaint, SW_SHOWNA);
+
+ EnterCriticalSection(&wma->cs);
dwFromFrame = wma->dwCurrVideoFrame;
dwToFrame = wma->dwPlayableVideoFrames - 1;
@@ -381,10 +444,14 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
TRACE("Playing from frame=%lu to frame=%lu\n", dwFromFrame, dwToFrame);
- if (dwToFrame <= wma->dwCurrVideoFrame)
- return TRUE;
wma->dwCurrVideoFrame = dwFromFrame;
+ if (dwToFrame <= wma->dwCurrVideoFrame)
+ {
+ dwRet = 0;
+ goto mci_play_done;
+ }
+
if (dwFlags & (MCI_DGV_PLAY_REPEAT|MCI_DGV_PLAY_REVERSE|MCI_MCIAVI_PLAY_WINDOW|MCI_MCIAVI_PLAY_FULLSCREEN))
FIXME("Unsupported flag %08lx\n", dwFlags);
@@ -392,13 +459,19 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
frameTime = (wma->mah.dwMicroSecPerFrame + 500) / 1000;
if (wma->lpWaveFormat) {
- if ((dwRet = MCIAVI_OpenAudio(wma, &nHdr, &waveHdr)) != 0)
- goto cleanUp;
+ if (MCIAVI_OpenAudio(wma, &nHdr, &waveHdr) != 0)
+ {
+ /* can't play audio */
+ HeapFree(GetProcessHeap(), 0, wma->lpWaveFormat);
+ wma->lpWaveFormat = NULL;
+ }
+ else
/* fill the queue with as many wave headers as possible */
MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
}
- while (wma->dwStatus != MCI_MODE_STOP && wma->dwStatus != MCI_MODE_NOT_READY) {
+ while (wma->dwStatus == MCI_MODE_PLAY)
+ {
tc = GetTickCount();
MCIAVI_DrawFrame(wma);
@@ -406,23 +479,36 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
if (wma->lpWaveFormat) {
MCIAVI_PlayAudioBlocks(wma, nHdr, waveHdr);
delta = GetTickCount() - tc;
- WaitForSingleObject(wma->hEvent, (delta >= frameTime) ? 0 : frameTime - delta);
+
+ LeaveCriticalSection(&wma->cs);
+ MsgWaitForMultipleObjects(1, &wma->hEvent, FALSE,
+ (delta >= frameTime) ? 0 : frameTime - delta, MWMO_INPUTAVAILABLE);
+ EnterCriticalSection(&wma->cs);
+
+ if (wma->dwStatus != MCI_MODE_PLAY) break;
}
delta = GetTickCount() - tc;
if (delta < frameTime)
- Sleep(frameTime - delta);
-
- if (wma->dwCurrVideoFrame++ >= dwToFrame) {
- wma->dwCurrVideoFrame--;
- wma->dwStatus = MCI_MODE_STOP;
- }
+ {
+ LeaveCriticalSection(&wma->cs);
+ MsgWaitForMultipleObjects(0, NULL, FALSE, frameTime - delta, MWMO_INPUTAVAILABLE);
+ EnterCriticalSection(&wma->cs);
+ }
+
+ if (wma->dwCurrVideoFrame < dwToFrame)
+ wma->dwCurrVideoFrame++;
+ else
+ break;
}
if (wma->lpWaveFormat) {
- while (*(volatile DWORD*)&wma->dwEventCount != nHdr - 1) {
- Sleep(100);
- }
+ while (wma->dwEventCount != nHdr - 1)
+ {
+ LeaveCriticalSection(&wma->cs);
+ Sleep(100);
+ EnterCriticalSection(&wma->cs);
+ }
/* just to get rid of some race conditions between play, stop and pause */
waveOutReset(wma->hWave);
@@ -432,7 +518,7 @@ static DWORD MCIAVI_mciPlay(UINT wDevID,
}
dwRet = 0;
-cleanUp:
+
if (wma->lpWaveFormat) {
HeapFree(GetProcessHeap(), 0, waveHdr);
@@ -443,14 +529,15 @@ cleanUp:
CloseHandle(wma->hEvent);
}
+mci_play_done:
+ wma->dwStatus = MCI_MODE_STOP;
+
if (lpParms && (dwFlags & MCI_NOTIFY)) {
TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
- wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ wDevID, MCI_NOTIFY_SUCCESSFUL);
}
-
- wma->dwStatus = MCI_MODE_STOP;
-
+ LeaveCriticalSection(&wma->cs);
return dwRet;
}
@@ -459,14 +546,20 @@ cleanUp:
*/
static DWORD MCIAVI_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECORD_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
wma->dwStatus = MCI_MODE_RECORD;
+ LeaveCriticalSection(&wma->cs);
return 0;
}
@@ -475,14 +568,16 @@ static DWORD MCIAVI_mciRecord(UINT wDevI
*/
static DWORD MCIAVI_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
DWORD dwRet = 0;
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
switch (wma->dwStatus) {
case MCI_MODE_PAUSE:
case MCI_MODE_PLAY:
@@ -493,19 +588,26 @@ static DWORD MCIAVI_mciStop(UINT wDevID,
if (oldStat == MCI_MODE_PAUSE)
dwRet = waveOutReset(wma->hWave);
}
- while (wma->dwStatus != MCI_MODE_STOP)
- Sleep(10);
- break;
+ /* fall through */
default:
- wma->dwStatus = MCI_MODE_STOP;
+ do /* one more chance for an async thread to finish */
+ {
+ LeaveCriticalSection(&wma->cs);
+ Sleep(10);
+ EnterCriticalSection(&wma->cs);
+ } while (wma->dwStatus != MCI_MODE_STOP);
+
break;
+
+ case MCI_MODE_NOT_READY:
+ break;
}
if ((dwFlags & MCI_NOTIFY) && lpParms) {
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
- wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ wDevID, MCI_NOTIFY_SUCCESSFUL);
}
-
+ LeaveCriticalSection(&wma->cs);
return dwRet;
}
@@ -514,15 +616,21 @@ static DWORD MCIAVI_mciStop(UINT wDevID,
*/
static DWORD MCIAVI_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
+ DWORD ret;
- if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (wma->dwStatus == MCI_MODE_PLAY)
wma->dwStatus = MCI_MODE_PAUSE;
- return (wma->lpWaveFormat) ? waveOutPause(wma->hWave) : 0;
+ ret = (wma->lpWaveFormat) ? waveOutPause(wma->hWave) : 0;
+
+ LeaveCriticalSection(&wma->cs);
+ return ret;
}
/***************************************************************************
@@ -530,17 +638,23 @@ static DWORD MCIAVI_mciPause(UINT wDevID
*/
static DWORD MCIAVI_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
+ DWORD ret;
FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
- if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (wma->dwStatus == MCI_MODE_PAUSE)
wma->dwStatus = MCI_MODE_PLAY;
- return (wma->lpWaveFormat) ? waveOutRestart(wma->hWave) : 0;
+ ret = (wma->lpWaveFormat) ? waveOutRestart(wma->hWave) : 0;
+
+ LeaveCriticalSection(&wma->cs);
+ return ret;
}
/***************************************************************************
@@ -548,17 +662,19 @@ static DWORD MCIAVI_mciResume(UINT wDevI
*/
static DWORD MCIAVI_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
EnterCriticalSection(&wma->cs);
- MCIAVI_mciStop(wDevID, MCI_WAIT, 0);
-
if (dwFlags & MCI_SEEK_TO_START) {
wma->dwCurrVideoFrame = 0;
} else if (dwFlags & MCI_SEEK_TO_END) {
@@ -575,11 +691,9 @@ static DWORD MCIAVI_mciSeek(UINT wDevID,
if (dwFlags & MCI_NOTIFY) {
mciDriverNotify(HWND_32(LOWORD(lpParms->dwCallback)),
- wma->openParms.wDeviceID, MCI_NOTIFY_SUCCESSFUL);
+ wDevID, MCI_NOTIFY_SUCCESSFUL);
}
-
LeaveCriticalSection(&wma->cs);
-
return 0;
}
@@ -588,11 +702,15 @@ static DWORD MCIAVI_mciSeek(UINT wDevID,
*/
static DWORD MCIAVI_mciLoad(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LOAD_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -603,11 +721,15 @@ static DWORD MCIAVI_mciLoad(UINT wDevID,
*/
static DWORD MCIAVI_mciSave(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SAVE_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -618,11 +740,15 @@ static DWORD MCIAVI_mciSave(UINT wDevID,
*/
static DWORD MCIAVI_mciFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -633,11 +759,15 @@ static DWORD MCIAVI_mciFreeze(UINT wDevI
*/
static DWORD MCIAVI_mciRealize(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -648,11 +778,15 @@ static DWORD MCIAVI_mciRealize(UINT wDev
*/
static DWORD MCIAVI_mciUnFreeze(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -663,11 +797,15 @@ static DWORD MCIAVI_mciUnFreeze(UINT wDe
*/
static DWORD MCIAVI_mciUpdate(UINT wDevID, DWORD dwFlags, LPMCI_DGV_UPDATE_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -678,11 +816,15 @@ static DWORD MCIAVI_mciUpdate(UINT wDevI
*/
static DWORD MCIAVI_mciStep(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STEP_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -693,11 +835,15 @@ static DWORD MCIAVI_mciStep(UINT wDevID,
*/
static DWORD MCIAVI_mciCopy(UINT wDevID, DWORD dwFlags, LPMCI_DGV_COPY_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -708,11 +854,15 @@ static DWORD MCIAVI_mciCopy(UINT wDevID,
*/
static DWORD MCIAVI_mciCut(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUT_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -723,11 +873,15 @@ static DWORD MCIAVI_mciCut(UINT wDevID,
*/
static DWORD MCIAVI_mciDelete(UINT wDevID, DWORD dwFlags, LPMCI_DGV_DELETE_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -738,11 +892,15 @@ static DWORD MCIAVI_mciDelete(UINT wDevI
*/
static DWORD MCIAVI_mciPaste(UINT wDevID, DWORD dwFlags, LPMCI_DGV_PASTE_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -753,11 +911,15 @@ static DWORD MCIAVI_mciPaste(UINT wDevID
*/
static DWORD MCIAVI_mciCue(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CUE_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -768,11 +930,15 @@ static DWORD MCIAVI_mciCue(UINT wDevID,
*/
static DWORD MCIAVI_mciCapture(UINT wDevID, DWORD dwFlags, LPMCI_DGV_CAPTURE_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -783,11 +949,15 @@ static DWORD MCIAVI_mciCapture(UINT wDev
*/
static DWORD MCIAVI_mciMonitor(UINT wDevID, DWORD dwFlags, LPMCI_DGV_MONITOR_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -798,11 +968,15 @@ static DWORD MCIAVI_mciMonitor(UINT wDev
*/
static DWORD MCIAVI_mciReserve(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESERVE_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -813,11 +987,15 @@ static DWORD MCIAVI_mciReserve(UINT wDev
*/
static DWORD MCIAVI_mciSetAudio(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETAUDIO_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -828,11 +1006,15 @@ static DWORD MCIAVI_mciSetAudio(UINT wDe
*/
static DWORD MCIAVI_mciSignal(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SIGNAL_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -843,11 +1025,15 @@ static DWORD MCIAVI_mciSignal(UINT wDevI
*/
static DWORD MCIAVI_mciSetVideo(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SETVIDEO_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -858,11 +1044,15 @@ static DWORD MCIAVI_mciSetVideo(UINT wDe
*/
static DWORD MCIAVI_mciQuality(UINT wDevID, DWORD dwFlags, LPMCI_DGV_QUALITY_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -873,11 +1063,15 @@ static DWORD MCIAVI_mciQuality(UINT wDev
*/
static DWORD MCIAVI_mciList(UINT wDevID, DWORD dwFlags, LPMCI_DGV_LIST_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -888,11 +1082,15 @@ static DWORD MCIAVI_mciList(UINT wDevID,
*/
static DWORD MCIAVI_mciUndo(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -903,11 +1101,15 @@ static DWORD MCIAVI_mciUndo(UINT wDevID,
*/
static DWORD MCIAVI_mciConfigure(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -918,11 +1120,15 @@ static DWORD MCIAVI_mciConfigure(UINT wD
*/
static DWORD MCIAVI_mciRestore(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RESTORE_PARMSA lpParms)
{
- WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
+ WINE_MCIAVI *wma;
FIXME("(%04x, %08lx, %p) : stub\n", wDevID, dwFlags, lpParms);
+ MCIAVI_mciStop(wDevID, MCI_WAIT, NULL);
+
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
+
+ wma = MCIAVI_mciGetOpenDev(wDevID);
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
return 0;
@@ -954,7 +1160,8 @@ LONG CALLBACK MCIAVI_DriverProc(DWORD dw
case DRV_REMOVE: return DRVCNF_RESTART;
}
- if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION;
+ /* session instance */
+ if (dwDevID == 0xFFFFFFFF) return 1;
switch (wMsg) {
case MCI_OPEN_DRIVER: return MCIAVI_mciOpen (dwDevID, dwParam1, (LPMCI_DGV_OPEN_PARMSA) dwParam2);
diff -u cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c wine/dlls/winmm/mciavi/mmoutput.c
--- cvs/hq/wine/dlls/winmm/mciavi/mmoutput.c 2003-12-30 22:44:20.000000000 +0800
+++ wine/dlls/winmm/mciavi/mmoutput.c 2003-12-30 23:28:23.000000000 +0800
@@ -4,6 +4,7 @@
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
+ * Copyright 2003 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,16 +26,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(mciavi);
-static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
+static BOOL MCIAVI_GetInfoAudio(WINE_MCIAVI* wma, const MMCKINFO* mmckList, MMCKINFO *mmckStream)
{
MMCKINFO mmckInfo;
- mmckInfo.ckid = ckidSTREAMHEADER;
- if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
- WARN("Can't find 'strh' chunk\n");
- return FALSE;
- }
-
mmioRead(wma->hFile, (LPSTR)&wma->ash_audio, sizeof(wma->ash_audio));
TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_audio.fccType)),
@@ -59,11 +54,12 @@ static BOOL MCIAVI_GetInfoAudio(WINE_MCI
TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_audio.rcFrame.top, wma->ash_audio.rcFrame.left,
wma->ash_audio.rcFrame.bottom, wma->ash_audio.rcFrame.right);
- mmioAscend(wma->hFile, &mmckInfo, 0);
+ /* rewind to the start of the stream */
+ mmioAscend(wma->hFile, mmckStream, 0);
mmckInfo.ckid = ckidSTREAMFORMAT;
if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
- WARN("Can't find 'strh' chunk\n");
+ WARN("Can't find 'strf' chunk\n");
return FALSE;
}
if (mmckInfo.cksize < sizeof(WAVEFORMAT)) {
@@ -87,21 +83,13 @@ static BOOL MCIAVI_GetInfoAudio(WINE_MCI
if (mmckInfo.cksize >= sizeof(WAVEFORMATEX))
TRACE("waveFormat.cbSize=%d\n", wma->lpWaveFormat->cbSize);
- mmioAscend(wma->hFile, &mmckInfo, 0);
-
return TRUE;
}
-static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList)
+static BOOL MCIAVI_GetInfoVideo(WINE_MCIAVI* wma, const MMCKINFO* mmckList, MMCKINFO* mmckStream)
{
MMCKINFO mmckInfo;
- mmckInfo.ckid = ckidSTREAMHEADER;
- if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
- WARN("Can't find 'strh' chunk\n");
- return FALSE;
- }
-
mmioRead(wma->hFile, (LPSTR)&wma->ash_video, sizeof(wma->ash_video));
TRACE("ash.fccType='%c%c%c%c'\n", LOBYTE(LOWORD(wma->ash_video.fccType)),
@@ -126,11 +114,12 @@ static BOOL MCIAVI_GetInfoVideo(WINE_MCI
TRACE("ash.rcFrame=(%d,%d,%d,%d)\n", wma->ash_video.rcFrame.top, wma->ash_video.rcFrame.left,
wma->ash_video.rcFrame.bottom, wma->ash_video.rcFrame.right);
- mmioAscend(wma->hFile, &mmckInfo, 0);
+ /* rewind to the start of the stream */
+ mmioAscend(wma->hFile, mmckStream, 0);
mmckInfo.ckid = ckidSTREAMFORMAT;
if (mmioDescend(wma->hFile, &mmckInfo, mmckList, MMIO_FINDCHUNK) != 0) {
- WARN("Can't find 'strh' chunk\n");
+ WARN("Can't find 'strf' chunk\n");
return FALSE;
}
@@ -154,7 +143,12 @@ static BOOL MCIAVI_GetInfoVideo(WINE_MCI
TRACE("bih.biClrUsed=%ld\n", wma->inbih->biClrUsed);
TRACE("bih.biClrImportant=%ld\n", wma->inbih->biClrImportant);
- mmioAscend(wma->hFile, &mmckInfo, 0);
+ wma->source.left = 0;
+ wma->source.top = 0;
+ wma->source.right = wma->inbih->biWidth;
+ wma->source.bottom = wma->inbih->biHeight;
+
+ wma->dest = wma->source;
return TRUE;
}
@@ -178,6 +172,9 @@ static BOOL MCIAVI_AddFrame(WINE_MCIAVI*
case cktypePALchange:
TRACE("Adding video frame[%ld]: %ld bytes\n",
alb->numVideoFrames, mmck->cksize);
+ if (!mmck->cksize)
+ TRACE("got a zero sized frame\n");
+
if (alb->numVideoFrames < wma->dwPlayableVideoFrames) {
wma->lpVideoIndex[alb->numVideoFrames].dwOffset = mmck->dwDataOffset;
wma->lpVideoIndex[alb->numVideoFrames].dwSize = mmck->cksize;
@@ -263,25 +260,43 @@ BOOL MCIAVI_GetInfo(WINE_MCIAVI* wma)
mmioAscend(wma->hFile, &mmckInfo, 0);
- mmckList.fccType = listtypeSTREAMHEADER;
- if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0) {
- WARN("Can't find 'strl' list\n");
- return FALSE;
- }
+ TRACE("Start of streams\n");
+ do
+ {
+ MMCKINFO mmckStream;
+
+ mmckList.fccType = listtypeSTREAMHEADER;
+ if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) != 0)
+ break;
+
+ mmckStream.ckid = ckidSTREAMHEADER;
+ if (mmioDescend(wma->hFile, &mmckStream, &mmckList, MMIO_FINDCHUNK) != 0)
+ {
+ WARN("Can't find 'strh' chunk\n");
+ continue;
+ }
+
+ TRACE("Stream fccType %4.4s\n", (LPSTR)&mmckStream.fccType);
+
+ if (mmckStream.fccType == streamtypeVIDEO)
+ {
+ TRACE("found video stream\n");
+ if (!MCIAVI_GetInfoVideo(wma, &mmckList, &mmckStream))
+ return FALSE;
+ }
+ else if (mmckStream.fccType == streamtypeAUDIO)
+ {
+ TRACE("found audio stream\n");
+ if (!MCIAVI_GetInfoAudio(wma, &mmckList, &mmckStream))
+ return FALSE;
+ }
+ else
+ TRACE("Unsupported stream type %4.4s\n", (LPSTR)&mmckStream.fccType);
- if (!MCIAVI_GetInfoVideo(wma, &mmckList)) {
- return FALSE;
- }
+ mmioAscend(wma->hFile, &mmckList, 0);
+ } while(1);
- mmioAscend(wma->hFile, &mmckList, 0);
-
- mmckList.fccType = listtypeSTREAMHEADER;
- if (mmioDescend(wma->hFile, &mmckList, &mmckHead, MMIO_FINDLIST) == 0) {
- if (!MCIAVI_GetInfoAudio(wma, &mmckList)) {
- return FALSE;
- }
- mmioAscend(wma->hFile, &mmckList, 0);
- }
+ TRACE("End of streams\n");
mmioAscend(wma->hFile, &mmckHead, 0);
@@ -351,6 +366,8 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wm
DWORD outSize;
FOURCC fcc = wma->ash_video.fccHandler;
+ TRACE("fcc %4.4s\n", (LPSTR)&fcc);
+
/* check uncompressed AVI */
if ((fcc == mmioFOURCC('D','I','B',' ')) ||
(fcc == mmioFOURCC('R','L','E',' '))) {
@@ -411,10 +428,14 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wm
return TRUE;
}
-static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance,
- DWORD dwParam1, DWORD dwParam2)
+static void CALLBACK MCIAVI_waveCallback(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
+ DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
- WINE_MCIAVI* wma = (WINE_MCIAVI*)dwInstance;
+ WINE_MCIAVI *wma = (WINE_MCIAVI *)MCIAVI_mciGetOpenDev(dwInstance);
+
+ if (!wma) return;
+
+ EnterCriticalSection(&wma->cs);
switch (uMsg) {
case WOM_OPEN:
@@ -428,6 +449,8 @@ static void CALLBACK MCIAVI_waveCallback
default:
ERR("Unknown uMsg=%d\n", uMsg);
}
+
+ LeaveCriticalSection(&wma->cs);
}
DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma, unsigned* nHdr, LPWAVEHDR* pWaveHdr)
@@ -437,7 +460,7 @@ DWORD MCIAVI_OpenAudio(WINE_MCIAVI* wma,
unsigned i;
dwRet = waveOutOpen((HWAVEOUT *)&wma->hWave, WAVE_MAPPER, wma->lpWaveFormat,
- (DWORD)MCIAVI_waveCallback, (DWORD)wma, CALLBACK_FUNCTION);
+ (DWORD_PTR)MCIAVI_waveCallback, wma->wDevID, CALLBACK_FUNCTION);
if (dwRet != 0) {
TRACE("Can't open low level audio device %ld\n", dwRet);
dwRet = MCIERR_DEVICE_OPEN;
@@ -543,7 +566,11 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* w
hdcMem = CreateCompatibleDC(hDC);
hbmOld = SelectObject(hdcMem, wma->hbmFrame);
- BitBlt(hDC, 0, 0, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY);
+ StretchBlt(hDC,
+ wma->dest.left, wma->dest.top, wma->dest.right, wma->dest.bottom,
+ hdcMem,
+ wma->source.left, wma->source.top, wma->source.right, wma->source.bottom,
+ SRCCOPY);
SelectObject(hdcMem, hbmOld);
DeleteDC(hdcMem);
@@ -559,8 +586,6 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm
if (!wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset)
return FALSE;
- EnterCriticalSection(&wma->cs);
-
mmioSeek(wma->hFile, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwOffset, SEEK_SET);
mmioRead(wma->hFile, wma->indata, wma->lpVideoIndex[wma->dwCurrVideoFrame].dwSize);
@@ -570,7 +595,6 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm
if (wma->hic &&
ICDecompress(wma->hic, 0, wma->inbih, wma->indata,
wma->outbih, wma->outdata) != ICERR_OK) {
- LeaveCriticalSection(&wma->cs);
WARN("Decompression error\n");
return FALSE;
}
@@ -580,8 +604,5 @@ LRESULT MCIAVI_DrawFrame(WINE_MCIAVI* wm
ReleaseDC(wma->hWndPaint, hDC);
}
- LeaveCriticalSection(&wma->cs);
-
return TRUE;
}
-
diff -u cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h wine/dlls/winmm/mciavi/private_mciavi.h
--- cvs/hq/wine/dlls/winmm/mciavi/private_mciavi.h 2003-12-30 22:44:20.000000000 +0800
+++ wine/dlls/winmm/mciavi/private_mciavi.h 2003-12-30 23:28:23.000000000 +0800
@@ -41,12 +41,12 @@ struct MMIOPos {
};
typedef struct {
- UINT wDevID;
+ MCIDEVICEID wDevID;
int nUseCount; /* Incremented for each shared open */
BOOL fShareable; /* TRUE if first open was shareable */
WORD wCommandTable; /* custom MCI command table */
- volatile DWORD dwStatus; /* One of MCI_MODE_XXX */
- MCI_OPEN_PARMSA openParms;
+ DWORD dwStatus; /* One of MCI_MODE_XXX */
+ LPSTR lpFileName;
DWORD dwMciTimeFormat; /* current time format */
DWORD dwSet; /* what's turned on: video & audio l&r */
/* information on the loaded AVI file */
@@ -75,6 +75,7 @@ typedef struct {
HWND hWnd, hWndPaint;
DWORD dwCurrVideoFrame; /* video frame to display and current position */
DWORD dwCurrAudioBlock; /* current audio block being played */
+ RECT source, dest;
/* data for the background mechanism */
CRITICAL_SECTION cs;
} WINE_MCIAVI;
@@ -99,6 +100,7 @@ LRESULT MCIAVI_PaintFrame(WINE_MCIAVI* w
/* mciavi.c */
WINE_MCIAVI* MCIAVI_mciGetOpenDev(UINT wDevID);
+DWORD MCIAVI_mciClose(UINT, DWORD, LPMCI_GENERIC_PARMS);
/* window.c */
BOOL MCIAVI_CreateWindow(WINE_MCIAVI* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARMSA lpOpenParms);
diff -u cvs/hq/wine/dlls/winmm/mciavi/wnd.c wine/dlls/winmm/mciavi/wnd.c
--- cvs/hq/wine/dlls/winmm/mciavi/wnd.c 2003-12-30 22:44:20.000000000 +0800
+++ wine/dlls/winmm/mciavi/wnd.c 2003-12-30 23:28:23.000000000 +0800
@@ -4,6 +4,7 @@
* Digital video MCI Wine Driver
*
* Copyright 1999, 2000 Eric POUECH
+ * Copyright 2003 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,15 +31,13 @@ static LRESULT WINAPI MCIAVI_WindowProc(
{
TRACE("hwnd=%p msg=%x wparam=%x lparam=%lx\n", hWnd, uMsg, wParam, lParam);
- if (!(WINE_MCIAVI*)GetWindowLongA(hWnd, 0) && uMsg != WM_CREATE)
- return DefWindowProcA(hWnd, uMsg, wParam, lParam);
-
switch (uMsg) {
case WM_CREATE:
SetWindowLongA(hWnd, 0, (LPARAM)((CREATESTRUCTA*)lParam)->lpCreateParams);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
case WM_DESTROY:
+ MCIAVI_mciClose(GetWindowLongA(hWnd, 0), MCI_WAIT, NULL);
SetWindowLongA(hWnd, 0, 0);
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
@@ -48,32 +47,38 @@ static LRESULT WINAPI MCIAVI_WindowProc(
GetClientRect(hWnd, &rect);
FillRect((HDC)wParam, &rect, GetStockObject(BLACK_BRUSH));
}
- break;
+ return 1;
+
case WM_PAINT:
{
- WINE_MCIAVI* wma = (WINE_MCIAVI*)GetWindowLongA(hWnd, 0);
+ WINE_MCIAVI *wma = (WINE_MCIAVI *)mciGetDriverData(GetWindowLongA(hWnd, 0));
+
+ if (!wma)
+ return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+
+ EnterCriticalSection(&wma->cs);
/* the animation isn't playing, don't paint */
if (wma->dwStatus == MCI_MODE_NOT_READY)
+ {
+ LeaveCriticalSection(&wma->cs);
/* default paint handling */
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
+ }
- if (wParam) {
- EnterCriticalSection(&wma->cs);
+ if (wParam)
MCIAVI_PaintFrame(wma, (HDC)wParam);
- LeaveCriticalSection(&wma->cs);
- } else {
+ else
+ {
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hWnd, &ps);
-
- EnterCriticalSection(&wma->cs);
MCIAVI_PaintFrame(wma, hDC);
- LeaveCriticalSection(&wma->cs);
-
EndPaint(hWnd, &ps);
}
+
+ LeaveCriticalSection(&wma->cs);
}
- break;
+ return 1;
default:
return DefWindowProcA(hWnd, uMsg, wParam, lParam);
@@ -93,15 +98,16 @@ BOOL MCIAVI_CreateWindow(WINE_MCIAVI*
if (wma->hWnd) return TRUE;
ZeroMemory(&wndClass, sizeof(WNDCLASSA));
- wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
+ wndClass.style = CS_DBLCLKS;
wndClass.lpfnWndProc = (WNDPROC)MCIAVI_WindowProc;
wndClass.cbClsExtra = 0;
- wndClass.cbWndExtra = sizeof(WINE_MCIAVI*);
+ wndClass.cbWndExtra = sizeof(MCIDEVICEID);
+ wndClass.hInstance = MCIAVI_hInstance;
wndClass.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszClassName = "MCIAVI";
- RegisterClassA(&wndClass);
+ if (!RegisterClassA(&wndClass)) return FALSE;
if (dwFlags & MCI_DGV_OPEN_PARENT) hParent = lpOpenParms->hWndParent;
if (dwFlags & MCI_DGV_OPEN_WS) dwStyle = lpOpenParms->dwStyle;
@@ -116,7 +122,8 @@ BOOL MCIAVI_CreateWindow(WINE_MCIAVI*
wma->hWnd = CreateWindowA("MCIAVI", "Wine MCI-AVI player",
dwStyle, rc.left, rc.top,
rc.right, rc.bottom,
- hParent, 0, MCIAVI_hInstance, wma);
+ hParent, 0, MCIAVI_hInstance,
+ (LPVOID)wma->wDevID);
wma->hWndPaint = wma->hWnd;
return (BOOL)wma->hWnd;
}
@@ -128,40 +135,49 @@ DWORD MCIAVI_mciPut(UINT wDevID, DWORD d
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
RECT rc;
- char buffer[256];
- FIXME("(%04x, %08lX, %p) : stub\n", wDevID, dwFlags, lpParms);
+ TRACE("(%04x, %08lX, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (dwFlags & MCI_DGV_RECT) {
rc = lpParms->rc;
} else {
- SetRectEmpty(&rc);
+ GetClientRect(wma->hWndPaint, &rc);
}
- *buffer = 0;
if (dwFlags & MCI_DGV_PUT_CLIENT) {
- strncat(buffer, "PUT_CLIENT", sizeof(buffer));
+ FIXME("PUT_CLIENT %s\n", wine_dbgstr_rect(&rc));
+ LeaveCriticalSection(&wma->cs);
+ return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_PUT_DESTINATION) {
- strncat(buffer, "PUT_DESTINATION", sizeof(buffer));
+ TRACE("PUT_DESTINATION %s\n", wine_dbgstr_rect(&rc));
+ wma->dest = rc;
}
if (dwFlags & MCI_DGV_PUT_FRAME) {
- strncat(buffer, "PUT_FRAME", sizeof(buffer));
+ FIXME("PUT_FRAME %s\n", wine_dbgstr_rect(&rc));
+ LeaveCriticalSection(&wma->cs);
+ return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_PUT_SOURCE) {
- strncat(buffer, "PUT_SOURCE", sizeof(buffer));
+ TRACE("PUT_SOURCE %s\n", wine_dbgstr_rect(&rc));
+ wma->source = rc;
}
if (dwFlags & MCI_DGV_PUT_VIDEO) {
- strncat(buffer, "PUT_VIDEO", sizeof(buffer));
+ FIXME("PUT_VIDEO %s\n", wine_dbgstr_rect(&rc));
+ LeaveCriticalSection(&wma->cs);
+ return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_PUT_WINDOW) {
- strncat(buffer, "PUT_WINDOW", sizeof(buffer));
+ FIXME("PUT_WINDOW %s\n", wine_dbgstr_rect(&rc));
+ LeaveCriticalSection(&wma->cs);
+ return MCIERR_UNRECOGNIZED_COMMAND;
}
- TRACE("%s (%ld,%ld,%ld,%ld)\n", buffer, rc.left, rc.top, rc.right, rc.bottom);
-
+ LeaveCriticalSection(&wma->cs);
return 0;
}
@@ -171,40 +187,43 @@ DWORD MCIAVI_mciPut(UINT wDevID, DWORD d
DWORD MCIAVI_mciWhere(UINT wDevID, DWORD dwFlags, LPMCI_DGV_RECT_PARMS lpParms)
{
WINE_MCIAVI* wma = MCIAVI_mciGetOpenDev(wDevID);
- LPCSTR x = "";
TRACE("(%04x, %08lx, %p)\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
- if (dwFlags & MCI_DGV_WHERE_MAX) FIXME("Max NIY\n");
+ if (dwFlags & MCI_DGV_WHERE_MAX)
+ {
+ FIXME("WHERE_MAX\n");
+ return MCIERR_UNRECOGNIZED_COMMAND;
+ }
+
+ EnterCriticalSection(&wma->cs);
if (dwFlags & MCI_DGV_WHERE_DESTINATION) {
- x = "Dest";
- GetClientRect(wma->hWnd, &lpParms->rc);
+ TRACE("WHERE_DESTINATION %s\n", wine_dbgstr_rect(&wma->dest));
+ lpParms->rc = wma->dest;
}
if (dwFlags & MCI_DGV_WHERE_FRAME) {
- FIXME(x = "Frame\n");
+ FIXME("MCI_DGV_WHERE_FRAME\n");
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_WHERE_SOURCE) {
- x = "Source";
- lpParms->rc.left = lpParms->rc.top = 0;
- lpParms->rc.right = wma->mah.dwWidth;
- lpParms->rc.bottom = wma->mah.dwHeight;
+ TRACE("WHERE_SOURCE %s\n", wine_dbgstr_rect(&wma->source));
+ lpParms->rc = wma->source;
}
if (dwFlags & MCI_DGV_WHERE_VIDEO) {
- FIXME(x = "Video\n");
+ FIXME("WHERE_VIDEO\n");
+ LeaveCriticalSection(&wma->cs);
return MCIERR_UNRECOGNIZED_COMMAND;
}
if (dwFlags & MCI_DGV_WHERE_WINDOW) {
- x = "Window";
- GetClientRect(wma->hWndPaint, &lpParms->rc);
+ GetClientRect(wma->hWndPaint, &lpParms->rc);
+ TRACE("WHERE_WINDOW %s\n", wine_dbgstr_rect(&lpParms->rc));
}
- TRACE("%s -> (%ld,%ld,%ld,%ld)\n",
- x, lpParms->rc.left, lpParms->rc.top, lpParms->rc.right, lpParms->rc.bottom);
-
+ LeaveCriticalSection(&wma->cs);
return 0;
}
@@ -220,11 +239,16 @@ DWORD MCIAVI_mciWindow(UINT wDevID, DWOR
if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
if (wma == NULL) return MCIERR_INVALID_DEVICE_ID;
+ EnterCriticalSection(&wma->cs);
+
if (dwFlags & MCI_DGV_WINDOW_HWND) {
- TRACE("Setting hWnd to %p\n", lpParms->hWnd);
- if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE);
- wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd;
- InvalidateRect(wma->hWndPaint, NULL, FALSE);
+ if (IsWindow(lpParms->hWnd))
+ {
+ TRACE("Setting hWnd to %p\n", lpParms->hWnd);
+ if (wma->hWnd) ShowWindow(wma->hWnd, SW_HIDE);
+ wma->hWndPaint = (lpParms->hWnd == MCI_DGV_WINDOW_DEFAULT) ? wma->hWnd : lpParms->hWnd;
+ InvalidateRect(wma->hWndPaint, NULL, FALSE);
+ }
}
if (dwFlags & MCI_DGV_WINDOW_STATE) {
TRACE("Setting nCmdShow to %d\n", lpParms->nCmdShow);
@@ -235,5 +259,6 @@ DWORD MCIAVI_mciWindow(UINT wDevID, DWOR
SetWindowTextA(wma->hWndPaint, lpParms->lpstrText);
}
+ LeaveCriticalSection(&wma->cs);
return 0;
}
diff -u cvs/hq/wine/dlls/winmm/mci.c wine/dlls/winmm/mci.c
--- cvs/hq/wine/dlls/winmm/mci.c 2003-12-30 22:44:20.000000000 +0800
+++ wine/dlls/winmm/mci.c 2003-12-30 23:28:23.000000000 +0800
@@ -1027,7 +1027,7 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstr
*/
if (lpstrRet && uRetLen) *lpstrRet = '\0';
-#define STR_OF(_x) (IsBadReadPtr((char*)_x,1)?"?":(char*)(_x))
+#define STR_OF(_x) ((!(_x) || IsBadReadPtr((char*)(_x),1)) ? "?" : (char*)(_x))
TRACE("[%d, %s, %08lx, %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s %08lx/%s]\n",
wmd->wDeviceID, MCI_MessageToString(MCI_GetMessage(lpCmd)), dwFlags,
data[0], STR_OF(data[0]), data[1], STR_OF(data[1]),
More information about the wine-patches
mailing list