/*
 * Copyright 1998 Marcus Meissner
 * Copyright 2000 Bradley Baetz 
 *
 * FIXME: This all assumes 32 bit codecs
 *		Win95 appears to prefer 32 bit codecs, even from 16 bit code.
 *		There is the ICOpenFunction16 to worry about still, though.
 */

#include <stdio.h>
#include <string.h>

#include "winbase.h"
#include "windef.h"
#include "winnls.h"
#include "wingdi.h"
#include "winuser.h"
#include "winver.h"
#include "vfw.h"
#include "vfw16.h"
#include "wine/winbase16.h"
#include "debugtools.h"
#include "heap.h"
#include "stackframe.h"

DEFAULT_DEBUG_CHANNEL(msvideo);

/* ### start build ### */
extern LONG CALLBACK MSVIDEO_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
/* ### stop build ### */

LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2);
void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID lpv, LPDWORD lParam1, LPDWORD lParam2);
LRESULT MSVIDEO_SendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2, BOOL bFrom32);

/***********************************************************************
 *		VideoForWindowsVersion		[MSVFW32.2]
 *		VideoForWindowsVersion		[MSVIDEO.2]
 * Returns the version in major.minor form.
 * In Windows95 this returns 0x040003b6 (4.950)
 */
DWORD WINAPI VideoForWindowsVersion(void) {
	return 0x040003B6; /* 4.950 */
}

/***********************************************************************
 *		VideoCapDriverDescAndVer	[MSVIDEO.22]
 */
DWORD WINAPI VideoCapDriverDescAndVer(
	WORD nr,LPSTR buf1,WORD buf1len,LPSTR buf2,WORD buf2len
) {
	DWORD	verhandle;
	WORD	xnr = nr;
	DWORD	infosize;
	UINT	subblocklen;
	char	*s,buf[2000],fn[260];
	LPBYTE	infobuf;
	LPVOID	subblock;

	TRACE("(%d,%p,%d,%p,%d)\n",nr,buf1,buf1len,buf2,buf2len);
	if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,sizeof(buf),"system.ini")) {
		s = buf;
		while (*s) {
		        if (!strncasecmp(s,"vid",3)) {
			    if (!xnr)
				break;
			    xnr--;
			}
			s=s+strlen(s)+1; /* either next char or \0 */
		}
	} else
	    return 20; /* hmm, out of entries even if we don't have any */
	if (xnr) {
		FIXME("No more VID* entries found\n");
		return 20;
	}
	GetPrivateProfileStringA("drivers32",s,NULL,fn,sizeof(fn),"system.ini");
	infosize = GetFileVersionInfoSizeA(fn,&verhandle);
	if (!infosize) {
	    TRACE("%s has no fileversioninfo.\n",fn);
	    return 18;
	}
	infobuf = HeapAlloc(GetProcessHeap(),0,infosize);
	if (GetFileVersionInfoA(fn,verhandle,infosize,infobuf)) {
	    char	vbuf[200];
	    /* Yes, two space behind : */
	    /* FIXME: test for buflen */
	    sprintf(vbuf,"Version:  %d.%d.%d.%d\n",
		    ((WORD*)infobuf)[0x0f],
		    ((WORD*)infobuf)[0x0e],
		    ((WORD*)infobuf)[0x11],
		    ((WORD*)infobuf)[0x10]
	    );
	    TRACE("version of %s is %s\n",fn,vbuf);
	    strncpy(buf2,vbuf,buf2len);
	} else {
	    TRACE("GetFileVersionInfoA failed for %s.\n",fn);
	    strncpy(buf2,fn,buf2len); /* msvideo.dll appears to copy fn*/
	}
	/* FIXME: language problem? */
	if (VerQueryValueA(	infobuf,
				"\\StringFileInfo\\040904E4\\FileDescription",
				&subblock,
				&subblocklen
	)) {
	    TRACE("VQA returned %s\n",(LPCSTR)subblock);
	    strncpy(buf1,subblock,buf1len);
	} else {
	    TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
	    strncpy(buf1,fn,buf1len); /* msvideo.dll appears to copy fn*/
	}
	HeapFree(GetProcessHeap(),0,infobuf);
	return 0;
}

/* system.ini: [drivers] */

/***********************************************************************
 *		ICInfo				[MSVFW32.@]
 * Get information about an installable compressor. Return TRUE if there
 * is one.
 */
