Set close on exec() flag at times when we leave /dev/dsp and
[wine/multimedia.git] / dlls / msvideo / msvideo_main.c
blob4fe0b845927ff12c9f096006a700f5096dfe8b76
1 /*
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.
8 */
10 #include <stdio.h>
11 #include <string.h>
13 #include "winbase.h"
14 #include "windef.h"
15 #include "wingdi.h"
16 #include "winuser.h"
17 #include "vfw.h"
18 #include "wine/winestring.h"
19 #include "debugtools.h"
20 #include "ldt.h"
21 #include "heap.h"
22 #include "stackframe.h"
24 DEFAULT_DEBUG_CHANNEL(msvideo);
26 /* ### start build ### */
27 extern LONG CALLBACK MSVIDEO_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
28 /* ### stop build ### */
30 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2);
31 void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID lpv, LPDWORD lParam1, LPDWORD lParam2);
32 LRESULT MSVIDEO_SendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2, BOOL bFrom32);
34 /***********************************************************************
35 * VideoForWindowsVersion [MSVFW.2][MSVIDEO.2]
36 * Returns the version in major.minor form.
37 * In Windows95 this returns 0x040003b6 (4.950)
39 DWORD WINAPI VideoForWindowsVersion(void) {
40 return 0x040003B6; /* 4.950 */
43 /***********************************************************************
44 * VideoCapDriverDescAndVer [MSVIDEO.22]
46 DWORD WINAPI VideoCapDriverDescAndVer(WORD nr,LPVOID buf1,WORD buf1len,LPVOID buf2,WORD buf2len) {
47 FIXME("(%d,%p,%d,%p,%d), stub!\n",nr,buf1,buf1len,buf2,buf2len);
48 return 0;
51 /* system.ini: [drivers] */
53 /***********************************************************************
54 * ICInfo [MSVFW.33]
55 * Get information about an installable compressor. Return TRUE if there
56 * is one.
58 BOOL VFWAPI ICInfo(
59 DWORD fccType, /* [in] type of compressor ('vidc') */
60 DWORD fccHandler, /* [in] <n>th compressor */
61 ICINFO *lpicinfo) /* [out] information about compressor */
63 char type[5],buf[2000];
65 memcpy(type,&fccType,4);type[4]=0;
66 TRACE("(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
67 /* does OpenDriver/CloseDriver */
68 lpicinfo->dwSize = sizeof(ICINFO);
69 lpicinfo->fccType = fccType;
70 lpicinfo->dwFlags = 0;
71 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
72 char *s = buf;
73 while (*s) {
74 if (!lstrncmpiA(type,s,4)) {
75 if(!fccHandler--) {
76 lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
77 return TRUE;
80 s=s+strlen(s)+1; /* either next char or \0 */
83 return FALSE;
86 BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16* /*SEGPTR*/ lpicinfo) {
87 BOOL16 ret;
88 LPVOID lpv;
89 DWORD lParam = (DWORD)lpicinfo;
90 DWORD size = ((ICINFO*)(PTR_SEG_TO_LIN(lpicinfo)))->dwSize;
92 /* Use the mapping functions to map the ICINFO structure */
93 lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO,&lParam,&size);
95 ret = ICInfo(fccType,fccHandler,(ICINFO*)lParam);
97 MSVIDEO_UnmapMsg16To32(ICM_GETINFO,lpv,&lParam,&size);
99 return ret;
102 /***********************************************************************
103 * ICOpen [MSVFW.37]
104 * Opens an installable compressor. Return special handle.
106 HIC VFWAPI ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
107 char type[5],handler[5],codecname[20];
108 ICOPEN icopen;
109 HDRVR hdrv;
110 HIC16 hic;
111 WINE_HIC *whic;
113 memcpy(type,&fccType,4);type[4]=0;
114 memcpy(handler,&fccHandler,4);handler[4]=0;
115 TRACE("(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
117 sprintf(codecname,"%s.%s",type,handler);
119 /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
120 * same layout as ICOPEN
122 icopen.fccType = fccType;
123 icopen.fccHandler = fccHandler;
124 icopen.dwSize = sizeof(ICOPEN);
125 icopen.dwFlags = wMode;
126 /* FIXME: do we need to fill out the rest too? */
127 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
128 if (!hdrv) {
129 if (!strcasecmp(type,"vids")) {
130 sprintf(codecname,"vidc.%s",handler);
131 fccType = mmioFOURCC('v','i','d','c');
133 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
134 if (!hdrv)
135 return 0;
137 /* The handle should be a valid 16-bit handle as well */
138 hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
139 whic = (WINE_HIC*)GlobalLock16(hic);
140 whic->hdrv = hdrv;
141 whic->driverproc= NULL;
142 whic->private = 0;
143 GlobalUnlock16(hic);
144 TRACE("=> 0x%08lx\n",(DWORD)hic);
145 return hic;
148 HIC MSVIDEO_OpenFunc(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler, BOOL bFrom32) {
149 char type[5],handler[5],codecname[20];
150 HIC16 hic;
151 ICOPEN* icopen = SEGPTR_NEW(ICOPEN);
152 WINE_HIC *whic;
154 memcpy(type,&fccType,4);type[4]=0;
155 memcpy(handler,&fccHandler,4);handler[4]=0;
156 TRACE("(%s,%s,%d,%p,%d)\n",type,handler,wMode,lpfnHandler,bFrom32?32:16);
158 icopen->fccType = fccType;
159 icopen->fccHandler = fccHandler;
160 icopen->dwSize = sizeof(ICOPEN);
161 icopen->dwFlags = wMode;
163 sprintf(codecname,"%s.%s",type,handler);
165 hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
166 if (!hic)
167 return 0;
168 whic = GlobalLock16(hic);
169 whic->driverproc = lpfnHandler;
171 whic->private = bFrom32;
173 /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
174 /* What if the function is used more than once? */
176 if (MSVIDEO_SendMessage(hic,DRV_LOAD,0L,0L,bFrom32) != DRV_SUCCESS) {
177 WARN("DRV_LOAD failed for hic 0x%08lx\n",(DWORD)hic);
178 GlobalFree16(hic);
179 return 0;
181 if (MSVIDEO_SendMessage(hic,DRV_ENABLE,0L,0L,bFrom32) != DRV_SUCCESS) {
182 WARN("DRV_ENABLE failed for hic 0x%08lx\n",(DWORD)hic);
183 GlobalFree16(hic);
184 return 0;
186 whic->hdrv = MSVIDEO_SendMessage(hic,DRV_OPEN,0,(LPARAM)(SEGPTR_GET(icopen)),FALSE);
187 if (whic->hdrv == 0) {
188 WARN("DRV_OPEN failed for hic 0x%08lx\n",(DWORD)hic);
189 GlobalFree16(hic);
190 return 0;
193 GlobalUnlock16(hic);
194 TRACE("=> 0x%08lx\n",(DWORD)hic);
195 return hic;
198 /***********************************************************************
199 * ICOpenFunction [MSVFW.38]
201 HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) {
202 return MSVIDEO_OpenFunc(fccType,fccHandler,wMode,lpfnHandler,TRUE);
205 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode) {
206 return (HIC16)ICOpen(fccType, fccHandler, wMode);
209 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler) {
210 return MSVIDEO_OpenFunc(fccType, fccHandler, wMode, lpfnHandler,FALSE);
213 /***********************************************************************
214 * ICGetInfo [MSVFW.30]
216 LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
217 LRESULT ret;
219 TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
220 ret = ICSendMessage(hic,ICM_GETINFO,(DWORD)picinfo,cb);
221 TRACE(" -> 0x%08lx\n",ret);
222 return ret;
225 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 *picinfo,DWORD cb) {
226 LRESULT ret;
228 TRACE("(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
229 ret = ICSendMessage16(hic,ICM_GETINFO,(DWORD)picinfo,cb);
230 TRACE(" -> 0x%08lx\n",ret);
231 return ret;
234 /***********************************************************************
235 * ICLocate [MSVFW.35]
237 HIC VFWAPI ICLocate(
238 DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
239 LPBITMAPINFOHEADER lpbiOut, WORD wMode)
241 char type[5],handler[5];
242 HIC hic;
243 DWORD querymsg;
244 LPSTR pszBuffer;
246 TRACE("(0x%08lx,0x%08lx,%p,%p,0x%04x)\n", fccType, fccHandler, lpbiIn, lpbiOut, wMode);
248 switch (wMode) {
249 case ICMODE_FASTCOMPRESS:
250 case ICMODE_COMPRESS:
251 querymsg = ICM_COMPRESS_QUERY;
252 break;
253 case ICMODE_FASTDECOMPRESS:
254 case ICMODE_DECOMPRESS:
255 querymsg = ICM_DECOMPRESS_QUERY;
256 break;
257 case ICMODE_DRAW:
258 querymsg = ICM_DRAW_QUERY;
259 break;
260 default:
261 WARN("Unknown mode (%d)\n",wMode);
262 return 0;
265 /* Easy case: handler/type match, we just fire a query and return */
266 hic = ICOpen(fccType,fccHandler,wMode);
267 if (hic) {
268 if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
269 return hic;
270 ICClose(hic);
273 type[4]='.';memcpy(type,&fccType,4);
274 handler[4]='.';memcpy(handler,&fccHandler,4);
276 /* Now try each driver in turn. 32 bit codecs only. */
277 /* FIXME: Move this to an init routine? */
279 pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(),0,1024);
280 if (GetPrivateProfileSectionA("drivers32",pszBuffer,1024,"system.ini")) {
281 char* s = pszBuffer;
282 while (*s) {
283 if (!lstrncmpiA(type,s,5)) {
284 char *s2 = s;
285 while (*s2 != '\0' && *s2 != '.') s2++;
286 if (*s2) {
287 HIC h;
289 *s2++ = '\0';
290 h = ICOpen(fccType,*(DWORD*)s2,wMode);
291 if (h) {
292 if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
293 return h;
294 ICClose(h);
298 s += strlen(s) + 1;
301 HeapFree(GetProcessHeap(),0,pszBuffer);
303 if (fccType==streamtypeVIDEO) {
304 hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
305 if (hic)
306 return hic;
309 type[4] = handler[4] = '\0';
310 FIXME("(%.4s,%.4s,%p,%p,0x%04x),unhandled!\n",type,handler,lpbiIn,lpbiOut,wMode);
311 return 0;
314 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
315 LPBITMAPINFOHEADER lpbiOut, WORD wFlags) {
316 return (HIC16)ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags);
319 /***********************************************************************
320 * ICGetDisplayFormat [MSVFW.29]
322 HIC VFWAPI ICGetDisplayFormat(
323 HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
324 INT depth,INT dx,INT dy)
326 HIC tmphic = hic;
327 LRESULT lres;
329 FIXME("(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
330 if (!tmphic) {
331 tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
332 if (!tmphic)
333 return tmphic;
335 if ((dy == lpbiIn->biHeight) || (dx == lpbiIn->biWidth))
336 dy = dx = 0; /* no resize needed */
337 /* Can we decompress it ? */
338 lres = ICDecompressQuery(tmphic,lpbiIn,NULL);
339 if (lres)
340 goto errout; /* no, sorry */
341 ICDecompressGetFormat(tmphic,lpbiIn,lpbiOut);
342 *lpbiOut=*lpbiIn;
343 lpbiOut->biCompression = 0;
344 lpbiOut->biSize = sizeof(*lpbiOut);
345 if (!depth) {
346 HDC hdc;
348 hdc = GetDC(0);
349 depth = GetDeviceCaps(hdc,12)*GetDeviceCaps(hdc,14);
350 ReleaseDC(0,hdc);
351 if (depth==15) depth = 16;
352 if (depth<8) depth = 8;
354 if (lpbiIn->biBitCount == 8)
355 depth = 8;
357 TRACE("=> 0x%08lx\n",(DWORD)tmphic);
358 return tmphic;
359 errout:
360 if (hic!=tmphic)
361 ICClose(tmphic);
363 TRACE("=> 0\n");
364 return 0;
367 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
368 LPBITMAPINFOHEADER lpbiOut, INT16 depth, INT16 dx, INT16 dy) {
369 return (HIC16)ICGetDisplayFormat(hic,lpbiIn,lpbiOut,depth,dx,dy);
372 /***********************************************************************
373 * ICCompress [MSVFW.23]
375 DWORD VFWAPIV
376 ICCompress(
377 HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
378 LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
379 LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
380 LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev)
382 ICCOMPRESS iccmp;
384 TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
386 iccmp.dwFlags = dwFlags;
388 iccmp.lpbiOutput = lpbiOutput;
389 iccmp.lpOutput = lpData;
390 iccmp.lpbiInput = lpbiInput;
391 iccmp.lpInput = lpBits;
393 iccmp.lpckid = lpckid;
394 iccmp.lpdwFlags = lpdwFlags;
395 iccmp.lFrameNum = lFrameNum;
396 iccmp.dwFrameSize = dwFrameSize;
397 iccmp.dwQuality = dwQuality;
398 iccmp.lpbiPrev = lpbiPrev;
399 iccmp.lpPrev = lpPrev;
400 return ICSendMessage(hic,ICM_COMPRESS,(DWORD)&iccmp,sizeof(iccmp));
403 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
404 LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits, LPDWORD lpckid,
405 LPDWORD lpdwFlags, LONG lFrameNum, DWORD dwFrameSize, DWORD dwQuality,
406 LPBITMAPINFOHEADER lpbiPrev, LPVOID lpPrev) {
408 DWORD ret;
409 ICCOMPRESS *iccmp = SEGPTR_NEW(ICCOMPRESS);
411 TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
413 iccmp->dwFlags = dwFlags;
415 iccmp->lpbiOutput = lpbiOutput;
416 iccmp->lpOutput = lpData;
417 iccmp->lpbiInput = lpbiInput;
418 iccmp->lpInput = lpBits;
420 iccmp->lpckid = lpckid;
421 iccmp->lpdwFlags = lpdwFlags;
422 iccmp->lFrameNum = lFrameNum;
423 iccmp->dwFrameSize = dwFrameSize;
424 iccmp->dwQuality = dwQuality;
425 iccmp->lpbiPrev = lpbiPrev;
426 iccmp->lpPrev = lpPrev;
427 ret = ICSendMessage16(hic,ICM_COMPRESS,(DWORD)SEGPTR_GET(iccmp),sizeof(ICCOMPRESS));
428 SEGPTR_FREE(iccmp);
429 return ret;
432 /***********************************************************************
433 * ICDecompress [MSVFW.26]
435 DWORD VFWAPIV ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
436 LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits)
438 ICDECOMPRESS icd;
439 DWORD ret;
441 TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
443 TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
445 icd.dwFlags = dwFlags;
446 icd.lpbiInput = lpbiFormat;
447 icd.lpInput = lpData;
449 icd.lpbiOutput = lpbi;
450 icd.lpOutput = lpBits;
451 icd.ckid = 0;
452 ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD)&icd,sizeof(ICDECOMPRESS));
454 TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
456 TRACE("-> %ld\n",ret);
458 return ret;
461 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat,
462 LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits) {
464 ICDECOMPRESS *icd = SEGPTR_NEW(ICDECOMPRESS);
465 DWORD ret;
467 TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
469 icd->dwFlags = dwFlags;
470 icd->lpbiInput = lpbiFormat;
471 icd->lpInput = lpData;
472 icd->lpbiOutput = lpbi;
473 icd->lpOutput = lpBits;
474 icd->ckid = 0;
476 ret = ICSendMessage16(hic,ICM_DECOMPRESS,(DWORD)SEGPTR_GET(icd),sizeof(ICDECOMPRESS));
478 SEGPTR_FREE(icd);
479 return ret;
482 #define COPY(x,y) (##x##->##y = ##x##16->##y);
483 #define COPYPTR(x,y) (##x##->##y = PTR_SEG_TO_LIN(##x##16->##y));
485 LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) {
486 LPVOID ret;
488 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESSEX));
489 ICDECOMPRESSEX16 *icdx16 = (ICDECOMPRESSEX16*)PTR_SEG_TO_LIN(*lParam);
490 ret = icdx16;
492 COPY(icdx,dwFlags);
493 COPYPTR(icdx,lpbiSrc);
494 COPYPTR(icdx,lpSrc);
495 COPYPTR(icdx,lpbiDst);
496 COPYPTR(icdx,lpDst);
497 COPY(icdx,xDst);
498 COPY(icdx,yDst);
499 COPY(icdx,dxDst);
500 COPY(icdx,dyDst);
501 COPY(icdx,xSrc);
502 COPY(icdx,ySrc);
503 COPY(icdx,dxSrc);
504 COPY(icdx,dySrc);
506 *lParam = (DWORD)(icdx);
507 return ret;
510 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) {
511 LPVOID ret = 0;
513 TRACE("Mapping %d\n",msg);
515 switch (msg) {
516 case DRV_LOAD:
517 case DRV_ENABLE:
518 case DRV_CLOSE:
519 case DRV_DISABLE:
520 case DRV_FREE:
521 case ICM_ABOUT:
522 case ICM_CONFIGURE:
523 case ICM_COMPRESS_END:
524 case ICM_DECOMPRESS_END:
525 case ICM_DECOMPRESSEX_END:
526 case ICM_SETQUALITY:
527 break;
528 case DRV_OPEN:
529 case ICM_GETDEFAULTQUALITY:
530 case ICM_GETQUALITY:
531 *lParam1 = (DWORD)PTR_SEG_TO_LIN(*lParam1);
532 break;
533 case ICM_GETINFO:
535 ICINFO *ici = HeapAlloc(GetProcessHeap(),0,sizeof(ICINFO));
536 ICINFO16 *ici16;
538 ici16 = (ICINFO16*)PTR_SEG_TO_LIN(*lParam1);
539 ret = ici16;
541 ici->dwSize = sizeof(ICINFO);
542 COPY(ici,fccType);
543 COPY(ici,fccHandler);
544 COPY(ici,dwFlags);
545 COPY(ici,dwVersion);
546 COPY(ici,dwVersionICM);
547 lstrcpynAtoW(ici->szName,ici16->szName,16);
548 lstrcpynAtoW(ici->szDescription,ici16->szDescription,128);
549 lstrcpynAtoW(ici->szDriver,ici16->szDriver,128);
551 *lParam1 = (DWORD)(ici);
552 *lParam2 = sizeof(ICINFO);
554 break;
555 case ICM_COMPRESS:
557 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(),0,sizeof(ICCOMPRESS));
558 ICCOMPRESS *icc16;
560 icc16 = (ICCOMPRESS*)PTR_SEG_TO_LIN(*lParam1);
561 ret = icc16;
563 COPY(icc,dwFlags);
564 COPYPTR(icc,lpbiOutput);
565 COPYPTR(icc,lpOutput);
566 COPYPTR(icc,lpbiInput);
567 COPYPTR(icc,lpInput);
568 COPYPTR(icc,lpckid);
569 COPYPTR(icc,lpdwFlags);
570 COPY(icc,lFrameNum);
571 COPY(icc,dwFrameSize);
572 COPY(icc,dwQuality);
573 COPYPTR(icc,lpbiPrev);
574 COPYPTR(icc,lpPrev);
576 *lParam1 = (DWORD)(icc);
577 *lParam2 = sizeof(ICCOMPRESS);
579 break;
580 case ICM_DECOMPRESS:
582 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESS));
583 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
585 icd16 = (ICDECOMPRESS*)PTR_SEG_TO_LIN(*lParam1);
586 ret = icd16;
588 COPY(icd,dwFlags);
589 COPYPTR(icd,lpbiInput);
590 COPYPTR(icd,lpInput);
591 COPYPTR(icd,lpbiOutput);
592 COPYPTR(icd,lpOutput);
593 COPY(icd,ckid);
595 *lParam1 = (DWORD)(icd);
596 *lParam2 = sizeof(ICDECOMPRESS);
598 break;
599 case ICM_COMPRESS_BEGIN:
600 case ICM_COMPRESS_GET_FORMAT:
601 case ICM_COMPRESS_GET_SIZE:
602 case ICM_COMPRESS_QUERY:
603 case ICM_DECOMPRESS_GET_FORMAT:
604 case ICM_DECOMPRESS_QUERY:
605 case ICM_DECOMPRESS_BEGIN:
606 case ICM_DECOMPRESS_SET_PALETTE:
607 case ICM_DECOMPRESS_GET_PALETTE:
608 *lParam1 = (DWORD)PTR_SEG_TO_LIN(*lParam1);
609 *lParam2 = (DWORD)PTR_SEG_TO_LIN(*lParam2);
610 break;
611 case ICM_DECOMPRESSEX_QUERY:
612 if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
613 WARN("*lParam2 has unknown value %p\n",(ICDECOMPRESSEX16*)*lParam2);
614 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
615 * This is because of ICMessage(). Special case it?
617 LPVOID* addr = HeapAlloc(GetProcessHeap(),0,2*sizeof(LPVOID));
618 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
619 if (*lParam2)
620 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
621 else
622 addr[1] = 0;
624 ret = addr;
626 break;*/
627 case ICM_DECOMPRESSEX_BEGIN:
628 case ICM_DECOMPRESSEX:
629 ret = MSVIDEO_MapICDEX16To32(lParam1);
630 *lParam2 = sizeof(ICDECOMPRESSEX);
631 break;
632 case ICM_DRAW_BEGIN:
634 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWBEGIN));
635 ICDRAWBEGIN16 *icdb16 = (ICDRAWBEGIN16*)PTR_SEG_TO_LIN(*lParam1);
636 ret = icdb16;
638 COPY(icdb,dwFlags);
639 COPY(icdb,hpal);
640 COPY(icdb,hwnd);
641 COPY(icdb,hdc);
642 COPY(icdb,xDst);
643 COPY(icdb,yDst);
644 COPY(icdb,dxDst);
645 COPY(icdb,dyDst);
646 COPYPTR(icdb,lpbi);
647 COPY(icdb,xSrc);
648 COPY(icdb,ySrc);
649 COPY(icdb,dxSrc);
650 COPY(icdb,dySrc);
651 COPY(icdb,dwRate);
652 COPY(icdb,dwScale);
654 *lParam1 = (DWORD)(icdb);
655 *lParam2 = sizeof(ICDRAWBEGIN);
657 break;
658 case ICM_DRAW_SUGGESTFORMAT:
660 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWSUGGEST));
661 ICDRAWSUGGEST16 *icds16 = (ICDRAWSUGGEST16*)PTR_SEG_TO_LIN(*lParam1);
663 ret = icds16;
665 COPY(icds,dwFlags);
666 COPYPTR(icds,lpbiIn);
667 COPYPTR(icds,lpbiSuggest);
668 COPY(icds,dxSrc);
669 COPY(icds,dySrc);
670 COPY(icds,dxDst);
671 COPY(icds,dyDst);
672 COPY(icds,hicDecompressor);
674 *lParam1 = (DWORD)(icds);
675 *lParam2 = sizeof(ICDRAWSUGGEST);
677 break;
678 case ICM_DRAW:
680 ICDRAW *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAW));
681 ICDRAW *icd16 = (ICDRAW*)PTR_SEG_TO_LIN(*lParam1);
682 ret = icd16;
684 COPY(icd,dwFlags);
685 COPYPTR(icd,lpFormat);
686 COPYPTR(icd,lpData);
687 COPY(icd,cbData);
688 COPY(icd,lTime);
690 *lParam1 = (DWORD)(icd);
691 *lParam2 = sizeof(ICDRAW);
693 break;
694 default:
695 FIXME("%d is not yet handled. Expect a crash.\n",msg);
697 return ret;
700 #undef COPY
701 #undef COPYPTR
703 void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2) {
704 TRACE("Unmapping %d\n",msg);
706 #define UNCOPY(x,y) (##x##16->##y = ##x##->##y);
708 switch (msg) {
709 case ICM_GETINFO:
711 ICINFO *ici = (ICINFO*)(*lParam1);
712 ICINFO16 *ici16 = (ICINFO16*)data16;
714 UNCOPY(ici,fccType);
715 UNCOPY(ici,fccHandler);
716 UNCOPY(ici,dwFlags);
717 UNCOPY(ici,dwVersion);
718 UNCOPY(ici,dwVersionICM);
719 lstrcpynWtoA(ici16->szName,ici->szName,16);
720 lstrcpynWtoA(ici16->szDescription,ici->szDescription,128);
721 /* This just gives garbage for some reason - BB
722 lstrcpynWtoA(ici16->szDriver,ici->szDriver,128);*/
724 HeapFree(GetProcessHeap(),0,ici);
726 break;
727 case ICM_DECOMPRESS_QUERY:
729 LPVOID* x = data16;
730 HeapFree(GetProcessHeap(),0,x[0]);
731 if (x[1])
732 HeapFree(GetProcessHeap(),0,x[1]);
734 break;*/
735 case ICM_COMPRESS:
736 case ICM_DECOMPRESS:
737 case ICM_DECOMPRESSEX_QUERY:
738 case ICM_DECOMPRESSEX_BEGIN:
739 case ICM_DECOMPRESSEX:
740 case ICM_DRAW_BEGIN:
741 case ICM_DRAW_SUGGESTFORMAT:
742 case ICM_DRAW:
743 HeapFree(GetProcessHeap(),0,data16);
744 break;
745 default:
746 ERR("Unmapping unmapped msg %d\n",msg);
748 #undef UNCOPY
751 LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2, BOOL bFrom32) {
752 LRESULT ret;
753 WINE_HIC *whic = GlobalLock16(hic);
754 LPVOID data16 = 0;
755 BOOL bDrv32;
757 #define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx,%d)\n",(DWORD)hic,lParam1,lParam2,bFrom32?32:16);break;
759 switch (msg) {
760 /* DRV_* */
761 XX(DRV_LOAD);
762 XX(DRV_ENABLE);
763 XX(DRV_OPEN);
764 XX(DRV_CLOSE);
765 XX(DRV_DISABLE);
766 XX(DRV_FREE);
767 /* ICM_RESERVED+X */
768 XX(ICM_ABOUT);
769 XX(ICM_CONFIGURE);
770 XX(ICM_GET);
771 XX(ICM_GETINFO);
772 XX(ICM_GETDEFAULTQUALITY);
773 XX(ICM_GETQUALITY);
774 XX(ICM_GETSTATE);
775 XX(ICM_SETQUALITY);
776 XX(ICM_SET);
777 XX(ICM_SETSTATE);
778 /* ICM_USER+X */
779 XX(ICM_COMPRESS_FRAMES_INFO);
780 XX(ICM_COMPRESS_GET_FORMAT);
781 XX(ICM_COMPRESS_GET_SIZE);
782 XX(ICM_COMPRESS_QUERY);
783 XX(ICM_COMPRESS_BEGIN);
784 XX(ICM_COMPRESS);
785 XX(ICM_COMPRESS_END);
786 XX(ICM_DECOMPRESS_GET_FORMAT);
787 XX(ICM_DECOMPRESS_QUERY);
788 XX(ICM_DECOMPRESS_BEGIN);
789 XX(ICM_DECOMPRESS);
790 XX(ICM_DECOMPRESS_END);
791 XX(ICM_DECOMPRESS_SET_PALETTE);
792 XX(ICM_DECOMPRESS_GET_PALETTE);
793 XX(ICM_DRAW_QUERY);
794 XX(ICM_DRAW_BEGIN);
795 XX(ICM_DRAW_GET_PALETTE);
796 XX(ICM_DRAW_START);
797 XX(ICM_DRAW_STOP);
798 XX(ICM_DRAW_END);
799 XX(ICM_DRAW_GETTIME);
800 XX(ICM_DRAW);
801 XX(ICM_DRAW_WINDOW);
802 XX(ICM_DRAW_SETTIME);
803 XX(ICM_DRAW_REALIZE);
804 XX(ICM_DRAW_FLUSH);
805 XX(ICM_DRAW_RENDERBUFFER);
806 XX(ICM_DRAW_START_PLAY);
807 XX(ICM_DRAW_STOP_PLAY);
808 XX(ICM_DRAW_SUGGESTFORMAT);
809 XX(ICM_DRAW_CHANGEPALETTE);
810 XX(ICM_GETBUFFERSWANTED);
811 XX(ICM_GETDEFAULTKEYFRAMERATE);
812 XX(ICM_DECOMPRESSEX_BEGIN);
813 XX(ICM_DECOMPRESSEX_QUERY);
814 XX(ICM_DECOMPRESSEX);
815 XX(ICM_DECOMPRESSEX_END);
816 XX(ICM_SET_STATUS_PROC);
817 default:
818 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,%i) unknown message\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,bFrom32?32:16);
821 #undef XX
823 if (whic->driverproc) { /* IC is a function */
824 bDrv32 = whic->private;
825 } else {
826 bDrv32 = ((GetDriverFlags(whic->hdrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST);
829 if (!bFrom32) {
830 if (bDrv32)
831 data16 = MSVIDEO_MapMsg16To32(msg,&lParam1,&lParam2);
832 } else {
833 if (!bDrv32) {
834 ERR("Can't do 32->16 mappings\n");
835 ret = -1;
836 goto out;
840 if (whic->driverproc) {
841 if (bDrv32) {
842 ret = whic->driverproc(whic->hdrv,hic,msg,lParam1,lParam2);
843 } else {
844 ret = MSVIDEO_CallTo16_long_lwwll((FARPROC16)whic->driverproc,whic->hdrv,hic,msg,lParam1,lParam2);
846 } else {
847 ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
850 if (data16)
851 MSVIDEO_UnmapMsg16To32(msg,data16,&lParam1,&lParam2);
853 out:
854 GlobalUnlock16(hic);
856 TRACE(" -> 0x%08lx\n",ret);
857 return ret;
860 /***********************************************************************
861 * ICSendMessage [MSVFW.40]
863 LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2) {
864 return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,TRUE);
867 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) {
868 return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,FALSE);
871 LRESULT VFWAPIV ICMessage16(void) {
872 HIC16 hic;
873 UINT16 msg;
874 UINT16 cb;
875 LPWORD lpData;
876 LRESULT ret;
877 UINT16 i;
879 VA_LIST16 valist;
881 VA_START16(valist);
882 hic = VA_ARG16(valist, HIC16);
883 msg = VA_ARG16(valist, UINT16);
884 cb = VA_ARG16(valist, UINT16);
886 lpData = SEGPTR_ALLOC(cb);
888 TRACE("0x%08lx, %u, %u, ...)\n",(DWORD)hic,msg,cb);
890 for(i=0;i<cb/sizeof(WORD);i++) {
891 lpData[i] = VA_ARG16(valist, WORD);
894 VA_END16(valist);
895 ret = ICSendMessage16(hic, msg, (DWORD)(SEGPTR_GET(lpData)), (DWORD)cb);
897 SEGPTR_FREE(lpData);
898 return ret;
901 /***********************************************************************
902 * ICDrawBegin [MSVFW.28]
904 DWORD VFWAPIV ICDrawBegin(
905 HIC hic,
906 DWORD dwFlags,/* flags */
907 HPALETTE hpal, /* palette to draw with */
908 HWND hwnd, /* window to draw to */
909 HDC hdc, /* HDC to draw to */
910 INT xDst, /* destination rectangle */
911 INT yDst,
912 INT dxDst,
913 INT dyDst,
914 LPBITMAPINFOHEADER lpbi, /* format of frame to draw */
915 INT xSrc, /* source rectangle */
916 INT ySrc,
917 INT dxSrc,
918 INT dySrc,
919 DWORD dwRate, /* frames/second = (dwRate/dwScale) */
920 DWORD dwScale) {
922 ICDRAWBEGIN icdb;
924 TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
925 (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)hdc, xDst, yDst, dxDst, dyDst,
926 lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
928 icdb.dwFlags = dwFlags;
929 icdb.hpal = hpal;
930 icdb.hwnd = hwnd;
931 icdb.hdc = hdc;
932 icdb.xDst = xDst;
933 icdb.yDst = yDst;
934 icdb.dxDst = dxDst;
935 icdb.dyDst = dyDst;
936 icdb.lpbi = lpbi;
937 icdb.xSrc = xSrc;
938 icdb.ySrc = ySrc;
939 icdb.dxSrc = dxSrc;
940 icdb.dySrc = dySrc;
941 icdb.dwRate = dwRate;
942 icdb.dwScale = dwScale;
943 return ICSendMessage(hic,ICM_DRAW_BEGIN,(DWORD)&icdb,sizeof(icdb));
946 DWORD VFWAPIV ICDrawBegin16(
947 HIC16 hic,
948 DWORD dwFlags,/* flags */
949 HPALETTE16 hpal, /* palette to draw with */
950 HWND16 hwnd, /* window to draw to */
951 HDC16 hdc, /* HDC to draw to */
952 INT16 xDst, /* destination rectangle */
953 INT16 yDst,
954 INT16 dxDst,
955 INT16 dyDst,
956 LPBITMAPINFOHEADER /*SEGPTR*/ lpbi, /* format of frame to draw */
957 INT16 xSrc, /* source rectangle */
958 INT16 ySrc,
959 INT16 dxSrc,
960 INT16 dySrc,
961 DWORD dwRate, /* frames/second = (dwRate/dwScale) */
962 DWORD dwScale) {
964 DWORD ret;
965 ICDRAWBEGIN16* icdb = SEGPTR_NEW(ICDRAWBEGIN16); /* SEGPTR for mapper to deal with */
967 TRACE("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
968 (DWORD)hic, dwFlags, (DWORD)hpal, (DWORD)hwnd, (DWORD)hdc, xDst, yDst, dxDst, dyDst,
969 lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, dwScale);
971 icdb->dwFlags = dwFlags;
972 icdb->hpal = hpal;
973 icdb->hwnd = hwnd;
974 icdb->hdc = hdc;
975 icdb->xDst = xDst;
976 icdb->yDst = yDst;
977 icdb->dxDst = dxDst;
978 icdb->dyDst = dyDst;
979 icdb->lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
980 icdb->xSrc = xSrc;
981 icdb->ySrc = ySrc;
982 icdb->dxSrc = dxSrc;
983 icdb->dySrc = dySrc;
984 icdb->dwRate = dwRate;
985 icdb->dwScale = dwScale;
987 ret = (DWORD)ICSendMessage16(hic,ICM_DRAW_BEGIN,(DWORD)SEGPTR_GET(icdb),sizeof(ICDRAWBEGIN16));
988 SEGPTR_FREE(icdb);
989 return ret;
992 /***********************************************************************
993 * ICDraw [MSVFW.27]
995 DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
996 ICDRAW icd;
998 TRACE("(0x%09lx,%ld,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
1000 icd.dwFlags = dwFlags;
1001 icd.lpFormat = lpFormat;
1002 icd.lpData = lpData;
1003 icd.cbData = cbData;
1004 icd.lTime = lTime;
1006 return ICSendMessage(hic,ICM_DRAW,(DWORD)&icd,sizeof(icd));
1009 DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags, LPVOID /*SEGPTR*/ lpFormat,
1010 LPVOID /*SEGPTR*/ lpData, DWORD cbData, LONG lTime) {
1012 ICDRAW* icd = SEGPTR_NEW(ICDRAW); /* SEGPTR for mapper to deal with */
1014 TRACE("(0x%08lx,0x%08lx,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
1015 icd->dwFlags = dwFlags;
1016 icd->lpFormat = lpFormat;
1017 icd->lpData = lpData;
1018 icd->cbData = cbData;
1019 icd->lTime = lTime;
1021 return ICSendMessage16(hic,ICM_DRAW,(DWORD)SEGPTR_GET(icd),sizeof(ICDRAW));
1024 /***********************************************************************
1025 * ICClose [MSVFW.22]
1027 LRESULT WINAPI ICClose(HIC hic) {
1028 WINE_HIC *whic = GlobalLock16(hic);
1029 TRACE("(0x%08lx)\n",(DWORD)hic);
1030 if (whic->driverproc) {
1031 ICSendMessage16(hic,DRV_CLOSE,0,0);
1032 ICSendMessage16(hic,DRV_DISABLE,0,0);
1033 ICSendMessage16(hic,DRV_FREE,0,0);
1034 } else {
1035 CloseDriver(whic->hdrv,0,0);
1038 GlobalUnlock16(hic);
1039 GlobalFree16(hic);
1040 return 0;
1043 LRESULT WINAPI ICClose16(HIC16 hic) {
1044 return ICClose(hic);
1047 /***********************************************************************
1048 * MCIWndCreateA [MSVFW.44 & MSVFW.45]
1050 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
1051 DWORD dwStyle,LPCSTR szFile)
1053 FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile);
1054 return 0;
1057 /***********************************************************************
1058 * MCIWndCreateW [MSVFW.46]
1060 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
1061 DWORD dwStyle,LPCWSTR szFile)
1063 FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile));
1064 return 0;