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