BOOL VFWAPI ICInfo(
	DWORD fccType,		/* [in] type of compressor ('vidc') */
	DWORD fccHandler,	/* [in] <n>th compressor */
	ICINFO *lpicinfo)	/* [out] information about compressor */
{
	char	type[5],buf[2000];

	memcpy(type,&fccType,4);type[4]=0;
	TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
	/* does OpenDriver/CloseDriver */
	lpicinfo->dwSize = sizeof(ICINFO);
	lpicinfo->fccType = fccType;
	lpicinfo->dwFlags = 0;
	if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
		char *s = buf;
		while (*s) {
			if (!strncasecmp(type,s,4)) {
				if(!fccHandler--) {
					lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
					return TRUE;
				}
			}
			s=s+strlen(s)+1; /* either next char or \0 */
		}
	}
	return FALSE;
}

/***********************************************************************
 *		ICInfo				[MSVIDEO.200]
 */
BOOL16 VFWAPI ICInfo16(
	DWORD     fccType,    /* [in] */
	DWORD     fccHandler, /* [in] */
	ICINFO16 *lpicinfo)   /* [in/out] NOTE: SEGPTR */
{
	BOOL16 ret;
	LPVOID lpv;
	DWORD lParam = (DWORD)lpicinfo;
	DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;

	/* Use the mapping functions to map the ICINFO structure */
	lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO,&lParam,&size);

	ret = ICInfo(fccType,fccHandler,(ICINFO*)lParam);

	MSVIDEO_UnmapMsg16To32(ICM_GETINFO,lpv,&lParam,&size);
	
	return ret;
}

/***********************************************************************
 *		ICOpen				[MSVFW32.@]
 * Opens an installable compressor. Return special handle.
 */
HIC VFWAPI ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
	char		type[5],handler[5],codecname[20];
	ICOPEN		icopen;
	HDRVR		hdrv;
	HIC16		hic;
	WINE_HIC	*whic;

	memcpy(type,&fccType,4);type[4]=0;
	memcpy(handler,&fccHandler,4);handler[4]=0;
	TRACE("(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);

	sprintf(codecname,"%s.%s",type,handler);

	/* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the 
	 * same layout as ICOPEN
	 */
	icopen.fccType		= fccType;
	icopen.fccHandler	= fccHandler;
	icopen.dwSize		= sizeof(ICOPEN);
	icopen.dwFlags		= wMode;
	/* FIXME: do we need to fill out the rest too? */
	hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
	if (!hdrv) {
	    if (!strcasecmp(type,"vids")) {
		sprintf(codecname,"vidc.%s",handler);
		fccType = mmioFOURCC('v','i','d','c');
	    }
	    hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
	    if (!hdrv)
		    return 0;
	}
	/* The handle should be a valid 16-bit handle as well */
	hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
	whic = (WINE_HIC*)GlobalLock16(hic);
	whic->hdrv	= hdrv;
	whic->driverproc= NULL;
	whic->private	= 0;
	GlobalUnlock16(hic);
	TRACE("=> 0x%08lx\n",(DWORD)hic);
	return hic;
}

HIC MSVIDEO_OpenFunc(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler, BOOL bFrom32) {
	char	type[5],handler[5],codecname[20];
	HIC16	hic;
	ICOPEN*  icopen = SEGPTR_NEW(ICOPEN);
	WINE_HIC	*whic;

	memcpy(type,&fccType,4);type[4]=0;
	memcpy(handler,&fccHandler,4);handler[4]=0;
	TRACE("(%s,%s,%d,%p,%d)\n",type,handler,wMode,lpfnHandler,bFrom32?32:16);
	
	icopen->fccType		= fccType;
	icopen->fccHandler	= fccHandler;
	icopen->dwSize		= sizeof(ICOPEN);
	icopen->dwFlags		= wMode;
	
	sprintf(codecname,"%s.%s",type,handler);

	hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
	if (!hic)
		return 0;
	whic = GlobalLock16(hic);
	whic->driverproc = lpfnHandler;
	
	whic->private = bFrom32;
	
	/* Now try opening/loading the driver. Taken from DRIVER_AddToList */
	/* What if the function is used more than once? */
	
	if (MSVIDEO_SendMessage(hic,DRV_LOAD,0L,0L,bFrom32) != DRV_SUCCESS) {
		WARN("DRV_LOAD failed for hic 0x%08lx\n",(DWORD)hic);
		GlobalFree16(hic);
		return 0;
	}
	/* return value is not checked */
	MSVIDEO_SendMessage(hic,DRV_ENABLE,0L,0L,bFrom32);

	whic->hdrv = MSVIDEO_SendMessage(hic,DRV_OPEN,0,(LPARAM)(SEGPTR_GET(icopen)),FALSE);
	if (whic->hdrv == 0) {
		WARN("DRV_OPEN failed for hic 0x%08lx\n",(DWORD)hic);
		GlobalFree16(hic);
		return 0;
	}

	GlobalUnlock16(hic);
	TRACE("=> 0x%08lx\n",(DWORD)hic);
	return hic;
}

