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