Implemented MakeSureDirectoryPathExists.
[wine] / dlls / msvideo / msvideo16.c
1 /*
2  * msvideo 16-bit functions
3  *
4  * Copyright 1998 Marcus Meissner
5  * Copyright 2000 Bradley Baetz
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #define COM_NO_WINDOWS_H
23 #include <stdio.h>
24 #include <string.h>
25
26 #include "msvideo_private.h"
27 #include "winver.h"
28 #include "vfw16.h"
29 #include "stackframe.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
33
34
35 /***********************************************************************
36  *              DrawDibOpen             [MSVIDEO.102]
37  */
38 HDRAWDIB16 VFWAPI DrawDibOpen16(void)
39 {
40     return HDRAWDIB_16(DrawDibOpen());
41 }
42
43 /***********************************************************************
44  *              DrawDibClose            [MSVIDEO.103]
45  */
46 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd)
47 {
48     return DrawDibClose(HDRAWDIB_32(hdd));
49 }
50
51 /************************************************************************
52  *              DrawDibBegin            [MSVIDEO.104]
53  */
54 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd, HDC16 hdc, INT16 dxDst,
55                              INT16 dyDst, LPBITMAPINFOHEADER lpbi, INT16 dxSrc,
56                              INT16 dySrc, UINT16 wFlags)
57 {
58     return DrawDibBegin(HDRAWDIB_32(hdd), HDC_32(hdc), dxDst, dyDst, lpbi,
59                         dxSrc, dySrc, wFlags);
60 }
61
62 /***********************************************************************
63  *              DrawDibEnd              [MSVIDEO.105]
64  */
65 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd)
66 {
67     return DrawDibEnd(HDRAWDIB_32(hdd));
68 }
69
70 /**********************************************************************
71  *              DrawDibDraw             [MSVIDEO.106]
72  */
73 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd, HDC16 hdc, INT16 xDst, INT16 yDst,
74                             INT16 dxDst, INT16 dyDst, LPBITMAPINFOHEADER lpbi,
75                             LPVOID lpBits, INT16 xSrc, INT16 ySrc, INT16 dxSrc,
76                             INT16 dySrc, UINT16 wFlags)
77 {
78     return DrawDibDraw(HDRAWDIB_32(hdd), HDC_32(hdc), xDst, yDst, dxDst,
79                        dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
80 }
81
82 /***********************************************************************
83  *              DrawDibGetPalette       [MSVIDEO.108]
84  */
85 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd)
86 {
87     return HPALETTE_16(DrawDibGetPalette(HDRAWDIB_32(hdd)));
88 }
89
90 /***********************************************************************
91  *              DrawDibSetPalette       [MSVIDEO.110]
92  */
93 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal)
94 {
95     return DrawDibSetPalette(HDRAWDIB_32(hdd), HPALETTE_32(hpal));
96 }
97
98 /***********************************************************************
99  *              DrawDibRealize          [MSVIDEO.112]
100  */
101 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc,
102                                BOOL16 fBackground)
103 {
104     return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
105 }
106
107 /*************************************************************************
108  *              DrawDibStart            [MSVIDEO.118]
109  */
110 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate)
111 {
112     return DrawDibStart(HDRAWDIB_32(hdd), rate);
113 }
114
115 /*************************************************************************
116  *              DrawDibStop             [MSVIDEO.119]
117  */
118 BOOL16 DrawDibStop16(HDRAWDIB16 hdd)
119 {
120     return DrawDibStop(HDRAWDIB_32(hdd));
121 }
122
123 /***********************************************************************
124  *              ICOpen                          [MSVIDEO.203]
125  */
126 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
127 {
128     return HIC_16(ICOpen(fccType, fccHandler, wMode));
129 }
130
131 /***********************************************************************
132  *              ICClose                 [MSVIDEO.204]
133  */
134 LRESULT WINAPI ICClose16(HIC16 hic)
135 {
136     return ICClose(HIC_32(hic));
137 }
138
139 /***********************************************************************
140  *              _ICMessage                      [MSVIDEO.207]
141  */
142 LRESULT VFWAPIV ICMessage16(void)
143 {
144     HIC16 hic;
145     UINT16 msg;
146     UINT16 cb;
147     LPWORD lpData;
148     SEGPTR segData;
149     LRESULT ret;
150     UINT16 i;
151
152     VA_LIST16 valist;
153
154     VA_START16(valist);
155     hic = VA_ARG16(valist, HIC16);
156     msg = VA_ARG16(valist, UINT16);
157     cb = VA_ARG16(valist, UINT16);
158
159     lpData = HeapAlloc(GetProcessHeap(), 0, cb);
160
161     TRACE("0x%08lx, %u, %u, ...)\n", (DWORD) hic, msg, cb);
162
163     for (i = 0; i < cb / sizeof(WORD); i++) 
164     {
165         lpData[i] = VA_ARG16(valist, WORD);
166     }
167
168     VA_END16(valist);
169     segData = MapLS(lpData);
170     ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
171     UnMapLS(segData);
172     HeapFree(GetProcessHeap(), 0, lpData);
173     return ret;
174 }
175
176 /***********************************************************************
177  *              ICGetInfo                       [MSVIDEO.212]
178  */
179 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb)
180 {
181     LRESULT ret;
182
183     TRACE("(0x%08lx,%p,%ld)\n", (DWORD) hic, picinfo, cb);
184     ret = ICSendMessage16(hic, ICM_GETINFO, (DWORD) picinfo, cb);
185     TRACE("     -> 0x%08lx\n", ret);
186     return ret;
187 }
188
189 /***********************************************************************
190  *              ICLocate                        [MSVIDEO.213]
191  */
192 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler,
193                         LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,
194                         WORD wFlags)
195 {
196     return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags));
197 }
198
199 /***********************************************************************
200  *              _ICCompress                     [MSVIDEO.224]
201  */
202 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags,
203                            LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
204                            LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits,
205                            LPDWORD lpckid, LPDWORD lpdwFlags,
206                            LONG lFrameNum, DWORD dwFrameSize,
207                            DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev,
208                            LPVOID lpPrev)
209 {
210     DWORD ret;
211     ICCOMPRESS iccmp;
212     SEGPTR seg_iccmp;
213     
214     TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags,
215           lpbiOutput, lpData, lpbiInput, lpBits);
216
217     iccmp.dwFlags = dwFlags;
218
219     iccmp.lpbiOutput = lpbiOutput;
220     iccmp.lpOutput = lpData;
221     iccmp.lpbiInput = lpbiInput;
222     iccmp.lpInput = lpBits;
223
224     iccmp.lpckid = lpckid;
225     iccmp.lpdwFlags = lpdwFlags;
226     iccmp.lFrameNum = lFrameNum;
227     iccmp.dwFrameSize = dwFrameSize;
228     iccmp.dwQuality = dwQuality;
229     iccmp.lpbiPrev = lpbiPrev;
230     iccmp.lpPrev = lpPrev;
231     seg_iccmp = MapLS(&iccmp);
232     ret = ICSendMessage16(hic, ICM_COMPRESS, seg_iccmp, sizeof(ICCOMPRESS));
233     UnMapLS(seg_iccmp);
234     return ret;
235 }
236
237 /***********************************************************************
238  *              _ICDecompress                   [MSVIDEO.230]
239  */
240 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags,
241                              LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData,
242                              LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
243 {
244     ICDECOMPRESS icd;
245     SEGPTR segptr;
246     DWORD ret;
247
248     TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n", (DWORD) hic, dwFlags, lpbiFormat,
249           lpData, lpbi, lpBits);
250
251     icd.dwFlags = dwFlags;
252     icd.lpbiInput = lpbiFormat;
253     icd.lpInput = lpData;
254     icd.lpbiOutput = lpbi;
255     icd.lpOutput = lpBits;
256     icd.ckid = 0;
257     segptr = MapLS(&icd);
258     ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS));
259     UnMapLS(segptr);
260     return ret;
261 }
262
263 /***********************************************************************
264  *              _ICDrawBegin            [MSVIDEO.232]
265  */
266 DWORD VFWAPIV ICDrawBegin16(HIC16 hic,          /* [in] */
267                             DWORD dwFlags,      /* [in] flags */
268                             HPALETTE16 hpal,    /* [in] palette to draw with */
269                             HWND16 hwnd,        /* [in] window to draw to */
270                             HDC16 hdc,          /* [in] HDC to draw to */
271                             INT16 xDst,         /* [in] destination rectangle */
272                             INT16 yDst,         /* [in] */
273                             INT16 dxDst,        /* [in] */
274                             INT16 dyDst,        /* [in] */
275                             LPBITMAPINFOHEADER lpbi,    /* [in] format of frame to draw NOTE: SEGPTR */
276                             INT16 xSrc,         /* [in] source rectangle */
277                             INT16 ySrc,         /* [in] */
278                             INT16 dxSrc,        /* [in] */
279                             INT16 dySrc,        /* [in] */
280                             DWORD dwRate,       /* [in] frames/second = (dwRate/dwScale) */
281                             DWORD dwScale)      /* [in] */
282 {
283     DWORD ret;
284     ICDRAWBEGIN16 icdb;
285     SEGPTR seg_icdb;
286
287     TRACE ("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n",
288            (DWORD) hic, dwFlags, (DWORD) hpal, (DWORD) hwnd, (DWORD) hdc,
289            xDst, yDst, dxDst, dyDst, lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate,
290            dwScale);
291
292     icdb.dwFlags = dwFlags;
293     icdb.hpal = hpal;
294     icdb.hwnd = hwnd;
295     icdb.hdc = hdc;
296     icdb.xDst = xDst;
297     icdb.yDst = yDst;
298     icdb.dxDst = dxDst;
299     icdb.dyDst = dyDst;
300     icdb.lpbi = lpbi;           /* Keep this as SEGPTR for the mapping code to deal with */
301     icdb.xSrc = xSrc;
302     icdb.ySrc = ySrc;
303     icdb.dxSrc = dxSrc;
304     icdb.dySrc = dySrc;
305     icdb.dwRate = dwRate;
306     icdb.dwScale = dwScale;
307     seg_icdb = MapLS(&icdb);
308     ret = (DWORD) ICSendMessage16(hic, ICM_DRAW_BEGIN, seg_icdb,
309                                   sizeof(ICDRAWBEGIN16));
310     UnMapLS(seg_icdb);
311     return ret;
312 }
313
314 /***********************************************************************
315  *              _ICDraw                 [MSVIDEO.234]
316  */
317 DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags,
318                        LPVOID lpFormat, /* [???] NOTE: SEGPTR */
319                        LPVOID lpData,   /* [???] NOTE: SEGPTR */
320                        DWORD cbData, LONG lTime)
321 {
322     DWORD ret;
323     ICDRAW icd;
324     SEGPTR seg_icd;
325
326     TRACE("(0x%08lx,0x%08lx,%p,%p,%ld,%ld)\n", (DWORD) hic, dwFlags,
327           lpFormat, lpData, cbData, lTime);
328     icd.dwFlags = dwFlags;
329     icd.lpFormat = lpFormat;
330     icd.lpData = lpData;
331     icd.cbData = cbData;
332     icd.lTime = lTime;
333     seg_icd = MapLS(&icd);
334     ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW));
335     UnMapLS(seg_icd);
336     return ret;
337 }
338
339 /***********************************************************************
340  *              ICGetDisplayFormat                      [MSVIDEO.239]
341  */
342 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
343                                   LPBITMAPINFOHEADER lpbiOut, INT16 depth,
344                                   INT16 dx, INT16 dy)
345 {
346     return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth,
347                                      dx, dy));
348 }
349
350 #define COPY(x,y) (x->y = x##16->y);
351 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
352
353 /******************************************************************
354  *              MSVIDEO_MapICDEX16To32
355  *
356  *
357  */
358 static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) 
359 {
360     LPVOID ret;
361
362     ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX));
363     ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
364     ret = icdx16;
365
366     COPY(icdx, dwFlags);
367     COPYPTR(icdx, lpbiSrc);
368     COPYPTR(icdx, lpSrc);
369     COPYPTR(icdx, lpbiDst);
370     COPYPTR(icdx, lpDst);
371     COPY(icdx, xDst);
372     COPY(icdx, yDst);
373     COPY(icdx, dxDst);
374     COPY(icdx, dyDst);
375     COPY(icdx, xSrc);
376     COPY(icdx, ySrc);
377     COPY(icdx, dxSrc);
378     COPY(icdx, dySrc);
379
380     *lParam = (DWORD)(icdx);
381     return ret;
382 }
383
384 /******************************************************************
385  *              MSVIDEO_MapMsg16To32
386  *
387  *
388  */
389 static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2)
390 {
391     LPVOID ret = 0;
392
393     TRACE("Mapping %d\n", msg);
394
395     switch (msg) 
396     {
397     case DRV_LOAD:
398     case DRV_ENABLE:
399     case DRV_CLOSE:
400     case DRV_DISABLE:
401     case DRV_FREE:
402     case ICM_ABOUT:
403     case ICM_CONFIGURE:
404     case ICM_COMPRESS_END:
405     case ICM_DECOMPRESS_END:
406     case ICM_DECOMPRESSEX_END:
407     case ICM_SETQUALITY:
408     case ICM_DRAW_START_PLAY:
409     case ICM_DRAW_STOP_PLAY:
410     case ICM_DRAW_REALIZE:
411     case ICM_DRAW_RENDERBUFFER:
412     case ICM_DRAW_END:
413         break;
414     case DRV_OPEN:
415     case ICM_GETDEFAULTQUALITY:
416     case ICM_GETQUALITY:
417     case ICM_SETSTATE:
418     case ICM_DRAW_WINDOW:
419     case ICM_GETBUFFERSWANTED:
420         *lParam1 = (DWORD)MapSL(*lParam1);
421         break;
422     case ICM_GETINFO:
423         {
424             ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO));
425             ICINFO16 *ici16;
426             
427             ici16 = MapSL(*lParam1);
428             ret = ici16;
429             
430             ici->dwSize = sizeof(ICINFO);
431             COPY(ici, fccType);
432             COPY(ici, fccHandler);
433             COPY(ici, dwFlags);
434             COPY(ici, dwVersion);
435             COPY(ici, dwVersionICM);
436             MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
437             MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
438             MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
439             *lParam1 = (DWORD)(ici);
440             *lParam2 = sizeof(ICINFO);
441         }
442         break;
443     case ICM_COMPRESS:
444         {
445             ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS));
446             ICCOMPRESS *icc16;
447
448             icc16 = MapSL(*lParam1);
449             ret = icc16;
450
451             COPY(icc, dwFlags);
452             COPYPTR(icc, lpbiOutput);
453             COPYPTR(icc, lpOutput);
454             COPYPTR(icc, lpbiInput);
455             COPYPTR(icc, lpInput);
456             COPYPTR(icc, lpckid);
457             COPYPTR(icc, lpdwFlags);
458             COPY(icc, lFrameNum);
459             COPY(icc, dwFrameSize);
460             COPY(icc, dwQuality);
461             COPYPTR(icc, lpbiPrev);
462             COPYPTR(icc, lpPrev);
463
464             *lParam1 = (DWORD)(icc);
465             *lParam2 = sizeof(ICCOMPRESS);
466         }
467         break;
468     case ICM_DECOMPRESS:
469         {
470             ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
471             ICDECOMPRESS *icd16; /* Same structure except for the pointers */
472
473             icd16 = MapSL(*lParam1);
474             ret = icd16;
475
476             COPY(icd, dwFlags);
477             COPYPTR(icd, lpbiInput);
478             COPYPTR(icd, lpInput);
479             COPYPTR(icd, lpbiOutput);
480             COPYPTR(icd, lpOutput);
481             COPY(icd, ckid);
482
483             *lParam1 = (DWORD)(icd);
484             *lParam2 = sizeof(ICDECOMPRESS);
485         }
486         break;
487     case ICM_COMPRESS_BEGIN:
488     case ICM_COMPRESS_GET_FORMAT:
489     case ICM_COMPRESS_GET_SIZE:
490     case ICM_COMPRESS_QUERY:
491     case ICM_DECOMPRESS_GET_FORMAT:
492     case ICM_DECOMPRESS_QUERY:
493     case ICM_DECOMPRESS_BEGIN:
494     case ICM_DECOMPRESS_SET_PALETTE:
495     case ICM_DECOMPRESS_GET_PALETTE:
496         *lParam1 = (DWORD)MapSL(*lParam1);
497         *lParam2 = (DWORD)MapSL(*lParam2);
498         break;
499     case ICM_DECOMPRESSEX_QUERY:
500         if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
501             WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2);
502         /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
503          * This is because of ICMessage(). Special case it?
504          {
505          LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
506          addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
507          if (*lParam2)
508          addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
509          else
510          addr[1] = 0;
511          
512          ret = addr;
513          }
514          break;*/
515     case ICM_DECOMPRESSEX_BEGIN:
516     case ICM_DECOMPRESSEX:
517         ret = MSVIDEO_MapICDEX16To32(lParam1);
518         *lParam2 = sizeof(ICDECOMPRESSEX);
519         break;
520     case ICM_DRAW_BEGIN:
521         {
522             ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
523             ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
524             ret = icdb16;
525
526             COPY(icdb, dwFlags);
527             icdb->hpal = HPALETTE_32(icdb16->hpal);
528             icdb->hwnd = HWND_32(icdb16->hwnd);
529             icdb->hdc = HDC_32(icdb16->hdc);
530             COPY(icdb, xDst);
531             COPY(icdb, yDst);
532             COPY(icdb, dxDst);
533             COPY(icdb, dyDst);
534             COPYPTR(icdb, lpbi);
535             COPY(icdb, xSrc);
536             COPY(icdb, ySrc);
537             COPY(icdb, dxSrc);
538             COPY(icdb, dySrc);
539             COPY(icdb, dwRate);
540             COPY(icdb, dwScale);
541
542             *lParam1 = (DWORD)(icdb);
543             *lParam2 = sizeof(ICDRAWBEGIN);
544         }
545         break;
546     case ICM_DRAW_SUGGESTFORMAT:
547         {
548             ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
549             ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
550
551             ret = icds16;
552
553             COPY(icds, dwFlags);
554             COPYPTR(icds, lpbiIn);
555             COPYPTR(icds, lpbiSuggest);
556             COPY(icds, dxSrc);
557             COPY(icds, dySrc);
558             COPY(icds, dxDst);
559             COPY(icds, dyDst);
560             icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
561
562             *lParam1 = (DWORD)(icds);
563             *lParam2 = sizeof(ICDRAWSUGGEST);
564         }
565         break;
566     case ICM_DRAW:
567         {
568             ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
569             ICDRAW *icd16 = MapSL(*lParam1);
570             ret = icd16;
571
572             COPY(icd, dwFlags);
573             COPYPTR(icd, lpFormat);
574             COPYPTR(icd, lpData);
575             COPY(icd, cbData);
576             COPY(icd, lTime);
577
578             *lParam1 = (DWORD)(icd);
579             *lParam2 = sizeof(ICDRAW);
580         }
581         break;
582     case ICM_DRAW_START:
583     case ICM_DRAW_STOP:
584         break;
585     default:
586         FIXME("%d is not yet handled. Expect a crash.\n", msg);
587     }
588     return ret;
589 }
590
591 #undef COPY
592 #undef COPYPTR
593
594 /******************************************************************
595  *              MSVIDEO_UnmapMsg16To32
596  *
597  *
598  */
599 static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2)
600 {
601     TRACE("Unmapping %d\n", msg);
602
603 #define UNCOPY(x, y) (x##16->y = x->y);
604
605     switch (msg) 
606     {
607     case ICM_GETINFO:
608         {
609             ICINFO *ici = (ICINFO*)(*lParam1);
610             ICINFO16 *ici16 = (ICINFO16*)data16;
611
612             UNCOPY(ici, fccType);
613             UNCOPY(ici, fccHandler);
614             UNCOPY(ici, dwFlags);
615             UNCOPY(ici, dwVersion);
616             UNCOPY(ici, dwVersionICM);
617             WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName, 
618                                  sizeof(ici16->szName), NULL, NULL );
619             ici16->szName[sizeof(ici16->szName)-1] = 0;
620             WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription, 
621                                  sizeof(ici16->szDescription), NULL, NULL );
622             ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
623             /* This just gives garbage for some reason - BB
624                lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
625
626             HeapFree(GetProcessHeap(), 0, ici);
627         }
628         break;
629     case ICM_DECOMPRESS_QUERY:
630         /*{
631           LPVOID* x = data16;
632           HeapFree(GetProcessHeap(), 0, x[0]);
633           if (x[1])
634           HeapFree(GetProcessHeap(), 0, x[1]);
635           }
636           break;*/
637     case ICM_COMPRESS:
638     case ICM_DECOMPRESS:
639     case ICM_DECOMPRESSEX_QUERY:
640     case ICM_DECOMPRESSEX_BEGIN:
641     case ICM_DECOMPRESSEX:
642     case ICM_DRAW_BEGIN:
643     case ICM_DRAW_SUGGESTFORMAT:
644     case ICM_DRAW:
645         HeapFree(GetProcessHeap(), 0, data16);
646         break;
647     default:
648         ERR("Unmapping unmapped msg %d\n", msg);
649     }
650 #undef UNCOPY
651 }
652
653 /***********************************************************************
654  *              ICInfo                          [MSVIDEO.200]
655  */
656 BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
657 {
658     BOOL16 ret;
659     LPVOID lpv;
660     DWORD lParam = (DWORD)lpicinfo;
661     DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
662     
663     /* Use the mapping functions to map the ICINFO structure */
664     lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size);
665
666     ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam);
667
668     MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size);
669
670     return ret;
671 }
672
673 /******************************************************************
674  *              IC_Callback3216
675  *
676  *
677  */
678 static  LRESULT CALLBACK  IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2)
679 {
680     WINE_HIC*   whic;
681     LRESULT     ret = 0;
682     WORD args[8];
683
684     whic = MSVIDEO_GetHicPtr(hic);
685     if (whic)
686     {
687         switch (msg)
688         {
689         case DRV_OPEN:
690             lp2 = (DWORD)MapLS((void*)lp2);
691             break;
692         }
693         args[7] = HIWORD(hic);
694         args[6] = LOWORD(hic);
695         args[5] = HDRVR_16(whic->hdrv);
696         args[4] = msg;
697         args[3] = HIWORD(lp1);
698         args[2] = LOWORD(lp1);
699         args[1] = HIWORD(lp2);
700         args[0] = LOWORD(lp2);
701         WOWCallback16Ex( (DWORD)whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret );
702
703         switch (msg)
704         {
705         case DRV_OPEN:
706             UnMapLS(lp2);
707             break;
708         }
709     }
710     else ret = ICERR_BADHANDLE;
711     return ret;
712 }
713
714 /***********************************************************************
715  *              ICOpenFunction                  [MSVIDEO.206]
716  */
717 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
718 {
719     HIC         hic32;
720
721     hic32 = MSVIDEO_OpenFunction(fccType, fccHandler, wMode, 
722                                  (DRIVERPROC)IC_Callback3216, (DWORD)lpfnHandler);
723     return HIC_16(hic32);
724 }
725
726 /***********************************************************************
727  *              ICSendMessage                   [MSVIDEO.205]
728  */
729 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) 
730 {
731     LRESULT     ret = ICERR_BADHANDLE;
732     WINE_HIC*   whic;
733
734     whic = MSVIDEO_GetHicPtr(HIC_32(hic));
735     if (whic)
736     {
737         /* we've got a 16 bit driver proc... call it directly */
738         if (whic->driverproc16)
739         {
740             WORD args[8];
741
742             /* FIXME: original code was passing hdrv first and hic second */
743             /* but this doesn't match what IC_Callback3216 does */
744             args[7] = HIWORD(hic);
745             args[6] = LOWORD(hic);
746             args[5] = HDRVR_16(whic->hdrv);
747             args[4] = msg;
748             args[3] = HIWORD(lParam1);
749             args[2] = LOWORD(lParam1);
750             args[1] = HIWORD(lParam2);
751             args[0] = LOWORD(lParam2);
752             WOWCallback16Ex( (DWORD)whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret );
753         }
754         else
755         {
756             /* map the message for a 32 bit infrastructure, and pass it along */
757             void*       data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
758     
759             ret = MSVIDEO_SendMessage(whic, msg, lParam1, lParam2);
760             if (data16)
761                 MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
762         }
763     }
764     return ret;
765 }
766
767 /***********************************************************************
768  *              VideoCapDriverDescAndVer        [MSVIDEO.22]
769  */
770 DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
771                                         LPSTR buf2, WORD buf2len)
772 {
773     DWORD       verhandle;
774     WORD        xnr = nr;
775     DWORD       infosize;
776     UINT        subblocklen;
777     char        *s,  buf[2000],  fn[260];
778     LPBYTE      infobuf;
779     LPVOID      subblock;
780
781     TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
782     if (GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini")) 
783     {
784         s = buf;
785         while (*s) 
786         {
787             if (!strncasecmp(s, "vid", 3)) 
788             {
789                 if (!xnr) break;
790                 xnr--;
791             }
792             s = s + strlen(s) + 1; /* either next char or \0 */
793         }
794     }
795     else
796         return 20; /* hmm, out of entries even if we don't have any */
797     if (xnr) 
798     {
799         FIXME("No more VID* entries found\n");
800         return 20;
801     }
802     GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini");
803     infosize = GetFileVersionInfoSizeA(fn, &verhandle);
804     if (!infosize) 
805     {
806         TRACE("%s has no fileversioninfo.\n", fn);
807         return 18;
808     }
809     infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
810     if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf)) 
811     {
812         char    vbuf[200];
813         /* Yes, two space behind : */
814         /* FIXME: test for buflen */
815         sprintf(vbuf, "Version:  %d.%d.%d.%d\n", 
816                 ((WORD*)infobuf)[0x0f],
817                 ((WORD*)infobuf)[0x0e],
818                 ((WORD*)infobuf)[0x11],
819                 ((WORD*)infobuf)[0x10]
820             );
821         TRACE("version of %s is %s\n", fn, vbuf);
822         strncpy(buf2, vbuf, buf2len);
823     }
824     else 
825     {
826         TRACE("GetFileVersionInfoA failed for %s.\n", fn);
827         strncpy(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
828     }
829     /* FIXME: language problem? */
830     if (VerQueryValueA( infobuf,
831                         "\\StringFileInfo\\040904E4\\FileDescription",
832                         &subblock,
833                         &subblocklen
834             )) 
835     {
836         TRACE("VQA returned %s\n", (LPCSTR)subblock);
837         strncpy(buf1, subblock, buf1len);
838     }
839     else 
840     {
841         TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
842         strncpy(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
843     }
844     HeapFree(GetProcessHeap(), 0, infobuf);
845     return 0;
846 }
847
848 /******************************************************************
849  *              IC_CallTo16
850  *
851  *
852  */
853 static  LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, LPARAM lp2)
854 {
855 #if 0
856     WINE_HIC*   whic = IC_GetPtr(hic);
857     LRESULT     ret = 0;
858     
859     
860     if (whic->driverproc) 
861     {
862         ret = whic->driverproc(hic, whic->hdrv, msg, lParam1, lParam2);
863     }
864     else
865     {
866         ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2);
867     }
868 #else
869     FIXME("No 32=>16 conversion yet\n");
870 #endif
871     return 0;
872 }
873
874 /**************************************************************************
875  *                      DllEntryPoint (MSVIDEO.300)
876  *
877  * MSVIDEO DLL entry point
878  *
879  */
880 BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
881                           WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
882 {
883     switch (fdwReason) 
884     {
885     case DLL_PROCESS_ATTACH:
886         /* hook in our 16 bit management functions */
887         pFnCallTo16 = IC_CallTo16;
888         break;
889     case DLL_PROCESS_DETACH:
890         /* remove our 16 bit management functions */
891         pFnCallTo16 = NULL;
892         break;
893     case DLL_THREAD_ATTACH:
894     case DLL_THREAD_DETACH:
895         break;
896     }
897     return TRUE;
898 }