/***********************************************************************
 *		ICOpenFunction			[MSVFW32.@]
 */
HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) {
	return MSVIDEO_OpenFunc(fccType,fccHandler,wMode,lpfnHandler,TRUE);
}

/***********************************************************************
 *		ICOpen				[MSVIDEO.203]
 */
HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode) {
	return (HIC16)ICOpen(fccType, fccHandler, wMode);
}

/***********************************************************************
 *		ICOpenFunction			[MSVIDEO.206]
 */
HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
{
	return MSVIDEO_OpenFunc(fccType, fccHandler, wMode, (FARPROC)lpfnHandler,FALSE);
}

/***********************************************************************
 *		ICGetInfo			[MSVFW32.@]
 */
LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
	LRESULT		ret;

	TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
	ret = ICSendMessage(hic,ICM_GETINFO,(DWORD)picinfo,cb);
	TRACE("	-> 0x%08lx\n",ret);
	return ret;
}

/***********************************************************************
 *		ICGetInfo			[MSVIDEO.212]
 */
LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 *picinfo,DWORD cb) {
	LRESULT		ret;

	TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
	ret = ICSendMessage16(hic,ICM_GETINFO,(DWORD)picinfo,cb);
	TRACE("	-> 0x%08lx\n",ret);
	return ret;
}

/***********************************************************************
 *		ICLocate			[MSVFW32.@]
 */
HIC VFWAPI ICLocate(
	DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
	LPBITMAPINFOHEADER lpbiOut, WORD wMode)
{
	char	type[5],handler[5];
	HIC	hic;
	DWORD	querymsg;
	LPSTR pszBuffer;

	type[4]=0;memcpy(type,&fccType,4);
	handler[4]=0;memcpy(handler,&fccHandler,4);

	TRACE("(%s,%s,%p,%p,0x%04x)\n", type, handler, lpbiIn, lpbiOut, wMode);

	switch (wMode) {
	case ICMODE_FASTCOMPRESS:
	case ICMODE_COMPRESS: 
		querymsg = ICM_COMPRESS_QUERY;
		break;
	case ICMODE_FASTDECOMPRESS:
	case ICMODE_DECOMPRESS:
		querymsg = ICM_DECOMPRESS_QUERY;
		break;
	case ICMODE_DRAW:
		querymsg = ICM_DRAW_QUERY;
		break;
	default:
		WARN("Unknown mode (%d)\n",wMode);
		return 0;
	}

	/* Easy case: handler/type match, we just fire a query and return */
	hic = ICOpen(fccType,fccHandler,wMode);
	if (hic) {
		if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
			return hic;
		ICClose(hic);
	}

	type[4]='.';memcpy(type,&fccType,4);
	handler[4]='.';memcpy(handler,&fccHandler,4);

	/* Now try each driver in turn. 32 bit codecs only. */
	/* FIXME: Move this to an init routine? */
	
	pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(),0,1024);
	if (GetPrivateProfileSectionA("drivers32",pszBuffer,1024,"system.ini")) {
		char* s = pszBuffer;
		while (*s) {
			if (!strncasecmp(type,s,5)) {
				char *s2 = s;
				while (*s2 != '\0' && *s2 != '.') s2++;
				if (*s2++) {
					HIC h;

					h = ICOpen(fccType,*(DWORD*)s2,wMode);
					if (h) {
						if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
							return h;
						ICClose(h);
					}
				}
			}
			s += strlen(s) + 1;
		}
	}
	HeapFree(GetProcessHeap(),0,pszBuffer);
	
	if (fccType==streamtypeVIDEO) {
		hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
		if (hic)
			return hic;
	}

	type[4] = handler[4] = '\0';
	WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type,handler,lpbiIn,lpbiOut,wMode);
	return 0;
}

/***********************************************************************
 *		ICLocate			[MSVIDEO.213]
 */
HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
						LPBITMAPINFOHEADER lpbiOut, WORD wFlags) {
	return (HIC16)ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags);
}

/***********************************************************************
 *		ICGetDisplayFormat			[MSVFW32.@]
 */
HIC VFWAPI ICGetDisplayFormat(
	HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
	INT depth,INT dx,INT dy)
{
	HIC	tmphic = hic; 

	FIXME("(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
	if (!tmphic) {
		tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
		if (!tmphic)
			return tmphic;
	}
	if ((dy == lpbiIn->biHeight) && (dx == lpbiIn->biWidth))
		dy = dx = 0; /* no resize needed */

	/* Can we decompress it ? */
	if (ICDecompressQuery(tmphic,lpbiIn,NULL) != 0)
		goto errout; /* no, sorry */

	ICDecompressGetFormat(tmphic,lpbiIn,lpbiOut);

	if (lpbiOut->biCompression != 0) {
	   FIXME("Ooch, how come decompressor outputs compressed data (%ld)??\n",
			 lpbiOut->biCompression);
	}
	if (lpbiOut->biSize < sizeof(*lpbiOut)) {
	   FIXME("Ooch, size of output BIH is too small (%ld)\n",
			 lpbiOut->biSize);
	   lpbiOut->biSize = sizeof(*lpbiOut);
	}
	if (!depth) {
		HDC	hdc;

		hdc = GetDC(0);
		depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
		ReleaseDC(0,hdc);
		if (depth==15)	depth = 16;
		if (depth<8)	depth =  8;
	}
	if (lpbiIn->biBitCount == 8)
		depth = 8;
	
	TRACE("=> 0x%08lx\n",(DWORD)tmphic);
	return tmphic;
errout:
	if (hic!=tmphic)
		ICClose(tmphic);

	TRACE("=> 0\n");
	return 0;
}

/***********************************************************************
 *		ICGetDisplayFormat			[MSVIDEO.239]
 */
HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
								  LPBITMAPINFOHEADER lpbiOut, INT16 depth, INT16 dx, INT16 dy) {
	return (HIC16)ICGetDisplayFormat(hic,lpbiIn,lpbiOut,depth,dx,dy);
}

/***********************************************************************
 *		ICCompress			[MSVFW32.@]
 */
DWORD VFWAPIV
ICCompress(
	HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
	LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
	LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
	LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev)
{
	ICCOMPRESS	iccmp;

	TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);

	iccmp.dwFlags		= dwFlags;

	iccmp.lpbiOutput	= lpbiOutput;
	iccmp.lpOutput		= lpData;
	iccmp.lpbiInput		= lpbiInput;
	iccmp.lpInput		= lpBits;

	iccmp.lpckid		= lpckid;
	iccmp.lpdwFlags		= lpdwFlags;
	iccmp.lFrameNum		= lFrameNum;
	iccmp.dwFrameSize	= dwFrameSize;
	iccmp.dwQuality		= dwQuality;
	iccmp.lpbiPrev		= lpbiPrev;
	iccmp.lpPrev		= lpPrev;
	return ICSendMessage(hic,ICM_COMPRESS,(DWORD)&iccmp,sizeof(iccmp));
}

/***********************************************************************
 *		_ICCompress			[MSVIDEO.224]
 */
DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
						   LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits, LPDWORD lpckid,
						   LPDWORD lpdwFlags, LONG lFrameNum, DWORD dwFrameSize, DWORD dwQuality,
						   LPBITMAPINFOHEADER lpbiPrev, LPVOID lpPrev) {

	DWORD ret;
	ICCOMPRESS *iccmp = SEGPTR_NEW(ICCOMPRESS);

	TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);

	iccmp->dwFlags		= dwFlags;

	iccmp->lpbiOutput	= lpbiOutput;
	iccmp->lpOutput		= lpData;
	iccmp->lpbiInput		= lpbiInput;
	iccmp->lpInput		= lpBits;

	iccmp->lpckid		= lpckid;
	iccmp->lpdwFlags		= lpdwFlags;
	iccmp->lFrameNum		= lFrameNum;
	iccmp->dwFrameSize	= dwFrameSize;
	iccmp->dwQuality		= dwQuality;
	iccmp->lpbiPrev		= lpbiPrev;
	iccmp->lpPrev		= lpPrev;
	ret = ICSendMessage16(hic,ICM_COMPRESS,(DWORD)SEGPTR_GET(iccmp),sizeof(ICCOMPRESS));
	SEGPTR_FREE(iccmp);
	return ret;
}

