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