| /* |
| * msvideo 16-bit functions |
| * |
| * Copyright 1998 Marcus Meissner |
| * Copyright 2000 Bradley Baetz |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #define COM_NO_WINDOWS_H |
| #include <stdarg.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winver.h" |
| #include "winnls.h" |
| #include "winreg.h" |
| #include "winuser.h" |
| #include "vfw16.h" |
| #include "msvideo_private.h" |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(msvideo); |
| |
| /* Drivers32 settings */ |
| #define HKLM_DRIVERS32 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32" |
| |
| /*********************************************************************** |
| * DrawDibOpen [MSVIDEO.102] |
| */ |
| HDRAWDIB16 VFWAPI DrawDibOpen16(void) |
| { |
| return HDRAWDIB_16(DrawDibOpen()); |
| } |
| |
| /*********************************************************************** |
| * DrawDibClose [MSVIDEO.103] |
| */ |
| BOOL16 VFWAPI DrawDibClose16(HDRAWDIB16 hdd) |
| { |
| return DrawDibClose(HDRAWDIB_32(hdd)); |
| } |
| |
| /************************************************************************ |
| * DrawDibBegin [MSVIDEO.104] |
| */ |
| BOOL16 VFWAPI DrawDibBegin16(HDRAWDIB16 hdd, HDC16 hdc, INT16 dxDst, |
| INT16 dyDst, LPBITMAPINFOHEADER lpbi, INT16 dxSrc, |
| INT16 dySrc, UINT16 wFlags) |
| { |
| return DrawDibBegin(HDRAWDIB_32(hdd), HDC_32(hdc), dxDst, dyDst, lpbi, |
| dxSrc, dySrc, wFlags); |
| } |
| |
| /*********************************************************************** |
| * DrawDibEnd [MSVIDEO.105] |
| */ |
| BOOL16 VFWAPI DrawDibEnd16(HDRAWDIB16 hdd) |
| { |
| return DrawDibEnd(HDRAWDIB_32(hdd)); |
| } |
| |
| /********************************************************************** |
| * DrawDibDraw [MSVIDEO.106] |
| */ |
| BOOL16 VFWAPI DrawDibDraw16(HDRAWDIB16 hdd, HDC16 hdc, INT16 xDst, INT16 yDst, |
| INT16 dxDst, INT16 dyDst, LPBITMAPINFOHEADER lpbi, |
| LPVOID lpBits, INT16 xSrc, INT16 ySrc, INT16 dxSrc, |
| INT16 dySrc, UINT16 wFlags) |
| { |
| return DrawDibDraw(HDRAWDIB_32(hdd), HDC_32(hdc), xDst, yDst, dxDst, |
| dyDst, lpbi, lpBits, xSrc, ySrc, dxSrc, dySrc, wFlags); |
| } |
| |
| /*********************************************************************** |
| * DrawDibGetPalette [MSVIDEO.108] |
| */ |
| HPALETTE16 VFWAPI DrawDibGetPalette16(HDRAWDIB16 hdd) |
| { |
| return HPALETTE_16(DrawDibGetPalette(HDRAWDIB_32(hdd))); |
| } |
| |
| /*********************************************************************** |
| * DrawDibSetPalette [MSVIDEO.110] |
| */ |
| BOOL16 VFWAPI DrawDibSetPalette16(HDRAWDIB16 hdd, HPALETTE16 hpal) |
| { |
| return DrawDibSetPalette(HDRAWDIB_32(hdd), HPALETTE_32(hpal)); |
| } |
| |
| /*********************************************************************** |
| * DrawDibRealize [MSVIDEO.112] |
| */ |
| UINT16 VFWAPI DrawDibRealize16(HDRAWDIB16 hdd, HDC16 hdc, |
| BOOL16 fBackground) |
| { |
| return (UINT16)DrawDibRealize(HDRAWDIB_32(hdd), HDC_32(hdc), fBackground); |
| } |
| |
| /************************************************************************* |
| * DrawDibStart [MSVIDEO.118] |
| */ |
| BOOL16 VFWAPI DrawDibStart16(HDRAWDIB16 hdd, DWORD rate) |
| { |
| return DrawDibStart(HDRAWDIB_32(hdd), rate); |
| } |
| |
| /************************************************************************* |
| * DrawDibStop [MSVIDEO.119] |
| */ |
| BOOL16 VFWAPI DrawDibStop16(HDRAWDIB16 hdd) |
| { |
| return DrawDibStop(HDRAWDIB_32(hdd)); |
| } |
| |
| /*********************************************************************** |
| * ICOpen [MSVIDEO.203] |
| */ |
| HIC16 VFWAPI ICOpen16(DWORD fccType, DWORD fccHandler, UINT16 wMode) |
| { |
| return HIC_16(ICOpen(fccType, fccHandler, wMode)); |
| } |
| |
| /*********************************************************************** |
| * ICClose [MSVIDEO.204] |
| */ |
| LRESULT WINAPI ICClose16(HIC16 hic) |
| { |
| return ICClose(HIC_32(hic)); |
| } |
| |
| /*********************************************************************** |
| * _ICMessage [MSVIDEO.207] |
| */ |
| LRESULT VFWAPIV ICMessage16( HIC16 hic, UINT16 msg, UINT16 cb, VA_LIST16 valist ) |
| { |
| LPWORD lpData; |
| SEGPTR segData; |
| LRESULT ret; |
| UINT16 i; |
| |
| lpData = HeapAlloc(GetProcessHeap(), 0, cb); |
| |
| TRACE("0x%08lx, %u, %u, ...)\n", (DWORD) hic, msg, cb); |
| |
| for (i = 0; i < cb / sizeof(WORD); i++) |
| { |
| lpData[i] = VA_ARG16(valist, WORD); |
| } |
| |
| segData = MapLS(lpData); |
| ret = ICSendMessage16(hic, msg, segData, (DWORD) cb); |
| UnMapLS(segData); |
| HeapFree(GetProcessHeap(), 0, lpData); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * ICGetInfo [MSVIDEO.212] |
| */ |
| LRESULT VFWAPI ICGetInfo16(HIC16 hic, ICINFO16 * picinfo, DWORD cb) |
| { |
| LRESULT ret; |
| |
| TRACE("(0x%08lx,%p,%ld)\n", (DWORD) hic, picinfo, cb); |
| ret = ICSendMessage16(hic, ICM_GETINFO, (DWORD) picinfo, cb); |
| TRACE(" -> 0x%08lx\n", ret); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * ICLocate [MSVIDEO.213] |
| */ |
| HIC16 VFWAPI ICLocate16(DWORD fccType, DWORD fccHandler, |
| LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, |
| WORD wFlags) |
| { |
| return HIC_16(ICLocate(fccType, fccHandler, lpbiIn, lpbiOut, wFlags)); |
| } |
| |
| /*********************************************************************** |
| * _ICCompress [MSVIDEO.224] |
| */ |
| DWORD VFWAPIV ICCompress16(HIC16 hic, DWORD dwFlags, |
| LPBITMAPINFOHEADER lpbiOutput, LPVOID lpData, |
| LPBITMAPINFOHEADER lpbiInput, LPVOID lpBits, |
| LPDWORD lpckid, LPDWORD lpdwFlags, |
| LONG lFrameNum, DWORD dwFrameSize, |
| DWORD dwQuality, LPBITMAPINFOHEADER lpbiPrev, |
| LPVOID lpPrev) |
| { |
| DWORD ret; |
| ICCOMPRESS iccmp; |
| SEGPTR seg_iccmp; |
| |
| TRACE("(0x%08lx,%ld,%p,%p,%p,%p,...)\n", (DWORD) hic, dwFlags, |
| lpbiOutput, lpData, lpbiInput, lpBits); |
| |
| iccmp.dwFlags = dwFlags; |
| |
| iccmp.lpbiOutput = lpbiOutput; |
| iccmp.lpOutput = lpData; |
| iccmp.lpbiInput = lpbiInput; |
| iccmp.lpInput = lpBits; |
| |
| iccmp.lpckid = lpckid; |
| iccmp.lpdwFlags = lpdwFlags; |
| iccmp.lFrameNum = lFrameNum; |
| iccmp.dwFrameSize = dwFrameSize; |
| iccmp.dwQuality = dwQuality; |
| iccmp.lpbiPrev = lpbiPrev; |
| iccmp.lpPrev = lpPrev; |
| seg_iccmp = MapLS(&iccmp); |
| ret = ICSendMessage16(hic, ICM_COMPRESS, seg_iccmp, sizeof(ICCOMPRESS)); |
| UnMapLS(seg_iccmp); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * _ICDecompress [MSVIDEO.230] |
| */ |
| DWORD VFWAPIV ICDecompress16(HIC16 hic, DWORD dwFlags, |
| LPBITMAPINFOHEADER lpbiFormat, LPVOID lpData, |
| LPBITMAPINFOHEADER lpbi, LPVOID lpBits) |
| { |
| ICDECOMPRESS icd; |
| SEGPTR segptr; |
| DWORD ret; |
| |
| TRACE("(0x%08lx,%ld,%p,%p,%p,%p)\n", (DWORD) hic, dwFlags, lpbiFormat, |
| lpData, lpbi, lpBits); |
| |
| icd.dwFlags = dwFlags; |
| icd.lpbiInput = lpbiFormat; |
| icd.lpInput = lpData; |
| icd.lpbiOutput = lpbi; |
| icd.lpOutput = lpBits; |
| icd.ckid = 0; |
| segptr = MapLS(&icd); |
| ret = ICSendMessage16(hic, ICM_DECOMPRESS, segptr, sizeof(ICDECOMPRESS)); |
| UnMapLS(segptr); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * _ICDrawBegin [MSVIDEO.232] |
| */ |
| DWORD VFWAPIV ICDrawBegin16(HIC16 hic, /* [in] */ |
| DWORD dwFlags, /* [in] flags */ |
| HPALETTE16 hpal, /* [in] palette to draw with */ |
| HWND16 hwnd, /* [in] window to draw to */ |
| HDC16 hdc, /* [in] HDC to draw to */ |
| INT16 xDst, /* [in] destination rectangle */ |
| INT16 yDst, /* [in] */ |
| INT16 dxDst, /* [in] */ |
| INT16 dyDst, /* [in] */ |
| LPBITMAPINFOHEADER lpbi, /* [in] format of frame to draw NOTE: SEGPTR */ |
| INT16 xSrc, /* [in] source rectangle */ |
| INT16 ySrc, /* [in] */ |
| INT16 dxSrc, /* [in] */ |
| INT16 dySrc, /* [in] */ |
| DWORD dwRate, /* [in] frames/second = (dwRate/dwScale) */ |
| DWORD dwScale) /* [in] */ |
| { |
| DWORD ret; |
| ICDRAWBEGIN16 icdb; |
| SEGPTR seg_icdb; |
| |
| TRACE ("(0x%08lx,%ld,0x%08lx,0x%08lx,0x%08lx,%u,%u,%u,%u,%p,%u,%u,%u,%u,%ld,%ld)\n", |
| (DWORD) hic, dwFlags, (DWORD) hpal, (DWORD) hwnd, (DWORD) hdc, |
| xDst, yDst, dxDst, dyDst, lpbi, xSrc, ySrc, dxSrc, dySrc, dwRate, |
| dwScale); |
| |
| icdb.dwFlags = dwFlags; |
| icdb.hpal = hpal; |
| icdb.hwnd = hwnd; |
| icdb.hdc = hdc; |
| icdb.xDst = xDst; |
| icdb.yDst = yDst; |
| icdb.dxDst = dxDst; |
| icdb.dyDst = dyDst; |
| icdb.lpbi = lpbi; /* Keep this as SEGPTR for the mapping code to deal with */ |
| icdb.xSrc = xSrc; |
| icdb.ySrc = ySrc; |
| icdb.dxSrc = dxSrc; |
| icdb.dySrc = dySrc; |
| icdb.dwRate = dwRate; |
| icdb.dwScale = dwScale; |
| seg_icdb = MapLS(&icdb); |
| ret = (DWORD) ICSendMessage16(hic, ICM_DRAW_BEGIN, seg_icdb, |
| sizeof(ICDRAWBEGIN16)); |
| UnMapLS(seg_icdb); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * _ICDraw [MSVIDEO.234] |
| */ |
| DWORD VFWAPIV ICDraw16(HIC16 hic, DWORD dwFlags, |
| LPVOID lpFormat, /* [???] NOTE: SEGPTR */ |
| LPVOID lpData, /* [???] NOTE: SEGPTR */ |
| DWORD cbData, LONG lTime) |
| { |
| DWORD ret; |
| ICDRAW icd; |
| SEGPTR seg_icd; |
| |
| TRACE("(0x%08lx,0x%08lx,%p,%p,%ld,%ld)\n", (DWORD) hic, dwFlags, |
| lpFormat, lpData, cbData, lTime); |
| icd.dwFlags = dwFlags; |
| icd.lpFormat = lpFormat; |
| icd.lpData = lpData; |
| icd.cbData = cbData; |
| icd.lTime = lTime; |
| seg_icd = MapLS(&icd); |
| ret = ICSendMessage16(hic, ICM_DRAW, seg_icd, sizeof(ICDRAW)); |
| UnMapLS(seg_icd); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * ICGetDisplayFormat [MSVIDEO.239] |
| */ |
| HIC16 VFWAPI ICGetDisplayFormat16(HIC16 hic, LPBITMAPINFOHEADER lpbiIn, |
| LPBITMAPINFOHEADER lpbiOut, INT16 depth, |
| INT16 dx, INT16 dy) |
| { |
| return HIC_16(ICGetDisplayFormat(HIC_32(hic), lpbiIn, lpbiOut, depth, |
| dx, dy)); |
| } |
| |
| #define COPY(x,y) (x->y = x##16->y); |
| #define COPYPTR(x,y) (x->y = MapSL((SEGPTR)x##16->y)); |
| |
| /****************************************************************** |
| * MSVIDEO_MapICDEX16To32 |
| * |
| * |
| */ |
| static LPVOID MSVIDEO_MapICDEX16To32(LPDWORD lParam) |
| { |
| LPVOID ret; |
| |
| ICDECOMPRESSEX *icdx = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESSEX)); |
| ICDECOMPRESSEX16 *icdx16 = MapSL(*lParam); |
| ret = icdx16; |
| |
| COPY(icdx, dwFlags); |
| COPYPTR(icdx, lpbiSrc); |
| COPYPTR(icdx, lpSrc); |
| COPYPTR(icdx, lpbiDst); |
| COPYPTR(icdx, lpDst); |
| COPY(icdx, xDst); |
| COPY(icdx, yDst); |
| COPY(icdx, dxDst); |
| COPY(icdx, dyDst); |
| COPY(icdx, xSrc); |
| COPY(icdx, ySrc); |
| COPY(icdx, dxSrc); |
| COPY(icdx, dySrc); |
| |
| *lParam = (DWORD)(icdx); |
| return ret; |
| } |
| |
| /****************************************************************** |
| * MSVIDEO_MapMsg16To32 |
| * |
| * |
| */ |
| static LPVOID MSVIDEO_MapMsg16To32(UINT msg, LPDWORD lParam1, LPDWORD lParam2) |
| { |
| LPVOID ret = 0; |
| |
| TRACE("Mapping %d\n", msg); |
| |
| switch (msg) |
| { |
| case DRV_LOAD: |
| case DRV_ENABLE: |
| case DRV_CLOSE: |
| case DRV_DISABLE: |
| case DRV_FREE: |
| case ICM_ABOUT: |
| case ICM_CONFIGURE: |
| case ICM_COMPRESS_END: |
| case ICM_DECOMPRESS_END: |
| case ICM_DECOMPRESSEX_END: |
| case ICM_SETQUALITY: |
| case ICM_DRAW_START_PLAY: |
| case ICM_DRAW_STOP_PLAY: |
| case ICM_DRAW_REALIZE: |
| case ICM_DRAW_RENDERBUFFER: |
| case ICM_DRAW_END: |
| break; |
| case DRV_OPEN: |
| case ICM_GETDEFAULTQUALITY: |
| case ICM_GETQUALITY: |
| case ICM_SETSTATE: |
| case ICM_DRAW_WINDOW: |
| case ICM_GETBUFFERSWANTED: |
| *lParam1 = (DWORD)MapSL(*lParam1); |
| break; |
| case ICM_GETINFO: |
| { |
| ICINFO *ici = HeapAlloc(GetProcessHeap(), 0, sizeof(ICINFO)); |
| ICINFO16 *ici16; |
| |
| ici16 = MapSL(*lParam1); |
| ret = ici16; |
| |
| ici->dwSize = sizeof(ICINFO); |
| COPY(ici, fccType); |
| COPY(ici, fccHandler); |
| COPY(ici, dwFlags); |
| COPY(ici, dwVersion); |
| COPY(ici, dwVersionICM); |
| MultiByteToWideChar( CP_ACP, 0, ici16->szName, -1, ici->szName, 16 ); |
| MultiByteToWideChar( CP_ACP, 0, ici16->szDescription, -1, ici->szDescription, 128 ); |
| MultiByteToWideChar( CP_ACP, 0, ici16->szDriver, -1, ici->szDriver, 128 ); |
| *lParam1 = (DWORD)(ici); |
| *lParam2 = sizeof(ICINFO); |
| } |
| break; |
| case ICM_COMPRESS: |
| { |
| ICCOMPRESS *icc = HeapAlloc(GetProcessHeap(), 0, sizeof(ICCOMPRESS)); |
| ICCOMPRESS *icc16; |
| |
| icc16 = MapSL(*lParam1); |
| ret = icc16; |
| |
| COPY(icc, dwFlags); |
| COPYPTR(icc, lpbiOutput); |
| COPYPTR(icc, lpOutput); |
| COPYPTR(icc, lpbiInput); |
| COPYPTR(icc, lpInput); |
| COPYPTR(icc, lpckid); |
| COPYPTR(icc, lpdwFlags); |
| COPY(icc, lFrameNum); |
| COPY(icc, dwFrameSize); |
| COPY(icc, dwQuality); |
| COPYPTR(icc, lpbiPrev); |
| COPYPTR(icc, lpPrev); |
| |
| *lParam1 = (DWORD)(icc); |
| *lParam2 = sizeof(ICCOMPRESS); |
| } |
| break; |
| case ICM_DECOMPRESS: |
| { |
| ICDECOMPRESS *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDECOMPRESS)); |
| ICDECOMPRESS *icd16; /* Same structure except for the pointers */ |
| |
| icd16 = MapSL(*lParam1); |
| ret = icd16; |
| |
| COPY(icd, dwFlags); |
| COPYPTR(icd, lpbiInput); |
| COPYPTR(icd, lpInput); |
| COPYPTR(icd, lpbiOutput); |
| COPYPTR(icd, lpOutput); |
| COPY(icd, ckid); |
| |
| *lParam1 = (DWORD)(icd); |
| *lParam2 = sizeof(ICDECOMPRESS); |
| } |
| break; |
| case ICM_COMPRESS_BEGIN: |
| case ICM_COMPRESS_GET_FORMAT: |
| case ICM_COMPRESS_GET_SIZE: |
| case ICM_COMPRESS_QUERY: |
| case ICM_DECOMPRESS_GET_FORMAT: |
| case ICM_DECOMPRESS_QUERY: |
| case ICM_DECOMPRESS_BEGIN: |
| case ICM_DECOMPRESS_SET_PALETTE: |
| case ICM_DECOMPRESS_GET_PALETTE: |
| *lParam1 = (DWORD)MapSL(*lParam1); |
| *lParam2 = (DWORD)MapSL(*lParam2); |
| break; |
| case ICM_DECOMPRESSEX_QUERY: |
| if ((*lParam2 != sizeof(ICDECOMPRESSEX16)) && (*lParam2 != 0)) |
| WARN("*lParam2 has unknown value %p\n", (ICDECOMPRESSEX16*)*lParam2); |
| /* FIXME: *lParm2 is meant to be 0 or an ICDECOMPRESSEX16*, but is sizeof(ICDECOMRPESSEX16) |
| * This is because of ICMessage(). Special case it? |
| { |
| LPVOID* addr = HeapAlloc(GetProcessHeap(), 0, 2*sizeof(LPVOID)); |
| addr[0] = MSVIDEO_MapICDEX16To32(lParam1); |
| if (*lParam2) |
| addr[1] = MSVIDEO_MapICDEX16To32(lParam2); |
| else |
| addr[1] = 0; |
| |
| ret = addr; |
| } |
| break;*/ |
| case ICM_DECOMPRESSEX_BEGIN: |
| case ICM_DECOMPRESSEX: |
| ret = MSVIDEO_MapICDEX16To32(lParam1); |
| *lParam2 = sizeof(ICDECOMPRESSEX); |
| break; |
| case ICM_DRAW_BEGIN: |
| { |
| ICDRAWBEGIN *icdb = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWBEGIN)); |
| ICDRAWBEGIN16 *icdb16 = MapSL(*lParam1); |
| ret = icdb16; |
| |
| COPY(icdb, dwFlags); |
| icdb->hpal = HPALETTE_32(icdb16->hpal); |
| icdb->hwnd = HWND_32(icdb16->hwnd); |
| icdb->hdc = HDC_32(icdb16->hdc); |
| COPY(icdb, xDst); |
| COPY(icdb, yDst); |
| COPY(icdb, dxDst); |
| COPY(icdb, dyDst); |
| COPYPTR(icdb, lpbi); |
| COPY(icdb, xSrc); |
| COPY(icdb, ySrc); |
| COPY(icdb, dxSrc); |
| COPY(icdb, dySrc); |
| COPY(icdb, dwRate); |
| COPY(icdb, dwScale); |
| |
| *lParam1 = (DWORD)(icdb); |
| *lParam2 = sizeof(ICDRAWBEGIN); |
| } |
| break; |
| case ICM_DRAW_SUGGESTFORMAT: |
| { |
| ICDRAWSUGGEST *icds = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAWSUGGEST)); |
| ICDRAWSUGGEST16 *icds16 = MapSL(*lParam1); |
| |
| ret = icds16; |
| |
| COPY(icds, dwFlags); |
| COPYPTR(icds, lpbiIn); |
| COPYPTR(icds, lpbiSuggest); |
| COPY(icds, dxSrc); |
| COPY(icds, dySrc); |
| COPY(icds, dxDst); |
| COPY(icds, dyDst); |
| icds->hicDecompressor = HIC_32(icds16->hicDecompressor); |
| |
| *lParam1 = (DWORD)(icds); |
| *lParam2 = sizeof(ICDRAWSUGGEST); |
| } |
| break; |
| case ICM_DRAW: |
| { |
| ICDRAW *icd = HeapAlloc(GetProcessHeap(), 0, sizeof(ICDRAW)); |
| ICDRAW *icd16 = MapSL(*lParam1); |
| ret = icd16; |
| |
| COPY(icd, dwFlags); |
| COPYPTR(icd, lpFormat); |
| COPYPTR(icd, lpData); |
| COPY(icd, cbData); |
| COPY(icd, lTime); |
| |
| *lParam1 = (DWORD)(icd); |
| *lParam2 = sizeof(ICDRAW); |
| } |
| break; |
| case ICM_DRAW_START: |
| case ICM_DRAW_STOP: |
| break; |
| default: |
| FIXME("%d is not yet handled. Expect a crash.\n", msg); |
| } |
| return ret; |
| } |
| |
| #undef COPY |
| #undef COPYPTR |
| |
| /****************************************************************** |
| * MSVIDEO_UnmapMsg16To32 |
| * |
| * |
| */ |
| static void MSVIDEO_UnmapMsg16To32(UINT msg, LPVOID data16, LPDWORD lParam1, LPDWORD lParam2) |
| { |
| TRACE("Unmapping %d\n", msg); |
| |
| #define UNCOPY(x, y) (x##16->y = x->y); |
| |
| switch (msg) |
| { |
| case ICM_GETINFO: |
| { |
| ICINFO *ici = (ICINFO*)(*lParam1); |
| ICINFO16 *ici16 = (ICINFO16*)data16; |
| |
| UNCOPY(ici, fccType); |
| UNCOPY(ici, fccHandler); |
| UNCOPY(ici, dwFlags); |
| UNCOPY(ici, dwVersion); |
| UNCOPY(ici, dwVersionICM); |
| WideCharToMultiByte( CP_ACP, 0, ici->szName, -1, ici16->szName, |
| sizeof(ici16->szName), NULL, NULL ); |
| ici16->szName[sizeof(ici16->szName)-1] = 0; |
| WideCharToMultiByte( CP_ACP, 0, ici->szDescription, -1, ici16->szDescription, |
| sizeof(ici16->szDescription), NULL, NULL ); |
| ici16->szDescription[sizeof(ici16->szDescription)-1] = 0; |
| /* This just gives garbage for some reason - BB |
| lstrcpynWtoA(ici16->szDriver, ici->szDriver, 128);*/ |
| |
| HeapFree(GetProcessHeap(), 0, ici); |
| } |
| break; |
| case ICM_DECOMPRESS_QUERY: |
| /*{ |
| LPVOID* x = data16; |
| HeapFree(GetProcessHeap(), 0, x[0]); |
| if (x[1]) |
| HeapFree(GetProcessHeap(), 0, x[1]); |
| } |
| break;*/ |
| case ICM_COMPRESS: |
| case ICM_DECOMPRESS: |
| case ICM_DECOMPRESSEX_QUERY: |
| case ICM_DECOMPRESSEX_BEGIN: |
| case ICM_DECOMPRESSEX: |
| case ICM_DRAW_BEGIN: |
| case ICM_DRAW_SUGGESTFORMAT: |
| case ICM_DRAW: |
| HeapFree(GetProcessHeap(), 0, data16); |
| break; |
| default: |
| ERR("Unmapping unmapped msg %d\n", msg); |
| } |
| #undef UNCOPY |
| } |
| |
| /*********************************************************************** |
| * ICInfo [MSVIDEO.200] |
| */ |
| BOOL16 VFWAPI ICInfo16(DWORD fccType, DWORD fccHandler, ICINFO16 *lpicinfo) |
| { |
| BOOL16 ret; |
| LPVOID lpv; |
| DWORD lParam = (DWORD)lpicinfo; |
| DWORD size = ((ICINFO*)(MapSL((SEGPTR)lpicinfo)))->dwSize; |
| |
| /* Use the mapping functions to map the ICINFO structure */ |
| lpv = MSVIDEO_MapMsg16To32(ICM_GETINFO, &lParam, &size); |
| |
| ret = ICInfo(fccType, fccHandler, (ICINFO*)lParam); |
| |
| MSVIDEO_UnmapMsg16To32(ICM_GETINFO, lpv, &lParam, &size); |
| |
| return ret; |
| } |
| |
| /****************************************************************** |
| * IC_Callback3216 |
| * |
| * |
| */ |
| static LRESULT CALLBACK IC_Callback3216(HIC hic, HDRVR hdrv, UINT msg, DWORD lp1, DWORD lp2) |
| { |
| WINE_HIC* whic; |
| WORD args[8]; |
| |
| whic = MSVIDEO_GetHicPtr(hic); |
| if (whic) |
| { |
| DWORD ret = 0; |
| switch (msg) |
| { |
| case DRV_OPEN: |
| lp2 = (DWORD)MapLS((void*)lp2); |
| break; |
| } |
| args[7] = HIWORD(hic); |
| args[6] = LOWORD(hic); |
| args[5] = HDRVR_16(whic->hdrv); |
| args[4] = msg; |
| args[3] = HIWORD(lp1); |
| args[2] = LOWORD(lp1); |
| args[1] = HIWORD(lp2); |
| args[0] = LOWORD(lp2); |
| WOWCallback16Ex( (DWORD)whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &ret ); |
| |
| switch (msg) |
| { |
| case DRV_OPEN: |
| UnMapLS(lp2); |
| break; |
| } |
| return ret; |
| } |
| else return ICERR_BADHANDLE; |
| } |
| |
| /*********************************************************************** |
| * ICOpenFunction [MSVIDEO.206] |
| */ |
| HIC16 VFWAPI ICOpenFunction16(DWORD fccType, DWORD fccHandler, UINT16 wMode, FARPROC16 lpfnHandler) |
| { |
| HIC hic32; |
| |
| hic32 = MSVIDEO_OpenFunction(fccType, fccHandler, wMode, |
| (DRIVERPROC)IC_Callback3216, (DWORD)lpfnHandler); |
| return HIC_16(hic32); |
| } |
| |
| /*********************************************************************** |
| * ICSendMessage [MSVIDEO.205] |
| */ |
| LRESULT VFWAPI ICSendMessage16(HIC16 hic, UINT16 msg, DWORD lParam1, DWORD lParam2) |
| { |
| LRESULT ret = ICERR_BADHANDLE; |
| WINE_HIC* whic; |
| |
| whic = MSVIDEO_GetHicPtr(HIC_32(hic)); |
| if (whic) |
| { |
| /* we've got a 16 bit driver proc... call it directly */ |
| if (whic->driverproc16) |
| { |
| WORD args[8]; |
| DWORD result; |
| |
| /* FIXME: original code was passing hdrv first and hic second */ |
| /* but this doesn't match what IC_Callback3216 does */ |
| args[7] = HIWORD(hic); |
| args[6] = LOWORD(hic); |
| args[5] = HDRVR_16(whic->hdrv); |
| args[4] = msg; |
| args[3] = HIWORD(lParam1); |
| args[2] = LOWORD(lParam1); |
| args[1] = HIWORD(lParam2); |
| args[0] = LOWORD(lParam2); |
| WOWCallback16Ex( (DWORD)whic->driverproc16, WCB16_PASCAL, sizeof(args), args, &result ); |
| ret = result; |
| } |
| else |
| { |
| /* map the message for a 32 bit infrastructure, and pass it along */ |
| void* data16 = MSVIDEO_MapMsg16To32(msg, &lParam1, &lParam2); |
| |
| ret = MSVIDEO_SendMessage(whic, msg, lParam1, lParam2); |
| if (data16) |
| MSVIDEO_UnmapMsg16To32(msg, data16, &lParam1, &lParam2); |
| } |
| } |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * VideoCapDriverDescAndVer [MSVIDEO.22] |
| */ |
| DWORD WINAPI VideoCapDriverDescAndVer16(WORD nr, LPSTR buf1, WORD buf1len, |
| LPSTR buf2, WORD buf2len) |
| { |
| DWORD verhandle; |
| DWORD infosize; |
| UINT subblocklen; |
| char *s, buf[2048], fn[260]; |
| static char version_info_spec[] = "\\StringFileInfo\\040904E4\\FileDescription"; |
| LPBYTE infobuf; |
| LPVOID subblock; |
| DWORD i, cnt = 0, lRet; |
| DWORD bufLen, fnLen; |
| FILETIME lastWrite; |
| HKEY hKey; |
| BOOL found = FALSE; |
| |
| TRACE("(%d,%p,%d,%p,%d)\n", nr, buf1, buf1len, buf2, buf2len); |
| lRet = RegOpenKeyExA(HKEY_LOCAL_MACHINE, HKLM_DRIVERS32, 0, KEY_QUERY_VALUE, &hKey); |
| if (lRet == ERROR_SUCCESS) |
| { |
| RegQueryInfoKeyA( hKey, 0, 0, 0, &cnt, 0, 0, 0, 0, 0, 0, 0); |
| for (i = 0; i < cnt; i++) |
| { |
| bufLen = sizeof(buf) / sizeof(buf[0]); |
| lRet = RegEnumKeyExA(hKey, i, buf, &bufLen, 0, 0, 0, &lastWrite); |
| if (lRet != ERROR_SUCCESS) continue; |
| if (strncasecmp(buf, "vid", 3)) continue; |
| if (nr--) continue; |
| fnLen = sizeof(fn); |
| lRet = RegQueryValueExA(hKey, buf, 0, 0, (LPBYTE)fn, &fnLen); |
| if (lRet == ERROR_SUCCESS) found = TRUE; |
| break; |
| } |
| RegCloseKey( hKey ); |
| } |
| |
| /* search system.ini if not found in the registry */ |
| if (!found && GetPrivateProfileStringA("drivers32", NULL, NULL, buf, sizeof(buf), "system.ini")) |
| { |
| for (s = buf; *s; s += strlen(s) + 1) |
| { |
| if (strncasecmp(s, "vid", 3)) continue; |
| if (nr--) continue; |
| if (GetPrivateProfileStringA("drivers32", s, NULL, fn, sizeof(fn), "system.ini")) |
| found = TRUE; |
| break; |
| } |
| } |
| |
| if (nr || !found) |
| { |
| TRACE("No more VID* entries found nr=%d\n", nr); |
| return 20; |
| } |
| infosize = GetFileVersionInfoSizeA(fn, &verhandle); |
| if (!infosize) |
| { |
| TRACE("%s has no fileversioninfo.\n", fn); |
| return 18; |
| } |
| infobuf = HeapAlloc(GetProcessHeap(), 0, infosize); |
| if (GetFileVersionInfoA(fn, verhandle, infosize, infobuf)) |
| { |
| /* Yes, two space behind : */ |
| /* FIXME: test for buflen */ |
| snprintf(buf2, buf2len, "Version: %d.%d.%d.%d\n", |
| ((WORD*)infobuf)[0x0f], |
| ((WORD*)infobuf)[0x0e], |
| ((WORD*)infobuf)[0x11], |
| ((WORD*)infobuf)[0x10] |
| ); |
| TRACE("version of %s is %s\n", fn, buf2); |
| } |
| else |
| { |
| TRACE("GetFileVersionInfoA failed for %s.\n", fn); |
| lstrcpynA(buf2, fn, buf2len); /* msvideo.dll appears to copy fn*/ |
| } |
| /* FIXME: language problem? */ |
| if (VerQueryValueA( infobuf, |
| version_info_spec, |
| &subblock, |
| &subblocklen |
| )) |
| { |
| UINT copylen = min(subblocklen,buf1len-1); |
| memcpy(buf1, subblock, copylen); |
| buf1[copylen] = '\0'; |
| TRACE("VQA returned %s\n", (LPCSTR)subblock); |
| } |
| else |
| { |
| TRACE("VQA did not return on query \\StringFileInfo\\040904E4\\FileDescription?\n"); |
| lstrcpynA(buf1, fn, buf1len); /* msvideo.dll appears to copy fn*/ |
| } |
| HeapFree(GetProcessHeap(), 0, infobuf); |
| return 0; |
| } |
| |
| /****************************************************************** |
| * IC_CallTo16 |
| * |
| * |
| */ |
| static LRESULT CALLBACK IC_CallTo16(HDRVR hdrv, HIC hic, UINT msg, LPARAM lp1, LPARAM lp2) |
| { |
| #if 0 |
| WINE_HIC* whic = IC_GetPtr(hic); |
| LRESULT ret = 0; |
| |
| |
| if (whic->driverproc) |
| { |
| ret = whic->driverproc(hic, whic->hdrv, msg, lParam1, lParam2); |
| } |
| else |
| { |
| ret = SendDriverMessage(whic->hdrv, msg, lParam1, lParam2); |
| } |
| #else |
| FIXME("No 32=>16 conversion yet\n"); |
| #endif |
| return 0; |
| } |
| |
| /************************************************************************** |
| * DllEntryPoint (MSVIDEO.3) |
| * |
| * MSVIDEO DLL entry point |
| * |
| */ |
| BOOL WINAPI VIDEO_LibMain(DWORD fdwReason, HINSTANCE hinstDLL, WORD ds, |
| WORD wHeapSize, DWORD dwReserved1, WORD wReserved2) |
| { |
| switch (fdwReason) |
| { |
| case DLL_PROCESS_ATTACH: |
| /* hook in our 16 bit management functions */ |
| pFnCallTo16 = IC_CallTo16; |
| break; |
| case DLL_PROCESS_DETACH: |
| /* remove our 16 bit management functions */ |
| pFnCallTo16 = NULL; |
| break; |
| case DLL_THREAD_ATTACH: |
| case DLL_THREAD_DETACH: |
| break; |
| } |
| return TRUE; |
| } |