/***********************************************************************
 *		ICDecompress			[MSVFW32.@]
 */
DWORD VFWAPIV  ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
				LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits)
{
	ICDECOMPRESS	icd;
	DWORD ret;

	TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);

	TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);

	icd.dwFlags	= dwFlags;
	icd.lpbiInput	= lpbiFormat;
	icd.lpInput	= lpData;

	icd.lpbiOutput	= lpbi;
	icd.lpOutput	= lpBits;
	icd.ckid	= 0;
	ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD)&icd,sizeof(ICDECOMPRESS));

	TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);

	TRACE("-> %ld\n",ret);

	return ret;
}

/***********************************************************************
 *		_ICDecompress			[MSVIDEO.230]
 */
DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat,
							 LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits) {

	ICDECOMPRESS *icd = SEGPTR_NEW(ICDECOMPRESS);
	DWORD ret;
	
	TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);

	icd->dwFlags = dwFlags;
	icd->lpbiInput = lpbiFormat;
	icd->lpInput = lpData;
	icd->lpbiOutput = lpbi;
	icd->lpOutput = lpBits;
	icd->ckid = 0;

	ret = ICSendMessage16(hic,ICM_DECOMPRESS,(DWORD)SEGPTR_GET(icd),sizeof(ICDECOMPRESS));

	SEGPTR_FREE(icd);
	return ret;
}

#define COPY(x,y) (x->y = x##16->y);
#define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));

LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) {
	LPVOID ret;

	ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESSEX));
	ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
	ret = icdx16;
	
	COPY(icdx,dwFlags);
	COPYPTR(icdx,lpbiSrc);
	COPYPTR(icdx,lpSrc);
	COPYPTR(icdx,lpbiDst);
	COPYPTR(icdx,lpDst);
	COPY(icdx,xDst);
	COPY(icdx,yDst);
	COPY(icdx,dxDst);
	COPY(icdx,dyDst);
	COPY(icdx,xSrc);
	COPY(icdx,ySrc);
	COPY(icdx,dxSrc);
	COPY(icdx,dySrc);
	
	*lParam = (DWORD)(icdx);
	return ret;
}

LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) {
	LPVOID ret = 0;
	
	TRACE("Mapping %d\n",msg);

	switch (msg) {
	case DRV_LOAD:
	case DRV_ENABLE:
	case DRV_CLOSE:
	case DRV_DISABLE:
	case DRV_FREE:
	case ICM_ABOUT:
	case ICM_CONFIGURE:
	case ICM_COMPRESS_END:
	case ICM_DECOMPRESS_END:
	case ICM_DECOMPRESSEX_END:
	case ICM_SETQUALITY:
	case ICM_DRAW_START_PLAY:
	case ICM_DRAW_STOP_PLAY:
	case ICM_DRAW_REALIZE:
	case ICM_DRAW_RENDERBUFFER:
	case ICM_DRAW_END:
		break;
	case DRV_OPEN:
	case ICM_GETDEFAULTQUALITY:
	case ICM_GETQUALITY:
	case ICM_SETSTATE:
	case ICM_DRAW_WINDOW:
	case ICM_GETBUFFERSWANTED:
		*lParam1 = (DWORD)MapSL(*lParam1);
		break;
	case ICM_GETINFO:
		{
			ICINFO *ici = HeapAlloc(GetProcessHeap(),0,sizeof(ICINFO));
			ICINFO16 *ici16;

			ici16 = MapSL(*lParam1);
			ret = ici16;

			ici->dwSize = sizeof(ICINFO);
			COPY(ici,fccType);
			COPY(ici,fccHandler);
			COPY(ici,dwFlags);
			COPY(ici,dwVersion);
			COPY(ici,dwVersionICM);
                        MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
                        MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
                        MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
			*lParam1 = (DWORD)(ici);
			*lParam2 = sizeof(ICINFO);
		}
		break;
	case ICM_COMPRESS:
		{
			ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(),0,sizeof(ICCOMPRESS));
			ICCOMPRESS *icc16;

			icc16 = MapSL(*lParam1);
			ret = icc16;

			COPY(icc,dwFlags);
			COPYPTR(icc,lpbiOutput);
			COPYPTR(icc,lpOutput);
			COPYPTR(icc,lpbiInput);
			COPYPTR(icc,lpInput);
			COPYPTR(icc,lpckid);
			COPYPTR(icc,lpdwFlags);
			COPY(icc,lFrameNum);
			COPY(icc,dwFrameSize);
			COPY(icc,dwQuality);
			COPYPTR(icc,lpbiPrev);
			COPYPTR(icc,lpPrev);
			
			*lParam1 = (DWORD)(icc);
			*lParam2 = sizeof(ICCOMPRESS);
		}
		break;
	case ICM_DECOMPRESS:
		{
			ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESS));
			ICDECOMPRESS *icd16; /* Same structure except for the pointers */
			
			icd16 = MapSL(*lParam1);
			ret = icd16;
			
			COPY(icd,dwFlags);
			COPYPTR(icd,lpbiInput);
			COPYPTR(icd,lpInput);
			COPYPTR(icd,lpbiOutput);
			COPYPTR(icd,lpOutput);
			COPY(icd,ckid);
			
			*lParam1 = (DWORD)(icd);
			*lParam2 = sizeof(ICDECOMPRESS);
		}
		break;
	case ICM_COMPRESS_BEGIN:
	case ICM_COMPRESS_GET_FORMAT:
	case ICM_COMPRESS_GET_SIZE:
	case ICM_COMPRESS_QUERY:
	case ICM_DECOMPRESS_GET_FORMAT:
	case ICM_DECOMPRESS_QUERY:
	case ICM_DECOMPRESS_BEGIN:
	case ICM_DECOMPRESS_SET_PALETTE:
	case ICM_DECOMPRESS_GET_PALETTE:
		*lParam1 = (DWORD)MapSL(*lParam1);
		*lParam2 = (DWORD)MapSL(*lParam2);
		break;
	case ICM_DECOMPRESSEX_QUERY:
		if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
			WARN("*lParam2 has unknown value %p\n",(ICDECOMPRESSEX16*)*lParam2);
		/* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
		 * This is because of ICMessage(). Special case it?
		 {
		 LPVOID* addr = HeapAlloc(GetProcessHeap(),0,2*sizeof(LPVOID));
		 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
		 if (*lParam2)
		 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
		 else
		 addr[1] = 0;
		 
		 ret = addr;
		 }
		 break;*/
	case ICM_DECOMPRESSEX_BEGIN:
	case ICM_DECOMPRESSEX:
		ret = MSVIDEO_MapICDEX16To32(lParam1);
		*lParam2 = sizeof(ICDECOMPRESSEX);
		break;
	case ICM_DRAW_BEGIN:
		{
			ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWBEGIN));
			ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
			ret = icdb16;

			COPY(icdb,dwFlags);
			COPY(icdb,hpal);
			COPY(icdb,hwnd);
			COPY(icdb,hdc);
			COPY(icdb,xDst);
			COPY(icdb,yDst);
			COPY(icdb,dxDst);
			COPY(icdb,dyDst);
			COPYPTR(icdb,lpbi);
			COPY(icdb,xSrc);
			COPY(icdb,ySrc);
			COPY(icdb,dxSrc);
			COPY(icdb,dySrc);
			COPY(icdb,dwRate);
			COPY(icdb,dwScale);

			*lParam1 = (DWORD)(icdb);
			*lParam2 = sizeof(ICDRAWBEGIN);
		}
		break;
	case ICM_DRAW_SUGGESTFORMAT:
		{
			ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWSUGGEST));
			ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
			
			ret = icds16;

			COPY(icds,dwFlags);
			COPYPTR(icds,lpbiIn);
			COPYPTR(icds,lpbiSuggest);
			COPY(icds,dxSrc);
			COPY(icds,dySrc);
			COPY(icds,dxDst);
			COPY(icds,dyDst);
			COPY(icds,hicDecompressor);

			*lParam1 = (DWORD)(icds);
			*lParam2 = sizeof(ICDRAWSUGGEST);
		}
		break;
	case ICM_DRAW:
		{
			ICDRAW *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAW));
			ICDRAW *icd16 = MapSL(*lParam1);
			ret = icd16;

			COPY(icd,dwFlags);
			COPYPTR(icd,lpFormat);
			COPYPTR(icd,lpData);
			COPY(icd,cbData);
			COPY(icd,lTime);

			*lParam1 = (DWORD)(icd);
			*lParam2 = sizeof(ICDRAW);
		}
		break;
	case ICM_DRAW_START:
	case ICM_DRAW_STOP:
		break;
	default:
		FIXME("%d is not yet handled. Expect a crash.\n",msg);
	}
	return ret;
}

