Commit f41e0470 authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

Much improved mciavi driver. Fixed synchronization, RIFF file with

many streams parsing, added support for some MCI_PUT and MCI_WHERE cases.
parent cd61ce85
......@@ -1027,13 +1027,11 @@ DWORD WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrRet,
*/
if (lpstrRet && uRetLen) *lpstrRet = '\0';
#define STR_OF(_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]),
data[2], STR_OF(data[2]), data[3], STR_OF(data[3]),
data[4], STR_OF(data[4]), data[5], STR_OF(data[5]));
#undef STR_OF
data[0], debugstr_a((char *)data[0]), data[1], debugstr_a((char *)data[1]),
data[2], debugstr_a((char *)data[2]), data[3], debugstr_a((char *)data[3]),
data[4], debugstr_a((char *)data[4]), data[5], debugstr_a((char *)data[5]));
if (strcmp(verb, "open") == 0) {
if ((dwRet = MCI_FinishOpen(wmd, (LPMCI_OPEN_PARMSA)data, dwFlags)))
......
......@@ -82,6 +82,8 @@ DWORD MCIAVI_mciGetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS l
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, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS l
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 dwFlags, LPMCI_DGV_INFO_PARMSA lpParms)
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 dwFlags, LPMCI_DGV_INFO_PARMSA lpParms)
} else {
lpParms->lpstrReturn[0] = 0;
}
LeaveCriticalSection(&wma->cs);
return ret;
}
......@@ -188,6 +198,8 @@ DWORD MCIAVI_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_DGV_SET_PARMS lpParms)
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 dwFlags, LPMCI_DGV_SET_PARMS lpParms)
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 dwFlags, LPMCI_DGV_SET_PARMS lpParms)
FIXME("Setting speed to %ld\n", lpParms->dwSpeed);
}
LeaveCriticalSection(&wma->cs);
return 0;
}
......@@ -316,6 +333,8 @@ DWORD MCIAVI_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
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, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
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, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
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, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
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, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
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, DWORD dwFlags, LPMCI_DGV_STATUS_PARMSA lpPar
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;
}
......@@ -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_MCIAVI* wma, const MMCKINFO* mmckList)
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_MCIAVI* wma, const MMCKINFO* mmckList)
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_MCIAVI* wma, const MMCKINFO* mmckList)
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_MCIAVI* wma, const MMCKINFO* mmckList)
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* wma, LPMMCKINFO mmck,
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;
}
if (!MCIAVI_GetInfoVideo(wma, &mmckList)) {
return FALSE;
}
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("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);
mmioAscend(wma->hFile, &mmckList, 0);
} while(1);
TRACE("End of streams\n");
mmioAscend(wma->hFile, &mmckHead, 0);
......@@ -351,6 +366,8 @@ BOOL MCIAVI_OpenVideo(WINE_MCIAVI* wma)
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* wma)
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(HWAVEOUT hwo, UINT uMsg, DWORD dwInstan
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* nHdr, LPWAVEHDR* pWaveHdr)
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* wma, HDC hDC)
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* wma)
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* wma)
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;
}
......
......@@ -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* wma, HDC hDC);
/* 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);
......
......@@ -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(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
{
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(HWND hWnd, UINT uMsg, WPARAM wParam, LPA
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* wma, DWORD dwFlags, LPMCI_DGV_OPEN_PARM
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, DWORD dwFlags, LPMCI_DGV_OPEN_PARM
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 dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
{
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 dwFlags, LPMCI_DGV_PUT_PARMS lpParms)
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, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpPar
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, DWORD dwFlags, LPMCI_DGV_WINDOW_PARMSA lpPar
SetWindowTextA(wma->hWndPaint, lpParms->lpstrText);
}
LeaveCriticalSection(&wma->cs);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment