comctl32: Fix a typo in comment.
[wine.git] / dlls / msvideo.dll16 / msvideo16.c
blobd390020eccd3d32744e5141c4b328acaf0abce3c
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <string.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winver.h"
29 #include "winnls.h"
30 #include "winreg.h"
31 #include "winuser.h"
32 #include "wine/winbase16.h"
33 #include "wownt32.h"
34 #include "vfw16.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msvideo);
39 /* Drivers32 settings */
40 #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"
42 /* handle16 --> handle conversions */
43 #define HDRAWDIB_32(h16) ((HDRAWDIB)(ULONG_PTR)(h16))
44 #define HIC_32(h16) ((HIC)(ULONG_PTR)(h16))
46 /* handle --> handle16 conversions */
47 #define HDRVR_16(h32) (LOWORD(h32))
48 #define HDRAWDIB_16(h32) (LOWORD(h32))
49 #define HIC_16(h32) (LOWORD(h32))
51 /***********************************************************************
52 * DrawDibOpen [MSVIDEO.102]
54 HDRAWDIB16 VFWAPI DrawDibOpen16(void)
56 return HDRAWDIB_16(DrawDibOpen());
59 /***********************************************************************
60 * DrawDibClose [MSVIDEO.103]
62 BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd)
64 return DrawDibClose(HDRAWDIB_32(hdd));
67 /************************************************************************
68 * DrawDibBegin [MSVIDEO.104]
70 BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd, HDC16 hdc, INT16 dxDst,
71 INT16 dyDst, LPBITMAPINFOHEADER lpbi, INT16 dxSrc,
72 INT16 dySrc, UINT16 wFlags)
74 return DrawDibBegin(HDRAWDIB_32(hdd), HDC_32(hdc), dxDst, dyDst, lpbi,
75 dxSrc, dySrc, wFlags);
78 /***********************************************************************
79 * DrawDibEnd [MSVIDEO.105]
81 BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd)
83 return DrawDibEnd(HDRAWDIB_32(hdd));
86 /**********************************************************************
87 * DrawDibDraw [MSVIDEO.106]
89 BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd, HDC16 hdc, INT16 xDst, INT16 yDst,
90 INT16 dxDst, INT16 dyDst, LPBITMAPINFOHEADER lpbi,
91 LPVOID lpBits, INT16 xSrc, INT16 ySrc, INT16 dxSrc,
92 INT16 dySrc, UINT16 wFlags)
94 return DrawDibDraw(HDRAWDIB_32(hdd), HDC_32(hdc), xDst, yDst, dxDst,
95 dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags);
98 /***********************************************************************
99 * DrawDibGetPalette [MSVIDEO.108]
101 HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd)
103 return HPALETTE_16(DrawDibGetPalette(HDRAWDIB_32(hdd)));
106 /***********************************************************************
107 * DrawDibSetPalette [MSVIDEO.110]
109 BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal)
111 return DrawDibSetPalette(HDRAWDIB_32(hdd), HPALETTE_32(hpal));
114 /***********************************************************************
115 * DrawDibRealize [MSVIDEO.112]
117 UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc,
118 BOOL16 fBackground)
120 return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground);
123 /*************************************************************************
124 * DrawDibProfileDisplay [MSVIDEO.114]
126 BOOL16 VFWAPI DrawDibProfileDisplay16(LPBITMAPINFOHEADER lpbi)
128 TRACE("(%p)\n", lpbi);
129 return DrawDibProfileDisplay(lpbi);
132 /*************************************************************************
133 * DrawDibStart [MSVIDEO.118]
135 BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate)
137 return DrawDibStart(HDRAWDIB_32(hdd), rate);
140 /*************************************************************************
141 * DrawDibStop [MSVIDEO.119]
143 BOOL16 VFWAPI DrawDibStop16(HDRAWDIB16 hdd)
145 return DrawDibStop(HDRAWDIB_32(hdd));
148 /***********************************************************************
149 * ICOpen [MSVIDEO.203]
151 HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode)
153 return HIC_16(ICOpen(fccType, fccHandler, wMode));
156 /***********************************************************************
157 * _ICMessage [MSVIDEO.207]
159 LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist )
161 LPWORD lpData;
162 SEGPTR segData;
163 LRESULT ret;
164 UINT16 i;
166 lpData = HeapAlloc(GetProcessHeap(), 0, cb);
168 TRACE("0x%08x, %u, %u, ...)\n", (DWORD) hic, msg, cb);
170 for (i = 0; i < cb / sizeof(WORD); i++)
172 lpData[i] = VA_ARG16(valist, WORD);
175 segData = MapLS(lpData);
176 ret = ICSendMessage16(hic, msg, segData, (DWORD) cb);
177 UnMapLS(segData);
178 HeapFree(GetProcessHeap(), 0, lpData);
179 return ret;
182 /***********************************************************************
183 * ICGetInfo [MSVIDEO.212]
185 LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb)
187 LRESULT ret;
189 TRACE("(0x%08x,%p,%d)\n", (DWORD) hic, picinfo, cb);
190 ret = ICSendMessage16(hic, ICM_GETINFO, (DWORD) picinfo, cb);
191 TRACE(" -> 0x%08lx\n", ret);
192 return ret;
195 /***********************************************************************
196 * ICLocate [MSVIDEO.213]
198 HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler,
199 LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut,
200 WORD wFlags)
202 return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags));
205 /***********************************************************************
206 * _ICCompress [MSVIDEO.224]
208 DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags,
209 LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData,
210 LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits,
211 LPDWORD lpckid, LPDWORD lpdwFlags,
212 LONG lFrameNum, DWORD dwFrameSize,
213 DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev,
214 LPVOID lpPrev)
216 DWORD ret;
217 ICCOMPRESS iccmp;
218 SEGPTR seg_iccmp;
220 TRACE("(0x%08x,%d,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags,
221 lpbiOutput, lpData, lpbiInput, lpBits);
223 iccmp.dwFlags = dwFlags;
225 iccmp.lpbiOutput = lpbiOutput;
226 iccmp.lpOutput = lpData;
227 iccmp.lpbiInput = lpbiInput;
228 iccmp.lpInput = lpBits;
230 iccmp.lpckid = lpckid;
231 iccmp.lpdwFlags = lpdwFlags;
232 iccmp.lFrameNum = lFrameNum;
233 iccmp.dwFrameSize = dwFrameSize;
234 iccmp.dwQuality = dwQuality;
235 iccmp.lpbiPrev = lpbiPrev;
236 iccmp.lpPrev = lpPrev;
237 seg_iccmp = MapLS(&iccmp);
238 ret = ICSendMessage16(hic, ICM_COMPRESS, seg_iccmp, sizeof(ICCOMPRESS));
239 UnMapLS(seg_iccmp);
240 return ret;
243 /***********************************************************************
244 * _ICDecompress [MSVIDEO.230]
246 DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags,
247 LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData,
248 LPBITMAPINFOHEADER lpbi, LPVOID lpBits)
250 ICDECOMPRESS icd;
251 SEGPTR segptr;
252 DWORD ret;
254 TRACE("(0x%08x,%d,%p,%p,%p,%p)\n", (DWORD) hic, dwFlags, lpbiFormat,
255 lpData, lpbi, lpBits);
257 icd.dwFlags = dwFlags;
258 icd.lpbiInput = lpbiFormat;
259 icd.lpInput = lpData;
260 icd.lpbiOutput = lpbi;
261 icd.lpOutput = lpBits;
262 icd.ckid = 0;
263 segptr = MapLS(&icd);
264 ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS));
265 UnMapLS(segptr);
266 return ret;
269 /***********************************************************************
270 * _ICDrawBegin [MSVIDEO.232]
272 DWORD VFWAPIV ICDrawBegin16(HIC16 hic, /* [in] */
273 DWORD dwFlags, /* [in] flags */
274 HPALETTE16 hpal, /* [in] palette to draw with */
275 HWND16 hwnd, /* [in] window to draw to */
276 HDC16 hdc, /* [in] HDC to draw to */
277 INT16 xDst, /* [in] destination rectangle */
278 INT16 yDst, /* [in] */
279 INT16 dxDst, /* [in] */
280 INT16 dyDst, /* [in] */
281 LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw NOTE: SEGPTR */
282 INT16 xSrc, /* [in] source rectangle */
283 INT16 ySrc, /* [in] */
284 INT16 dxSrc, /* [in] */
285 INT16 dySrc, /* [in] */
286 DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */
287 DWORD dwScale) /* [in] */
289 DWORD ret;
290 ICDRAWBEGIN16 icdb;
291 SEGPTR seg_icdb;
293 TRACE ("(0x%08x,%d,0x%08x,0x%08x,0x%08x,%u,%u,%u,%u,%p,%u,%u,%u,%u,%d,%d)\n",
294 (DWORD) hic, dwFlags, (DWORD) hpal, (DWORD) hwnd, (DWORD) hdc,
295 xDst, yDst, dxDst, dyDst, lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate,
296 dwScale);
298 icdb.dwFlags = dwFlags;
299 icdb.hpal = hpal;
300 icdb.hwnd = hwnd;
301 icdb.hdc = hdc;
302 icdb.xDst = xDst;
303 icdb.yDst = yDst;
304 icdb.dxDst = dxDst;
305 icdb.dyDst = dyDst;
306 icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */
307 icdb.xSrc = xSrc;
308 icdb.ySrc = ySrc;
309 icdb.dxSrc = dxSrc;
310 icdb.dySrc = dySrc;
311 icdb.dwRate = dwRate;
312 icdb.dwScale = dwScale;
313 seg_icdb = MapLS(&icdb);
314 ret = (DWORD) ICSendMessage16(hic, ICM_DRAW_BEGIN, seg_icdb,
315 sizeof(ICDRAWBEGIN16));
316 UnMapLS(seg_icdb);
317 return ret;
320 /***********************************************************************
321 * _ICDraw [MSVIDEO.234]
323 DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags,
324 LPVOID lpFormat, /* [???] NOTE: SEGPTR */
325 LPVOID lpData, /* [???] NOTE: SEGPTR */
326 DWORD cbData, LONG lTime)
328 DWORD ret;
329 ICDRAW icd;
330 SEGPTR seg_icd;
332 TRACE("(0x%08x,0x%08x,%p,%p,%d,%d)\n", (DWORD) hic, dwFlags,
333 lpFormat, lpData, cbData, lTime);
334 icd.dwFlags = dwFlags;
335 icd.lpFormat = lpFormat;
336 icd.lpData = lpData;
337 icd.cbData = cbData;
338 icd.lTime = lTime;
339 seg_icd = MapLS(&icd);
340 ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW));
341 UnMapLS(seg_icd);
342 return ret;
345 /***********************************************************************
346 * ICGetDisplayFormat [MSVIDEO.239]
348 HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn,
349 LPBITMAPINFOHEADER lpbiOut, INT16 depth,
350 INT16 dx, INT16 dy)
352 return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth,
353 dx, dy));
356 #define COPY(x,y) (x->y = x##16->y);
357 #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y));
359 /******************************************************************
360 * MSVIDEO_MapICDEX16To32
364 static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam)
366 LPVOID ret;
368 ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX));
369 ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam);
370 ret = icdx16;
372 COPY(icdx, dwFlags);
373 COPYPTR(icdx, lpbiSrc);
374 COPYPTR(icdx, lpSrc);
375 COPYPTR(icdx, lpbiDst);
376 COPYPTR(icdx, lpDst);
377 COPY(icdx, xDst);
378 COPY(icdx, yDst);
379 COPY(icdx, dxDst);
380 COPY(icdx, dyDst);
381 COPY(icdx, xSrc);
382 COPY(icdx, ySrc);
383 COPY(icdx, dxSrc);
384 COPY(icdx, dySrc);
386 *lParam = (DWORD)(icdx);
387 return ret;
390 /******************************************************************
391 * MSVIDEO_MapMsg16To32
395 static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2)
397 LPVOID ret = 0;
399 TRACE("Mapping %d\n", msg);
401 switch (msg)
403 case DRV_LOAD:
404 case DRV_ENABLE:
405 case DRV_CLOSE:
406 case DRV_DISABLE:
407 case DRV_FREE:
408 case ICM_ABOUT:
409 case ICM_CONFIGURE:
410 case ICM_COMPRESS_END:
411 case ICM_DECOMPRESS_END:
412 case ICM_DECOMPRESSEX_END:
413 case ICM_SETQUALITY:
414 case ICM_DRAW_START_PLAY:
415 case ICM_DRAW_STOP_PLAY:
416 case ICM_DRAW_REALIZE:
417 case ICM_DRAW_RENDERBUFFER:
418 case ICM_DRAW_END:
419 break;
420 case DRV_OPEN:
421 case ICM_GETDEFAULTQUALITY:
422 case ICM_GETQUALITY:
423 case ICM_SETSTATE:
424 case ICM_DRAW_WINDOW:
425 case ICM_GETBUFFERSWANTED:
426 *lParam1 = (DWORD)MapSL(*lParam1);
427 break;
428 case ICM_GETINFO:
430 ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO));
431 ICINFO16 *ici16;
433 ici16 = MapSL(*lParam1);
434 ret = ici16;
436 ici->dwSize = sizeof(ICINFO);
437 COPY(ici, fccType);
438 COPY(ici, fccHandler);
439 COPY(ici, dwFlags);
440 COPY(ici, dwVersion);
441 COPY(ici, dwVersionICM);
442 MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 );
443 MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 );
444 MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 );
445 *lParam1 = (DWORD)(ici);
446 *lParam2 = sizeof(ICINFO);
448 break;
449 case ICM_COMPRESS:
451 ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS));
452 ICCOMPRESS *icc16;
454 icc16 = MapSL(*lParam1);
455 ret = icc16;
457 COPY(icc, dwFlags);
458 COPYPTR(icc, lpbiOutput);
459 COPYPTR(icc, lpOutput);
460 COPYPTR(icc, lpbiInput);
461 COPYPTR(icc, lpInput);
462 COPYPTR(icc, lpckid);
463 COPYPTR(icc, lpdwFlags);
464 COPY(icc, lFrameNum);
465 COPY(icc, dwFrameSize);
466 COPY(icc, dwQuality);
467 COPYPTR(icc, lpbiPrev);
468 COPYPTR(icc, lpPrev);
470 *lParam1 = (DWORD)(icc);
471 *lParam2 = sizeof(ICCOMPRESS);
473 break;
474 case ICM_DECOMPRESS:
476 ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS));
477 ICDECOMPRESS *icd16; /* Same structure except for the pointers */
479 icd16 = MapSL(*lParam1);
480 ret = icd16;
482 COPY(icd, dwFlags);
483 COPYPTR(icd, lpbiInput);
484 COPYPTR(icd, lpInput);
485 COPYPTR(icd, lpbiOutput);
486 COPYPTR(icd, lpOutput);
487 COPY(icd, ckid);
489 *lParam1 = (DWORD)(icd);
490 *lParam2 = sizeof(ICDECOMPRESS);
492 break;
493 case ICM_COMPRESS_BEGIN:
494 case ICM_COMPRESS_GET_FORMAT:
495 case ICM_COMPRESS_GET_SIZE:
496 case ICM_COMPRESS_QUERY:
497 case ICM_DECOMPRESS_GET_FORMAT:
498 case ICM_DECOMPRESS_QUERY:
499 case ICM_DECOMPRESS_BEGIN:
500 case ICM_DECOMPRESS_SET_PALETTE:
501 case ICM_DECOMPRESS_GET_PALETTE:
502 *lParam1 = (DWORD)MapSL(*lParam1);
503 *lParam2 = (DWORD)MapSL(*lParam2);
504 break;
505 case ICM_DECOMPRESSEX_QUERY:
506 if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0))
507 WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2);
508 /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16)
509 * This is because of ICMessage(). Special case it?
511 LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID));
512 addr[0] = MSVIDEO_MapICDEX16To32(lParam1);
513 if (*lParam2)
514 addr[1] = MSVIDEO_MapICDEX16To32(lParam2);
515 else
516 addr[1] = 0;
518 ret = addr;
520 break;*/
521 case ICM_DECOMPRESSEX_BEGIN:
522 case ICM_DECOMPRESSEX:
523 ret = MSVIDEO_MapICDEX16To32(lParam1);
524 *lParam2 = sizeof(ICDECOMPRESSEX);
525 break;
526 case ICM_DRAW_BEGIN:
528 ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN));
529 ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1);
530 ret = icdb16;
532 COPY(icdb, dwFlags);
533 icdb->hpal = HPALETTE_32(icdb16->hpal);
534 icdb->hwnd = HWND_32(icdb16->hwnd);
535 icdb->hdc = HDC_32(icdb16->hdc);
536 COPY(icdb, xDst);
537 COPY(icdb, yDst);
538 COPY(icdb, dxDst);
539 COPY(icdb, dyDst);
540 COPYPTR(icdb, lpbi);
541 COPY(icdb, xSrc);
542 COPY(icdb, ySrc);
543 COPY(icdb, dxSrc);
544 COPY(icdb, dySrc);
545 COPY(icdb, dwRate);
546 COPY(icdb, dwScale);
548 *lParam1 = (DWORD)(icdb);
549 *lParam2 = sizeof(ICDRAWBEGIN);
551 break;
552 case ICM_DRAW_SUGGESTFORMAT:
554 ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST));
555 ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1);
557 ret = icds16;
559 COPY(icds, dwFlags);
560 COPYPTR(icds, lpbiIn);
561 COPYPTR(icds, lpbiSuggest);
562 COPY(icds, dxSrc);
563 COPY(icds, dySrc);
564 COPY(icds, dxDst);
565 COPY(icds, dyDst);
566 icds->hicDecompressor = HIC_32(icds16->hicDecompressor);
568 *lParam1 = (DWORD)(icds);
569 *lParam2 = sizeof(ICDRAWSUGGEST);
571 break;
572 case ICM_DRAW:
574 ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW));
575 ICDRAW *icd16 = MapSL(*lParam1);
576 ret = icd16;
578 COPY(icd, dwFlags);
579 COPYPTR(icd, lpFormat);
580 COPYPTR(icd, lpData);
581 COPY(icd, cbData);
582 COPY(icd, lTime);
584 *lParam1 = (DWORD)(icd);
585 *lParam2 = sizeof(ICDRAW);
587 break;
588 case ICM_DRAW_START:
589 case ICM_DRAW_STOP:
590 break;
591 default:
592 FIXME("%d is not yet handled. Expect a crash.\n", msg);
594 return ret;
597 #undef COPY
598 #undef COPYPTR
600 /******************************************************************
601 * MSVIDEO_UnmapMsg16To32
605 static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2)
607 TRACE("Unmapping %d\n", msg);
609 #define UNCOPY(x, y) (x##16->y = x->y);
611 switch (msg)
613 case ICM_GETINFO:
615 ICINFO *ici = (ICINFO*)(*lParam1);
616 ICINFO16 *ici16 = data16;
618 UNCOPY(ici, fccType);
619 UNCOPY(ici, fccHandler);
620 UNCOPY(ici, dwFlags);
621 UNCOPY(ici, dwVersion);
622 UNCOPY(ici, dwVersionICM);
623 WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName,
624 sizeof(ici16->szName), NULL, NULL );
625 ici16->szName[sizeof(ici16->szName)-1] = 0;
626 WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription,
627 sizeof(ici16->szDescription), NULL, NULL );
628 ici16->szDescription[sizeof(ici16->szDescription)-1] = 0;
629 /* This just gives garbage for some reason - BB
630 lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/
632 HeapFree(GetProcessHeap(), 0, ici);
634 break;
635 case ICM_DECOMPRESS_QUERY:
637 LPVOID* x = data16;
638 HeapFree(GetProcessHeap(), 0, x[0]);
639 if (x[1])
640 HeapFree(GetProcessHeap(), 0, x[1]);
642 break;*/
643 case ICM_COMPRESS:
644 case ICM_DECOMPRESS:
645 case ICM_DECOMPRESSEX_QUERY:
646 case ICM_DECOMPRESSEX_BEGIN:
647 case ICM_DECOMPRESSEX:
648 case ICM_DRAW_BEGIN:
649 case ICM_DRAW_SUGGESTFORMAT:
650 case ICM_DRAW:
651 HeapFree(GetProcessHeap(), 0, data16);
652 break;
653 default:
654 ERR("Unmapping unmapped msg %d\n", msg);
656 #undef UNCOPY
659 /***********************************************************************
660 * ICInfo [MSVIDEO.200]
662 BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo)
664 BOOL16 ret;
665 LPVOID lpv;
666 DWORD lParam = (DWORD)lpicinfo;
667 DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize;
669 /* Use the mapping functions to map the ICINFO structure */
670 lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size);
672 ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam);
674 MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size);
676 return ret;
679 /******************************************************************
680 * IC_Callback3216
684 static LRESULT CALLBACK IC_Callback3216(DWORD pfn16, HIC hic, HDRVR hdrv, UINT msg, LPARAM lp1, LPARAM lp2)
686 WORD args[8];
687 DWORD ret = 0;
689 switch (msg)
691 case DRV_OPEN:
692 lp2 = (DWORD)MapLS((void*)lp2);
693 break;
695 args[7] = HIWORD(hic);
696 args[6] = LOWORD(hic);
697 args[5] = HDRVR_16(hdrv);
698 args[4] = msg;
699 args[3] = HIWORD(lp1);
700 args[2] = LOWORD(lp1);
701 args[1] = HIWORD(lp2);
702 args[0] = LOWORD(lp2);
703 WOWCallback16Ex( pfn16, WCB16_PASCAL, sizeof(args), args, &ret );
705 switch (msg)
707 case DRV_OPEN:
708 UnMapLS(lp2);
709 break;
711 return ret;
714 #define MAX_THUNKS 32
716 #include "pshpack1.h"
717 static struct msvideo_thunk
719 BYTE popl_eax; /* popl %eax (return address) */
720 BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
721 DWORD pfn16;
722 BYTE pushl_eax; /* pushl %eax */
723 BYTE jmp; /* ljmp WDML_InvokeCallback16 */
724 DWORD callback;
725 HIC16 hIC16; /* driver's handle */
726 } *MSVIDEO_Thunks;
727 #include "poppack.h"
729 static CRITICAL_SECTION msvideo_cs;
730 static CRITICAL_SECTION_DEBUG critsect_debug =
732 0, 0, &msvideo_cs,
733 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
734 0, 0, { (DWORD_PTR)(__FILE__ ": msvideo_cs") }
736 static CRITICAL_SECTION msvideo_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
738 static struct msvideo_thunk* MSVIDEO_AddThunk(DWORD pfn16)
740 struct msvideo_thunk* thunk;
742 if (!MSVIDEO_Thunks)
744 MSVIDEO_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*MSVIDEO_Thunks), MEM_COMMIT,
745 PAGE_EXECUTE_READWRITE);
746 if (!MSVIDEO_Thunks) return NULL;
747 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
749 thunk->popl_eax = 0x58; /* popl %eax */
750 thunk->pushl_func = 0x68; /* pushl $pfn16 */
751 thunk->pfn16 = 0;
752 thunk->pushl_eax = 0x50; /* pushl %eax */
753 thunk->jmp = 0xe9; /* jmp IC_Callback3216 */
754 thunk->callback = (char *)IC_Callback3216 - (char *)(&thunk->callback + 1);
755 thunk->hIC16 = 0;
758 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
760 if (thunk->pfn16 == 0)
762 thunk->pfn16 = pfn16;
763 return thunk;
766 FIXME("Out of msvideo-thunks. Bump MAX_THUNKS\n");
767 return NULL;
770 static struct msvideo_thunk* MSVIDEO_HasThunk(HIC16 hic)
772 struct msvideo_thunk* thunk;
774 if (!MSVIDEO_Thunks)
775 return NULL;
777 for (thunk = MSVIDEO_Thunks; thunk < &MSVIDEO_Thunks[MAX_THUNKS]; thunk++)
779 if (thunk->hIC16 == hic) return thunk;
781 return NULL;
784 /***********************************************************************
785 * ICOpenFunction [MSVIDEO.206]
787 HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler)
789 HIC hic32;
790 struct msvideo_thunk* thunk;
792 EnterCriticalSection(&msvideo_cs);
793 if (!(thunk = MSVIDEO_AddThunk((DWORD)lpfnHandler)))
795 LeaveCriticalSection(&msvideo_cs);
796 return 0;
798 if ((hic32 = ICOpenFunction(fccType, fccHandler, wMode, (DRIVERPROC)thunk)))
799 thunk->hIC16 = HIC_16(hic32);
800 else
801 thunk->pfn16 = 0;
802 LeaveCriticalSection(&msvideo_cs);
803 return HIC_16(hic32);
806 /***********************************************************************
807 * ICSendMessage [MSVIDEO.205]
809 LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2)
811 LRESULT ret = ICERR_BADHANDLE;
812 struct msvideo_thunk* thunk;
814 if ((thunk = MSVIDEO_HasThunk(hic)))
816 WORD args[8];
817 DWORD result;
819 /* FIXME: original code was passing hdrv first and hic second */
820 /* but this doesn't match what IC_Callback3216 does */
821 args[7] = HIWORD(hic);
822 args[6] = LOWORD(hic);
823 args[5] = 0; /* the 32bit also sets it to NULL */
824 args[4] = msg;
825 args[3] = HIWORD(lParam1);
826 args[2] = LOWORD(lParam1);
827 args[1] = HIWORD(lParam2);
828 args[0] = LOWORD(lParam2);
829 WOWCallback16Ex( thunk->pfn16, WCB16_PASCAL, sizeof(args), args, &result );
830 ret = result;
832 else
834 /* map the message for a 32 bit infrastructure, and pass it along */
835 void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2);
837 ret = ICSendMessage(HIC_32(hic), msg, lParam1, lParam2);
838 if (data16)
839 MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2);
841 return ret;
844 /***********************************************************************
845 * ICClose [MSVIDEO.204]
847 LRESULT WINAPI ICClose16(HIC16 hic)
849 BOOL ret = ICClose(HIC_32(hic));
851 EnterCriticalSection(&msvideo_cs);
852 if (ret)
854 struct msvideo_thunk* thunk;
855 if ((thunk = MSVIDEO_HasThunk(hic)))
857 thunk->pfn16 = 0;
858 thunk->hIC16 = 0;
860 else ret = FALSE;
862 LeaveCriticalSection(&msvideo_cs);
863 return ret;
866 /***********************************************************************
867 * VideoCapDriverDescAndVer [MSVIDEO.22]
869 DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len,
870 LPSTR buf2, WORD buf2len)
872 static const char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription";
873 DWORD verhandle;
874 DWORD infosize;
875 UINT subblocklen;
876 char *s, buf[2048], fn[260];
877 LPBYTE infobuf;
878 LPVOID subblock;
879 DWORD i, cnt = 0, lRet;
880 DWORD bufLen, fnLen;
881 FILETIME lastWrite;
882 HKEY hKey;
883 BOOL found = FALSE;
885 TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len);
886 lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey);
887 if (lRet == ERROR_SUCCESS)
889 RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0);
890 for (i = 0; i < cnt; i++)
892 bufLen = sizeof(buf) / sizeof(buf[0]);
893 lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite);
894 if (lRet != ERROR_SUCCESS) continue;
895 if (strncasecmp(buf, "vid", 3)) continue;
896 if (nr--) continue;
897 fnLen = sizeof(fn);
898 lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen);
899 if (lRet == ERROR_SUCCESS) found = TRUE;
900 break;
902 RegCloseKey( hKey );
905 /* search system.ini if not found in the registry */
906 if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini"))
908 for (s = buf; *s; s += strlen(s) + 1)
910 if (strncasecmp(s, "vid", 3)) continue;
911 if (nr--) continue;
912 if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini"))
913 found = TRUE;
914 break;
918 if (!found)
920 TRACE("No more VID* entries found nr=%d\n", nr);
921 return 20;
923 infosize = GetFileVersionInfoSizeA(fn, &verhandle);
924 if (!infosize)
926 TRACE("%s has no fileversioninfo.\n", fn);
927 return 18;
929 infobuf = HeapAlloc(GetProcessHeap(), 0, infosize);
930 if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf))
932 /* Yes, two space behind : */
933 /* FIXME: test for buflen */
934 snprintf(buf2, buf2len, "Version: %d.%d.%d.%d\n",
935 ((WORD*)infobuf)[0x0f],
936 ((WORD*)infobuf)[0x0e],
937 ((WORD*)infobuf)[0x11],
938 ((WORD*)infobuf)[0x10]
940 TRACE("version of %s is %s\n", fn, buf2);
942 else
944 TRACE("GetFileVersionInfoA failed for %s.\n", fn);
945 lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/
947 /* FIXME: language problem? */
948 if (VerQueryValueA( infobuf,
949 version_info_spec,
950 &subblock,
951 &subblocklen
954 UINT copylen = min(subblocklen,buf1len-1);
955 memcpy(buf1, subblock, copylen);
956 buf1[copylen] = '\0';
957 TRACE("VQA returned %s\n", (LPCSTR)subblock);
959 else
961 TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n");
962 lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/
964 HeapFree(GetProcessHeap(), 0, infobuf);
965 return 0;
968 /**************************************************************************
969 * DllEntryPoint (MSVIDEO.3)
971 * MSVIDEO DLL entry point
974 BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds,
975 WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
977 switch (fdwReason)
979 case DLL_PROCESS_ATTACH:
980 break;
981 case DLL_PROCESS_DETACH:
982 DeleteCriticalSection(&msvideo_cs);
983 break;
985 return TRUE;
988 /***********************************************************************
989 * MCIWndRegisterClass(MSVIDEO.251)
991 BOOL CDECL MCIWndRegisterClass16(void)
993 return MCIWndRegisterClass();
996 static LRESULT (WINAPI *pMCIWndProc)(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
998 static LRESULT WINAPI MCIWndProc16(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
1000 switch (msg)
1002 case MCIWNDM_SENDSTRINGA:
1003 case MCIWNDM_SETTIMEFORMATA:
1004 lparam = (ULONG_PTR)MapSL(lparam);
1005 break;
1007 default:
1008 break;
1011 return CallWindowProcA(pMCIWndProc, hwnd, msg, wparam, lparam);
1014 /***********************************************************************
1015 * MCIWndCreate(MSVIDEO.250)
1017 HWND16 CDECL MCIWndCreate16(HWND16 parent, HINSTANCE16 hinst16,
1018 DWORD style, LPSTR file)
1020 HWND hwnd = MCIWndCreateA(HWND_32(parent), 0, style, file);
1021 if (hwnd)
1022 pMCIWndProc = (void *)SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (ULONG_PTR)MCIWndProc16);
1023 return HWND_16(hwnd);