#undef COPY
#undef COPYPTR

void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2) {
	TRACE("Unmapping %d\n",msg);

#define UNCOPY(x,y) (x##16->y = x->y);

	switch (msg) {
	case ICM_GETINFO:
		{
			ICINFO *ici = (ICINFO*)(*lParam1);
			ICINFO16 *ici16 = (ICINFO16*)data16;

			UNCOPY(ici,fccType);
			UNCOPY(ici,fccHandler);
			UNCOPY(ici,dwFlags);
			UNCOPY(ici,dwVersion);
			UNCOPY(ici,dwVersionICM);
                        WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
                                             sizeof(ici16->szName), NULL, NULL );
                        ici16->szName[sizeof(ici16->szName)-1] = 0;
                        WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
                                             sizeof(ici16->szDescription), NULL, NULL );
                        ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
			/* This just gives garbage for some reason - BB
			   lstrcpynWtoA(ici16->szDriver,ici->szDriver,128);*/

			HeapFree(GetProcessHeap(),0,ici);
		}
		break;
	case ICM_DECOMPRESS_QUERY:
		/*{
		  LPVOID* x = data16;
		  HeapFree(GetProcessHeap(),0,x[0]);
		  if (x[1])
		  HeapFree(GetProcessHeap(),0,x[1]);
		  }
		  break;*/
	case ICM_COMPRESS:
	case ICM_DECOMPRESS:
	case ICM_DECOMPRESSEX_QUERY:
	case ICM_DECOMPRESSEX_BEGIN:
	case ICM_DECOMPRESSEX:
	case ICM_DRAW_BEGIN:
	case ICM_DRAW_SUGGESTFORMAT:
	case ICM_DRAW:
		HeapFree(GetProcessHeap(),0,data16);
		break;
	default:
		ERR("Unmapping unmapped msg %d\n",msg);
	}
#undef UNCOPY		
}

LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2, BOOL bFrom32) {
	LRESULT		ret;
	WINE_HIC	*whic = GlobalLock16(hic);
	LPVOID data16 = 0;
	BOOL bDrv32;

#define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx,%d)\n",(DWORD)hic,lParam1,lParam2,bFrom32?32:16);break;

	switch (msg) {
		/* DRV_* */
		XX(DRV_LOAD);
		XX(DRV_ENABLE);
		XX(DRV_OPEN);
		XX(DRV_CLOSE);
		XX(DRV_DISABLE);
		XX(DRV_FREE);
		/* 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("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,%i) unknown message\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,bFrom32?32:16);
	}

#undef XX

	if (!whic) return ICERR_BADHANDLE;

	if (whic->driverproc) { /* IC is a function */
		bDrv32 = whic->private;
	} else {
		bDrv32 = ((GetDriverFlags(whic->hdrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST);
	}

	if (!bFrom32) {
		if (bDrv32)
			data16 = MSVIDEO_MapMsg16To32(msg,&lParam1,&lParam2);
	} else {
		if (!bDrv32) {
			ERR("Can't do 32->16 mappings\n");
			ret = -1;
			goto out;
		}
	}
	
	if (whic->driverproc) {
		if (bDrv32) {
			ret = whic->driverproc(whic->hdrv,hic,msg,lParam1,lParam2);
		} else {
			ret = MSVIDEO_CallTo16_long_lwwll((FARPROC16)whic->driverproc,whic->hdrv,hic,msg,lParam1,lParam2);
		}
	} else {
		ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
	}

	if (data16)
		MSVIDEO_UnmapMsg16To32(msg,data16,&lParam1,&lParam2);
 
 out:
	GlobalUnlock16(hic);
	
	TRACE("	-> 0x%08lx\n",ret);
	return ret;
}

/***********************************************************************
 *		ICSendMessage			[MSVFW32.@]
 */
LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2) {
	return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,TRUE);
}

/***********************************************************************
 *		ICSendMessage			[MSVIDEO.205]
 */
LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) {
	return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,FALSE);
}

/***********************************************************************
 *		_ICMessage			[MSVIDEO.207]
 */
