2 * Copyright 1998 Marcus Meissner
3 * Copyright 2000 Bradley Baetz
5 * FIXME: This all assumes 32 bit codecs
6 * Win95 appears to prefer 32 bit codecs, even from 16 bit code.
7 * There is the ICOpenFunction16 to worry about still, though.
21 #include "wine/winbase16.h"
22 #include "debugtools.h"
24 #include "stackframe.h"
26 DEFAULT_DEBUG_CHANNEL(msvideo);
28 /* ### start build ### */
29 extern LONG CALLBACK MSVIDEO_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
30 /* ### stop build ### */
32 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2);
33 void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID lpv, LPDWORD lParam1, LPDWORD lParam2);
34 LRESULT MSVIDEO_SendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2, BOOL bFrom32);
36 /***********************************************************************
37 * VideoForWindowsVersion [MSVFW.2][MSVIDEO.2]
38 * Returns the version in major.minor form.
39 * In Windows95 this returns 0x040003b6 (4.950)
41 DWORD WINAPI VideoForWindowsVersion(void) {
42 return 0x040003B6; /* 4.950 */
45 /***********************************************************************
46 * VideoCapDriverDescAndVer [MSVIDEO.22]
48 DWORD WINAPI VideoCapDriverDescAndVer(
49 WORD nr,LPSTR buf1,WORD buf1len,LPSTR buf2,WORD buf2len
55 char *s,buf[2000],fn[260];
59 TRACE("(%d,%p,%d,%p,%d)\n",nr,buf1,buf1len,buf2,buf2len);
60 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,sizeof(buf),"system.ini")) {
63 if (!strncasecmp(s,"vid",3)) {
68 s=s+strlen(s)+1; /* either next char or \0 */
71 return 20; /* hmm, out of entries even if we don't have any */
73 FIXME("No more VID* entries found\n");
76 GetPrivateProfileStringA("drivers32",s,NULL,fn,sizeof(fn),"system.ini");
77 infosize = GetFileVersionInfoSizeA(fn,&verhandle);
79 TRACE("%s has no fileversioninfo.\n",fn);
82 infobuf = HeapAlloc(GetProcessHeap(),0,infosize);
83 if (GetFileVersionInfoA(fn,verhandle,infosize,infobuf)) {
85 /* Yes, two space behind : */
86 /* FIXME: test for buflen */
87 sprintf(vbuf,"Version: %d.%d.%d.%d\n",
88 ((WORD*)infobuf)[0x0f],
89 ((WORD*)infobuf)[0x0e],
90 ((WORD*)infobuf)[0x11],
91 ((WORD*)infobuf)[0x10]
93 TRACE("version of %s is %s\n",fn,vbuf);
94 strncpy(buf2,vbuf,buf2len);
96 TRACE("GetFileVersionInfoA failed for %s.\n",fn);
97 strncpy(buf2,fn,buf2len); /* msvideo.dll appears to copy fn*/
99 /* FIXME: language problem? */
100 if (VerQueryValueA( infobuf,
101 "\\StringFileInfo\\040904E4\\FileDescription",
105 TRACE("VQA returned %s\n",(LPCSTR)subblock);
106 strncpy(buf1,subblock,buf1len);
108 TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
109 strncpy(buf1,fn,buf1len); /* msvideo.dll appears to copy fn*/
111 HeapFree(GetProcessHeap(),0,infobuf);
115 /* system.ini: [drivers] */
117 /***********************************************************************
119 * Get information about an installable compressor. Return TRUE if there
123 DWORD fccType, /* [in] type of compressor ('vidc') */
124 DWORD fccHandler, /* [in] <n>th compressor */
125 ICINFO *lpicinfo) /* [out] information about compressor */
127 char type[5],buf[2000];
129 memcpy(type,&fccType,4);type[4]=0;
130 TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
131 /* does OpenDriver/CloseDriver */
132 lpicinfo->dwSize = sizeof(ICINFO);
133 lpicinfo->fccType = fccType;
134 lpicinfo->dwFlags = 0;
135 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
138 if (!strncasecmp(type,s,4)) {
140 lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
144 s=s+strlen(s)+1; /* either next char or \0 */
150 /**********************************************************************/
152 BOOL16 VFWAPI ICInfo16(
153 DWORD fccType, /* [in] */
154 DWORD fccHandler, /* [in] */
155 ICINFO16 *lpicinfo) /* [in/out] NOTE: SEGPTR */
159 DWORD lParam = (DWORD)lpicinfo;
160 DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
162 /* Use the mapping functions to map the ICINFO structure */
163 lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO,&lParam,&size);
165 ret = ICInfo(fccType,fccHandler,(ICINFO*)lParam);
167 MSVIDEO_UnmapMsg16To32(ICM_GETINFO,lpv,&lParam,&size);
172 /***********************************************************************
174 * Opens an installable compressor. Return special handle.
176 HIC VFWAPI ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
177 char type[5],handler[5],codecname[20];
183 memcpy(type,&fccType,4);type[4]=0;
184 memcpy(handler,&fccHandler,4);handler[4]=0;
185 TRACE("(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
187 sprintf(codecname,"%s.%s",type,handler);
189 /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
190 * same layout as ICOPEN
192 icopen.fccType = fccType;
193 icopen.fccHandler = fccHandler;
194 icopen.dwSize = sizeof(ICOPEN);
195 icopen.dwFlags = wMode;
196 /* FIXME: do we need to fill out the rest too? */
197 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
199 if (!strcasecmp(type,"vids")) {
200 sprintf(codecname,"vidc.%s",handler);
201 fccType = mmioFOURCC('v','i','d','c');
203 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
207 /* The handle should be a valid 16-bit handle as well */
208 hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
209 whic = (WINE_HIC*)GlobalLock16(hic);
211 whic->driverproc= NULL;
214 TRACE("=> 0x%08lx\n",(DWORD)hic);
218 HIC MSVIDEO_OpenFunc(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler, BOOL bFrom32) {
219 char type[5],handler[5],codecname[20];
221 ICOPEN* icopen = SEGPTR_NEW(ICOPEN);
224 memcpy(type,&fccType,4);type[4]=0;
225 memcpy(handler,&fccHandler,4);handler[4]=0;
226 TRACE("(%s,%s,%d,%p,%d)\n",type,handler,wMode,lpfnHandler,bFrom32?32:16);
228 icopen->fccType = fccType;
229 icopen->fccHandler = fccHandler;
230 icopen->dwSize = sizeof(ICOPEN);
231 icopen->dwFlags = wMode;
233 sprintf(codecname,"%s.%s",type,handler);
235 hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
238 whic = GlobalLock16(hic);
239 whic->driverproc = lpfnHandler;
241 whic->private = bFrom32;
243 /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
244 /* What if the function is used more than once? */
246 if (MSVIDEO_SendMessage(hic,DRV_LOAD,0L,0L,bFrom32) != DRV_SUCCESS) {
247 WARN("DRV_LOAD failed for hic 0x%08lx\n",(DWORD)hic);
251 /* return value is not checked */
252 MSVIDEO_SendMessage(hic,DRV_ENABLE,0L,0L,bFrom32);
254 whic->hdrv = MSVIDEO_SendMessage(hic,DRV_OPEN,0,(LPARAM)(SEGPTR_GET(icopen)),FALSE);
255 if (whic->hdrv == 0) {
256 WARN("DRV_OPEN failed for hic 0x%08lx\n",(DWORD)hic);
262 TRACE("=> 0x%08lx\n",(DWORD)hic);
266 /***********************************************************************
267 * ICOpenFunction [MSVFW.38]
269 HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) {
270 return MSVIDEO_OpenFunc(fccType,fccHandler,wMode,lpfnHandler,TRUE);
273 /***********************************************************************
274 * ICOpen [MSVIDEO.203]
276 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode) {
277 return (HIC16)ICOpen(fccType, fccHandler, wMode);
280 /***********************************************************************
281 * ICOpenFunction [MSVIDEO.206]
283 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
285 return MSVIDEO_OpenFunc(fccType, fccHandler, wMode, (FARPROC)lpfnHandler,FALSE);
288 /***********************************************************************
289 * ICGetInfo [MSVFW.30]
291 LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
294 TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
295 ret = ICSendMessage(hic,ICM_GETINFO,(DWORD)picinfo,cb);
296 TRACE(" -> 0x%08lx\n",ret);
300 /***********************************************************************
301 * ICGetInfo [MSVIDEO.212]
303 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 *picinfo,DWORD cb) {
306 TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
307 ret = ICSendMessage16(hic,ICM_GETINFO,(DWORD)picinfo,cb);
308 TRACE(" -> 0x%08lx\n",ret);
312 /***********************************************************************
313 * ICLocate [MSVFW.35]
316 DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
317 LPBITMAPINFOHEADER lpbiOut, WORD wMode)
319 char type[5],handler[5];
324 type[4]=0;memcpy(type,&fccType,4);
325 handler[4]=0;memcpy(handler,&fccHandler,4);
327 TRACE("(%s,%s,%p,%p,0x%04x)\n", type, handler, lpbiIn, lpbiOut, wMode);
330 case ICMODE_FASTCOMPRESS:
331 case ICMODE_COMPRESS:
332 querymsg = ICM_COMPRESS_QUERY;
334 case ICMODE_FASTDECOMPRESS:
335 case ICMODE_DECOMPRESS:
336 querymsg = ICM_DECOMPRESS_QUERY;
339 querymsg = ICM_DRAW_QUERY;
342 WARN("Unknown mode (%d)\n",wMode);
346 /* Easy case: handler/type match, we just fire a query and return */
347 hic = ICOpen(fccType,fccHandler,wMode);
349 if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
354 type[4]='.';memcpy(type,&fccType,4);
355 handler[4]='.';memcpy(handler,&fccHandler,4);
357 /* Now try each driver in turn. 32 bit codecs only. */
358 /* FIXME: Move this to an init routine? */
360 pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(),0,1024);
361 if (GetPrivateProfileSectionA("drivers32",pszBuffer,1024,"system.ini")) {
364 if (!strncasecmp(type,s,5)) {
366 while (*s2 != '\0' && *s2 != '.') s2++;
370 h = ICOpen(fccType,*(DWORD*)s2,wMode);
372 if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
381 HeapFree(GetProcessHeap(),0,pszBuffer);
383 if (fccType==streamtypeVIDEO) {
384 hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
389 type[4] = handler[4] = '\0';
390 WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type,handler,lpbiIn,lpbiOut,wMode);
394 /***********************************************************************
395 * ICLocate [MSVIDEO.213]
397 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
398 LPBITMAPINFOHEADER lpbiOut, WORD wFlags) {
399 return (HIC16)ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags);
402 /***********************************************************************
403 * ICGetDisplayFormat [MSVFW.29]
405 HIC VFWAPI ICGetDisplayFormat(
406 HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
407 INT depth,INT dx,INT dy)
411 FIXME("(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
413 tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
417 if ((dy == lpbiIn->biHeight) && (dx == lpbiIn->biWidth))
418 dy = dx = 0; /* no resize needed */
420 /* Can we decompress it ? */
421 if (ICDecompressQuery(tmphic,lpbiIn,NULL) != 0)
422 goto errout; /* no, sorry */
424 ICDecompressGetFormat(tmphic,lpbiIn,lpbiOut);
426 if (lpbiOut->biCompression != 0) {
427 FIXME("Ooch, how come decompressor outputs compressed data (%ld)??\n",
428 lpbiOut->biCompression);
430 if (lpbiOut->biSize < sizeof(*lpbiOut)) {
431 FIXME("Ooch, size of output BIH is too small (%ld)\n",
433 lpbiOut->biSize = sizeof(*lpbiOut);
439 depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
441 if (depth==15) depth = 16;
442 if (depth<8) depth = 8;
444 if (lpbiIn->biBitCount == 8)
447 TRACE("=> 0x%08lx\n",(DWORD)tmphic);
457 /**********************************************************************/
459 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
460 LPBITMAPINFOHEADER lpbiOut, INT16 depth, INT16 dx, INT16 dy) {
461 return (HIC16)ICGetDisplayFormat(hic,lpbiIn,lpbiOut,depth,dx,dy);
464 /***********************************************************************
465 * ICCompress [MSVFW.23]
469 HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
470 LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
471 LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
472 LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev)
476 TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
478 iccmp.dwFlags = dwFlags;
480 iccmp.lpbiOutput = lpbiOutput;
481 iccmp.lpOutput = lpData;
482 iccmp.lpbiInput = lpbiInput;
483 iccmp.lpInput = lpBits;
485 iccmp.lpckid = lpckid;
486 iccmp.lpdwFlags = lpdwFlags;
487 iccmp.lFrameNum = lFrameNum;
488 iccmp.dwFrameSize = dwFrameSize;
489 iccmp.dwQuality = dwQuality;
490 iccmp.lpbiPrev = lpbiPrev;
491 iccmp.lpPrev = lpPrev;
492 return ICSendMessage(hic,ICM_COMPRESS,(DWORD)&iccmp,sizeof(iccmp));
495 /***********************************************************************
496 * _ICCompress [MSVIDEO.224]
498 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
499 LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits, LPDWORD lpckid,
500 LPDWORD lpdwFlags, LONG lFrameNum, DWORD dwFrameSize, DWORD dwQuality,
501 LPBITMAPINFOHEADER lpbiPrev, LPVOID lpPrev) {
504 ICCOMPRESS *iccmp = SEGPTR_NEW(ICCOMPRESS);
506 TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
508 iccmp->dwFlags = dwFlags;
510 iccmp->lpbiOutput = lpbiOutput;
511 iccmp->lpOutput = lpData;
512 iccmp->lpbiInput = lpbiInput;
513 iccmp->lpInput = lpBits;
515 iccmp->lpckid = lpckid;
516 iccmp->lpdwFlags = lpdwFlags;
517 iccmp->lFrameNum = lFrameNum;
518 iccmp->dwFrameSize = dwFrameSize;
519 iccmp->dwQuality = dwQuality;
520 iccmp->lpbiPrev = lpbiPrev;
521 iccmp->lpPrev = lpPrev;
522 ret = ICSendMessage16(hic,ICM_COMPRESS,(DWORD)SEGPTR_GET(iccmp),sizeof(ICCOMPRESS));
527 /***********************************************************************
528 * ICDecompress [MSVFW.26]
530 DWORD VFWAPIV ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
531 LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits)
536 TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
538 TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
540 icd.dwFlags = dwFlags;
541 icd.lpbiInput = lpbiFormat;
542 icd.lpInput = lpData;
544 icd.lpbiOutput = lpbi;
545 icd.lpOutput = lpBits;
547 ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD)&icd,sizeof(ICDECOMPRESS));
549 TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
551 TRACE("-> %ld\n",ret);
556 /***********************************************************************
557 * _ICDecompress [MSVIDEO.230]
559 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat,
560 LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits) {
562 ICDECOMPRESS *icd = SEGPTR_NEW(ICDECOMPRESS);
565 TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
567 icd->dwFlags = dwFlags;
568 icd->lpbiInput = lpbiFormat;
569 icd->lpInput = lpData;
570 icd->lpbiOutput = lpbi;
571 icd->lpOutput = lpBits;
574 ret = ICSendMessage16(hic,ICM_DECOMPRESS,(DWORD)SEGPTR_GET(icd),sizeof(ICDECOMPRESS));
580 #define COPY(x,y) (x->y = x##16->y);
581 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
583 LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) {
586 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESSEX));
587 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
591 COPYPTR(icdx,lpbiSrc);
593 COPYPTR(icdx,lpbiDst);
604 *lParam = (DWORD)(icdx);
608 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) {
611 TRACE("Mapping %d\n",msg);
621 case ICM_COMPRESS_END:
622 case ICM_DECOMPRESS_END:
623 case ICM_DECOMPRESSEX_END:
625 case ICM_DRAW_START_PLAY:
626 case ICM_DRAW_STOP_PLAY:
627 case ICM_DRAW_REALIZE:
628 case ICM_DRAW_RENDERBUFFER:
632 case ICM_GETDEFAULTQUALITY:
635 case ICM_DRAW_WINDOW:
636 case ICM_GETBUFFERSWANTED:
637 *lParam1 = (DWORD)MapSL(*lParam1);
641 ICINFO *ici = HeapAlloc(GetProcessHeap(),0,sizeof(ICINFO));
644 ici16 = MapSL(*lParam1);
647 ici->dwSize = sizeof(ICINFO);
649 COPY(ici,fccHandler);
652 COPY(ici,dwVersionICM);
653 MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
654 MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
655 MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
656 *lParam1 = (DWORD)(ici);
657 *lParam2 = sizeof(ICINFO);
662 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(),0,sizeof(ICCOMPRESS));
665 icc16 = MapSL(*lParam1);
669 COPYPTR(icc,lpbiOutput);
670 COPYPTR(icc,lpOutput);
671 COPYPTR(icc,lpbiInput);
672 COPYPTR(icc,lpInput);
674 COPYPTR(icc,lpdwFlags);
676 COPY(icc,dwFrameSize);
678 COPYPTR(icc,lpbiPrev);
681 *lParam1 = (DWORD)(icc);
682 *lParam2 = sizeof(ICCOMPRESS);
687 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESS));
688 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
690 icd16 = MapSL(*lParam1);
694 COPYPTR(icd,lpbiInput);
695 COPYPTR(icd,lpInput);
696 COPYPTR(icd,lpbiOutput);
697 COPYPTR(icd,lpOutput);
700 *lParam1 = (DWORD)(icd);
701 *lParam2 = sizeof(ICDECOMPRESS);
704 case ICM_COMPRESS_BEGIN:
705 case ICM_COMPRESS_GET_FORMAT:
706 case ICM_COMPRESS_GET_SIZE:
707 case ICM_COMPRESS_QUERY:
708 case ICM_DECOMPRESS_GET_FORMAT:
709 case ICM_DECOMPRESS_QUERY:
710 case ICM_DECOMPRESS_BEGIN:
711 case ICM_DECOMPRESS_SET_PALETTE:
712 case ICM_DECOMPRESS_GET_PALETTE:
713 *lParam1 = (DWORD)MapSL(*lParam1);
714 *lParam2 = (DWORD)MapSL(*lParam2);
716 case ICM_DECOMPRESSEX_QUERY:
717 if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
718 WARN("*lParam2 has unknown value %p\n",(ICDECOMPRESSEX16*)*lParam2);
719 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
720 * This is because of ICMessage(). Special case it?
722 LPVOID* addr = HeapAlloc(GetProcessHeap(),0,2*sizeof(LPVOID));
723 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
725 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
732 case ICM_DECOMPRESSEX_BEGIN:
733 case ICM_DECOMPRESSEX:
734 ret = MSVIDEO_MapICDEX16To32(lParam1);
735 *lParam2 = sizeof(ICDECOMPRESSEX);
739 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWBEGIN));
740 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
759 *lParam1 = (DWORD)(icdb);
760 *lParam2 = sizeof(ICDRAWBEGIN);
763 case ICM_DRAW_SUGGESTFORMAT:
765 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWSUGGEST));
766 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
771 COPYPTR(icds,lpbiIn);
772 COPYPTR(icds,lpbiSuggest);
777 COPY(icds,hicDecompressor);
779 *lParam1 = (DWORD)(icds);
780 *lParam2 = sizeof(ICDRAWSUGGEST);
785 ICDRAW *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAW));
786 ICDRAW *icd16 = MapSL(*lParam1);
790 COPYPTR(icd,lpFormat);
795 *lParam1 = (DWORD)(icd);
796 *lParam2 = sizeof(ICDRAW);
803 FIXME("%d is not yet handled. Expect a crash.\n",msg);
811 void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2) {
812 TRACE("Unmapping %d\n",msg);
814 #define UNCOPY(x,y) (x##16->y = x->y);
819 ICINFO *ici = (ICINFO*)(*lParam1);
820 ICINFO16 *ici16 = (ICINFO16*)data16;
823 UNCOPY(ici,fccHandler);
825 UNCOPY(ici,dwVersion);
826 UNCOPY(ici,dwVersionICM);
827 WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
828 sizeof(ici16->szName), NULL, NULL );
829 ici16->szName[sizeof(ici16->szName)-1] = 0;
830 WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
831 sizeof(ici16->szDescription), NULL, NULL );
832 ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
833 /* This just gives garbage for some reason - BB
834 lstrcpynWtoA(ici16->szDriver,ici->szDriver,128);*/
836 HeapFree(GetProcessHeap(),0,ici);
839 case ICM_DECOMPRESS_QUERY:
842 HeapFree(GetProcessHeap(),0,x[0]);
844 HeapFree(GetProcessHeap(),0,x[1]);
849 case ICM_DECOMPRESSEX_QUERY:
850 case ICM_DECOMPRESSEX_BEGIN:
851 case ICM_DECOMPRESSEX:
853 case ICM_DRAW_SUGGESTFORMAT:
855 HeapFree(GetProcessHeap(),0,data16);
858 ERR("Unmapping unmapped msg %d\n",msg);
863 LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2, BOOL bFrom32) {
865 WINE_HIC *whic = GlobalLock16(hic);
869 #define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx,%d)\n",(DWORD)hic,lParam1,lParam2,bFrom32?32:16);break;
884 XX(ICM_GETDEFAULTQUALITY);
891 XX(ICM_COMPRESS_FRAMES_INFO);
892 XX(ICM_COMPRESS_GET_FORMAT);
893 XX(ICM_COMPRESS_GET_SIZE);
894 XX(ICM_COMPRESS_QUERY);
895 XX(ICM_COMPRESS_BEGIN);
897 XX(ICM_COMPRESS_END);
898 XX(ICM_DECOMPRESS_GET_FORMAT);
899 XX(ICM_DECOMPRESS_QUERY);
900 XX(ICM_DECOMPRESS_BEGIN);
902 XX(ICM_DECOMPRESS_END);
903 XX(ICM_DECOMPRESS_SET_PALETTE);
904 XX(ICM_DECOMPRESS_GET_PALETTE);
907 XX(ICM_DRAW_GET_PALETTE);
911 XX(ICM_DRAW_GETTIME);
914 XX(ICM_DRAW_SETTIME);
915 XX(ICM_DRAW_REALIZE);
917 XX(ICM_DRAW_RENDERBUFFER);
918 XX(ICM_DRAW_START_PLAY);
919 XX(ICM_DRAW_STOP_PLAY);
920 XX(ICM_DRAW_SUGGESTFORMAT);
921 XX(ICM_DRAW_CHANGEPALETTE);
922 XX(ICM_GETBUFFERSWANTED);
923 XX(ICM_GETDEFAULTKEYFRAMERATE);
924 XX(ICM_DECOMPRESSEX_BEGIN);
925 XX(ICM_DECOMPRESSEX_QUERY);
926 XX(ICM_DECOMPRESSEX);
927 XX(ICM_DECOMPRESSEX_END);
928 XX(ICM_SET_STATUS_PROC);
930 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,%i) unknown message\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,bFrom32?32:16);
935 if (!whic) return ICERR_BADHANDLE;
937 if (whic->driverproc) { /* IC is a function */
938 bDrv32 = whic->private;
940 bDrv32 = ((GetDriverFlags(whic->hdrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST);
945 data16 = MSVIDEO_MapMsg16To32(msg,&lParam1,&lParam2);
948 ERR("Can't do 32->16 mappings\n");
954 if (whic->driverproc) {
956 ret = whic->driverproc(whic->hdrv,hic,msg,lParam1,lParam2);
958 ret = MSVIDEO_CallTo16_long_lwwll((FARPROC16)whic->driverproc,whic->hdrv,hic,msg,lParam1,lParam2);
961 ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
965 MSVIDEO_UnmapMsg16To32(msg,data16,&lParam1,&lParam2);
970 TRACE(" -> 0x%08lx\n",ret);
974 /***********************************************************************
975 * ICSendMessage [MSVFW.40]
977 LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2) {
978 return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,TRUE);
981 /***********************************************************************
982 * ICSendMessage [MSVIDEO.205]
984 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) {
985 return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,FALSE);
988 /***********************************************************************
989 * _ICMessage [MSVIDEO.207]
991 LRESULT VFWAPIV ICMessage16(void) {
1002 hic = VA_ARG16(valist, HIC16);
1003 msg = VA_ARG16(valist, UINT16);
1004 cb = VA_ARG16(valist, UINT16);
1006 lpData = SEGPTR_ALLOC(cb);
1008 TRACE("0x%08lx, %u, %u, ...)\n",(DWORD)hic,msg,cb);
1010 for(i=0;i<cb/sizeof(WORD);i++) {
1011 lpData[i] = VA_ARG16(valist, WORD);
1015 ret = ICSendMessage16(hic, msg, (DWORD)(SEGPTR_GET(lpData)), (DWORD)cb);
1017 SEGPTR_FREE(lpData);
1021 /***********************************************************************
1022 * ICDrawBegin [MSVFW.28]
1024 DWORD VFWAPIV ICDrawBegin(
1026 DWORD dwFlags, /* [in] flags */
1027 HPALETTE hpal, /* [in] palette to draw with */
1028 HWND hwnd, /* [in] window to draw to */
1029 HDC hdc, /* [in] HDC to draw to */
1030 INT xDst, /* [in] destination rectangle */
1031 INT yDst, /* [in] */
1032 INT dxDst, /* [in] */
1033 INT dyDst, /* [in] */
1034 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw */
1035 INT xSrc, /* [in] source rectangle */
1036 INT ySrc, /* [in] */
1037 INT dxSrc, /* [in] */
1038 INT dySrc, /* [in] */
1039 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
1040 DWORD dwScale) /* [in] */
1045 TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
1046 (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)hdc, xDst, yDst, dxDst, dyDst,
1047 lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
1049 icdb.dwFlags = dwFlags;
1062 icdb.dwRate = dwRate;
1063 icdb.dwScale = dwScale;
1064 return ICSendMessage(hic,ICM_DRAW_BEGIN,(DWORD)&icdb,sizeof(icdb));
1067 /***********************************************************************
1068 * _ICDrawBegin [MSVIDEO.232]
1070 DWORD VFWAPIV ICDrawBegin16(
1071 HIC16 hic, /* [in] */
1072 DWORD dwFlags, /* [in] flags */
1073 HPALETTE16 hpal, /* [in] palette to draw with */
1074 HWND16 hwnd, /* [in] window to draw to */
1075 HDC16 hdc, /* [in] HDC to draw to */
1076 INT16 xDst, /* [in] destination rectangle */
1077 INT16 yDst, /* [in] */
1078 INT16 dxDst, /* [in] */
1079 INT16 dyDst, /* [in] */
1080 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw NOTE: SEGPTR */
1081 INT16 xSrc, /* [in] source rectangle */
1082 INT16 ySrc, /* [in] */
1083 INT16 dxSrc, /* [in] */
1084 INT16 dySrc, /* [in] */
1085 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
1086 DWORD dwScale) /* [in] */
1089 ICDRAWBEGIN16* icdb = SEGPTR_NEW(ICDRAWBEGIN16); /* SEGPTR for mapper to deal with */
1091 TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
1092 (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)hdc, xDst, yDst, dxDst, dyDst,
1093 lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
1095 icdb->dwFlags = dwFlags;
1101 icdb->dxDst = dxDst;
1102 icdb->dyDst = dyDst;
1103 icdb->lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
1106 icdb->dxSrc = dxSrc;
1107 icdb->dySrc = dySrc;
1108 icdb->dwRate = dwRate;
1109 icdb->dwScale = dwScale;
1111 ret = (DWORD)ICSendMessage16(hic,ICM_DRAW_BEGIN,(DWORD)SEGPTR_GET(icdb),sizeof(ICDRAWBEGIN16));
1116 /***********************************************************************
1119 DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
1122 TRACE("(0x%09lx,%ld,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
1124 icd.dwFlags = dwFlags;
1125 icd.lpFormat = lpFormat;
1126 icd.lpData = lpData;
1127 icd.cbData = cbData;
1130 return ICSendMessage(hic,ICM_DRAW,(DWORD)&icd,sizeof(icd));
1133 /***********************************************************************
1134 * _ICDraw [MSVIDEO.234]
1136 DWORD VFWAPIV ICDraw16(
1139 LPVOID lpFormat, /* [???] NOTE: SEGPTR */
1140 LPVOID lpData, /* [???] NOTE: SEGPTR */
1144 ICDRAW* icd = SEGPTR_NEW(ICDRAW); /* SEGPTR for mapper to deal with */
1146 TRACE("(0x%08lx,0x%08lx,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
1147 icd->dwFlags = dwFlags;
1148 icd->lpFormat = lpFormat;
1149 icd->lpData = lpData;
1150 icd->cbData = cbData;
1153 return ICSendMessage16(hic,ICM_DRAW,(DWORD)SEGPTR_GET(icd),sizeof(ICDRAW));
1156 /***********************************************************************
1157 * ICClose [MSVFW.22]
1159 LRESULT WINAPI ICClose(HIC hic) {
1160 WINE_HIC *whic = GlobalLock16(hic);
1161 TRACE("(0x%08lx)\n",(DWORD)hic);
1162 if (whic->driverproc) {
1163 ICSendMessage16(hic,DRV_CLOSE,0,0);
1164 ICSendMessage16(hic,DRV_DISABLE,0,0);
1165 ICSendMessage16(hic,DRV_FREE,0,0);
1167 CloseDriver(whic->hdrv,0,0);
1170 GlobalUnlock16(hic);
1175 /***********************************************************************
1176 * ICClose [MSVIDEO.204]
1178 LRESULT WINAPI ICClose16(HIC16 hic) {
1179 return ICClose(hic);
1182 /***********************************************************************
1183 * MCIWndCreateA [MSVFW.44 & MSVFW.45]
1185 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
1186 DWORD dwStyle,LPCSTR szFile)
1188 FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile);
1192 /***********************************************************************
1193 * MCIWndCreateW [MSVFW.46]
1195 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
1196 DWORD dwStyle,LPCWSTR szFile)
1198 FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile));