Fixed a silly VGA-emulation palette bug.
[wine/multimedia.git] / multimedia / msvideo.c
blob79a3acf90dfebfe901d0072e12395332231f05e3
1 /*
2 * Copyright 1998 Marcus Meissner
3 */
4 #include <stdio.h>
5 #include <strings.h>
7 #include "winbase.h"
8 #include "winuser.h"
9 #include "wingdi.h"
10 #include "vfw.h"
11 #include "wine/winestring.h"
12 #include "driver.h"
13 #include "debug.h"
15 /****************************************************************************
16 * VideoForWindowsVersion [MSVFW.2][MSVIDEO.2]
17 * Returns the version in major.minor form.
18 * In Windows95 this returns 0x040003b6 (4.950)
20 DWORD WINAPI
21 VideoForWindowsVersion(void) {
22 return 0x040003B6; /* 4.950 */
25 /* system.ini: [drivers] */
27 /**************************************************************************
28 * ICInfo [MSVFW.33]
29 * Get information about an installable compressor. Return TRUE if there
30 * is one.
32 BOOL WINAPI
33 ICInfo(
34 DWORD fccType, /* [in] type of compressor ('vidc') */
35 DWORD fccHandler, /* [in] <n>th compressor */
36 ICINFO *lpicinfo /* [out] information about compressor */
37 ) {
38 char type[5],buf[2000];
40 memcpy(type,&fccType,4);type[4]=0;
41 TRACE(msvideo,"(%s,%ld,%p).\n",type,fccHandler,lpicinfo);
42 /* does OpenDriver/CloseDriver */
43 lpicinfo->dwSize = sizeof(ICINFO);
44 lpicinfo->fccType = fccType;
45 lpicinfo->dwFlags = 0;
46 if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
47 char *s = buf;
48 while (*s) {
49 if (!lstrncmpiA(type,s,4)) {
50 if(!fccHandler--) {
51 lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
52 return TRUE;
55 s=s+lstrlenA(s)+1; /* either next char or \0 */
58 return FALSE;
61 /**************************************************************************
62 * ICOpen [MSVFW.37]
63 * Opens an installable compressor. Return special handle.
65 HIC WINAPI
66 ICOpen(DWORD fccType,DWORD fccHandler,UINT wMode) {
67 char type[5],handler[5],codecname[20];
68 ICOPEN icopen;
69 HDRVR hdrv;
70 WINE_HIC *whic;
72 memcpy(type,&fccType,4);type[4]=0;
73 memcpy(handler,&fccHandler,4);handler[4]=0;
74 TRACE(msvideo,"(%s,%s,0x%08lx)\n",type,handler,(DWORD)wMode);
75 sprintf(codecname,"%s.%s",type,handler);
77 /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
78 * same layout as ICOPEN
80 icopen.fccType = fccType;
81 icopen.fccHandler = fccHandler;
82 icopen.dwSize = sizeof(ICOPEN);
83 icopen.dwFlags = wMode;
84 /* FIXME: do we need to fill out the rest too? */
85 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
86 if (!hdrv) {
87 if (!strcasecmp(type,"vids")) {
88 sprintf(codecname,"vidc.%s",handler);
89 fccType = mmioFOURCC('v','i','d','c');
91 hdrv=OpenDriverA(codecname,"drivers32",(LPARAM)&icopen);
92 if (!hdrv)
93 return 0;
95 whic = HeapAlloc(GetProcessHeap(),0,sizeof(WINE_HIC));
96 whic->hdrv = hdrv;
97 whic->driverproc= NULL;
98 whic->private = ICSendMessage((HIC)whic,DRV_OPEN,0,(LPARAM)&icopen);
99 return (HIC)whic;
101 HIC VFWAPI ICOpenFunction(DWORD fccType, DWORD fccHandler, UINT wMode,
102 FARPROC lpfnHandler) {
103 char type[5],handler[5];
104 HIC hic;
105 WINE_HIC *whic;
107 memcpy(type,&fccType,4);type[4]=0;
108 memcpy(handler,&fccHandler,4);handler[4]=0;
109 FIXME(msvideo,"(%s,%s,%d,%p), stub!\n",type,handler,wMode,lpfnHandler);
110 hic = ICOpen(fccType,fccHandler,wMode);
111 if (!hic)
112 return hic;
113 whic = (WINE_HIC*)hic;
114 whic->driverproc = lpfnHandler;
115 return hic;
119 LRESULT WINAPI
120 ICGetInfo(HIC hic,ICINFO *picinfo,DWORD cb) {
121 LRESULT ret;
123 TRACE(msvideo,"(0x%08lx,%p,%ld)\n",(DWORD)hic,picinfo,cb);
124 ret = ICSendMessage(hic,ICM_GETINFO,(DWORD)picinfo,cb);
125 TRACE(msvideo," -> 0x%08lx\n",ret);
126 return ret;
129 HIC VFWAPI
130 ICLocate(
131 DWORD fccType, DWORD fccHandler, LPBITMAPINFOHEADER lpbiIn,
132 LPBITMAPINFOHEADER lpbiOut, WORD wMode
134 char type[5],handler[5];
135 HIC hic;
136 DWORD querymsg;
138 switch (wMode) {
139 case ICMODE_FASTCOMPRESS:
140 case ICMODE_COMPRESS:
141 querymsg = ICM_COMPRESS_QUERY;
142 break;
143 case ICMODE_DECOMPRESS:
144 case ICMODE_FASTDECOMPRESS:
145 querymsg = ICM_DECOMPRESS_QUERY;
146 break;
147 case ICMODE_DRAW:
148 querymsg = ICM_DRAW_QUERY;
149 break;
150 default:
151 FIXME(msvideo,"Unknown mode (%d)\n",wMode);
152 return 0;
155 /* Easy case: handler/type match, we just fire a query and return */
156 hic = ICOpen(fccType,fccHandler,wMode);
157 if (hic) {
158 if (!ICSendMessage(hic,querymsg,(DWORD)lpbiIn,(DWORD)lpbiOut))
159 return hic;
160 ICClose(hic);
162 type[4]='\0';memcpy(type,&fccType,4);
163 handler[4]='\0';memcpy(handler,&fccHandler,4);
164 if (fccType==streamtypeVIDEO) {
165 hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
166 if (hic)
167 return hic;
169 FIXME(msvideo,"(%s,%s,%p,%p,0x%04x),unhandled!\n",type,handler,lpbiIn,lpbiOut,wMode);
170 return 0;
173 HIC VFWAPI ICGetDisplayFormat(
174 HIC hic,LPBITMAPINFOHEADER lpbiIn,LPBITMAPINFOHEADER lpbiOut,
175 INT depth,INT dx,INT dy
177 HIC tmphic = hic;
178 LRESULT lres;
180 FIXME(msvideo,"(0x%08lx,%p,%p,%d,%d,%d),stub!\n",(DWORD)hic,lpbiIn,lpbiOut,depth,dx,dy);
181 if (!tmphic) {
182 tmphic=ICLocate(ICTYPE_VIDEO,0,lpbiIn,NULL,ICMODE_DECOMPRESS);
183 if (!tmphic)
184 return tmphic;
186 if ((dy == lpbiIn->biHeight) || (dx == lpbiIn->biWidth))
187 dy = dx = 0; /* no resize needed */
188 /* Can we decompress it ? */
189 lres = ICDecompressQuery(tmphic,lpbiIn,NULL);
190 if (lres)
191 goto errout; /* no, sorry */
192 ICDecompressGetFormat(hic,lpbiIn,lpbiOut);
193 *lpbiOut=*lpbiIn;
194 lpbiOut->biCompression = 0;
195 lpbiOut->biSize = sizeof(*lpbiOut);
196 if (!depth) {
197 HDC hdc;
199 hdc = GetDC(0);
200 depth = GetDeviceCaps(hdc,12)*GetDeviceCaps(hdc,14);
201 ReleaseDC(0,hdc);
202 if (depth==15) depth = 16;
203 if (depth<8) depth = 8;
204 /* more constraints and tests */
206 if (lpbiIn->biBitCount == 8)
207 depth = 8;
209 return hic;
210 errout:
211 if (hic!=tmphic)
212 ICClose(tmphic);
213 return 0;
216 DWORD VFWAPIV
217 ICCompress(
218 HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiOutput,LPVOID lpData,
219 LPBITMAPINFOHEADER lpbiInput,LPVOID lpBits,LPDWORD lpckid,
220 LPDWORD lpdwFlags,LONG lFrameNum,DWORD dwFrameSize,DWORD dwQuality,
221 LPBITMAPINFOHEADER lpbiPrev,LPVOID lpPrev
223 ICCOMPRESS iccmp;
225 iccmp.dwFlags = dwFlags;
227 iccmp.lpbiOutput = lpbiOutput;
228 iccmp.lpOutput = lpData;
229 iccmp.lpbiInput = lpbiInput;
230 iccmp.lpInput = lpBits;
232 iccmp.lpckid = lpckid;
233 iccmp.lpdwFlags = lpdwFlags;
234 iccmp.lFrameNum = lFrameNum;
235 iccmp.dwFrameSize = dwFrameSize;
236 iccmp.dwQuality = dwQuality;
237 iccmp.lpbiPrev = lpbiPrev;
238 iccmp.lpPrev = lpPrev;
239 return ICSendMessage(hic,ICM_COMPRESS,(LPARAM)&iccmp,sizeof(iccmp));
242 DWORD VFWAPIV
243 ICDecompress(HIC hic,DWORD dwFlags,LPBITMAPINFOHEADER lpbiFormat,LPVOID lpData,LPBITMAPINFOHEADER lpbi,LPVOID lpBits) {
244 ICDECOMPRESS icd;
246 icd.dwFlags = dwFlags;
247 icd.lpbiInput = lpbiFormat;
248 icd.lpInput = lpData;
250 icd.lpbiOutput = lpbi;
251 icd.lpOutput = lpBits;
252 icd.ckid = 0;
253 return ICSendMessage(hic,ICM_DECOMPRESS,(LPARAM)&icd,sizeof(icd));
256 LRESULT VFWAPI
257 ICSendMessage(HIC hic,UINT msg,DWORD lParam1,DWORD lParam2) {
258 LRESULT ret;
259 WINE_HIC *whic = (WINE_HIC*)hic;
261 #define XX(x) case x: TRACE(msvideo,"(0x%08lx,"#x",0x%08lx,0x%08lx)\n",(DWORD)hic,lParam1,lParam2);break;
263 switch (msg) {
264 XX(ICM_ABOUT)
265 XX(ICM_GETINFO)
266 XX(ICM_COMPRESS_FRAMES_INFO)
267 XX(ICM_COMPRESS_GET_FORMAT)
268 XX(ICM_COMPRESS_GET_SIZE)
269 XX(ICM_COMPRESS_QUERY)
270 XX(ICM_COMPRESS_BEGIN)
271 XX(ICM_COMPRESS)
272 XX(ICM_COMPRESS_END)
273 XX(ICM_DECOMPRESS_GET_FORMAT)
274 XX(ICM_DECOMPRESS_QUERY)
275 XX(ICM_DECOMPRESS_BEGIN)
276 XX(ICM_DECOMPRESS)
277 XX(ICM_DECOMPRESS_END)
278 XX(ICM_DECOMPRESS_SET_PALETTE)
279 XX(ICM_DECOMPRESS_GET_PALETTE)
280 XX(ICM_DRAW_QUERY)
281 XX(ICM_DRAW_BEGIN)
282 XX(ICM_DRAW_GET_PALETTE)
283 XX(ICM_DRAW_START)
284 XX(ICM_DRAW_STOP)
285 XX(ICM_DRAW_END)
286 XX(ICM_DRAW_GETTIME)
287 XX(ICM_DRAW)
288 XX(ICM_DRAW_WINDOW)
289 XX(ICM_DRAW_SETTIME)
290 XX(ICM_DRAW_REALIZE)
291 XX(ICM_DRAW_FLUSH)
292 XX(ICM_DRAW_RENDERBUFFER)
293 XX(ICM_DRAW_START_PLAY)
294 XX(ICM_DRAW_STOP_PLAY)
295 XX(ICM_DRAW_SUGGESTFORMAT)
296 XX(ICM_DRAW_CHANGEPALETTE)
297 XX(ICM_GETBUFFERSWANTED)
298 XX(ICM_GETDEFAULTKEYFRAMERATE)
299 XX(ICM_DECOMPRESSEX_BEGIN)
300 XX(ICM_DECOMPRESSEX_QUERY)
301 XX(ICM_DECOMPRESSEX)
302 XX(ICM_DECOMPRESSEX_END)
303 XX(ICM_SET_STATUS_PROC)
304 default:
305 FIXME(msvideo,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2);
307 #if 0
308 if (whic->driverproc) {
309 FIXME(msvideo,"(0x%08lx,0x%08lx,0x%08lx,0x%08lx), calling %p\n",(DWORD)hic,(DWORD)msg,lParam1,lParam2,whic->driverproc);
310 ret = whic->driverproc(whic->hdrv,1,msg,lParam1,lParam2);
311 } else
312 #endif
313 ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
314 TRACE(msvideo," -> 0x%08lx\n",ret);
315 return ret;
318 DWORD VFWAPIV ICDrawBegin(
319 HIC hic,
320 DWORD dwFlags,/* flags */
321 HPALETTE hpal, /* palette to draw with */
322 HWND hwnd, /* window to draw to */
323 HDC hdc, /* HDC to draw to */
324 INT xDst, /* destination rectangle */
325 INT yDst,
326 INT dxDst,
327 INT dyDst,
328 LPBITMAPINFOHEADER lpbi, /* format of frame to draw */
329 INT xSrc, /* source rectangle */
330 INT ySrc,
331 INT dxSrc,
332 INT dySrc,
333 DWORD dwRate, /* frames/second = (dwRate/dwScale) */
334 DWORD dwScale) {
335 ICDRAWBEGIN icdb;
337 icdb.dwFlags = dwFlags;
338 icdb.hpal = hpal;
339 icdb.hwnd = hwnd;
340 icdb.hdc = hdc;
341 icdb.xDst = xDst;
342 icdb.yDst = yDst;
343 icdb.dxDst = dxDst;
344 icdb.dyDst = dyDst;
345 icdb.lpbi = lpbi;
346 icdb.xSrc = xSrc;
347 icdb.ySrc = ySrc;
348 icdb.dxSrc = dxSrc;
349 icdb.dySrc = dySrc;
350 icdb.dwRate = dwRate;
351 icdb.dwScale = dwScale;
352 return ICSendMessage(hic,ICM_DRAW_BEGIN,(LPARAM)&icdb,sizeof(icdb));
355 DWORD VFWAPIV ICDraw(
356 HIC hic,DWORD dwFlags,LPVOID lpFormat,LPVOID lpData,DWORD cbData,
357 LONG lTime
359 ICDRAW icd;
361 icd.dwFlags = dwFlags;
362 icd.lpFormat = lpFormat;
363 icd.lpData = lpData;
364 icd.cbData = cbData;
365 icd.lTime = lTime;
366 return ICSendMessage(hic,ICM_DRAW,(LPARAM)&icd,sizeof(icd));
369 LRESULT WINAPI ICClose(HIC hic) {
370 WINE_HIC *whic = (WINE_HIC*)hic;
371 TRACE(msvideo,"(%d).\n",hic);
372 /* FIXME: correct? */
373 CloseDriver(whic->hdrv,0,0);
374 HeapFree(GetProcessHeap(),0,whic);
375 return 0;
378 HANDLE /* HDRAWDIB */ WINAPI
379 DrawDibOpen( void ) {
380 FIXME(msvideo,"stub!\n");
381 return 0xdead;
384 BOOL VFWAPI DrawDibBegin(HANDLE /*HDRAWDIB*/ hdd,
385 HDC hdc,
386 INT dxDst,
387 INT dyDst,
388 LPBITMAPINFOHEADER lpbi,
389 INT dxSrc,
390 INT dySrc,
391 UINT wFlags) {
392 FIXME(msvideo,"(%d,0x%lx,%d,%d,%p,%d,%d,0x%08lx), stub!\n",
393 hdd,(DWORD)hdc,dxDst,dyDst,lpbi,dxSrc,dySrc,(DWORD)wFlags
395 return TRUE;
399 BOOL VFWAPI
400 DrawDibSetPalette(HANDLE /*HDRAWDIB*/ hdd, HPALETTE hpal) {
401 FIXME(msvideo,"(%d,%d),stub!\n",hdd,hpal);
402 return TRUE;
405 UINT VFWAPI DrawDibRealize(HANDLE /*HDRAWDIB*/ hdd, HDC hdc, BOOL fBackground) {
406 FIXME(msvideo,"(0x%08lx,0x%08lx,%d),stub!\n",(DWORD)hdd,(DWORD)hdc,fBackground);
407 return 0;
411 HWND VFWAPIV MCIWndCreate (HWND hwndParent, HINSTANCE hInstance,
412 DWORD dwStyle,LPVOID szFile)
413 { FIXME(msvideo,"%x %x %lx %p\n",hwndParent, hInstance, dwStyle, szFile);
414 return 0;
416 HWND VFWAPIV MCIWndCreateA(HWND hwndParent, HINSTANCE hInstance,
417 DWORD dwStyle,LPCSTR szFile)
418 { FIXME(msvideo,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, szFile);
419 return 0;
421 HWND VFWAPIV MCIWndCreateW(HWND hwndParent, HINSTANCE hInstance,
422 DWORD dwStyle,LPCWSTR szFile)
423 { FIXME(msvideo,"%x %x %lx %s\n",hwndParent, hInstance, dwStyle, debugstr_w(szFile));
424 return 0;