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