Release 980118
[wine] / graphics / ddraw.c
1 /*              DirectDraw
2  *
3  * Copyright 1997,1998 Marcus Meissner
4  */
5 /* When DirectVideo mode is enabled you can no longer use 'normal' X 
6  * applications nor can you switch to a virtual console. Also, enabling
7  * only works, if you have switched to the screen where the application
8  * is running.
9  * Some ways to debug this stuff are:
10  * - A terminal connected to the serial port. Can be bought used for cheap.
11  *   (This is the method I am using.)
12  * - Another machine connected over some kind of network.
13  */
14 /* Progress on following programs:
15  *
16  * - Diablo:
17  *   The movies play. The game doesn't yet. No sound. (Needs clone())
18  *
19  * - WingCommander 4 (not 5!) / Win95 Patch:
20  *   The intromovie plays, in 8 bit mode (to reconfigure wc4, run wine
21  *   "wc4w.exe -I"). The 16bit mode looks broken, but I think this is due to
22  *   my Matrox Mystique which uses 565 (rgb) colorweight instead of the usual
23  *   555. Specifying it in DDPIXELFORMAT didn't help.
24  *   Requires to be run in 640x480xdepth mode (doesn't seem to heed
25  *   DDSURFACEDESC.lPitch).
26  *
27  * - Monkey Island 3:
28  *   Goes to the easy/hard selection screen, then hangs due to not MT safe
29  *   XLibs.
30  * 
31  * - Dark Angel Demo (Some shoot and run game):
32  *   The graphics stuff works fine, you can play it.
33  *
34  * - XvT:
35  *   Doesn't work, I am still unsure why not.
36  */
37
38 #include "config.h"
39 #include <stdio.h>
40 #include <unistd.h>
41 #include <assert.h>
42 #include <X11/Xlib.h>
43 #include <sys/signal.h>
44
45 #include "windows.h"
46 #include "winerror.h"
47 #include "interfaces.h"
48 #include "gdi.h"
49 #include "heap.h"
50 #include "ldt.h"
51 #include "dc.h"
52 #include "win.h"
53 #include "debug.h"
54 #include "stddebug.h"
55 #include "miscemu.h"
56 #include "mmsystem.h"
57 #include "ddraw.h"
58
59 #ifdef HAVE_LIBXXF86DGA
60 #include <X11/extensions/xf86dga.h>
61 #endif
62
63 static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE,REFIID,LPVOID*);
64 static HRESULT WINAPI IDirectDraw_QueryInterface(LPDIRECTDRAW this,REFIID refiid,LPVOID *obj);
65 static HRESULT WINAPI IDirectDraw2_CreateSurface( LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk);
66 static HRESULT WINAPI IDirectDraw_CreateSurface( LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk);
67 static struct IDirectDrawSurface2_VTable dds2vt;
68 static struct IDirectDrawSurface_VTable ddsvt;
69
70
71 HRESULT WINAPI
72 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
73         fprintf(stderr,"DirectDrawEnumerateA(%p,%p).\n",ddenumproc,data);
74         ddenumproc(0,"WINE Display","display",data);
75         ddenumproc((void*)&IID_IDirectDraw,"WINE DirectDraw","directdraw",data);
76         ddenumproc((void*)&IID_IDirectDrawPalette,"WINE DirectPalette","directpalette",data);
77         return 0;
78 }
79
80 HRESULT WINAPI 
81 DSoundHelp(DWORD x,DWORD y,DWORD z) {
82         fprintf(stderr,"DSoundHelp(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
83         return 0;
84 }
85
86 #ifdef HAVE_LIBXXF86DGA
87
88 static void _dump_DDSCAPS(DWORD flagmask) {
89         int     i;
90         const struct {
91                 DWORD   mask;
92                 char    *name;
93         } flags[] = {
94 #define FE(x) { x, #x},
95                 FE(DDSCAPS_3D)
96                 FE(DDSCAPS_ALPHA)
97                 FE(DDSCAPS_BACKBUFFER)
98                 FE(DDSCAPS_COMPLEX)
99                 FE(DDSCAPS_FLIP)
100                 FE(DDSCAPS_FRONTBUFFER)
101                 FE(DDSCAPS_OFFSCREENPLAIN)
102                 FE(DDSCAPS_OVERLAY)
103                 FE(DDSCAPS_PALETTE)
104                 FE(DDSCAPS_PRIMARYSURFACE)
105                 FE(DDSCAPS_PRIMARYSURFACELEFT)
106                 FE(DDSCAPS_SYSTEMMEMORY)
107                 FE(DDSCAPS_TEXTURE)
108                 FE(DDSCAPS_3DDEVICE)
109                 FE(DDSCAPS_VIDEOMEMORY)
110                 FE(DDSCAPS_VISIBLE)
111                 FE(DDSCAPS_WRITEONLY)
112                 FE(DDSCAPS_ZBUFFER)
113                 FE(DDSCAPS_OWNDC)
114                 FE(DDSCAPS_LIVEVIDEO)
115                 FE(DDSCAPS_HWCODEC)
116                 FE(DDSCAPS_MODEX)
117                 FE(DDSCAPS_MIPMAP)
118                 FE(DDSCAPS_ALLOCONLOAD)
119         };
120         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
121                 if (flags[i].mask & flagmask)
122                         fprintf(stderr,"%s ",flags[i].name);
123 }
124
125 static void _dump_DDCAPS(DWORD flagmask) {
126         int     i;
127         const struct {
128                 DWORD   mask;
129                 char    *name;
130 } flags[] = {
131 #define FE(x) { x, #x},
132                 FE(DDCAPS_3D)
133                 FE(DDCAPS_ALIGNBOUNDARYDEST)
134                 FE(DDCAPS_ALIGNSIZEDEST)
135                 FE(DDCAPS_ALIGNBOUNDARYSRC)
136                 FE(DDCAPS_ALIGNSIZESRC)
137                 FE(DDCAPS_ALIGNSTRIDE)
138                 FE(DDCAPS_BLT)
139                 FE(DDCAPS_BLTQUEUE)
140                 FE(DDCAPS_BLTFOURCC)
141                 FE(DDCAPS_BLTSTRETCH)
142                 FE(DDCAPS_GDI)
143                 FE(DDCAPS_OVERLAY)
144                 FE(DDCAPS_OVERLAYCANTCLIP)
145                 FE(DDCAPS_OVERLAYFOURCC)
146                 FE(DDCAPS_OVERLAYSTRETCH)
147                 FE(DDCAPS_PALETTE)
148                 FE(DDCAPS_PALETTEVSYNC)
149                 FE(DDCAPS_READSCANLINE)
150                 FE(DDCAPS_STEREOVIEW)
151                 FE(DDCAPS_VBI)
152                 FE(DDCAPS_ZBLTS)
153                 FE(DDCAPS_ZOVERLAYS)
154                 FE(DDCAPS_COLORKEY)
155                 FE(DDCAPS_ALPHA)
156                 FE(DDCAPS_COLORKEYHWASSIST)
157                 FE(DDCAPS_NOHARDWARE)
158                 FE(DDCAPS_BLTCOLORFILL)
159                 FE(DDCAPS_BANKSWITCHED)
160                 FE(DDCAPS_BLTDEPTHFILL)
161                 FE(DDCAPS_CANCLIP)
162                 FE(DDCAPS_CANCLIPSTRETCHED)
163                 FE(DDCAPS_CANBLTSYSMEM)
164         };
165         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
166                 if (flags[i].mask & flagmask)
167                         fprintf(stderr,"%s ",flags[i].name);
168 }
169
170 static void _dump_DDSD(DWORD flagmask) {
171         int     i;
172         const struct {
173                 DWORD   mask;
174                 char    *name;
175         } flags[] = {
176                 FE(DDSD_CAPS)
177                 FE(DDSD_HEIGHT)
178                 FE(DDSD_WIDTH)
179                 FE(DDSD_PITCH)
180                 FE(DDSD_BACKBUFFERCOUNT)
181                 FE(DDSD_ZBUFFERBITDEPTH)
182                 FE(DDSD_ALPHABITDEPTH)
183                 FE(DDSD_PIXELFORMAT)
184                 FE(DDSD_CKDESTOVERLAY)
185                 FE(DDSD_CKDESTBLT)
186                 FE(DDSD_CKSRCOVERLAY)
187                 FE(DDSD_CKSRCBLT)
188                 FE(DDSD_MIPMAPCOUNT)
189                 FE(DDSD_REFRESHRATE)
190         };
191         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
192                 if (flags[i].mask & flagmask)
193                         fprintf(stderr,"%s ",flags[i].name);
194 }
195
196 static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) {
197         static XVisualInfo      *vi;
198         XVisualInfo             vt;
199         int                     nitems;
200
201         if (!vi)
202                 vi = XGetVisualInfo(display,VisualNoMask,&vt,&nitems);
203
204         pf->dwFourCC = mmioFOURCC('R','G','B',' ');
205         if (ddraw->d.depth==8) {
206                 pf->dwFlags             = DDPF_RGB|DDPF_PALETTEINDEXED8;
207                 pf->x.dwRGBBitCount     = 8;
208                 pf->y.dwRBitMask        = 0;
209                 pf->z.dwGBitMask        = 0;
210                 pf->xx.dwBBitMask       = 0;
211                 return 0;
212         }
213         if (ddraw->d.depth==16) {
214                 pf->dwFlags             = DDPF_RGB;
215                 pf->x.dwRGBBitCount     = 16;
216                 pf->y.dwRBitMask        = vi[0].red_mask;
217                 pf->z.dwGBitMask        = vi[0].green_mask;
218                 pf->xx.dwBBitMask       = vi[0].blue_mask;
219                 return 0;
220         }
221         fprintf(stderr,"_getpixelformat:oops?\n");
222         return DDERR_GENERIC;
223 }
224
225
226 static HRESULT WINAPI IDirectDrawSurface_Lock(
227     LPDIRECTDRAWSURFACE this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
228 ) {
229         /*
230         fprintf(stderr,"IDirectDrawSurface(%p)->Lock(%p,%p,%08lx,%08lx)\n",
231                 this,lprect,lpddsd,flags,(DWORD)hnd
232         );
233         fprintf(stderr,".");
234         */
235         if (lprect) {
236                 /*
237                 fprintf(stderr,"        lprect: %dx%d-%dx%d\n",
238                         lprect->top,lprect->left,lprect->bottom,lprect->right
239                 );
240                  */
241                 lpddsd->lpSurface =     this->surface+
242                                         (lprect->top*this->lpitch)+
243                                         (lprect->left*(this->ddraw->d.depth/8));
244         } else
245                 lpddsd->lpSurface = this->surface;
246         lpddsd->dwWidth         = this->width;
247         lpddsd->dwHeight        = this->height;
248         lpddsd->lPitch          = this->lpitch;
249         _getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat));
250         return 0;
251 }
252
253 static HRESULT WINAPI IDirectDrawSurface2_Lock(
254     LPDIRECTDRAWSURFACE2 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
255 ) {
256         fprintf(stderr,"IDirectDrawSurface2(%p)->Lock(%p,%p,%08lx,%08lx)\n",
257                 this,lprect,lpddsd,flags,(DWORD)hnd
258         );
259         /*fprintf(stderr,".");*/
260         if (lprect) {
261                 /*
262                 fprintf(stderr,"        lprect: %dx%d-%dx%d\n",
263                         lprect->top,lprect->left,lprect->bottom,lprect->right
264                 );
265                  */
266                 lpddsd->lpSurface =     this->surface+
267                                         (lprect->top*this->lpitch)+
268                                         (lprect->left*(this->ddraw->d.depth/8));
269         } else
270                 lpddsd->lpSurface = this->surface;
271         lpddsd->dwWidth         = this->width;
272         lpddsd->dwHeight        = this->height;
273         lpddsd->lPitch          = this->lpitch;
274         _getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat));
275         return 0;
276 }
277
278 static HRESULT WINAPI IDirectDrawSurface_Unlock(
279         LPDIRECTDRAWSURFACE this,LPVOID surface
280 ) {
281         dprintf_relay(stderr,"IDirectDrawSurface(%p)->Unlock(%p)\n",this,surface);
282         return 0;
283 }
284
285 static HRESULT WINAPI IDirectDrawSurface_Flip(
286         LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE flipto,DWORD dwFlags
287 ) {
288 /*      fprintf(stderr,"IDirectDrawSurface(%p)->Flip(%p,%08lx),STUB\n",this,flipto,dwFlags);*/
289         if (!flipto) {
290                 if (this->backbuffer)
291                         flipto = this->backbuffer;
292                 else
293                         flipto = this;
294         }
295 /*      fprintf(stderr,"f>%ld",flipto->fb_height);*/
296         XF86DGASetViewPort(display,DefaultScreen(display),0,flipto->fb_height);
297         if (flipto->palette && flipto->palette->cm)
298                 XF86DGAInstallColormap(display,DefaultScreen(display),flipto->palette->cm);
299         while (!XF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
300                 fprintf(stderr,"w");
301         }
302         /* is this a good idea ? */
303         if (flipto!=this) {
304                 int     tmp;
305                 LPVOID  ptmp;
306
307                 tmp = this->fb_height;
308                 this->fb_height = flipto->fb_height;
309                 flipto->fb_height = tmp;
310
311                 ptmp = this->surface;
312                 this->surface = flipto->surface;
313                 flipto->surface = ptmp;
314         }
315         return 0;
316 }
317
318 static HRESULT WINAPI IDirectDrawSurface2_Unlock(
319         LPDIRECTDRAWSURFACE2 this,LPVOID surface
320 ) {
321         dprintf_relay(stderr,"IDirectDrawSurface2(%p)->Unlock(%p)\n",this,surface);
322         return 0;
323 }
324
325 static HRESULT WINAPI IDirectDrawSurface_SetPalette(
326         LPDIRECTDRAWSURFACE this,LPDIRECTDRAWPALETTE pal
327 ) {
328         fprintf(stderr,"IDirectDrawSurface(%p)->SetPalette(%p)\n",this,pal);
329         this->palette = pal;
330         return 0;
331 }
332
333 static HRESULT WINAPI IDirectDrawSurface2_SetPalette(
334         LPDIRECTDRAWSURFACE2 this,LPDIRECTDRAWPALETTE pal
335 ) {
336         fprintf(stderr,"IDirectDrawSurface2(%p)->SetPalette(%p)\n",this,pal);
337         this->palette = pal;
338         return 0;
339 }
340
341 static HRESULT WINAPI IDirectDrawSurface_Blt(
342         LPDIRECTDRAWSURFACE this,LPRECT32 rdst,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
343 ) {
344         fprintf(stderr,"IDirectDrawSurface(%p)->Blt(%p,%p,%p,%08lx,%p),stub!\n",
345                 this,rdst,src,rsrc,dwFlags,lpbltfx
346         );
347         if (rdst) fprintf(stderr,"      destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
348         if (rsrc) fprintf(stderr,"      srcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
349         fprintf(stderr,"        blitfx: 0x%08lx\n",lpbltfx->dwDDFX);
350         return 0;
351 }
352
353 static HRESULT WINAPI IDirectDrawSurface_BltFast(
354         LPDIRECTDRAWSURFACE this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD trans
355 ) {
356         int     i,bpp;
357         fprintf(stderr,"IDirectDrawSurface(%p)->BltFast(%ld,%ld,%p,%p,%08lx),stub!\n",
358                 this,dstx,dsty,src,rsrc,trans
359         );
360         fprintf(stderr,"        srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
361         bpp = this->ddraw->d.depth/8;
362         for (i=0;i<rsrc->bottom-rsrc->top;i++) {
363                 memcpy( this->surface+((i+dsty)*this->width*bpp)+dstx*bpp,
364                         src->surface +(rsrc->top+i)*src->width*bpp+rsrc->left*bpp,
365                         (rsrc->right-rsrc->left)*bpp
366                 );
367         }
368         return 0;
369 }
370
371 static HRESULT WINAPI IDirectDrawSurface_BltBatch(
372         LPDIRECTDRAWSURFACE this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
373 ) {
374         fprintf(stderr,"IDirectDrawSurface(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
375                 this,ddbltbatch,x,y
376         );
377         return 0;
378 }
379
380 static HRESULT WINAPI IDirectDrawSurface_GetCaps(
381         LPDIRECTDRAWSURFACE this,LPDDSCAPS caps
382 ) {
383         fprintf(stderr,"IDirectDrawSurface(%p)->GetCaps(%p)\n",this,caps);
384         caps->dwCaps = DDCAPS_PALETTE; /* probably more */
385         return 0;
386 }
387
388 static HRESULT WINAPI IDirectDrawSurface_GetSurfaceDesc(
389         LPDIRECTDRAWSURFACE this,LPDDSURFACEDESC ddsd
390 ) { 
391         fprintf(stderr,"IDirectDrawSurface(%p)->GetSurfaceDesc(%p)\n",this,ddsd);
392         fprintf(stderr,"        flags: ");
393         _dump_DDSD(ddsd->dwFlags);
394         fprintf(stderr,"\n");
395
396         ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
397         ddsd->ddsCaps.dwCaps    = DDSCAPS_PALETTE;
398         ddsd->dwBackBufferCount = 1;
399         ddsd->dwHeight          = this->height;
400         ddsd->dwWidth           = this->width;
401         ddsd->lPitch            = this->lpitch;
402         if (this->backbuffer)
403                 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
404         _getpixelformat(this->ddraw,&(ddsd->ddpfPixelFormat));
405         
406         return 0;
407 }
408
409 static ULONG WINAPI IDirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE this) {
410         dprintf_relay(stderr,"IDirectDrawSurface(%p)->AddRef()\n",this);
411         return ++(this->ref);
412 }
413
414 static ULONG WINAPI IDirectDrawSurface_Release(LPDIRECTDRAWSURFACE this) {
415         dprintf_relay(stderr,"IDirectDrawSurface(%p)->Release()\n",this);
416         if (!--(this->ref)) {
417                 this->ddraw->lpvtbl->fnRelease(this->ddraw);
418                 /* clear out of surface list */
419                 this->ddraw->d.vpmask &= ~(1<<(this->fb_height/this->ddraw->d.fb_height));
420                 HeapFree(GetProcessHeap(),0,this);
421                 return 0;
422         }
423         return this->ref;
424 }
425
426 static ULONG WINAPI IDirectDrawSurface2_AddRef(LPDIRECTDRAWSURFACE2 this) {
427         dprintf_relay(stderr,"IDirectDrawSurface2(%p)->AddRef()\n",this);
428         return ++(this->ref);
429 }
430
431 static ULONG WINAPI IDirectDrawSurface2_Release(LPDIRECTDRAWSURFACE2 this) {
432         dprintf_relay(stderr,"IDirectDrawSurface2(%p)->Release()\n",this);
433         if (!--(this->ref)) {
434                 this->ddraw->lpvtbl->fnRelease(this->ddraw);
435                 this->ddraw->d.vpmask &= ~(1<<(this->fb_height/this->ddraw->d.fb_height));
436                 HeapFree(GetProcessHeap(),0,this);
437                 return 0;
438         }
439         return this->ref;
440 }
441
442 static HRESULT WINAPI IDirectDrawSurface2_GetAttachedSurface(
443         LPDIRECTDRAWSURFACE2 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE2 *lpdsf
444 ) {
445         fprintf(stderr,"IDirectDrawSurface2(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf);
446         fprintf(stderr,"        caps ");_dump_DDSCAPS(lpddsd->dwCaps);fprintf(stderr,"\n");
447         if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
448                 fprintf(stderr,"whoops, can only handle backbuffers for now\n");
449                 return E_FAIL;
450         }
451         /* FIXME: should handle more than one backbuffer */
452         *lpdsf = this->backbuffer;
453         return 0;
454 }
455
456 static HRESULT WINAPI IDirectDrawSurface_GetAttachedSurface(
457         LPDIRECTDRAWSURFACE this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE *lpdsf
458 ) {
459         fprintf(stderr,"IDirectDrawSurface(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf);
460         fprintf(stderr,"        caps ");_dump_DDSCAPS(lpddsd->dwCaps);fprintf(stderr,"\n");
461         if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
462                 fprintf(stderr,"whoops, can only handle backbuffers for now\n");
463                 return E_FAIL;
464         }
465         /* FIXME: should handle more than one backbuffer */
466         *lpdsf = this->backbuffer;
467         return 0;
468 }
469
470 static HRESULT WINAPI IDirectDrawSurface_Initialize(
471         LPDIRECTDRAWSURFACE this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
472 ) {
473         fprintf(stderr,"IDirectDrawSurface(%p)->Initialize(%p,%p)\n",
474                 this,ddraw,lpdsfd
475         );
476         return DDERR_ALREADYINITIALIZED;
477 }
478
479 static HRESULT WINAPI IDirectDrawSurface_GetPixelFormat(
480         LPDIRECTDRAWSURFACE this,LPDDPIXELFORMAT pf
481 ) {
482         fprintf(stderr,"IDirectDrawSurface(%p)->GetPixelFormat(%p)\n",this,pf);
483         return _getpixelformat(this->ddraw,pf);
484 }
485
486 static HRESULT WINAPI IDirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE this,DWORD dwFlags) {
487         fprintf(stderr,"IDirectDrawSurface(%p)->GetBltStatus(0x%08lx),stub!\n",
488                 this,dwFlags
489         );
490         return 0;
491 }
492
493 static HRESULT WINAPI IDirectDrawSurface_GetOverlayPosition(
494         LPDIRECTDRAWSURFACE this,LPLONG x1,LPLONG x2
495 ) {
496         fprintf(stderr,"IDirectDrawSurface(%p)->GetOverlayPosition(%p,%p),stub!\n",
497                 this,x1,x2
498         );
499         return 0;
500 }
501
502 static HRESULT WINAPI IDirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE this,HDC32* lphdc) {
503         fprintf(stderr,"IDirectDrawSurface(%p)->GetDC(%p),stub!\n",this,lphdc);
504         return 0;
505 }
506
507 static HRESULT WINAPI IDirectDrawSurface2_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
508         /* none yet? */
509         return 0;
510 }
511
512 static struct IDirectDrawSurface2_VTable dds2vt = {
513         (void*)1/*IDirectDrawSurface2_QueryInterface*/,
514         IDirectDrawSurface2_AddRef,
515         IDirectDrawSurface2_Release,
516         (void*)4,
517         (void*)5,
518         (void*)6/*IDirectDrawSurface_Blt*/,
519         (void*)7/*IDirectDrawSurface_BltBatch*/,
520         (void*)8,
521         (void*)9,
522         IDirectDrawSurface2_EnumAttachedSurfaces,
523         (void*)11,
524         (void*)12,
525         IDirectDrawSurface2_GetAttachedSurface,
526         (void*)14,
527         (void*)15/*IDirectDrawSurface_GetCaps*/,
528         (void*)16,
529         (void*)17,
530         (void*)18,
531         (void*)19,
532         (void*)20,
533         (void*)21,
534         (void*)22,
535         (void*)23/*IDirectDrawSurface_GetSurfaceDesc*/,
536         (void*)24,
537         (void*)25,
538         IDirectDrawSurface2_Lock,
539         (void*)27,
540         (void*)28,
541         (void*)29,
542         (void*)30,
543         (void*)31,
544         IDirectDrawSurface2_SetPalette,
545         IDirectDrawSurface2_Unlock,
546         (void*)34,
547         (void*)35,
548         (void*)36,
549         (void*)37,
550         (void*)38,
551         (void*)39,
552 };
553
554
555 static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE this,REFIID refiid,LPVOID *obj) {
556         char    xrefiid[50];
557
558         StringFromCLSID((LPCLSID)refiid,xrefiid);
559         fprintf(stderr,"IDirectDrawSurface(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
560         
561         /* thats version 2 */
562         if (    !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID_IDirectDrawSurface2))) {
563                 this->lpvtbl->fnAddRef(this);
564                 this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds2vt;
565                 *obj = this;
566                 return 0;
567         }
568         /* thats us */
569         if (!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID_IDirectDrawSurface))) {
570                 this->lpvtbl->fnAddRef(this);
571                 *obj = this;
572                 return 0;
573         }
574         return OLE_E_ENUM_NOMORE;
575 }
576
577 static struct IDirectDrawSurface_VTable ddsvt = {
578         IDirectDrawSurface_QueryInterface,
579         IDirectDrawSurface_AddRef,
580         IDirectDrawSurface_Release,
581         (void*)4,
582         (void*)5,
583         IDirectDrawSurface_Blt,
584         IDirectDrawSurface_BltBatch,
585         IDirectDrawSurface_BltFast,
586         (void*)9,
587         (void*)10,
588         (void*)11,
589         IDirectDrawSurface_Flip,
590         IDirectDrawSurface_GetAttachedSurface,
591         IDirectDrawSurface_GetBltStatus,
592         IDirectDrawSurface_GetCaps,
593         (void*)16,
594         (void*)17,
595         IDirectDrawSurface_GetDC,
596         (void*)19,
597         IDirectDrawSurface_GetOverlayPosition,
598         (void*)21,
599         IDirectDrawSurface_GetPixelFormat,
600         IDirectDrawSurface_GetSurfaceDesc,
601         IDirectDrawSurface_Initialize,
602         (void*)25,
603         IDirectDrawSurface_Lock,
604         (void*)27,
605         (void*)28,
606         (void*)29,
607         (void*)30,
608         (void*)31,
609         IDirectDrawSurface_SetPalette,
610         IDirectDrawSurface_Unlock,
611         (void*)34,
612         (void*)35,
613         (void*)36,
614 };
615
616 static HRESULT WINAPI IDirectDraw_CreateSurface(
617         LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
618 ) {
619         int     i;
620
621         fprintf(stderr,"IDirectDraw(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
622         fprintf(stderr," [w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
623         _dump_DDSD(lpddsd->dwFlags);
624         fprintf(stderr,"caps ");_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
625         fprintf(stderr,"]\n");
626
627         *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
628         this->lpvtbl->fnAddRef(this);
629         (*lpdsf)->ref = 1;
630         (*lpdsf)->lpvtbl = &ddsvt;
631         for (i=0;i<32;i++)
632                 if (!(this->d.vpmask & (1<<i)))
633                         break;
634         fprintf(stderr,"using viewport %d for a primary surface\n",i);
635         /* if i == 32 or maximum ... return error */
636         this->d.vpmask|=(1<<i);
637         (*lpdsf)->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
638         (*lpdsf)->fb_height = i*this->d.fb_height;
639
640         (*lpdsf)->width = this->d.width;
641         (*lpdsf)->height = this->d.height;
642         (*lpdsf)->ddraw = this;
643         (*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8;
644         (*lpdsf)->backbuffer = NULL;
645         if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
646                 LPDIRECTDRAWSURFACE     back;
647
648                 if (lpddsd->dwBackBufferCount>1)
649                         fprintf(stderr,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
650
651                 (*lpdsf)->backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
652                 this->lpvtbl->fnAddRef(this);
653                 back->ref = 1;
654                 back->lpvtbl = &ddsvt;
655                 for (i=0;i<32;i++)
656                         if (!(this->d.vpmask & (1<<i)))
657                                 break;
658                 fprintf(stderr,"using viewport %d for backbuffer\n",i);
659                 /* if i == 32 or maximum ... return error */
660                 this->d.vpmask|=(1<<i);
661                 back->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
662                 back->fb_height = i*this->d.fb_height;
663
664                 back->width = this->d.width;
665                 back->height = this->d.height;
666                 back->ddraw = this;
667                 back->lpitch = this->d.fb_width*this->d.depth/8;
668                 back->backbuffer = NULL; /* does not have a backbuffer, it is
669                                           * one! */
670         }
671         return 0;
672 }
673
674 static HRESULT WINAPI IDirectDraw_DuplicateSurface(
675         LPDIRECTDRAW this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
676 ) {
677         fprintf(stderr,"IDirectDraw(%p)->DuplicateSurface(%p,%p)\n",this,src,dst);
678         *dst = src; /* FIXME */
679         return 0;
680 }
681
682 static HRESULT WINAPI IDirectDraw2_CreateSurface(
683         LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
684 ) {
685         int     i;
686
687         fprintf(stderr,"IDirectDraw2(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
688         *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
689         this->lpvtbl->fnAddRef(this);
690         (*lpdsf)->ref = 1;
691         (*lpdsf)->lpvtbl = &ddsvt;
692
693         for (i=0;i<32;i++)
694                 if (!(this->d.vpmask & (1<<i)))
695                         break;
696         fprintf(stderr,"using viewport %d for primary\n",i);
697         /* if i == 32 or maximum ... return error */
698         this->d.vpmask|=(1<<i);
699         (*lpdsf)->surface = this->d.fb_addr+((i*this->d.fb_height)*this->d.fb_width*this->d.depth/8);
700         (*lpdsf)->width = this->d.width;
701         (*lpdsf)->height = this->d.height;
702         (*lpdsf)->ddraw = (LPDIRECTDRAW)this;
703         (*lpdsf)->fb_height = i*this->d.fb_height;
704         (*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8;
705         (*lpdsf)->backbuffer = NULL;
706         if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
707                 LPDIRECTDRAWSURFACE     back;
708
709                 if (lpddsd->dwBackBufferCount>1)
710                         fprintf(stderr,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
711
712                 (*lpdsf)->backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface2));
713                 this->lpvtbl->fnAddRef(this);
714                 back->ref = 1;
715                 back->lpvtbl = &ddsvt;
716                 for (i=0;i<32;i++)
717                         if (!(this->d.vpmask & (1<<i)))
718                                 break;
719                 fprintf(stderr,"using viewport %d for backbuffer\n",i);
720                 /* if i == 32 or maximum ... return error */
721                 this->d.vpmask|=(1<<i);
722                 back->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
723                 back->fb_height = i*this->d.fb_height;
724
725                 back->width = this->d.width;
726                 back->height = this->d.height;
727                 back->ddraw = (LPDIRECTDRAW)this;
728                 back->lpitch = this->d.fb_width*this->d.depth/8;
729                 back->backbuffer = NULL; /* does not have a backbuffer, it is
730                                           * one! */
731         }
732         return 0;
733 }
734
735 static HRESULT WINAPI IDirectDraw_SetCooperativeLevel(
736         LPDIRECTDRAW this,HWND32 hwnd,DWORD cooplevel
737 ) {
738         int     i;
739         const struct {
740                 int     mask;
741                 char    *name;
742         } flagmap[] = {
743                 FE(DDSCL_FULLSCREEN)
744                 FE(DDSCL_ALLOWREBOOT)
745                 FE(DDSCL_NOWINDOWCHANGES)
746                 FE(DDSCL_NORMAL)
747                 FE(DDSCL_ALLOWMODEX)
748                 FE(DDSCL_EXCLUSIVE)
749         };
750         fprintf(stderr,"IDirectDraw(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n",
751                 this,(DWORD)hwnd,cooplevel
752         );
753         fprintf(stderr,"        cooperative level ");
754         for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
755                 if (flagmap[i].mask & cooplevel)
756                         fprintf(stderr,"%s ",flagmap[i].name);
757         fprintf(stderr,"\n");
758         this->d.mainwindow = hwnd;
759         return 0;
760 }
761
762 extern BOOL32 SIGNAL_InitEmulator(void);
763
764 static HRESULT WINAPI IDirectDraw_SetDisplayMode(
765         LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
766 ) {
767         int     i,*depths,depcount;
768         char    buf[200];
769
770         fprintf(stderr,"IDirectDraw(%p)->SetDisplayMode(%ld,%ld,%ld),stub!\n",this,width,height,depth);
771
772         depths = XListDepths(display,DefaultScreen(display),&depcount);
773         for (i=0;i<depcount;i++)
774                 if (depths[i]==depth)
775                         break;
776         XFree(depths);
777         if (i==depcount) {/* not found */
778                 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
779                 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
780                 return DDERR_UNSUPPORTEDMODE;
781         }
782         if (this->d.fb_width < width) {
783                 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.fb_width);
784                 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
785                 return DDERR_UNSUPPORTEDMODE;
786         }
787         this->d.width   = width;
788         this->d.height  = height;
789         /* adjust fb_height, so we don't overlap */
790         if (this->d.fb_height < height)
791                 this->d.fb_height = height;
792         this->d.depth   = depth;
793
794         /* FIXME: this function OVERWRITES several signal handlers. 
795          * can we save them? and restore them later? In a way that
796          * it works for the library too?
797          */
798         XF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
799 /* FIXME:  can't call this in winelib... so comment only in for debugging.
800         SIGNAL_InitEmulator();
801  */
802         return 0;
803 }
804
805 static HRESULT WINAPI IDirectDraw_GetCaps(
806         LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
807 )  {
808         fprintf(stderr,"IDirectDraw(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2);
809         caps1->dwVidMemTotal = this->d.fb_memsize;
810         caps1->dwCaps = 0; /* we cannot do anything */
811         caps1->ddsCaps.dwCaps = 0; /* we cannot do anything */
812         return 0;
813 }
814
815 static HRESULT WINAPI IDirectDraw2_GetCaps(
816         LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
817 )  {
818         fprintf(stderr,"IDirectDraw2(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2);
819         caps1->dwVidMemTotal = this->d.fb_memsize;
820         caps1->dwCaps = 0; /* we cannot do anything */
821         caps1->ddsCaps.dwCaps = 0;
822         return 0;
823 }
824
825
826 static struct IDirectDrawClipper_VTable ddclipvt = {
827         (void*)1,
828         (void*)2,(void*)3,(void*)4,(void*)5,
829         (void*)6,
830         (void*)7,(void*)8,(void*)9
831 };
832
833 static HRESULT WINAPI IDirectDraw_CreateClipper(
834         LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
835 ) {
836         fprintf(stderr,"IDirectDraw(%p)->CreateClipper(%08lx,%p,%p),stub!\n",
837                 this,x,lpddclip,lpunk
838         );
839         *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
840         (*lpddclip)->ref = 1;
841         (*lpddclip)->lpvtbl = &ddclipvt;
842         return 0;
843 }
844
845 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
846         LPDIRECTDRAWPALETTE this,DWORD x,DWORD y,DWORD z,LPPALETTEENTRY palent
847 ) {
848         fprintf(stderr,"IDirectDrawPalette(%p)->GetEntries(%08lx,%08lx,%08lx,%p),stub!\n",
849                 this,x,y,z,palent
850         );
851         return 0;
852 }
853
854 static HRESULT WINAPI IDirectDrawPalette_SetEntries(
855         LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
856 ) {
857         XColor          xc;
858         int             i;
859
860 /*
861         fprintf(stderr,"IDirectDrawPalette(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
862                 this,x,start,end,palent
863         );
864  */
865         if (!this->cm) /* should not happen */ {
866                 fprintf(stderr,"no colormap in SetEntries???\n");
867                 return DDERR_GENERIC;
868         }
869 /* FIXME: free colorcells instead of freeing whole map */
870         XFreeColormap(display,this->cm);
871         this->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll);
872         if (start>0) {
873                 xc.red = xc.blue = xc.green = 0; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 0; XStoreColor(display,this->cm,&xc);
874         }
875         if (end<256) {
876                 xc.red = xc.blue = xc.green = 0xffff; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 255; XStoreColor(display,this->cm,&xc);
877         }
878         for (i=start;i<end;i++) {
879                 xc.red = palent[i-start].peRed<<8;
880                 xc.blue = palent[i-start].peBlue<<8;
881                 xc.green = palent[i-start].peGreen<<8;
882                 xc.flags = DoRed|DoBlue|DoGreen;
883                 xc.pixel = i;
884                 XStoreColor(display,this->cm,&xc);
885         }
886         XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
887         return 0;
888 }
889
890 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
891         fprintf(stderr,"IDirectDrawPalette(%p)->Release()\n",this);
892         if (!--(this->ref)) {
893                 fprintf(stderr,"IDirectDrawPalette(%p) freed!\n",this);
894                 if (this->cm) {
895                         XFreeColormap(display,this->cm);
896                         this->cm = 0;
897                 }
898                 HeapFree(GetProcessHeap(),0,this);
899                 return 0;
900         }
901         return this->ref;
902 }
903
904 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
905         fprintf(stderr,"IDirectDrawPalette(%p)->AddRef()\n",this);
906         return ++(this->ref);
907 }
908
909 static HRESULT WINAPI IDirectDrawPalette_Initialize(
910         LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
911 ) {
912         fprintf(stderr,"IDirectDrawPalette(%p)->Initialize(%p,0x%08lx,%p)\n",this,ddraw,x,palent);
913         return DDERR_ALREADYINITIALIZED;
914 }
915
916 static struct IDirectDrawPalette_VTable ddpalvt = {
917         (void*)1,
918         IDirectDrawPalette_AddRef,
919         IDirectDrawPalette_Release,
920         (void*)4,
921         IDirectDrawPalette_GetEntries,
922         IDirectDrawPalette_Initialize,
923         IDirectDrawPalette_SetEntries
924 };
925
926 static HRESULT WINAPI IDirectDraw_CreatePalette(
927         LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
928 ) {
929         fprintf(stderr,"IDirectDraw(%p)->CreatePalette(%08lx,%p,%p,%p),stub!\n",
930                 this,x,palent,lpddpal,lpunk
931         );
932         *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
933         (*lpddpal)->ref = 1;
934         (*lpddpal)->lpvtbl = &ddpalvt;
935         (*lpddpal)->ddraw = this;
936         if (this->d.depth<=8) {
937                 (*lpddpal)->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll);
938                 fprintf(stderr,"created colormap...\n");
939         } else /* we don't want palettes in hicolor or truecolor */
940                 (*lpddpal)->cm = 0;
941
942         return 0;
943 }
944
945 static HRESULT WINAPI IDirectDraw2_CreatePalette(
946         LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
947 ) {
948         return IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
949 }
950
951 static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank(
952         LPDIRECTDRAW this,DWORD x,HANDLE32 h
953 ) {
954         fprintf(stderr,"IDirectDraw(%p)->WaitForVerticalBlank(0x%08lx,0x%08x),stub!\n",this,x,h);
955         return 0;
956 }
957
958 static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) {
959         dprintf_relay(stderr,"IDirectDraw(%p)->AddRef()\n",this);
960         return ++(this->ref);
961 }
962
963 static ULONG WINAPI IDirectDraw_Release(LPDIRECTDRAW this) {
964         dprintf_relay(stderr,"IDirectDraw(%p)->Release()\n",this);
965         if (!--(this->ref)) {
966                 fprintf(stderr,"IDirectDraw::Release:freeing IDirectDraw(%p)\n",this);
967                 XF86DGADirectVideo(display,DefaultScreen(display),0);
968                 HeapFree(GetProcessHeap(),0,this);
969                 return 0;
970         }
971         return this->ref;
972 }
973
974 static HRESULT WINAPI IDirectDraw2_QueryInterface(
975         LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
976 ) {
977         return IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
978 }
979
980 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
981         return IDirectDraw_AddRef((LPDIRECTDRAW)this);
982 }
983
984 static ULONG WINAPI IDirectDraw2_Release(LPDIRECTDRAW2 this) {
985         return IDirectDraw_Release((LPDIRECTDRAW)this);
986 }
987
988 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
989         LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x
990 ) {
991         fprintf(stderr,"IDirectDraw2(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n",
992                 this,(DWORD)hwnd,x
993         );
994         this->d.mainwindow = hwnd;
995         return 0;
996 }
997
998 static HRESULT WINAPI IDirectDraw2_SetDisplayMode(
999         LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
1000 ) {
1001         fprintf(stderr,"IDirectDraw2(%p)->SetDisplayMode(%ld,%ld,%ld,%08lx,%08lx),stub!\n",this,width,height,depth,xx,yy);
1002
1003         return IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
1004 }
1005
1006 static HRESULT WINAPI IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1007         fprintf(stderr,"IDirectDraw2(%p)->RestoreDisplayMode(),stub!\n",this);
1008         XF86DGADirectVideo(display,DefaultScreen(display),0);
1009         return 0;
1010 }
1011
1012 static HRESULT WINAPI IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
1013         fprintf(stderr,"IDirectDraw(%p)->RestoreDisplayMode(),stub!\n",this);
1014         XF86DGADirectVideo(display,DefaultScreen(display),0);
1015         return 0;
1016 }
1017
1018 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
1019         LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
1020 ) {
1021         fprintf(stderr,"IDirectDraw2(%p)->EnumSurfaces(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
1022         return 0;
1023 }
1024
1025 static IDirectDraw2_VTable dd2vt = {
1026         IDirectDraw2_QueryInterface,
1027         IDirectDraw2_AddRef,
1028         IDirectDraw2_Release,
1029         (void*)4,
1030         (void*)5/*IDirectDraw_CreateClipper*/,
1031         IDirectDraw2_CreatePalette,
1032         IDirectDraw2_CreateSurface,
1033         (void*)8,
1034         (void*)9,
1035         IDirectDraw2_EnumSurfaces,
1036         (void*)11,
1037         IDirectDraw2_GetCaps,
1038         (void*)13,
1039         (void*)14,
1040         (void*)15,
1041         (void*)16,
1042         (void*)17,
1043         (void*)18,
1044         (void*)19,
1045         IDirectDraw2_RestoreDisplayMode,
1046         IDirectDraw2_SetCooperativeLevel,
1047         IDirectDraw2_SetDisplayMode,
1048         (void*)23/*IDirectDraw_WaitForVerticalBlank*/,
1049         (void*)24
1050 };
1051
1052 static HRESULT WINAPI IDirectDraw_QueryInterface(
1053         LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
1054 ) {
1055         char    xrefiid[50];
1056
1057         StringFromCLSID((LPCLSID)refiid,xrefiid);
1058         fprintf(stderr,"IDirectDraw(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
1059         if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1060                 *obj = this;
1061                 this->lpvtbl->fnAddRef(this);
1062                 return 0;
1063         }
1064         if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1065                 /* FIXME FIXME FIXME */
1066                 this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dd2vt;
1067                 this->lpvtbl->fnAddRef(this);
1068                 *obj = this;
1069                 return 0;
1070         }
1071         return OLE_E_ENUM_NOMORE;
1072 }
1073
1074 static HRESULT WINAPI IDirectDraw_GetVerticalBlankStatus(
1075         LPDIRECTDRAW this,BOOL32 *status
1076 ) {
1077         fprintf(stderr,"IDirectDraw(%p)->GetVerticalBlankSatus(%p)\n",this,status);
1078         *status = TRUE;
1079         return 0;
1080 }
1081
1082 static HRESULT WINAPI IDirectDraw_EnumDisplayModes(
1083         LPDIRECTDRAW this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1084 ) {
1085         DDSURFACEDESC   ddsfd;
1086
1087         fprintf(stderr,"IDirectDraw(%p)->EnumDisplayModes(0x%08lx,%p,%p,%p),stub!\n",this,dwFlags,lpddsfd,context,modescb);
1088         ddsfd.dwSize = sizeof(ddsfd);
1089         fprintf(stderr,"size is %d\n",sizeof(ddsfd));
1090         ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1091         ddsfd.dwHeight = 480;
1092         ddsfd.dwWidth = 640;
1093         ddsfd.lPitch = 640;
1094         ddsfd.dwBackBufferCount = 1;
1095         ddsfd.x.dwRefreshRate = 60;
1096         ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
1097         this->d.depth = 8;
1098         _getpixelformat(this,&(ddsfd.ddpfPixelFormat));
1099         fprintf(stderr,"modescb returned: 0x%lx\n",(DWORD)modescb(&ddsfd,context));
1100         return DD_OK;
1101 }
1102
1103 static HRESULT WINAPI IDirectDraw_GetDisplayMode(
1104         LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
1105 ) {
1106         fprintf(stderr,"IDirectDraw(%p)->GetDisplayMode(%p),stub!\n",this,lpddsfd);
1107         lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1108         lpddsfd->dwHeight = this->d.vp_height;
1109         lpddsfd->dwWidth = this->d.vp_width;
1110         lpddsfd->lPitch = this->d.fb_width*this->d.depth/8;
1111         lpddsfd->dwBackBufferCount = 1;
1112         lpddsfd->x.dwRefreshRate = 60;
1113         lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1114         _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1115         return DD_OK;
1116 }
1117
1118
1119 static IDirectDraw_VTable ddvt = {
1120         IDirectDraw_QueryInterface,
1121         IDirectDraw_AddRef,
1122         IDirectDraw_Release,
1123         (void*)4,
1124         IDirectDraw_CreateClipper,
1125         IDirectDraw_CreatePalette,
1126         IDirectDraw_CreateSurface,
1127         IDirectDraw_DuplicateSurface,
1128         IDirectDraw_EnumDisplayModes,
1129         (void*)10,
1130         (void*)11,
1131         IDirectDraw_GetCaps,
1132         IDirectDraw_GetDisplayMode,
1133         (void*)14,
1134         (void*)15,
1135         (void*)16,
1136         (void*)17,
1137         IDirectDraw_GetVerticalBlankStatus,
1138         (void*)19,
1139         IDirectDraw_RestoreDisplayMode,
1140         IDirectDraw_SetCooperativeLevel,
1141         IDirectDraw_SetDisplayMode,
1142         IDirectDraw_WaitForVerticalBlank,
1143 };
1144
1145
1146 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1147
1148         char    xclsid[50];
1149         int     memsize,banksize,width,evbase,evret,major,minor,flags,height;
1150         char    *addr;
1151         
1152
1153         if (lpGUID)
1154                 StringFromCLSID(lpGUID,xclsid);
1155         else
1156                 strcpy(xclsid,"<null>");
1157
1158         fprintf(stderr,"DirectDrawCreate(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
1159         if (getuid()) {
1160                 MessageBox32A(0,"Using the XF86DGA extensions requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1161                 return E_UNEXPECTED;
1162         }
1163         *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
1164         (*lplpDD)->lpvtbl = &ddvt;
1165         (*lplpDD)->ref = 1;
1166         if (!XF86DGAQueryExtension(display,&evbase,&evret)) {
1167                 fprintf(stderr,"No XF86DGA detected.\n");
1168                 return 0;
1169         }
1170         XF86DGAQueryVersion(display,&major,&minor);
1171         fprintf(stderr,"XF86DGA is version %d.%d\n",major,minor);
1172         XF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
1173         if (!(flags & XF86DGADirectPresent))
1174                 fprintf(stderr,"direct video is NOT ENABLED.\n");
1175         XF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
1176         fprintf(stderr,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
1177                 addr,width,banksize,memsize
1178         );
1179         (*lplpDD)->d.fb_width = width;
1180         (*lplpDD)->d.fb_addr = addr;
1181         (*lplpDD)->d.fb_memsize = memsize;
1182         (*lplpDD)->d.fb_banksize = banksize;
1183
1184         XF86DGASetViewPort(display,DefaultScreen(display),0,0);
1185         XF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
1186         (*lplpDD)->d.vp_width = width;
1187         (*lplpDD)->d.vp_height = height;
1188         (*lplpDD)->d.fb_height = height;
1189         (*lplpDD)->d.vpmask = 0;
1190         return 0;
1191 }
1192 #else
1193
1194 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1195         MessageBox32A(0,"WINE DirectDraw needs the XF86DGA extensions compiled in. (libXxf86dga.a).","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1196         return E_OUTOFMEMORY;
1197 }
1198 #endif