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