📄 msvideo_main.c
字号:
/* ICM_RESERVED+X */
XX(ICM_ABOUT);
XX(ICM_CONFIGURE);
XX(ICM_GET);
XX(ICM_GETINFO);
XX(ICM_GETDEFAULTQUALITY);
XX(ICM_GETQUALITY);
XX(ICM_GETSTATE);
XX(ICM_SETQUALITY);
XX(ICM_SET);
XX(ICM_SETSTATE);
/* ICM_USER+X */
XX(ICM_COMPRESS_FRAMES_INFO);
XX(ICM_COMPRESS_GET_FORMAT);
XX(ICM_COMPRESS_GET_SIZE);
XX(ICM_COMPRESS_QUERY);
XX(ICM_COMPRESS_BEGIN);
XX(ICM_COMPRESS);
XX(ICM_COMPRESS_END);
XX(ICM_DECOMPRESS_GET_FORMAT);
XX(ICM_DECOMPRESS_QUERY);
XX(ICM_DECOMPRESS_BEGIN);
XX(ICM_DECOMPRESS);
XX(ICM_DECOMPRESS_END);
XX(ICM_DECOMPRESS_SET_PALETTE);
XX(ICM_DECOMPRESS_GET_PALETTE);
XX(ICM_DRAW_QUERY);
XX(ICM_DRAW_BEGIN);
XX(ICM_DRAW_GET_PALETTE);
XX(ICM_DRAW_START);
XX(ICM_DRAW_STOP);
XX(ICM_DRAW_END);
XX(ICM_DRAW_GETTIME);
XX(ICM_DRAW);
XX(ICM_DRAW_WINDOW);
XX(ICM_DRAW_SETTIME);
XX(ICM_DRAW_REALIZE);
XX(ICM_DRAW_FLUSH);
XX(ICM_DRAW_RENDERBUFFER);
XX(ICM_DRAW_START_PLAY);
XX(ICM_DRAW_STOP_PLAY);
XX(ICM_DRAW_SUGGESTFORMAT);
XX(ICM_DRAW_CHANGEPALETTE);
XX(ICM_GETBUFFERSWANTED);
XX(ICM_GETDEFAULTKEYFRAMERATE);
XX(ICM_DECOMPRESSEX_BEGIN);
XX(ICM_DECOMPRESSEX_QUERY);
XX(ICM_DECOMPRESSEX);
XX(ICM_DECOMPRESSEX_END);
XX(ICM_SET_STATUS_PROC);
default:
FIXME("(%p,0x%08lx,0x%08lx,0x%08lx) unknown message\n",whic,(DWORD)msg,lParam1,lParam2);
}
#undef XX
if (whic->driverproc) {
/* dwDriverId parameter is the value returned by the DRV_OPEN */
ret = whic->driverproc(whic->driverId, whic->hdrv, msg, lParam1, lParam2);
} else {
ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
}
TRACE(" -> 0x%08lx\n", ret);
return ret;
}
/***********************************************************************
* ICSendMessage [MSVFW32.@]
*/
LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2)
{
WINE_HIC* whic = MSVIDEO_GetHicPtr(hic);
if (!whic) return ICERR_BADHANDLE;
return MSVIDEO_SendMessage(whic, msg, lParam1, lParam2);
}
/***********************************************************************
* ICDrawBegin [MSVFW32.@]
*/
DWORD VFWAPIV ICDrawBegin(
HIC hic, /* [in] */
DWORD dwFlags, /* [in] flags */
HPALETTE hpal, /* [in] palette to draw with */
HWND hwnd, /* [in] window to draw to */
HDC hdc, /* [in] HDC to draw to */
INT xDst, /* [in] destination rectangle */
INT yDst, /* [in] */
INT dxDst, /* [in] */
INT dyDst, /* [in] */
LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw */
INT xSrc, /* [in] source rectangle */
INT ySrc, /* [in] */
INT dxSrc, /* [in] */
INT dySrc, /* [in] */
DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
DWORD dwScale) /* [in] */
{
ICDRAWBEGIN icdb;
TRACE("(%p,%ld,%p,%p,%p,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
hic, dwFlags, hpal, hwnd, hdc, xDst, yDst, dxDst, dyDst,
lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
icdb.dwFlags = dwFlags;
icdb.hpal = hpal;
icdb.hwnd = hwnd;
icdb.hdc = hdc;
icdb.xDst = xDst;
icdb.yDst = yDst;
icdb.dxDst = dxDst;
icdb.dyDst = dyDst;
icdb.lpbi = lpbi;
icdb.xSrc = xSrc;
icdb.ySrc = ySrc;
icdb.dxSrc = dxSrc;
icdb.dySrc = dySrc;
icdb.dwRate = dwRate;
icdb.dwScale = dwScale;
return ICSendMessage(hic,ICM_DRAW_BEGIN,(DWORD)&icdb,sizeof(icdb));
}
/***********************************************************************
* ICDraw [MSVFW32.@]
*/
DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
ICDRAW icd;
TRACE("(%p,%ld,%p,%p,%ld,%ld)\n",hic,dwFlags,lpFormat,lpData,cbData,lTime);
icd.dwFlags = dwFlags;
icd.lpFormat = lpFormat;
icd.lpData = lpData;
icd.cbData = cbData;
icd.lTime = lTime;
return ICSendMessage(hic,ICM_DRAW,(DWORD)&icd,sizeof(icd));
}
/***********************************************************************
* ICClose [MSVFW32.@]
*/
LRESULT WINAPI ICClose(HIC hic)
{
WINE_HIC* whic = MSVIDEO_GetHicPtr(hic);
WINE_HIC** p;
TRACE("(%p)\n",hic);
if (!whic) return ICERR_BADHANDLE;
if (whic->driverproc)
{
MSVIDEO_SendMessage(whic, DRV_CLOSE, 0, 0);
MSVIDEO_SendMessage(whic, DRV_DISABLE, 0, 0);
MSVIDEO_SendMessage(whic, DRV_FREE, 0, 0);
}
else
{
CloseDriver(whic->hdrv, 0, 0);
}
/* remove whic from list */
for (p = &MSVIDEO_FirstHic; *p != NULL; p = &((*p)->next))
{
if ((*p) == whic)
{
*p = whic->next;
break;
}
}
HeapFree(GetProcessHeap(), 0, whic);
return 0;
}
/***********************************************************************
* ICImageCompress [MSVFW32.@]
*/
HANDLE VFWAPI ICImageCompress(
HIC hic, UINT uiFlags,
LPBITMAPINFO lpbiIn, LPVOID lpBits,
LPBITMAPINFO lpbiOut, LONG lQuality,
LONG* plSize)
{
FIXME("(%p,%08x,%p,%p,%p,%ld,%p)\n",
hic, uiFlags, lpbiIn, lpBits, lpbiOut, lQuality, plSize);
return NULL;
}
/***********************************************************************
* ICImageDecompress [MSVFW32.@]
*/
HANDLE VFWAPI ICImageDecompress(
HIC hic, UINT uiFlags, LPBITMAPINFO lpbiIn,
LPVOID lpBits, LPBITMAPINFO lpbiOut)
{
HGLOBAL hMem = NULL;
BYTE* pMem = NULL;
BOOL bReleaseIC = FALSE;
BYTE* pHdr = NULL;
LONG cbHdr = 0;
BOOL bSucceeded = FALSE;
BOOL bInDecompress = FALSE;
DWORD biSizeImage;
TRACE("(%p,%08x,%p,%p,%p)\n",
hic, uiFlags, lpbiIn, lpBits, lpbiOut);
if ( hic == NULL )
{
hic = ICDecompressOpen( ICTYPE_VIDEO, 0, &lpbiIn->bmiHeader, (lpbiOut != NULL) ? &lpbiOut->bmiHeader : NULL );
if ( hic == NULL )
{
WARN("no handler\n" );
goto err;
}
bReleaseIC = TRUE;
}
if ( uiFlags != 0 )
{
FIXME( "unknown flag %08x\n", uiFlags );
goto err;
}
if ( lpbiIn == NULL || lpBits == NULL )
{
WARN("invalid argument\n");
goto err;
}
if ( lpbiOut != NULL )
{
if ( lpbiOut->bmiHeader.biSize != sizeof(BITMAPINFOHEADER) )
goto err;
cbHdr = sizeof(BITMAPINFOHEADER);
if ( lpbiOut->bmiHeader.biCompression == 3 )
cbHdr += sizeof(DWORD)*3;
else
if ( lpbiOut->bmiHeader.biBitCount <= 8 )
{
if ( lpbiOut->bmiHeader.biClrUsed == 0 )
cbHdr += sizeof(RGBQUAD) * (1<<lpbiOut->bmiHeader.biBitCount);
else
cbHdr += sizeof(RGBQUAD) * lpbiOut->bmiHeader.biClrUsed;
}
}
else
{
TRACE( "get format\n" );
cbHdr = ICDecompressGetFormatSize(hic,lpbiIn);
if ( cbHdr < sizeof(BITMAPINFOHEADER) )
goto err;
pHdr = (BYTE*)HeapAlloc(GetProcessHeap(),0,cbHdr+sizeof(RGBQUAD)*256);
if ( pHdr == NULL )
goto err;
ZeroMemory( pHdr, cbHdr+sizeof(RGBQUAD)*256 );
if ( ICDecompressGetFormat( hic, lpbiIn, (BITMAPINFO*)pHdr ) != ICERR_OK )
goto err;
lpbiOut = (BITMAPINFO*)pHdr;
if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
ICDecompressGetPalette( hic, lpbiIn, lpbiOut ) != ICERR_OK &&
lpbiIn->bmiHeader.biBitCount == lpbiOut->bmiHeader.biBitCount )
{
if ( lpbiIn->bmiHeader.biClrUsed == 0 )
memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*(1<<lpbiOut->bmiHeader.biBitCount) );
else
memcpy( lpbiOut->bmiColors, lpbiIn->bmiColors, sizeof(RGBQUAD)*lpbiIn->bmiHeader.biClrUsed );
}
if ( lpbiOut->bmiHeader.biBitCount <= 8 &&
lpbiOut->bmiHeader.biClrUsed == 0 )
lpbiOut->bmiHeader.biClrUsed = 1<<lpbiOut->bmiHeader.biBitCount;
lpbiOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
cbHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*lpbiOut->bmiHeader.biClrUsed;
}
biSizeImage = lpbiOut->bmiHeader.biSizeImage;
if ( biSizeImage == 0 )
biSizeImage = ((((lpbiOut->bmiHeader.biWidth * lpbiOut->bmiHeader.biBitCount + 7) >> 3) + 3) & (~3)) * abs(lpbiOut->bmiHeader.biHeight);
TRACE( "call ICDecompressBegin\n" );
if ( ICDecompressBegin( hic, lpbiIn, lpbiOut ) != ICERR_OK )
goto err;
bInDecompress = TRUE;
TRACE( "cbHdr %ld, biSizeImage %ld\n", cbHdr, biSizeImage );
hMem = GlobalAlloc( GMEM_MOVEABLE|GMEM_ZEROINIT, cbHdr + biSizeImage );
if ( hMem == NULL )
{
WARN( "out of memory\n" );
goto err;
}
pMem = (BYTE*)GlobalLock( hMem );
if ( pMem == NULL )
goto err;
memcpy( pMem, lpbiOut, cbHdr );
TRACE( "call ICDecompress\n" );
if ( ICDecompress( hic, 0, &lpbiIn->bmiHeader, lpBits, &lpbiOut->bmiHeader, pMem+cbHdr ) != ICERR_OK )
goto err;
bSucceeded = TRUE;
err:
if ( bInDecompress )
ICDecompressEnd( hic );
if ( bReleaseIC )
ICClose(hic);
if ( pHdr != NULL )
HeapFree(GetProcessHeap(),0,pHdr);
if ( pMem != NULL )
GlobalUnlock( hMem );
if ( !bSucceeded && hMem != NULL )
{
GlobalFree(hMem); hMem = NULL;
}
return (HANDLE)hMem;
}
static BOOL GetFileNamePreview(LPVOID lpofn,BOOL bSave,BOOL bUnicode)
{
CHAR szFunctionName[20];
BOOL (*fnGetFileName)(LPVOID);
HMODULE hComdlg32;
BOOL ret;
FIXME("(%p,%d,%d), semi-stub!\n",lpofn,bSave,bUnicode);
lstrcpyA(szFunctionName, (bSave ? "GetSaveFileName" : "GetOpenFileName"));
lstrcatA(szFunctionName, (bUnicode ? "W" : "A"));
hComdlg32 = LoadLibraryA("COMDLG32.DLL");
if (hComdlg32 == NULL)
return FALSE;
fnGetFileName = (LPVOID)GetProcAddress(hComdlg32, szFunctionName);
if (fnGetFileName == NULL)
return FALSE;
/* FIXME: need to add OFN_ENABLEHOOK and our own handler */
ret = fnGetFileName(lpofn);
FreeLibrary(hComdlg32);
return ret;
}
/***********************************************************************
* GetOpenFileNamePreviewA [MSVFW32.@]
*/
BOOL WINAPI GetOpenFileNamePreviewA(LPOPENFILENAMEA lpofn)
{
FIXME("(%p), semi-stub!\n", lpofn);
return GetFileNamePreview(lpofn, FALSE, FALSE);
}
/***********************************************************************
* GetOpenFileNamePreviewW [MSVFW32.@]
*/
BOOL WINAPI GetOpenFileNamePreviewW(LPOPENFILENAMEW lpofn)
{
FIXME("(%p), semi-stub!\n", lpofn);
return GetFileNamePreview(lpofn, FALSE, TRUE);
}
/***********************************************************************
* GetSaveFileNamePreviewA [MSVFW32.@]
*/
BOOL WINAPI GetSaveFileNamePreviewA(LPOPENFILENAMEA lpofn)
{
FIXME("(%p), semi-stub!\n", lpofn);
return GetFileNamePreview(lpofn, TRUE, FALSE);
}
/***********************************************************************
* GetSaveFileNamePreviewW [MSVFW32.@]
*/
BOOL WINAPI GetSaveFileNamePreviewW(LPOPENFILENAMEW lpofn)
{
FIXME("(%p), semi-stub!\n", lpofn);
return GetFileNamePreview(lpofn, TRUE, TRUE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -