Updated.
[wine] / dlls / msvideo / msvideo_main.c
1 /*
2  * Copyright 1998 Marcus Meissner
3  * Copyright 2000 Bradley Baetz 
4  *
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  */
9
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "winbase.h"
14 #include "windef.h"
15 #include "winnls.h"
16 #include "wingdi.h"
17 #include "winuser.h"
18 #include "winver.h"
19 #include "vfw.h"
20 #include "vfw16.h"
21 #include "wine/winbase16.h"
22 #include "debugtools.h"
23 #include "heap.h"
24 #include "stackframe.h"
25
26 DEFAULT_DEBUG_CHANNEL(msvideo);
27
28 /* ### start build ### */
29 extern LONG CALLBACK MSVIDEO_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
30 /* ### stop build ### */
31
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);
35
36 /***********************************************************************
37  *              VideoForWindowsVersion          [MSVFW.2][MSVIDEO.2]
38  * Returns the version in major.minor form.
39  * In Windows95 this returns 0x040003b6 (4.950)
40  */
41 DWORD WINAPI VideoForWindowsVersion(void) {
42         return 0x040003B6; /* 4.950 */
43 }
44
45 /***********************************************************************
46  *              VideoCapDriverDescAndVer        [MSVIDEO.22]
47  */
48 DWORD WINAPI VideoCapDriverDescAndVer(
49         WORD nr,LPSTR buf1,WORD buf1len,LPSTR buf2,WORD buf2len
50 ) {
51         DWORD   verhandle;
52         WORD    xnr = nr;
53         DWORD   infosize;
54         UINT    subblocklen;
55         char    *s,buf[2000],fn[260];
56         LPBYTE  infobuf;
57         LPVOID  subblock;
58
59         TRACE("(%d,%p,%d,%p,%d)\n",nr,buf1,buf1len,buf2,buf2len);
60         if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,sizeof(buf),"system.ini")) {
61                 s = buf;
62                 while (*s) {
63                         if (!strncasecmp(s,"vid",3)) {
64                             if (!xnr)
65                                 break;
66                             xnr--;
67                         }
68                         s=s+strlen(s)+1; /* either next char or \0 */
69                 }
70         } else
71             return 20; /* hmm, out of entries even if we don't have any */
72         if (xnr) {
73                 FIXME("No more VID* entries found\n");
74                 return 20;
75         }
76         GetPrivateProfileStringA("drivers32",s,NULL,fn,sizeof(fn),"system.ini");
77         infosize = GetFileVersionInfoSizeA(fn,&verhandle);
78         if (!infosize) {
79             TRACE("%s has no fileversioninfo.\n",fn);
80             return 18;
81         }
82         infobuf = HeapAlloc(GetProcessHeap(),0,infosize);
83         if (GetFileVersionInfoA(fn,verhandle,infosize,infobuf)) {
84             char        vbuf[200];
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]
92             );
93             TRACE("version of %s is %s\n",fn,vbuf);
94             strncpy(buf2,vbuf,buf2len);
95         } else {
96             TRACE("GetFileVersionInfoA failed for %s.\n",fn);
97             strncpy(buf2,fn,buf2len); /* msvideo.dll appears to copy fn*/
98         }
99         /* FIXME: language problem? */
100         if (VerQueryValueA(     infobuf,
101                                 "\\StringFileInfo\\040904E4\\FileDescription",
102                                 &subblock,
103                                 &subblocklen
104         )) {
105             TRACE("VQA returned %s\n",(LPCSTR)subblock);
106             strncpy(buf1,subblock,buf1len);
107         } else {
108             TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
109             strncpy(buf1,fn,buf1len); /* msvideo.dll appears to copy fn*/
110         }
111         HeapFree(GetProcessHeap(),0,infobuf);
112         return 0;
113 }
114
115 /* system.ini: [drivers] */
116
117 /***********************************************************************
118  *              ICInfo                          [MSVFW.33]
119  * Get information about an installable compressor. Return TRUE if there
120  * is one.
121  */
122 BOOL VFWAPI ICInfo(
123         DWORD fccType,          /* [in] type of compressor ('vidc') */
124         DWORD fccHandler,       /* [in] <n>th compressor */
125         ICINFO *lpicinfo)       /* [out] information about compressor */
126 {
127         char    type[5],buf[2000];
128
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")) {
136                 char *s = buf;
137                 while (*s) {
138                         if (!strncasecmp(type,s,4)) {
139                                 if(!fccHandler--) {
140                                         lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
141                                         return TRUE;
142                                 }
143                         }
144                         s=s+strlen(s)+1; /* either next char or \0 */
145                 }
146         }
147         return FALSE;
148 }
149
150 /**********************************************************************/
151
152 BOOL16 VFWAPI ICInfo16(
153         DWORD     fccType,    /* [in] */
154         DWORD     fccHandler, /* [in] */
155         ICINFO16 *lpicinfo)   /* [in/out] NOTE: SEGPTR */
156 {
157         BOOL16 ret;
158         LPVOID lpv;
159         DWORD lParam = (DWORD)lpicinfo;
160         DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
161
162         /* Use the mapping functions to map the ICINFO structure */
163         lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO,&lParam,&size);
164
165         ret = ICInfo(fccType,fccHandler,(ICINFO*)lParam);
166
167         MSVIDEO_UnmapMsg16To32(ICM_GETINFO,lpv,&lParam,&size);
168         
169         return ret;
170 }
171
172 /***********************************************************************
173  *              ICOpen                          [MSVFW.37]
174  * Opens an installable compressor. Return special handle.
175  */
176 HIC VFWAPI ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
177         char            type[5],handler[5],codecname[20];
178         ICOPEN          icopen;
179         HDRVR           hdrv;
180         HIC16           hic;
181         WINE_HIC        *whic;
182
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);
186
187         sprintf(codecname,"%s.%s",type,handler);
188
189         /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the 
190          * same layout as ICOPEN
191          */
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);
198         if (!hdrv) {
199             if (!strcasecmp(type,"vids")) {
200                 sprintf(codecname,"vidc.%s",handler);
201                 fccType = mmioFOURCC('v','i','d','c');
202             }
203             hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
204             if (!hdrv)
205                     return 0;
206         }
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);
210         whic->hdrv      = hdrv;
211         whic->driverproc= NULL;
212         whic->private   = 0;
213         GlobalUnlock16(hic);
214         TRACE("=> 0x%08lx\n",(DWORD)hic);
215         return hic;
216 }
217
218 HIC MSVIDEO_OpenFunc(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler, BOOL bFrom32) {
219         char    type[5],handler[5],codecname[20];
220         HIC16   hic;
221         ICOPEN*  icopen = SEGPTR_NEW(ICOPEN);
222         WINE_HIC        *whic;
223
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);
227         
228         icopen->fccType         = fccType;
229         icopen->fccHandler      = fccHandler;
230         icopen->dwSize          = sizeof(ICOPEN);
231         icopen->dwFlags         = wMode;
232         
233         sprintf(codecname,"%s.%s",type,handler);
234
235         hic = GlobalAlloc16(GHND,sizeof(WINE_HIC));
236         if (!hic)
237                 return 0;
238         whic = GlobalLock16(hic);
239         whic->driverproc = lpfnHandler;
240         
241         whic->private = bFrom32;
242         
243         /* Now try opening/loading the driver. Taken from DRIVER_AddToList */
244         /* What if the function is used more than once? */
245         
246         if (MSVIDEO_SendMessage(hic,DRV_LOAD,0L,0L,bFrom32) != DRV_SUCCESS) {
247                 WARN("DRV_LOAD failed for hic 0x%08lx\n",(DWORD)hic);
248                 GlobalFree16(hic);
249                 return 0;
250         }
251         /* return value is not checked */
252         MSVIDEO_SendMessage(hic,DRV_ENABLE,0L,0L,bFrom32);
253
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);
257                 GlobalFree16(hic);
258                 return 0;
259         }
260
261         GlobalUnlock16(hic);
262         TRACE("=> 0x%08lx\n",(DWORD)hic);
263         return hic;
264 }
265
266 /***********************************************************************
267  *              ICOpenFunction                  [MSVFW.38]
268  */
269 HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode, FARPROC lpfnHandler) {
270         return MSVIDEO_OpenFunc(fccType,fccHandler,wMode,lpfnHandler,TRUE);
271 }
272
273 /***********************************************************************
274  *              ICOpen                          [MSVIDEO.203]
275  */
276 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode) {
277         return (HIC16)ICOpen(fccType, fccHandler, wMode);
278 }
279
280 /***********************************************************************
281  *              ICOpenFunction                  [MSVIDEO.206]
282  */
283 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
284 {
285         return MSVIDEO_OpenFunc(fccType, fccHandler, wMode, (FARPROC)lpfnHandler,FALSE);
286 }
287
288 /***********************************************************************
289  *              ICGetInfo                       [MSVFW.30]
290  */
291 LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
292         LRESULT         ret;
293
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);
297         return ret;
298 }
299
300 /***********************************************************************
301  *              ICGetInfo                       [MSVIDEO.212]
302  */
303 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 *picinfo,DWORD cb) {
304         LRESULT         ret;
305
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);
309         return ret;
310 }
311
312 /***********************************************************************
313  *              ICLocate                        [MSVFW.35]
314  */
315 HIC VFWAPI ICLocate(
316         DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
317         LPBITMAPINFOHEADER lpbiOut, WORD wMode)
318 {
319         char    type[5],handler[5];
320         HIC     hic;
321         DWORD   querymsg;
322         LPSTR pszBuffer;
323
324         type[4]=0;memcpy(type,&fccType,4);
325         handler[4]=0;memcpy(handler,&fccHandler,4);
326
327         TRACE("(%s,%s,%p,%p,0x%04x)\n", type, handler, lpbiIn, lpbiOut, wMode);
328
329         switch (wMode) {
330         case ICMODE_FASTCOMPRESS:
331         case ICMODE_COMPRESS: 
332                 querymsg = ICM_COMPRESS_QUERY;
333                 break;
334         case ICMODE_FASTDECOMPRESS:
335         case ICMODE_DECOMPRESS:
336                 querymsg = ICM_DECOMPRESS_QUERY;
337                 break;
338         case ICMODE_DRAW:
339                 querymsg = ICM_DRAW_QUERY;
340                 break;
341         default:
342                 WARN("Unknown mode (%d)\n",wMode);
343                 return 0;
344         }
345
346         /* Easy case: handler/type match, we just fire a query and return */
347         hic = ICOpen(fccType,fccHandler,wMode);
348         if (hic) {
349                 if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
350                         return hic;
351                 ICClose(hic);
352         }
353
354         type[4]='.';memcpy(type,&fccType,4);
355         handler[4]='.';memcpy(handler,&fccHandler,4);
356
357         /* Now try each driver in turn. 32 bit codecs only. */
358         /* FIXME: Move this to an init routine? */
359         
360         pszBuffer = (LPSTR)HeapAlloc(GetProcessHeap(),0,1024);
361         if (GetPrivateProfileSectionA("drivers32",pszBuffer,1024,"system.ini")) {
362                 char* s = pszBuffer;
363                 while (*s) {
364                         if (!strncasecmp(type,s,5)) {
365                                 char *s2 = s;
366                                 while (*s2 != '\0' && *s2 != '.') s2++;
367                                 if (*s2++) {
368                                         HIC h;
369
370                                         h = ICOpen(fccType,*(DWORD*)s2,wMode);
371                                         if (h) {
372                                                 if (!ICSendMessage(h,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
373                                                         return h;
374                                                 ICClose(h);
375                                         }
376                                 }
377                         }
378                         s += strlen(s) + 1;
379                 }
380         }
381         HeapFree(GetProcessHeap(),0,pszBuffer);
382         
383         if (fccType==streamtypeVIDEO) {
384                 hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
385                 if (hic)
386                         return hic;
387         }
388
389         type[4] = handler[4] = '\0';
390         WARN("(%.4s,%.4s,%p,%p,0x%04x) not found!\n",type,handler,lpbiIn,lpbiOut,wMode);
391         return 0;
392 }
393
394 /***********************************************************************
395  *              ICLocate                        [MSVIDEO.213]
396  */
397 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
398                                                 LPBITMAPINFOHEADER lpbiOut, WORD wFlags) {
399         return (HIC16)ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags);
400 }
401
402 /***********************************************************************
403  *              ICGetDisplayFormat                      [MSVFW.29]
404  */
405 HIC VFWAPI ICGetDisplayFormat(
406         HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
407         INT depth,INT dx,INT dy)
408 {
409         HIC     tmphic = hic; 
410
411         FIXME("(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
412         if (!tmphic) {
413                 tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
414                 if (!tmphic)
415                         return tmphic;
416         }
417         if ((dy == lpbiIn->biHeight) && (dx == lpbiIn->biWidth))
418                 dy = dx = 0; /* no resize needed */
419
420         /* Can we decompress it ? */
421         if (ICDecompressQuery(tmphic,lpbiIn,NULL) != 0)
422                 goto errout; /* no, sorry */
423
424         ICDecompressGetFormat(tmphic,lpbiIn,lpbiOut);
425
426         if (lpbiOut->biCompression != 0) {
427            FIXME("Ooch, how come decompressor outputs compressed data (%ld)??\n",
428                          lpbiOut->biCompression);
429         }
430         if (lpbiOut->biSize < sizeof(*lpbiOut)) {
431            FIXME("Ooch, size of output BIH is too small (%ld)\n",
432                          lpbiOut->biSize);
433            lpbiOut->biSize = sizeof(*lpbiOut);
434         }
435         if (!depth) {
436                 HDC     hdc;
437
438                 hdc = GetDC(0);
439                 depth = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
440                 ReleaseDC(0,hdc);
441                 if (depth==15)  depth = 16;
442                 if (depth<8)    depth =  8;
443         }
444         if (lpbiIn->biBitCount == 8)
445                 depth = 8;
446         
447         TRACE("=> 0x%08lx\n",(DWORD)tmphic);
448         return tmphic;
449 errout:
450         if (hic!=tmphic)
451                 ICClose(tmphic);
452
453         TRACE("=> 0\n");
454         return 0;
455 }
456
457 /**********************************************************************/
458
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);
462 }
463
464 /***********************************************************************
465  *              ICCompress                      [MSVFW.23]
466  */
467 DWORD VFWAPIV
468 ICCompress(
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)
473 {
474         ICCOMPRESS      iccmp;
475
476         TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
477
478         iccmp.dwFlags           = dwFlags;
479
480         iccmp.lpbiOutput        = lpbiOutput;
481         iccmp.lpOutput          = lpData;
482         iccmp.lpbiInput         = lpbiInput;
483         iccmp.lpInput           = lpBits;
484
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));
493 }
494
495 /***********************************************************************
496  *              _ICCompress                     [MSVIDEO.224]
497  */
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) {
502
503         DWORD ret;
504         ICCOMPRESS *iccmp = SEGPTR_NEW(ICCOMPRESS);
505
506         TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n",(DWORD)hic,dwFlags,lpbiOutput,lpData,lpbiInput,lpBits);
507
508         iccmp->dwFlags          = dwFlags;
509
510         iccmp->lpbiOutput       = lpbiOutput;
511         iccmp->lpOutput         = lpData;
512         iccmp->lpbiInput                = lpbiInput;
513         iccmp->lpInput          = lpBits;
514
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));
523         SEGPTR_FREE(iccmp);
524         return ret;
525 }
526
527 /***********************************************************************
528  *              ICDecompress                    [MSVFW.26]
529  */
530 DWORD VFWAPIV  ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,
531                                 LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits)
532 {
533         ICDECOMPRESS    icd;
534         DWORD ret;
535
536         TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
537
538         TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
539
540         icd.dwFlags     = dwFlags;
541         icd.lpbiInput   = lpbiFormat;
542         icd.lpInput     = lpData;
543
544         icd.lpbiOutput  = lpbi;
545         icd.lpOutput    = lpBits;
546         icd.ckid        = 0;
547         ret = ICSendMessage(hic,ICM_DECOMPRESS,(DWORD)&icd,sizeof(ICDECOMPRESS));
548
549         TRACE("lpBits[0] == %ld\n",((LPDWORD)lpBits)[0]);
550
551         TRACE("-> %ld\n",ret);
552
553         return ret;
554 }
555
556 /***********************************************************************
557  *              _ICDecompress                   [MSVIDEO.230]
558  */
559 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags, LPBITMAPINFOHEADER lpbiFormat,
560                                                          LPVOID lpData, LPBITMAPINFOHEADER lpbi, LPVOID lpBits) {
561
562         ICDECOMPRESS *icd = SEGPTR_NEW(ICDECOMPRESS);
563         DWORD ret;
564         
565         TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n",(DWORD)hic,dwFlags,lpbiFormat,lpData,lpbi,lpBits);
566
567         icd->dwFlags = dwFlags;
568         icd->lpbiInput = lpbiFormat;
569         icd->lpInput = lpData;
570         icd->lpbiOutput = lpbi;
571         icd->lpOutput = lpBits;
572         icd->ckid = 0;
573
574         ret = ICSendMessage16(hic,ICM_DECOMPRESS,(DWORD)SEGPTR_GET(icd),sizeof(ICDECOMPRESS));
575
576         SEGPTR_FREE(icd);
577         return ret;
578 }
579
580 #define COPY(x,y) (x->y = x##16->y);
581 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
582
583 LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) {
584         LPVOID ret;
585
586         ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESSEX));
587         ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
588         ret = icdx16;
589         
590         COPY(icdx,dwFlags);
591         COPYPTR(icdx,lpbiSrc);
592         COPYPTR(icdx,lpSrc);
593         COPYPTR(icdx,lpbiDst);
594         COPYPTR(icdx,lpDst);
595         COPY(icdx,xDst);
596         COPY(icdx,yDst);
597         COPY(icdx,dxDst);
598         COPY(icdx,dyDst);
599         COPY(icdx,xSrc);
600         COPY(icdx,ySrc);
601         COPY(icdx,dxSrc);
602         COPY(icdx,dySrc);
603         
604         *lParam = (DWORD)(icdx);
605         return ret;
606 }
607
608 LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) {
609         LPVOID ret = 0;
610         
611         TRACE("Mapping %d\n",msg);
612
613         switch (msg) {
614         case DRV_LOAD:
615         case DRV_ENABLE:
616         case DRV_CLOSE:
617         case DRV_DISABLE:
618         case DRV_FREE:
619         case ICM_ABOUT:
620         case ICM_CONFIGURE:
621         case ICM_COMPRESS_END:
622         case ICM_DECOMPRESS_END:
623         case ICM_DECOMPRESSEX_END:
624         case ICM_SETQUALITY:
625         case ICM_DRAW_START_PLAY:
626         case ICM_DRAW_STOP_PLAY:
627         case ICM_DRAW_REALIZE:
628         case ICM_DRAW_RENDERBUFFER:
629         case ICM_DRAW_END:
630                 break;
631         case DRV_OPEN:
632         case ICM_GETDEFAULTQUALITY:
633         case ICM_GETQUALITY:
634         case ICM_SETSTATE:
635         case ICM_DRAW_WINDOW:
636         case ICM_GETBUFFERSWANTED:
637                 *lParam1 = (DWORD)MapSL(*lParam1);
638                 break;
639         case ICM_GETINFO:
640                 {
641                         ICINFO *ici = HeapAlloc(GetProcessHeap(),0,sizeof(ICINFO));
642                         ICINFO16 *ici16;
643
644                         ici16 = MapSL(*lParam1);
645                         ret = ici16;
646
647                         ici->dwSize = sizeof(ICINFO);
648                         COPY(ici,fccType);
649                         COPY(ici,fccHandler);
650                         COPY(ici,dwFlags);
651                         COPY(ici,dwVersion);
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);
658                 }
659                 break;
660         case ICM_COMPRESS:
661                 {
662                         ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(),0,sizeof(ICCOMPRESS));
663                         ICCOMPRESS *icc16;
664
665                         icc16 = MapSL(*lParam1);
666                         ret = icc16;
667
668                         COPY(icc,dwFlags);
669                         COPYPTR(icc,lpbiOutput);
670                         COPYPTR(icc,lpOutput);
671                         COPYPTR(icc,lpbiInput);
672                         COPYPTR(icc,lpInput);
673                         COPYPTR(icc,lpckid);
674                         COPYPTR(icc,lpdwFlags);
675                         COPY(icc,lFrameNum);
676                         COPY(icc,dwFrameSize);
677                         COPY(icc,dwQuality);
678                         COPYPTR(icc,lpbiPrev);
679                         COPYPTR(icc,lpPrev);
680                         
681                         *lParam1 = (DWORD)(icc);
682                         *lParam2 = sizeof(ICCOMPRESS);
683                 }
684                 break;
685         case ICM_DECOMPRESS:
686                 {
687                         ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDECOMPRESS));
688                         ICDECOMPRESS *icd16; /* Same structure except for the pointers */
689                         
690                         icd16 = MapSL(*lParam1);
691                         ret = icd16;
692                         
693                         COPY(icd,dwFlags);
694                         COPYPTR(icd,lpbiInput);
695                         COPYPTR(icd,lpInput);
696                         COPYPTR(icd,lpbiOutput);
697                         COPYPTR(icd,lpOutput);
698                         COPY(icd,ckid);
699                         
700                         *lParam1 = (DWORD)(icd);
701                         *lParam2 = sizeof(ICDECOMPRESS);
702                 }
703                 break;
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);
715                 break;
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?
721                  {
722                  LPVOID* addr = HeapAlloc(GetProcessHeap(),0,2*sizeof(LPVOID));
723                  addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
724                  if (*lParam2)
725                  addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
726                  else
727                  addr[1] = 0;
728                  
729                  ret = addr;
730                  }
731                  break;*/
732         case ICM_DECOMPRESSEX_BEGIN:
733         case ICM_DECOMPRESSEX:
734                 ret = MSVIDEO_MapICDEX16To32(lParam1);
735                 *lParam2 = sizeof(ICDECOMPRESSEX);
736                 break;
737         case ICM_DRAW_BEGIN:
738                 {
739                         ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWBEGIN));
740                         ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
741                         ret = icdb16;
742
743                         COPY(icdb,dwFlags);
744                         COPY(icdb,hpal);
745                         COPY(icdb,hwnd);
746                         COPY(icdb,hdc);
747                         COPY(icdb,xDst);
748                         COPY(icdb,yDst);
749                         COPY(icdb,dxDst);
750                         COPY(icdb,dyDst);
751                         COPYPTR(icdb,lpbi);
752                         COPY(icdb,xSrc);
753                         COPY(icdb,ySrc);
754                         COPY(icdb,dxSrc);
755                         COPY(icdb,dySrc);
756                         COPY(icdb,dwRate);
757                         COPY(icdb,dwScale);
758
759                         *lParam1 = (DWORD)(icdb);
760                         *lParam2 = sizeof(ICDRAWBEGIN);
761                 }
762                 break;
763         case ICM_DRAW_SUGGESTFORMAT:
764                 {
765                         ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAWSUGGEST));
766                         ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
767                         
768                         ret = icds16;
769
770                         COPY(icds,dwFlags);
771                         COPYPTR(icds,lpbiIn);
772                         COPYPTR(icds,lpbiSuggest);
773                         COPY(icds,dxSrc);
774                         COPY(icds,dySrc);
775                         COPY(icds,dxDst);
776                         COPY(icds,dyDst);
777                         COPY(icds,hicDecompressor);
778
779                         *lParam1 = (DWORD)(icds);
780                         *lParam2 = sizeof(ICDRAWSUGGEST);
781                 }
782                 break;
783         case ICM_DRAW:
784                 {
785                         ICDRAW *icd = HeapAlloc(GetProcessHeap(),0,sizeof(ICDRAW));
786                         ICDRAW *icd16 = MapSL(*lParam1);
787                         ret = icd16;
788
789                         COPY(icd,dwFlags);
790                         COPYPTR(icd,lpFormat);
791                         COPYPTR(icd,lpData);
792                         COPY(icd,cbData);
793                         COPY(icd,lTime);
794
795                         *lParam1 = (DWORD)(icd);
796                         *lParam2 = sizeof(ICDRAW);
797                 }
798                 break;
799         case ICM_DRAW_START:
800         case ICM_DRAW_STOP:
801                 break;
802         default:
803                 FIXME("%d is not yet handled. Expect a crash.\n",msg);
804         }
805         return ret;
806 }
807
808 #undef COPY
809 #undef COPYPTR
810
811 void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2) {
812         TRACE("Unmapping %d\n",msg);
813
814 #define UNCOPY(x,y) (x##16->y = x->y);
815
816         switch (msg) {
817         case ICM_GETINFO:
818                 {
819                         ICINFO *ici = (ICINFO*)(*lParam1);
820                         ICINFO16 *ici16 = (ICINFO16*)data16;
821
822                         UNCOPY(ici,fccType);
823                         UNCOPY(ici,fccHandler);
824                         UNCOPY(ici,dwFlags);
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);*/
835
836                         HeapFree(GetProcessHeap(),0,ici);
837                 }
838                 break;
839         case ICM_DECOMPRESS_QUERY:
840                 /*{
841                   LPVOID* x = data16;
842                   HeapFree(GetProcessHeap(),0,x[0]);
843                   if (x[1])
844                   HeapFree(GetProcessHeap(),0,x[1]);
845                   }
846                   break;*/
847         case ICM_COMPRESS:
848         case ICM_DECOMPRESS:
849         case ICM_DECOMPRESSEX_QUERY:
850         case ICM_DECOMPRESSEX_BEGIN:
851         case ICM_DECOMPRESSEX:
852         case ICM_DRAW_BEGIN:
853         case ICM_DRAW_SUGGESTFORMAT:
854         case ICM_DRAW:
855                 HeapFree(GetProcessHeap(),0,data16);
856                 break;
857         default:
858                 ERR("Unmapping unmapped msg %d\n",msg);
859         }
860 #undef UNCOPY           
861 }
862
863 LRESULT MSVIDEO_SendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2, BOOL bFrom32) {
864         LRESULT         ret;
865         WINE_HIC        *whic = GlobalLock16(hic);
866         LPVOID data16 = 0;
867         BOOL bDrv32;
868
869 #define XX(x) case x: TRACE("(0x%08lx,"#x",0x%08lx,0x%08lx,%d)\n",(DWORD)hic,lParam1,lParam2,bFrom32?32:16);break;
870
871         switch (msg) {
872                 /* DRV_* */
873                 XX(DRV_LOAD);
874                 XX(DRV_ENABLE);
875                 XX(DRV_OPEN);
876                 XX(DRV_CLOSE);
877                 XX(DRV_DISABLE);
878                 XX(DRV_FREE);
879                 /* ICM_RESERVED+X */
880                 XX(ICM_ABOUT);
881                 XX(ICM_CONFIGURE);
882                 XX(ICM_GET);
883                 XX(ICM_GETINFO);
884                 XX(ICM_GETDEFAULTQUALITY);
885                 XX(ICM_GETQUALITY);
886                 XX(ICM_GETSTATE);
887                 XX(ICM_SETQUALITY);
888                 XX(ICM_SET);
889                 XX(ICM_SETSTATE);
890                 /* ICM_USER+X */
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);
896                 XX(ICM_COMPRESS);
897                 XX(ICM_COMPRESS_END);
898                 XX(ICM_DECOMPRESS_GET_FORMAT);
899                 XX(ICM_DECOMPRESS_QUERY);
900                 XX(ICM_DECOMPRESS_BEGIN);
901                 XX(ICM_DECOMPRESS);
902                 XX(ICM_DECOMPRESS_END);
903                 XX(ICM_DECOMPRESS_SET_PALETTE);
904                 XX(ICM_DECOMPRESS_GET_PALETTE);
905                 XX(ICM_DRAW_QUERY);
906                 XX(ICM_DRAW_BEGIN);
907                 XX(ICM_DRAW_GET_PALETTE);
908                 XX(ICM_DRAW_START);
909                 XX(ICM_DRAW_STOP);
910                 XX(ICM_DRAW_END);
911                 XX(ICM_DRAW_GETTIME);
912                 XX(ICM_DRAW);
913                 XX(ICM_DRAW_WINDOW);
914                 XX(ICM_DRAW_SETTIME);
915                 XX(ICM_DRAW_REALIZE);
916                 XX(ICM_DRAW_FLUSH);
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);
929         default:
930                 FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx,%i) unknown message\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,bFrom32?32:16);
931         }
932
933 #undef XX
934
935         if (!whic) return ICERR_BADHANDLE;
936
937         if (whic->driverproc) { /* IC is a function */
938                 bDrv32 = whic->private;
939         } else {
940                 bDrv32 = ((GetDriverFlags(whic->hdrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST);
941         }
942
943         if (!bFrom32) {
944                 if (bDrv32)
945                         data16 = MSVIDEO_MapMsg16To32(msg,&lParam1,&lParam2);
946         } else {
947                 if (!bDrv32) {
948                         ERR("Can't do 32->16 mappings\n");
949                         ret = -1;
950                         goto out;
951                 }
952         }
953         
954         if (whic->driverproc) {
955                 if (bDrv32) {
956                         ret = whic->driverproc(whic->hdrv,hic,msg,lParam1,lParam2);
957                 } else {
958                         ret = MSVIDEO_CallTo16_long_lwwll((FARPROC16)whic->driverproc,whic->hdrv,hic,msg,lParam1,lParam2);
959                 }
960         } else {
961                 ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
962         }
963
964         if (data16)
965                 MSVIDEO_UnmapMsg16To32(msg,data16,&lParam1,&lParam2);
966  
967  out:
968         GlobalUnlock16(hic);
969         
970         TRACE(" -> 0x%08lx\n",ret);
971         return ret;
972 }
973
974 /***********************************************************************
975  *              ICSendMessage                   [MSVFW.40]
976  */
977 LRESULT VFWAPI ICSendMessage(HIC hic, UINT msg, DWORD lParam1, DWORD lParam2) {
978         return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,TRUE);
979 }
980
981 /***********************************************************************
982  *              ICSendMessage                   [MSVIDEO.205]
983  */
984 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) {
985         return MSVIDEO_SendMessage(hic,msg,lParam1,lParam2,FALSE);
986 }
987
988 /***********************************************************************
989  *              _ICMessage                      [MSVIDEO.207]
990  */
991 LRESULT VFWAPIV ICMessage16(void) {
992         HIC16 hic;
993         UINT16 msg;
994         UINT16 cb;
995         LPWORD lpData;
996         LRESULT ret;
997         UINT16 i;
998
999         VA_LIST16 valist;
1000         
1001         VA_START16(valist);
1002         hic = VA_ARG16(valist, HIC16);
1003         msg = VA_ARG16(valist, UINT16);
1004         cb  = VA_ARG16(valist, UINT16);
1005
1006         lpData = SEGPTR_ALLOC(cb);
1007
1008         TRACE("0x%08lx, %u, %u, ...)\n",(DWORD)hic,msg,cb);
1009
1010         for(i=0;i<cb/sizeof(WORD);i++) {
1011                 lpData[i] = VA_ARG16(valist, WORD);
1012         }
1013                 
1014         VA_END16(valist);
1015         ret = ICSendMessage16(hic, msg, (DWORD)(SEGPTR_GET(lpData)), (DWORD)cb);
1016
1017         SEGPTR_FREE(lpData);
1018         return ret;
1019 }
1020
1021 /***********************************************************************
1022  *              ICDrawBegin             [MSVFW.28]
1023  */
1024 DWORD VFWAPIV ICDrawBegin(
1025         HIC                hic,     /* [in] */
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] */
1041 {
1042         
1043         ICDRAWBEGIN     icdb;
1044
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);
1048
1049         icdb.dwFlags = dwFlags;
1050         icdb.hpal = hpal;
1051         icdb.hwnd = hwnd;
1052         icdb.hdc = hdc;
1053         icdb.xDst = xDst;
1054         icdb.yDst = yDst;
1055         icdb.dxDst = dxDst;
1056         icdb.dyDst = dyDst;
1057         icdb.lpbi = lpbi;
1058         icdb.xSrc = xSrc;
1059         icdb.ySrc = ySrc;
1060         icdb.dxSrc = dxSrc;
1061         icdb.dySrc = dySrc;
1062         icdb.dwRate = dwRate;
1063         icdb.dwScale = dwScale;
1064         return ICSendMessage(hic,ICM_DRAW_BEGIN,(DWORD)&icdb,sizeof(icdb));
1065 }
1066
1067 /***********************************************************************
1068  *              _ICDrawBegin            [MSVIDEO.232]
1069  */
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] */
1087 {
1088         DWORD ret;
1089         ICDRAWBEGIN16* icdb = SEGPTR_NEW(ICDRAWBEGIN16); /* SEGPTR for mapper to deal with */
1090
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);
1094
1095         icdb->dwFlags = dwFlags;
1096         icdb->hpal = hpal;
1097         icdb->hwnd = hwnd;
1098         icdb->hdc = hdc;
1099         icdb->xDst = xDst;
1100         icdb->yDst = yDst;
1101         icdb->dxDst = dxDst;
1102         icdb->dyDst = dyDst;
1103         icdb->lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
1104         icdb->xSrc = xSrc;
1105         icdb->ySrc = ySrc;
1106         icdb->dxSrc = dxSrc;
1107         icdb->dySrc = dySrc;
1108         icdb->dwRate = dwRate;
1109         icdb->dwScale = dwScale;
1110         
1111         ret = (DWORD)ICSendMessage16(hic,ICM_DRAW_BEGIN,(DWORD)SEGPTR_GET(icdb),sizeof(ICDRAWBEGIN16));
1112         SEGPTR_FREE(icdb);
1113         return ret;
1114 }
1115
1116 /***********************************************************************
1117  *              ICDraw                  [MSVFW.27]
1118  */
1119 DWORD VFWAPIV ICDraw(HIC hic, DWORD dwFlags, LPVOID lpFormat, LPVOID lpData, DWORD cbData, LONG lTime) {
1120         ICDRAW  icd;
1121
1122         TRACE("(0x%09lx,%ld,%p,%p,%ld,%ld)\n",(DWORD)hic,dwFlags,lpFormat,lpData,cbData,lTime);
1123
1124         icd.dwFlags = dwFlags;
1125         icd.lpFormat = lpFormat;
1126         icd.lpData = lpData;
1127         icd.cbData = cbData;
1128         icd.lTime = lTime;
1129
1130         return ICSendMessage(hic,ICM_DRAW,(DWORD)&icd,sizeof(icd));
1131 }
1132
1133 /***********************************************************************
1134  *              _ICDraw                 [MSVIDEO.234]
1135  */
1136 DWORD VFWAPIV ICDraw16(
1137         HIC16 hic,
1138         DWORD dwFlags,
1139         LPVOID lpFormat, /* [???] NOTE: SEGPTR */
1140         LPVOID lpData,   /* [???] NOTE: SEGPTR */
1141         DWORD cbData, 
1142         LONG lTime) 
1143 {
1144         ICDRAW* icd = SEGPTR_NEW(ICDRAW); /* SEGPTR for mapper to deal with */
1145
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;
1151         icd->lTime = lTime;
1152
1153         return ICSendMessage16(hic,ICM_DRAW,(DWORD)SEGPTR_GET(icd),sizeof(ICDRAW));
1154 }
1155
1156 /***********************************************************************
1157  *              ICClose                 [MSVFW.22]
1158  */
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);
1166         } else {
1167                 CloseDriver(whic->hdrv,0,0);
1168 }
1169
1170         GlobalUnlock16(hic);
1171         GlobalFree16(hic);
1172         return 0;
1173 }
1174
1175 /***********************************************************************
1176  *              ICClose                 [MSVIDEO.204]
1177  */
1178 LRESULT WINAPI ICClose16(HIC16 hic) {
1179         return ICClose(hic);
1180 }
1181
1182 /***********************************************************************
1183  *              MCIWndCreateA           [MSVFW.44 & MSVFW.45]
1184  */
1185 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
1186                       DWORD dwStyle,LPCSTR szFile)
1187 {
1188         FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile);
1189         return 0;
1190 }
1191
1192 /***********************************************************************
1193  *              MCIWndCreateW           [MSVFW.46]
1194  */
1195 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
1196                       DWORD dwStyle,LPCWSTR szFile)
1197 {
1198         FIXME("%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile));
1199         return 0;
1200 }