LRESULT VFWAPIV ICMessage16(void) {
	HIC16 hic;
	UINT16 msg;
	UINT16 cb;
	LPWORD lpData;
	LRESULT ret;
	UINT16 i;

	VA_LIST16 valist;
	
	VA_START16(valist);
	hic = VA_ARG16(valist, HIC16);
	msg = VA_ARG16(valist, UINT16);
	cb  = VA_ARG16(valist, UINT16);

	lpData = SEGPTR_ALLOC(cb);

	TRACE("0x%08lx, %u, %u, ...)\n",(DWORD)hic,msg,cb);

	for(i=0;i<cb/sizeof(WORD);i++) {
		lpData[i] = VA_ARG16(valist, WORD);
	}
		
	VA_END16(valist);
	ret = ICSendMessage16(hic, msg, (DWORD)(SEGPTR_GET(lpData)), (DWORD)cb);

	SEGPTR_FREE(lpData);
	return ret;
}

/***********************************************************************
 *		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("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
		  (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)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));
}

/***********************************************************************
 *		_ICDrawBegin		[MSVIDEO.232]
 */
DWORD VFWAPIV ICDrawBegin16(
	HIC16               hic,     /* [in] */
	DWORD               dwFlags, /* [in] flags */
	HPALETTE16          hpal,    /* [in] palette to draw with */
	HWND16              hwnd,    /* [in] window to draw to */
	HDC16               hdc,     /* [in] HDC to draw to */
	INT16               xDst,    /* [in] destination rectangle */
	INT16               yDst,    /* [in] */
	INT16               dxDst,   /* [in] */
	INT16               dyDst,   /* [in] */
	LPBITMAPINFOHEADER  lpbi,    /* [in] format of frame to draw NOTE: SEGPTR */
	INT16		    xSrc,    /* [in] source rectangle */
	INT16		    ySrc,    /* [in] */
	INT16		    dxSrc,   /* [in] */
	INT16		    dySrc,   /* [in] */
	DWORD		    dwRate,  /* [in] frames/second = (dwRate/dwScale) */
	DWORD		    dwScale) /* [in] */
{
	DWORD ret;
	ICDRAWBEGIN16* icdb = SEGPTR_NEW(ICDRAWBEGIN16); /* SEGPTR for mapper to deal with */

	TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
		  (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)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; /* Keep this as SEGPTR for the mapping code to deal with */
	icdb->xSrc = xSrc;
	icdb->ySrc = ySrc;
	icdb->dxSrc = dxSrc;
	icdb->dySrc = dySrc;
	icdb->dwRate = dwRate;
	icdb->dwScale = dwScale;
	
	ret = (DWORD)ICSendMessage16(hic,ICM_DRAW_BEGIN,(DWORD)SEGPTR_GET(icdb),sizeof(ICDRAWBEGIN16));
	SEGPTR_FREE(icdb);
	return ret;
}

/***********************************************************************
 *		ICDraw			[MSVFW32.@]
 */
DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
	ICDRAW	icd;

	TRACE("(0x%09lx,%ld,%p,%p,%ld,%ld)\n",(DWORD)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));
}

/***********************************************************************
 *		_ICDraw			[MSVIDEO.234]
 */
DWORD VFWAPIV ICDraw16(
	HIC16 hic,
	DWORD dwFlags,
	LPVOID lpFormat, /* [???] NOTE: SEGPTR */
	LPVOID lpData,   /* [???] NOTE: SEGPTR */
	DWORD cbData, 
	LONG lTime) 
{
	ICDRAW* icd = SEGPTR_NEW(ICDRAW); /* SEGPTR for mapper to deal with */

	TRACE("(0x%08lx,0x%08lx,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
	icd->dwFlags = dwFlags;
	icd->lpFormat = lpFormat;
	icd->lpData = lpData;
	icd->cbData = cbData;
	icd->lTime = lTime;

	return ICSendMessage16(hic,ICM_DRAW,(DWORD)SEGPTR_GET(icd),sizeof(ICDRAW));
}

/***********************************************************************
 *		ICClose			[MSVFW32.@]
 */
LRESULT WINAPI ICClose(HIC hic) {
	WINE_HIC *whic = GlobalLock16(hic);
	TRACE("(0x%08lx)\n",(DWORD)hic);
	if (whic->driverproc) {
		ICSendMessage(hic,DRV_CLOSE,0,0);
		ICSendMessage(hic,DRV_DISABLE,0,0);
		ICSendMessage(hic,DRV_FREE,0,0);
	} else {
		CloseDriver(whic->hdrv,0,0);
	}

	GlobalUnlock16(hic);
	GlobalFree16(hic);
	return 0;
}

/***********************************************************************
 *		ICClose			[MSVIDEO.204]
 */
LRESULT WINAPI ICClose16(HIC16 hic) {
	return ICClose(hic);
}

