Do not clip source rectangle even by visible region for bitblts.
[wine] / graphics / ddraw.c
1 /*              DirectDraw using DGA or Xlib
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  * FIXME: The Xshm implementation has been temporarily removed. It will be
15  * later reintegrated into the Xlib implementation.
16  */
17
18 #include "config.h"
19 #include <unistd.h>
20 #include <assert.h>
21 #include "ts_xlib.h"
22 #include <sys/signal.h>
23
24 #include "windows.h"
25 #include "winerror.h"
26 #include "interfaces.h"
27 #include "gdi.h"
28 #include "heap.h"
29 #include "ldt.h"
30 #include "dc.h"
31 #include "win.h"
32 #include "miscemu.h"
33 #include "ddraw.h"
34 #include "d3d.h"
35 #include "debug.h"
36 #include "compobj.h"
37 #include "spy.h"
38 #include "message.h"
39
40 #ifdef HAVE_LIBXXF86DGA
41 #include "ts_xf86dga.h"
42 #endif
43
44 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
45 #undef DIABLO_HACK
46
47 /* restore signal handlers overwritten by XF86DGA 
48  * this is a define, for it will only work in emulator mode
49  */
50 #undef RESTORE_SIGNALS
51
52 /* Where do these GUIDs come from?  mkuuid.
53  * They exist solely to distinguish between the targets Wine support,
54  * and should be different than any other GUIDs in existence.
55  */
56 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
57         0xe2dcb020,
58         0xdc60,
59         0x11d1,
60         {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
61 };
62
63 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
64     0x1574a740,
65     0xdc61,
66     0x11d1,
67     {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
68 };
69
70 static struct IDirectDrawSurface3_VTable        dga_dds3vt, xlib_dds3vt;
71 static struct IDirectDraw_VTable                dga_ddvt, xlib_ddvt;
72 static struct IDirectDraw2_VTable               dga_dd2vt, xlib_dd2vt;
73 static struct IDirectDrawClipper_VTable ddclipvt;
74 static struct IDirectDrawPalette_VTable dga_ddpalvt, xlib_ddpalvt;
75 static struct IDirect3D_VTable                  d3dvt;
76 static struct IDirect3D2_VTable                 d3d2vt;
77
78 void Xlib_MessagePump(HWND32 hwnd) {
79         MSG32   msg32;
80
81         while (EVENT_WaitNetEvent(FALSE,FALSE)) {
82                 while (PeekMessage32A(&msg32,0,0,0,0)) {
83                         GetMessage32A(&msg32,0,0,0);
84                         TranslateMessage32(&msg32);
85                         DispatchMessage32A(&msg32);
86                 }
87         }
88 }
89
90 BOOL32
91 DDRAW_DGA_Available()
92 {
93 #ifdef HAVE_LIBXXF86DGA
94         int evbase, evret;
95         return (getuid() == 0)&&TSXF86DGAQueryExtension(display,&evbase,&evret);
96 #else /* defined(HAVE_LIBXXF86DGA) */
97         return 0;
98 #endif /* defined(HAVE_LIBXXF86DGA) */
99 }
100
101 HRESULT WINAPI
102 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
103         if (DDRAW_DGA_Available()) {
104                 ddenumproc(&DGA_DirectDraw_GUID,"WINE with XFree86 DGA","display",data);
105         }
106         ddenumproc(&XLIB_DirectDraw_GUID,"WINE with Xlib","display",data);
107         ddenumproc(NULL,"WINE","display",data);
108         return 0;
109 }
110
111 /* What is this doing here? */
112 HRESULT WINAPI 
113 DSoundHelp(DWORD x,DWORD y,DWORD z) {
114         FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
115         return 0;
116 }
117
118
119 /******************************************************************************
120  *              internal helper functions
121  */
122 static void _dump_DDBLTFX(DWORD flagmask) {
123         int     i;
124         const struct {
125                 DWORD   mask;
126                 char    *name;
127         } flags[] = {
128 #define FE(x) { x, #x},
129                 FE(DDBLTFX_ARITHSTRETCHY)
130                 FE(DDBLTFX_MIRRORLEFTRIGHT)
131                 FE(DDBLTFX_MIRRORUPDOWN)
132                 FE(DDBLTFX_NOTEARING)
133                 FE(DDBLTFX_ROTATE180)
134                 FE(DDBLTFX_ROTATE270)
135                 FE(DDBLTFX_ROTATE90)
136                 FE(DDBLTFX_ZBUFFERRANGE)
137                 FE(DDBLTFX_ZBUFFERBASEDEST)
138         };
139         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
140            if (flags[i].mask & flagmask) {
141               DUMP("%s ",flags[i].name);
142               
143            };
144         DUMP("\n");
145         
146 }
147
148 static void _dump_DDBLTFAST(DWORD flagmask) {
149         int     i;
150         const struct {
151                 DWORD   mask;
152                 char    *name;
153         } flags[] = {
154 #define FE(x) { x, #x},
155                 FE(DDBLTFAST_NOCOLORKEY)
156                 FE(DDBLTFAST_SRCCOLORKEY)
157                 FE(DDBLTFAST_DESTCOLORKEY)
158                 FE(DDBLTFAST_WAIT)
159         };
160         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
161                 if (flags[i].mask & flagmask)
162                         DUMP("%s ",flags[i].name);
163         DUMP("\n");
164 }
165
166 static void _dump_DDBLT(DWORD flagmask) {
167         int     i;
168         const struct {
169                 DWORD   mask;
170                 char    *name;
171         } flags[] = {
172 #define FE(x) { x, #x},
173                 FE(DDBLT_ALPHADEST)
174                 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
175                 FE(DDBLT_ALPHADESTNEG)
176                 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
177                 FE(DDBLT_ALPHAEDGEBLEND)
178                 FE(DDBLT_ALPHASRC)
179                 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
180                 FE(DDBLT_ALPHASRCNEG)
181                 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
182                 FE(DDBLT_ASYNC)
183                 FE(DDBLT_COLORFILL)
184                 FE(DDBLT_DDFX)
185                 FE(DDBLT_DDROPS)
186                 FE(DDBLT_KEYDEST)
187                 FE(DDBLT_KEYDESTOVERRIDE)
188                 FE(DDBLT_KEYSRC)
189                 FE(DDBLT_KEYSRCOVERRIDE)
190                 FE(DDBLT_ROP)
191                 FE(DDBLT_ROTATIONANGLE)
192                 FE(DDBLT_ZBUFFER)
193                 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
194                 FE(DDBLT_ZBUFFERDESTOVERRIDE)
195                 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
196                 FE(DDBLT_ZBUFFERSRCOVERRIDE)
197                 FE(DDBLT_WAIT)
198                 FE(DDBLT_DEPTHFILL)
199         };
200         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
201                 if (flags[i].mask & flagmask)
202                         DUMP("%s ",flags[i].name);
203 }
204
205 static void _dump_DDSCAPS(DWORD flagmask) {
206         int     i;
207         const struct {
208                 DWORD   mask;
209                 char    *name;
210         } flags[] = {
211 #define FE(x) { x, #x},
212                 FE(DDSCAPS_RESERVED1)
213                 FE(DDSCAPS_ALPHA)
214                 FE(DDSCAPS_BACKBUFFER)
215                 FE(DDSCAPS_COMPLEX)
216                 FE(DDSCAPS_FLIP)
217                 FE(DDSCAPS_FRONTBUFFER)
218                 FE(DDSCAPS_OFFSCREENPLAIN)
219                 FE(DDSCAPS_OVERLAY)
220                 FE(DDSCAPS_PALETTE)
221                 FE(DDSCAPS_PRIMARYSURFACE)
222                 FE(DDSCAPS_PRIMARYSURFACELEFT)
223                 FE(DDSCAPS_SYSTEMMEMORY)
224                 FE(DDSCAPS_TEXTURE)
225                 FE(DDSCAPS_3DDEVICE)
226                 FE(DDSCAPS_VIDEOMEMORY)
227                 FE(DDSCAPS_VISIBLE)
228                 FE(DDSCAPS_WRITEONLY)
229                 FE(DDSCAPS_ZBUFFER)
230                 FE(DDSCAPS_OWNDC)
231                 FE(DDSCAPS_LIVEVIDEO)
232                 FE(DDSCAPS_HWCODEC)
233                 FE(DDSCAPS_MODEX)
234                 FE(DDSCAPS_MIPMAP)
235                 FE(DDSCAPS_RESERVED2)
236                 FE(DDSCAPS_ALLOCONLOAD)
237                 FE(DDSCAPS_VIDEOPORT)
238                 FE(DDSCAPS_LOCALVIDMEM)
239                 FE(DDSCAPS_NONLOCALVIDMEM)
240                 FE(DDSCAPS_STANDARDVGAMODE)
241                 FE(DDSCAPS_OPTIMIZED)
242         };
243         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
244                 if (flags[i].mask & flagmask)
245                         DUMP("%s ",flags[i].name);
246         DUMP("\n");
247 }
248
249 static void _dump_DDSD(DWORD flagmask) {
250         int     i;
251         const struct {
252                 DWORD   mask;
253                 char    *name;
254         } flags[] = {
255                 FE(DDSD_CAPS)
256                 FE(DDSD_HEIGHT)
257                 FE(DDSD_WIDTH)
258                 FE(DDSD_PITCH)
259                 FE(DDSD_BACKBUFFERCOUNT)
260                 FE(DDSD_ZBUFFERBITDEPTH)
261                 FE(DDSD_ALPHABITDEPTH)
262                 FE(DDSD_PIXELFORMAT)
263                 FE(DDSD_CKDESTOVERLAY)
264                 FE(DDSD_CKDESTBLT)
265                 FE(DDSD_CKSRCOVERLAY)
266                 FE(DDSD_CKSRCBLT)
267                 FE(DDSD_MIPMAPCOUNT)
268                 FE(DDSD_REFRESHRATE)
269                 FE(DDSD_LINEARSIZE)
270                 FE(DDSD_LPSURFACE)
271         };
272         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
273                 if (flags[i].mask & flagmask)
274                         DUMP("%s ",flags[i].name);
275         DUMP("\n");
276 }
277
278 static int _getpixelformat(LPDIRECTDRAW2 ddraw,LPDDPIXELFORMAT pf) {
279         static XVisualInfo      *vi;
280         XVisualInfo             vt;
281         int                     nitems;
282
283         if (!vi)
284                 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
285
286         pf->dwFourCC = 0;
287         if (ddraw->d.depth==8) {
288                 pf->dwFlags             = DDPF_RGB|DDPF_PALETTEINDEXED8;
289                 pf->x.dwRGBBitCount     = 8;
290                 pf->y.dwRBitMask        = 0;
291                 pf->z.dwGBitMask        = 0;
292                 pf->xx.dwBBitMask       = 0;
293                 pf->xy.dwRGBAlphaBitMask= 0;
294                 return 0;
295         }
296         if (ddraw->d.depth==16) {
297                 pf->dwFlags             = DDPF_RGB;
298                 pf->x.dwRGBBitCount     = 16;
299                 pf->y.dwRBitMask        = vi[0].red_mask;
300                 pf->z.dwGBitMask        = vi[0].green_mask;
301                 pf->xx.dwBBitMask       = vi[0].blue_mask;
302                 pf->xy.dwRGBAlphaBitMask= 0;
303                 return 0;
304         }
305         FIXME(ddraw,"_getpixelformat:unknown depth %ld?\n",ddraw->d.depth);
306         return DDERR_GENERIC;
307 }
308
309 /******************************************************************************
310  *              IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
311  *
312  * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
313  * DDS and DDS2 use those functions. (Function calls did not change (except
314  * using different DirectDrawSurfaceX version), just added flags and functions)
315  */
316 static HRESULT WINAPI IDirectDrawSurface3_Lock(
317     LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
318 ) {
319         TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
320                 this,lprect,lpddsd,flags,(DWORD)hnd);
321         if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
322             WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
323                          this,lprect,lpddsd,flags,(DWORD)hnd);
324
325         if (lprect) {
326                 FIXME(ddraw,"   lprect: %dx%d-%dx%d\n",
327                         lprect->top,lprect->left,lprect->bottom,lprect->right
328                 );
329                 lpddsd->y.lpSurface = this->s.surface +
330                         (lprect->top*this->s.lpitch) +
331                         (lprect->left*(this->s.ddraw->d.depth/8));
332         } else {
333                 assert(this->s.surface);
334                 lpddsd->y.lpSurface = this->s.surface;
335         }
336         lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
337         lpddsd->dwWidth         = this->s.width;
338         lpddsd->dwHeight        = this->s.height;
339         lpddsd->lPitch          = this->s.lpitch;
340         _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
341         return 0;
342 }
343
344 static HRESULT WINAPI DGA_IDirectDrawSurface3_Unlock(
345         LPDIRECTDRAWSURFACE3 this,LPVOID surface
346 ) {
347         TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
348         return 0;
349 }
350
351 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Unlock(
352         LPDIRECTDRAWSURFACE3 this,LPVOID surface
353 ) {
354         Xlib_MessagePump(this->s.ddraw->e.xlib.window);
355
356         TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
357
358         if (!this->s.ddraw->e.xlib.paintable)
359         {
360                 return DD_OK;
361         }
362
363         TSXPutImage(            display,
364                                 this->s.ddraw->e.xlib.drawable,
365                                 DefaultGCOfScreen(screen),
366                                 this->t.xlib.image,
367                                 0, 0, 0, 0,
368                                 this->t.xlib.image->width,
369                                 this->t.xlib.image->height
370         );
371         if (this->s.palette && this->s.palette->cm)
372                 TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
373
374         return DD_OK;
375 }
376
377 static HRESULT WINAPI DGA_IDirectDrawSurface3_Flip(
378         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
379 ) {
380 #ifdef HAVE_LIBXXF86DGA
381         TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
382         if (!flipto) {
383                 if (this->s.backbuffer)
384                         flipto = this->s.backbuffer;
385                 else
386                         flipto = this;
387         }
388         TSXF86DGASetViewPort(display,DefaultScreen(display),0,flipto->t.dga.fb_height);
389
390         if (flipto->s.palette && flipto->s.palette->cm) {
391                 TSXF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
392         }
393         while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
394         }
395         if (flipto!=this) {
396                 int     tmp;
397                 LPVOID  ptmp;
398
399                 tmp = this->t.dga.fb_height;
400                 this->t.dga.fb_height = flipto->t.dga.fb_height;
401                 flipto->t.dga.fb_height = tmp;
402
403                 ptmp = this->s.surface;
404                 this->s.surface = flipto->s.surface;
405                 flipto->s.surface = ptmp;
406         }
407         return 0;
408 #else /* defined(HAVE_LIBXXF86DGA) */
409         return E_UNEXPECTED;
410 #endif /* defined(HAVE_LIBXXF86DGA) */
411 }
412
413 static HRESULT WINAPI Xlib_IDirectDrawSurface3_Flip(
414         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
415 ) {
416         TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
417         Xlib_MessagePump(this->s.ddraw->e.xlib.window);
418         if (!this->s.ddraw->e.xlib.paintable)
419                 return 0;
420
421         if (!flipto) {
422                 if (this->s.backbuffer)
423                         flipto = this->s.backbuffer;
424                 else
425                         flipto = this;
426         }
427   
428         TSXPutImage(display,
429                                 this->s.ddraw->e.xlib.drawable,
430                                 DefaultGCOfScreen(screen),
431                                 flipto->t.xlib.image,
432                                 0, 0, 0, 0,
433                                 flipto->t.xlib.image->width,
434                                 flipto->t.xlib.image->height);
435         TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
436         if (flipto!=this) {
437                 XImage *tmp;
438                 LPVOID  *surf;
439                 tmp = this->t.xlib.image;
440                 this->t.xlib.image = flipto->t.xlib.image;
441                 flipto->t.xlib.image = tmp;
442                 surf = this->s.surface;
443                 this->s.surface = flipto->s.surface;
444                 flipto->s.surface = surf;
445         }
446         return 0;
447 }
448
449 /* The IDirectDrawSurface3::SetPalette method attaches the specified
450  * DirectDrawPalette object to a surface. The surface uses this palette for all
451  * subsequent operations. The palette change takes place immediately.
452  */
453 static HRESULT WINAPI Xlib_IDirectDrawSurface3_SetPalette(
454         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
455 ) {
456         TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
457
458         /* According to spec, we are only supposed to 
459          * AddRef if this is not the same palette.
460          */
461         if( this->s.palette != pal )
462         {
463           if( pal != NULL )
464             pal->lpvtbl->fnAddRef( pal );
465           if( this->s.palette != NULL )
466             this->s.palette->lpvtbl->fnRelease( this->s.palette );
467           this->s.palette = pal; 
468
469           /* I think that we need to attach it to all backbuffers...*/
470           if( this->s.backbuffer ) {
471              if( this->s.backbuffer->s.palette )
472                this->s.backbuffer->s.palette->lpvtbl->fnRelease(
473                  this->s.backbuffer->s.palette );
474              this->s.backbuffer->s.palette = pal;
475              if( pal )
476                 pal->lpvtbl->fnAddRef( pal );
477            }
478       
479           /* Perform the refresh */
480           TSXSetWindowColormap(display,this->s.ddraw->e.xlib.drawable,this->s.palette->cm);
481         }
482
483         return 0;
484 }
485
486 static HRESULT WINAPI DGA_IDirectDrawSurface3_SetPalette(
487         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
488 ) {
489         TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
490
491         /* According to spec, we are only supposed to 
492          * AddRef if this is not the same palette.
493          */
494         if( this->s.palette != pal )
495         {
496           if( pal != NULL ) 
497                 pal->lpvtbl->fnAddRef( pal );
498           if( this->s.palette != NULL )
499             this->s.palette->lpvtbl->fnRelease( this->s.palette );
500           this->s.palette = pal; 
501
502           /* I think that we need to attach it to all backbuffers...*/
503           if( this->s.backbuffer ) {
504              if( this->s.backbuffer->s.palette )
505                this->s.backbuffer->s.palette->lpvtbl->fnRelease(this->s.backbuffer->s.palette );
506              this->s.backbuffer->s.palette = pal;
507              if( pal ) pal->lpvtbl->fnAddRef( pal );
508           }
509           TSXF86DGAInstallColormap(display,DefaultScreen(display),this->s.palette->cm);
510         }
511         return 0;
512 }
513
514 static HRESULT WINAPI IDirectDrawSurface3_Blt(
515         LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
516 ) {
517         RECT32  xdst,xsrc;
518         int     i,j;
519
520         if (rdst) {
521                 memcpy(&xdst,rdst,sizeof(xdst));
522         } else {
523                 xdst.top        = 0;
524                 xdst.bottom     = this->s.height;
525                 xdst.left       = 0;
526                 xdst.right      = this->s.width;
527         }
528
529         if (rsrc) {
530                 memcpy(&xsrc,rsrc,sizeof(xsrc));
531         } else if (src) {
532                 xsrc.top        = 0;
533                 xsrc.bottom     = src->s.height;
534                 xsrc.left       = 0;
535                 xsrc.right      = src->s.width;
536         }
537
538         if (dwFlags & DDBLT_COLORFILL) {
539                 int     bpp = this->s.ddraw->d.depth/8;
540                 LPBYTE  xline,xpixel;
541
542                 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
543                 for (i=xdst.top;i<xdst.bottom;i++) {
544                         xpixel = xline+bpp*xdst.left;
545
546                         for (j=xdst.left;j<xdst.right;j++) {
547                                 /* FIXME: this only works on little endian
548                                  * architectures, where DWORD starts with low
549                                  * byte first!
550                                  */
551                                 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
552                                 xpixel += bpp;
553                         }
554                         xline += this->s.lpitch;
555                 }
556                 dwFlags &= ~(DDBLT_COLORFILL);
557         }
558         dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
559         if (    (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
560                 (xsrc.left==0) && (xsrc.right  ==this->s.width) &&
561                 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
562                 (xdst.left==0) && (xdst.right  ==this->s.width)  &&
563                 !dwFlags
564         ) {
565                 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
566                 return 0;
567         }
568         if (dwFlags) {
569                 FIXME(ddraw,"(%p)->(%p,%p,%p,%08lx,%p),stub!\n",
570                         this,rdst,src,rsrc,dwFlags,lpbltfx
571                 );
572                 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
573                 if (rsrc) TRACE(ddraw," srcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
574                 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
575         }
576         if (dwFlags & DDBLT_DDFX) {
577                 TRACE(ddraw,"   blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
578         }
579         return 0;
580 }
581
582 static HRESULT WINAPI IDirectDrawSurface3_BltFast(
583         LPDIRECTDRAWSURFACE3 this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE3 src,LPRECT32 rsrc,DWORD trans
584 ) {
585         int     i,bpp;
586         if (TRACE_ON(ddraw)) {
587             FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx),stub!\n",
588                     this,dstx,dsty,src,rsrc,trans
589             );
590             TRACE(ddraw,"       trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
591             TRACE(ddraw,"       srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
592         }
593         bpp = this->s.ddraw->d.depth/8;
594         for (i=0;i<rsrc->bottom-rsrc->top;i++) {
595                 memcpy( this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
596                         src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
597                         (rsrc->right-rsrc->left)*bpp
598                 );
599         }
600         return 0;
601 }
602
603 static HRESULT WINAPI IDirectDrawSurface3_BltBatch(
604         LPDIRECTDRAWSURFACE3 this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
605 ) {
606         TRACE(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
607                 this,ddbltbatch,x,y
608         );
609         return 0;
610 }
611
612 static HRESULT WINAPI IDirectDrawSurface3_GetCaps(
613         LPDIRECTDRAWSURFACE3 this,LPDDSCAPS caps
614 ) {
615         TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
616         caps->dwCaps = DDCAPS_PALETTE; /* probably more */
617         return 0;
618 }
619
620 static HRESULT WINAPI IDirectDrawSurface3_GetSurfaceDesc(
621         LPDIRECTDRAWSURFACE3 this,LPDDSURFACEDESC ddsd
622 ) { 
623         if (TRACE_ON(ddraw)) {
624                 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
625                              this,ddsd);
626                 fprintf(stderr,"        flags: ");
627                 _dump_DDSD(ddsd->dwFlags);
628                 fprintf(stderr,"\n");
629         }
630
631         ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
632         ddsd->ddsCaps.dwCaps    = DDSCAPS_PALETTE;
633         ddsd->dwBackBufferCount = 1;
634         ddsd->dwHeight          = this->s.height;
635         ddsd->dwWidth           = this->s.width;
636         ddsd->lPitch            = this->s.lpitch;
637         if (this->s.backbuffer)
638                 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
639         _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
640         
641         return 0;
642 }
643
644 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
645         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
646
647         return ++(this->ref);
648 }
649
650 static ULONG WINAPI DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
651         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
652
653 #ifdef HAVE_LIBXXF86DGA
654         if (!--(this->ref)) {
655                 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
656                 /* clear out of surface list */
657                 if (this->t.dga.fb_height == -1) {
658                         HeapFree(GetProcessHeap(),0,this->s.surface);
659                 } else {
660                         this->s.ddraw->e.dga.vpmask &= ~(1<<(this->t.dga.fb_height/this->s.ddraw->e.dga.fb_height));
661                 }
662                 HeapFree(GetProcessHeap(),0,this);
663                 return 0;
664         }
665 #endif /* defined(HAVE_LIBXXF86DGA) */
666         return this->ref;
667 }
668
669 static ULONG WINAPI Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
670         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
671
672         if (!--(this->ref)) {
673                 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
674                 HeapFree(GetProcessHeap(),0,this->s.surface);
675
676                 if( this->s.backbuffer )
677                 {
678                   this->s.backbuffer->lpvtbl->fnRelease(this->s.backbuffer);
679                 }
680
681                 this->t.xlib.image->data = NULL;
682                 TSXDestroyImage(this->t.xlib.image);
683                 this->t.xlib.image = 0;
684
685                 if (this->s.palette)
686                         this->s.palette->lpvtbl->fnRelease(this->s.palette);
687
688
689                 HeapFree(GetProcessHeap(),0,this);
690                 return 0;
691         }
692         return this->ref;
693 }
694
695 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
696         LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
697 ) {
698         TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
699                      this, lpddsd, lpdsf);
700
701         if (TRACE_ON(ddraw)) {
702                 TRACE(ddraw,"   caps ");
703                 _dump_DDSCAPS(lpddsd->dwCaps);
704         }
705
706         if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
707                 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
708                 return E_FAIL;
709         }
710
711         /* FIXME: should handle more than one backbuffer */
712         *lpdsf = this->s.backbuffer;
713  
714         if( this->s.backbuffer )
715         {
716           this->s.backbuffer->lpvtbl->fnAddRef( this->s.backbuffer );
717         }
718
719         return 0;
720 }
721
722 static HRESULT WINAPI IDirectDrawSurface3_Initialize(
723         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
724 ) {
725         return DDERR_ALREADYINITIALIZED;
726 }
727
728 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
729         LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
730 ) {
731         return _getpixelformat(this->s.ddraw,pf);
732 }
733
734 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3 this,DWORD dwFlags) {
735         FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,dwFlags);
736         return 0;
737 }
738
739 static HRESULT WINAPI IDirectDrawSurface3_GetOverlayPosition(
740         LPDIRECTDRAWSURFACE3 this,LPLONG x1,LPLONG x2
741 ) {
742         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,x1,x2);
743         return 0;
744 }
745
746 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
747         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
748 ) {
749         FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
750         return 0;
751 }
752
753 static HRESULT WINAPI IDirectDrawSurface3_AddAttachedSurface(
754         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 surf
755 ) {
756         FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
757         this->s.backbuffer = surf;
758         return 0;
759 }
760
761 static HRESULT WINAPI IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3 this,HDC32* lphdc) {
762         FIXME(ddraw,"(%p)->GetDC(%p)\n",this,lphdc);
763         *lphdc = BeginPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
764         return 0;
765 }
766
767 static HRESULT WINAPI IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3 this,HDC32 hdc) {
768         FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",this,(long)hdc);
769         EndPaint32(this->s.ddraw->e.xlib.window,&this->s.ddraw->e.xlib.ps);
770         return 0;
771 }
772
773
774 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3 this,REFIID refiid,LPVOID *obj) {
775         char    xrefiid[50];
776
777         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
778         TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
779         
780         /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
781          * the same interface. And IUnknown does that too of course.
782          */
783         if (    !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID))    ||
784                 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID))    ||
785                 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID))     ||
786                 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
787         ) {
788                 *obj = this;
789                 this->lpvtbl->fnAddRef(this);
790                 return 0;
791         }
792         FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
793         return OLE_E_ENUM_NOMORE;
794 }
795
796 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
797         TRACE(ddraw,"(%p)->(), stub!\n",this);
798         return 0; /* hmm */
799 }
800
801 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
802         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
803         return 0;
804 }
805
806 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
807         FIXME(ddraw,"(%p)->(),stub!\n",this);
808         return 0;
809 }
810
811 static HRESULT WINAPI IDirectDrawSurface3_SetColorKey(
812         LPDIRECTDRAWSURFACE3 this, DWORD dwFlags, LPDDCOLORKEY ckey
813 ) {
814         FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags,ckey);
815
816         if( dwFlags & DDCKEY_SRCBLT )
817         {
818            dwFlags &= ~DDCKEY_SRCBLT;
819         } 
820
821         if( dwFlags )
822         {
823           TRACE( ddraw, "unhandled dwFlags: %08lx\n", dwFlags );
824         }
825
826         return DD_OK;
827 }
828
829 static struct IDirectDrawSurface3_VTable dga_dds3vt = {
830         IDirectDrawSurface3_QueryInterface,
831         IDirectDrawSurface3_AddRef,
832         DGA_IDirectDrawSurface3_Release,
833         IDirectDrawSurface3_AddAttachedSurface,
834         (void*)5,
835         IDirectDrawSurface3_Blt,
836         IDirectDrawSurface3_BltBatch,
837         IDirectDrawSurface3_BltFast,
838         (void*)9,
839         IDirectDrawSurface3_EnumAttachedSurfaces,
840         (void*)11,
841         DGA_IDirectDrawSurface3_Flip,
842         IDirectDrawSurface3_GetAttachedSurface,
843         IDirectDrawSurface3_GetBltStatus,
844         IDirectDrawSurface3_GetCaps,
845         (void*)16,
846         (void*)17,
847         IDirectDrawSurface3_GetDC,
848         (void*)19,
849         IDirectDrawSurface3_GetOverlayPosition,
850         (void*)21,
851         IDirectDrawSurface3_GetPixelFormat,
852         IDirectDrawSurface3_GetSurfaceDesc,
853         IDirectDrawSurface3_Initialize,
854         IDirectDrawSurface3_IsLost,
855         IDirectDrawSurface3_Lock,
856         IDirectDrawSurface3_ReleaseDC,
857         IDirectDrawSurface3_Restore,
858         IDirectDrawSurface3_SetClipper,
859         IDirectDrawSurface3_SetColorKey,
860         (void*)31,
861         DGA_IDirectDrawSurface3_SetPalette,
862         DGA_IDirectDrawSurface3_Unlock,
863         (void*)34,
864         (void*)35,
865         (void*)36,
866         (void*)37,
867         (void*)38,
868         (void*)39,
869         (void*)40,
870 };
871
872 static struct IDirectDrawSurface3_VTable xlib_dds3vt = {
873         IDirectDrawSurface3_QueryInterface,
874         IDirectDrawSurface3_AddRef,
875         Xlib_IDirectDrawSurface3_Release,
876         IDirectDrawSurface3_AddAttachedSurface,
877         (void*)5,
878         IDirectDrawSurface3_Blt,
879         IDirectDrawSurface3_BltBatch,
880         IDirectDrawSurface3_BltFast,
881         (void*)9,
882         IDirectDrawSurface3_EnumAttachedSurfaces,
883         (void*)11,
884         Xlib_IDirectDrawSurface3_Flip,
885         IDirectDrawSurface3_GetAttachedSurface,
886         IDirectDrawSurface3_GetBltStatus,
887         IDirectDrawSurface3_GetCaps,
888         (void*)16,
889         (void*)17,
890         IDirectDrawSurface3_GetDC,
891         (void*)19,
892         IDirectDrawSurface3_GetOverlayPosition,
893         (void*)21,
894         IDirectDrawSurface3_GetPixelFormat,
895         IDirectDrawSurface3_GetSurfaceDesc,
896         IDirectDrawSurface3_Initialize,
897         IDirectDrawSurface3_IsLost,
898         IDirectDrawSurface3_Lock,
899         IDirectDrawSurface3_ReleaseDC,
900         IDirectDrawSurface3_Restore,
901         IDirectDrawSurface3_SetClipper,
902         IDirectDrawSurface3_SetColorKey,
903         (void*)31,
904         Xlib_IDirectDrawSurface3_SetPalette,
905         Xlib_IDirectDrawSurface3_Unlock,
906         (void*)34,
907         (void*)35,
908         (void*)36,
909         (void*)37,
910         (void*)38,
911         (void*)39,
912         (void*)40,
913 };
914
915 /******************************************************************************
916  *                      IDirectDrawClipper
917  */
918 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
919         LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
920 ) {
921         FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
922         return 0;
923 }
924
925 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
926         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
927
928         this->ref--;
929         if (this->ref)
930                 return this->ref;
931         HeapFree(GetProcessHeap(),0,this);
932         return 0;
933 }
934
935 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
936         LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
937 ) {
938         FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
939         if (hmm) *hmm=0;
940         return 0;
941 }
942
943 static HRESULT WINAPI IDirectDrawClipper_SetClipList(
944         LPDIRECTDRAWCLIPPER this,LPRGNDATA lprgn,DWORD hmm
945 ) {
946         FIXME(ddraw,"(%p,%p,%ld),stub!\n",this,lprgn,hmm);
947         return 0;
948 }
949
950 static struct IDirectDrawClipper_VTable ddclipvt = {
951         (void*)1,
952         (void*)2,
953         IDirectDrawClipper_Release,
954         IDirectDrawClipper_GetClipList,
955         (void*)5,
956         (void*)6,
957         (void*)7,
958         IDirectDrawClipper_SetClipList,
959         IDirectDrawClipper_SetHwnd
960 };
961
962 /******************************************************************************
963  *                      IDirectDrawPalette
964  */
965 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
966         LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
967 ) {
968         XColor xc;
969         int     i;
970
971         if (!this->cm) /* should not happen */ {
972                 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
973                 return DDERR_GENERIC;
974         }
975         for (i=0;i<count;i++) {
976 #if 0
977 PH
978                 xc.pixel = i+start;
979                 TSXQueryColor(display,this->cm,&xc);
980                 palent[i].peRed = xc.red>>8;
981                 palent[i].peGreen = xc.green>>8;
982                 palent[i].peBlue = xc.blue>>8;
983 #endif
984
985                 palent[i].peRed   = this->palents[start+i].peRed;
986                 palent[i].peBlue  = this->palents[start+i].peBlue;
987                 palent[i].peGreen = this->palents[start+i].peGreen;
988                 palent[i].peFlags = this->palents[start+i].peFlags;
989
990         }
991         return 0;
992 }
993
994 static HRESULT WINAPI Xlib_IDirectDrawPalette_SetEntries(
995         LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
996 ) {
997         XColor          xc;
998         int             i;
999
1000         TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1001                 this,x,start,count,palent
1002         );
1003         if (!this->cm) /* should not happen */ {
1004                 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1005                 return DDERR_GENERIC;
1006         }
1007         if (!this->ddraw->e.xlib.paintable)
1008                 return 0;
1009         for (i=0;i<count;i++) {
1010                 xc.red = palent[i].peRed<<8;
1011                 xc.blue = palent[i].peBlue<<8;
1012                 xc.green = palent[i].peGreen<<8;
1013                 xc.flags = DoRed|DoBlue|DoGreen;
1014                 xc.pixel = start+i;
1015
1016                 TSXStoreColor(display,this->cm,&xc);
1017
1018                 this->palents[start+i].peRed = palent[i].peRed;
1019                 this->palents[start+i].peBlue = palent[i].peBlue;
1020                 this->palents[start+i].peGreen = palent[i].peGreen;
1021                 this->palents[start+i].peFlags = palent[i].peFlags;
1022         }
1023         return 0;
1024 }
1025
1026 static HRESULT WINAPI DGA_IDirectDrawPalette_SetEntries(
1027         LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1028 ) {
1029 #ifdef HAVE_LIBXXF86DGA
1030         XColor          xc;
1031         Colormap        cm;
1032         int             i;
1033
1034         TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1035                 this,x,start,count,palent
1036         );
1037         if (!this->cm) /* should not happen */ {
1038                 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
1039                 return DDERR_GENERIC;
1040         }
1041         /* FIXME: free colorcells instead of freeing whole map */
1042         cm = this->cm;
1043         this->cm = TSXCopyColormapAndFree(display,this->cm);
1044         TSXFreeColormap(display,cm);
1045
1046         for (i=0;i<count;i++) {
1047                 xc.red = palent[i].peRed<<8;
1048                 xc.blue = palent[i].peBlue<<8;
1049                 xc.green = palent[i].peGreen<<8;
1050                 xc.flags = DoRed|DoBlue|DoGreen;
1051                 xc.pixel = i+start;
1052
1053                 TSXStoreColor(display,this->cm,&xc);
1054
1055                 this->palents[start+i].peRed = palent[i].peRed;
1056                 this->palents[start+i].peBlue = palent[i].peBlue;
1057                 this->palents[start+i].peGreen = palent[i].peGreen;
1058                 this->palents[start+i].peFlags = palent[i].peFlags;
1059         }
1060         TSXF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1061         return 0;
1062 #else /* defined(HAVE_LIBXXF86DGA) */
1063         return E_UNEXPECTED;
1064 #endif /* defined(HAVE_LIBXXF86DGA) */
1065 }
1066
1067 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1068         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1069         if (!--(this->ref)) {
1070                 if (this->cm) {
1071                         TSXFreeColormap(display,this->cm);
1072                         this->cm = 0;
1073                 }
1074                 HeapFree(GetProcessHeap(),0,this);
1075                 return 0;
1076         }
1077         return this->ref;
1078 }
1079
1080 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1081
1082         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1083         return ++(this->ref);
1084 }
1085
1086 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1087         LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1088 ) {
1089         return DDERR_ALREADYINITIALIZED;
1090 }
1091
1092 static HRESULT WINAPI IDirectDrawPalette_GetCaps(
1093          LPDIRECTDRAWPALETTE this, LPDWORD lpdwCaps )
1094 {
1095    FIXME( ddraw, "(%p)->(%p) stub.\n", this, lpdwCaps );
1096    return DD_OK;
1097
1098
1099 static HRESULT WINAPI IDirectDrawPalette_QueryInterface(
1100         LPDIRECTDRAWPALETTE this,REFIID refiid,LPVOID *obj ) 
1101 {
1102   char    xrefiid[50];
1103
1104   WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1105   FIXME(ddraw,"(%p)->(%s,%p) stub.\n",this,xrefiid,obj);
1106
1107   return S_OK;
1108 }
1109
1110 static struct IDirectDrawPalette_VTable dga_ddpalvt = {
1111         IDirectDrawPalette_QueryInterface,
1112         IDirectDrawPalette_AddRef,
1113         IDirectDrawPalette_Release,
1114         IDirectDrawPalette_GetCaps,
1115         IDirectDrawPalette_GetEntries,
1116         IDirectDrawPalette_Initialize,
1117         DGA_IDirectDrawPalette_SetEntries
1118 };
1119
1120 static struct IDirectDrawPalette_VTable xlib_ddpalvt = {
1121         IDirectDrawPalette_QueryInterface,
1122         IDirectDrawPalette_AddRef,
1123         IDirectDrawPalette_Release,
1124         IDirectDrawPalette_GetCaps,
1125         IDirectDrawPalette_GetEntries,
1126         IDirectDrawPalette_Initialize,
1127         Xlib_IDirectDrawPalette_SetEntries
1128 };
1129
1130 static HRESULT WINAPI IDirect3D_QueryInterface(
1131         LPDIRECT3D this,REFIID refiid,LPVOID *obj
1132 ) {
1133         /* FIXME: Not sure if this is correct */
1134         char    xrefiid[50];
1135
1136         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1137         TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1138         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1139                 *obj = this;
1140                 this->lpvtbl->fnAddRef(this);
1141                 return 0;
1142         }
1143         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1144                 LPDIRECT3D      d3d;
1145
1146                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1147                 d3d->ref = 1;
1148                 d3d->ddraw = (LPDIRECTDRAW)this;
1149                 this->lpvtbl->fnAddRef(this);
1150                 d3d->lpvtbl = &d3dvt;
1151                 *obj = d3d;
1152                 return 0;
1153         }
1154         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1155                 LPDIRECT3D2     d3d;
1156
1157                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1158                 d3d->ref = 1;
1159                 d3d->ddraw = (LPDIRECTDRAW)this;
1160                 this->lpvtbl->fnAddRef(this);
1161                 d3d->lpvtbl = &d3d2vt;
1162                 *obj = d3d;
1163                 return 0;
1164         }
1165         FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",this,xrefiid);
1166         return OLE_E_ENUM_NOMORE;
1167 }
1168
1169 static ULONG WINAPI IDirect3D_AddRef(LPDIRECT3D this) {
1170         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1171
1172         return ++(this->ref);
1173 }
1174
1175 static ULONG WINAPI IDirect3D_Release(LPDIRECT3D this)
1176 {
1177         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1178
1179         if (!--(this->ref)) {
1180                 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1181                 HeapFree(GetProcessHeap(),0,this);
1182                 return 0;
1183         }
1184         return this->ref;
1185 }
1186
1187 static HRESULT WINAPI IDirect3D_Initialize(
1188          LPDIRECT3D this, REFIID refiid )
1189 {
1190   /* FIXME: Not sure if this is correct */
1191   char    xrefiid[50];
1192
1193   WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1194   FIXME(ddraw,"(%p)->(%s):stub.\n",this,xrefiid);
1195   
1196   return DDERR_ALREADYINITIALIZED;
1197 }
1198
1199 /*******************************************************************************
1200  *                              IDirect3D
1201  */
1202 static struct IDirect3D_VTable d3dvt = {
1203         (void*)IDirect3D_QueryInterface,
1204         (void*)IDirect3D_AddRef,
1205         (void*)IDirect3D_Release,
1206         IDirect3D_Initialize,
1207         (void*)5,
1208         (void*)6,
1209         (void*)7,
1210         (void*)8,
1211         (void*)9,
1212 };
1213
1214 /*******************************************************************************
1215  *                              IDirect3D2
1216  */
1217 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1218         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1219
1220         if (!--(this->ref)) {
1221                 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1222                 HeapFree(GetProcessHeap(),0,this);
1223                 return 0;
1224         }
1225         return this->ref;
1226 }
1227
1228 static HRESULT WINAPI IDirect3D2_EnumDevices(
1229         LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1230 ) {
1231         D3DDEVICEDESC   d1,d2;
1232
1233         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1234         d1.dwSize       = sizeof(d1);
1235         d1.dwFlags      = 0;
1236
1237         d2.dwSize       = sizeof(d2);
1238         d2.dwFlags      = 0;
1239         cb((void*)&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1240         return 0;
1241 }
1242
1243 static struct IDirect3D2_VTable d3d2vt = {
1244         (void*)1,
1245         (void*)2,
1246         IDirect3D2_Release,
1247         IDirect3D2_EnumDevices,
1248         (void*)5,
1249         (void*)6,
1250         (void*)7,
1251         (void*)8,
1252         (void*)9,
1253 };
1254
1255 /*******************************************************************************
1256  *                              IDirectDraw
1257  */
1258
1259 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1260  * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1261  */
1262 static INT32 ddrawXlibThisOffset = 0;
1263
1264 static HRESULT WINAPI DGA_IDirectDraw2_CreateSurface(
1265         LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1266 ) {
1267 #ifdef HAVE_LIBXXF86DGA
1268         int     i;
1269
1270         TRACE(ddraw, "(%p)->(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
1271         if (TRACE_ON(ddraw)) {
1272                 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1273                 _dump_DDSD(lpddsd->dwFlags);
1274                 fprintf(stderr,"caps ");
1275                 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1276                 fprintf(stderr,"]\n");
1277         }
1278
1279         *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1280         this->lpvtbl->fnAddRef(this);
1281         (*lpdsf)->ref = 1;
1282         (*lpdsf)->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dga_dds3vt;
1283         if (    (lpddsd->dwFlags & DDSD_CAPS) && 
1284                 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1285         ) {
1286                 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1287                         lpddsd->dwWidth = this->e.dga.fb_width;
1288                 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1289                         lpddsd->dwHeight = this->e.dga.fb_height;
1290                 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1291                 (*lpdsf)->t.dga.fb_height = -1;
1292                 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1293                 TRACE(ddraw,"using system memory for a primary surface\n");
1294         } else {
1295                 for (i=0;i<32;i++)
1296                         if (!(this->e.dga.vpmask & (1<<i)))
1297                                 break;
1298                 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1299                 /* if i == 32 or maximum ... return error */
1300                 this->e.dga.vpmask|=(1<<i);
1301                 (*lpdsf)->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1302                 (*lpdsf)->t.dga.fb_height = i*this->e.dga.fb_height;
1303                 (*lpdsf)->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1304         }
1305
1306         lpddsd->lPitch = (*lpdsf)->s.lpitch;
1307
1308         (*lpdsf)->s.width = this->d.width;
1309         (*lpdsf)->s.height = this->d.height;
1310         (*lpdsf)->s.ddraw = this;
1311         (*lpdsf)->s.backbuffer = NULL;
1312         if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1313                 LPDIRECTDRAWSURFACE3    back;
1314
1315                 if (lpddsd->dwBackBufferCount>1)
1316                         FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1317
1318                 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1319                 this->lpvtbl->fnAddRef(this);
1320                 back->ref = 1;
1321                 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&dga_dds3vt;
1322                 for (i=0;i<32;i++)
1323                         if (!(this->e.dga.vpmask & (1<<i)))
1324                                 break;
1325                 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1326                 /* if i == 32 or maximum ... return error */
1327                 this->e.dga.vpmask|=(1<<i);
1328                 back->s.surface = this->e.dga.fb_addr+((i*this->e.dga.fb_height)*this->e.dga.fb_width*this->d.depth/8);
1329                 back->t.dga.fb_height = i*this->e.dga.fb_height;
1330
1331                 back->s.width = this->d.width;
1332                 back->s.height = this->d.height;
1333                 back->s.ddraw = this;
1334                 back->s.lpitch = this->e.dga.fb_width*this->d.depth/8;
1335                 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1336                                             * one! */
1337         }
1338         return 0;
1339 #else /* defined(HAVE_LIBXXF86DGA) */
1340         return E_UNEXPECTED;
1341 #endif /* defined(HAVE_LIBXXF86DGA) */
1342 }
1343
1344 static HRESULT WINAPI Xlib_IDirectDraw2_CreateSurface(
1345         LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1346 ) {
1347         XImage *img;
1348
1349         TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
1350                      this,lpddsd,lpdsf,lpunk);
1351
1352         if (TRACE_ON(ddraw)) {
1353                 fprintf(stderr,"[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1354                 _dump_DDSD(lpddsd->dwFlags);
1355                 fprintf(stderr,"caps ");
1356                 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1357                 fprintf(stderr,"]\n");
1358         }
1359
1360         *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1361
1362         this->lpvtbl->fnAddRef(this);
1363         (*lpdsf)->s.ddraw             = this;
1364         (*lpdsf)->ref                 = 1;
1365         (*lpdsf)->lpvtbl              = (LPDIRECTDRAWSURFACE_VTABLE)&xlib_dds3vt;
1366
1367         if (    (lpddsd->dwFlags & DDSD_CAPS) && 
1368                 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1369         ) {
1370                 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1371                         lpddsd->dwWidth = this->e.dga.fb_width;
1372                 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1373                         lpddsd->dwHeight = this->e.dga.fb_height;
1374                 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1375                 TRACE(ddraw,"using system memory for a primary surface\n");
1376         } else {
1377                 TRACE(ddraw,"using standard XImage for a primary surface\n");
1378                         /* FIXME: !8 bit images */
1379                 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1380                         lpddsd->dwWidth  = this->d.width;
1381                 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1382                         lpddsd->dwHeight = this->d.height;
1383         }
1384         (*lpdsf)->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,lpddsd->dwHeight*lpddsd->dwWidth*this->d.depth/8);
1385         (*lpdsf)->s.width       = lpddsd->dwWidth;
1386         (*lpdsf)->s.height      = lpddsd->dwHeight;
1387
1388         {
1389         (*lpdsf)->t.xlib.image = img =
1390                 TSXCreateImage( display,
1391                                 DefaultVisualOfScreen(screen),
1392                                 /*FIXME: depth*/8,
1393                                 ZPixmap,
1394                                 0,
1395                                 (*lpdsf)->s.surface,
1396                                 (*lpdsf)->s.width,
1397                                 (*lpdsf)->s.height,
1398                                 32,
1399                                 (*lpdsf)->s.width*1
1400                 /* FIXME: !8 bit images */
1401                 );
1402                 /* END FIXME: Xlib */
1403         }
1404         (*lpdsf)->s.lpitch = img->bytes_per_line;
1405         if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1406                 LPDIRECTDRAWSURFACE3    back;
1407
1408                 if (lpddsd->dwBackBufferCount>1)
1409                         FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1410
1411                 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE3)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface3));
1412
1413                 this->lpvtbl->fnAddRef(this);
1414                 back->s.ddraw = this;
1415
1416                 back->ref = 1;
1417                 back->lpvtbl = (LPDIRECTDRAWSURFACE3_VTABLE)&xlib_dds3vt;
1418                 /* FIXME: !8 bit images */
1419                 back->s.surface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1420                         img->width*img->height
1421                 );
1422                 back->t.xlib.image = TSXCreateImage(
1423                         display,
1424                         DefaultVisualOfScreen(screen),
1425                         /*FIXME: depth*/8,
1426                         ZPixmap,
1427                         0,
1428                         back->s.surface,
1429                         this->d.width,
1430                         this->d.height,
1431                         32,
1432                         this->d.width*1
1433                         /* FIXME: !8 bit images */
1434                 );
1435                 back->s.width = this->d.width;
1436                 back->s.height = this->d.height;
1437                 back->s.lpitch = back->t.xlib.image->bytes_per_line;
1438                 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1439                                             * one! */
1440         }
1441         return 0;
1442 }
1443
1444 static HRESULT WINAPI IDirectDraw2_DuplicateSurface(
1445         LPDIRECTDRAW2 this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1446 ) {
1447         FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1448         *dst = src; /* FIXME */
1449         return 0;
1450 }
1451
1452 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1453         LPDIRECTDRAW2 this,HWND32 hwnd,DWORD cooplevel
1454 ) {
1455         int     i;
1456         const struct {
1457                 int     mask;
1458                 char    *name;
1459         } flagmap[] = {
1460                 FE(DDSCL_FULLSCREEN)
1461                 FE(DDSCL_ALLOWREBOOT)
1462                 FE(DDSCL_NOWINDOWCHANGES)
1463                 FE(DDSCL_NORMAL)
1464                 FE(DDSCL_ALLOWMODEX)
1465                 FE(DDSCL_EXCLUSIVE)
1466                 FE(DDSCL_SETFOCUSWINDOW)
1467                 FE(DDSCL_SETDEVICEWINDOW)
1468                 FE(DDSCL_CREATEDEVICEWINDOW)
1469         };
1470
1471         TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",this,(DWORD)hwnd,cooplevel);
1472         if(TRACE_ON(ddraw)){
1473           dbg_decl_str(ddraw, 512);
1474           for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1475             if (flagmap[i].mask & cooplevel)
1476               dsprintf(ddraw, "%s ", flagmap[i].name);
1477           TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1478         }
1479         this->d.mainWindow = hwnd;
1480         return 0;
1481 }
1482
1483
1484 static HRESULT WINAPI DGA_IDirectDraw_SetDisplayMode(
1485         LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1486 ) {
1487 #ifdef HAVE_LIBXXF86DGA
1488         int     i,*depths,depcount;
1489
1490         TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", this, width, height, depth);
1491
1492         depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1493         for (i=0;i<depcount;i++)
1494                 if (depths[i]==depth)
1495                         break;
1496         TSXFree(depths);
1497         if (i==depcount) {/* not found */
1498                 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1499                 return DDERR_UNSUPPORTEDMODE;
1500         }
1501         if (this->d.width < width) {
1502                 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.width);
1503                 return DDERR_UNSUPPORTEDMODE;
1504         }
1505         this->d.width   = width;
1506         this->d.height  = height;
1507         /* adjust fb_height, so we don't overlap */
1508         if (this->e.dga.fb_height < height)
1509                 this->e.dga.fb_height = height;
1510         this->d.depth   = depth;
1511
1512         /* FIXME: this function OVERWRITES several signal handlers. 
1513          * can we save them? and restore them later? In a way that
1514          * it works for the library too?
1515          */
1516         TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1517 #ifdef DIABLO_HACK
1518         TSXF86DGASetViewPort(display,DefaultScreen(display),0,this->e.dga.fb_height);
1519 #endif
1520
1521 #ifdef RESTORE_SIGNALS
1522         SIGNAL_InitEmulator();
1523 #endif
1524         return 0;
1525 #else /* defined(HAVE_LIBXXF86DGA) */
1526         return E_UNEXPECTED;
1527 #endif /* defined(HAVE_LIBXXF86DGA) */
1528 }
1529
1530 static HRESULT WINAPI Xlib_IDirectDraw_SetDisplayMode(
1531         LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1532 ) {
1533         int     i,*depths,depcount;
1534         char    buf[200];
1535
1536         TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
1537                       this, width, height, depth);
1538
1539         depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1540         for (i=0;i<depcount;i++)
1541                 if (depths[i]==depth)
1542                         break;
1543         TSXFree(depths);
1544         if (i==depcount) {/* not found */
1545                 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
1546                 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1547                 return DDERR_UNSUPPORTEDMODE;
1548         }
1549         /*
1550         if (this->d.width < width) {
1551                 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld",width,height,depth,width,this->d.width);
1552                 MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
1553                 return DDERR_UNSUPPORTEDMODE;
1554         }
1555         */
1556         this->e.xlib.window = CreateWindowEx32A(
1557                 0,
1558                 "WINE_DirectDraw",
1559                 "WINE_DirectDraw",
1560                 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
1561                 0,0,
1562                 width,
1563                 height,
1564                 0,
1565                 0,
1566                 0,
1567                 NULL
1568         );
1569
1570         /* Store this with the window. We'll use it for the window procedure */
1571         SetWindowLong32A(this->e.xlib.window,ddrawXlibThisOffset,(LONG)this);
1572
1573         this->e.xlib.paintable = 1;
1574
1575         ShowWindow32(this->e.xlib.window,TRUE);
1576         UpdateWindow32(this->e.xlib.window);
1577
1578         assert(this->e.xlib.window);
1579
1580         this->e.xlib.drawable  = WIN_FindWndPtr(this->e.xlib.window)->window;  
1581
1582         /* We don't have a context for this window. Host off the desktop */
1583         if( !this->e.xlib.drawable )
1584         {
1585            this->e.xlib.drawable = WIN_GetDesktop()->window;
1586         }
1587
1588         this->d.width   = width;
1589         this->d.height  = height;
1590
1591         /* adjust fb_height, so we don't overlap */
1592         /*
1593         if (this->e.dga.fb_height < height)
1594                 this->e.dga.fb_height = height;*/
1595         this->d.depth   = depth;
1596         return 0;
1597 }
1598
1599 static HRESULT WINAPI DGA_IDirectDraw2_GetCaps(
1600         LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1601 ) {
1602 #ifdef HAVE_LIBXXF86DGA
1603         TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1604         caps1->dwVidMemTotal = this->e.dga.fb_memsize;
1605         caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
1606         caps1->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
1607         if (caps2) {
1608                 caps2->dwVidMemTotal = this->e.dga.fb_memsize;
1609                 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
1610                 caps2->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
1611         }
1612         return 0;
1613 #else /* defined(HAVE_LIBXXF86DGA) */
1614         return E_UNEXPECTED;
1615 #endif /* defined(HAVE_LIBXXF86DGA) */
1616 }
1617
1618 static HRESULT WINAPI Xlib_IDirectDraw2_GetCaps(
1619         LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1620 )  {
1621         TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
1622         /* FIXME: Xlib */
1623         caps1->dwVidMemTotal = 2048*1024;
1624         caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
1625         caps1->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
1626         if (caps2) {
1627                 caps2->dwVidMemTotal = 2048*1024;
1628                 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
1629                 caps2->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
1630         }
1631         /* END FIXME: Xlib */
1632         return 0;
1633 }
1634
1635 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1636         LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1637 ) {
1638         FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1639                 this,x,lpddclip,lpunk
1640         );
1641         *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1642         (*lpddclip)->ref = 1;
1643         (*lpddclip)->lpvtbl = &ddclipvt;
1644         return 0;
1645 }
1646
1647 static HRESULT WINAPI common_IDirectDraw2_CreatePalette(
1648         LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1649 ) {
1650         *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1651         if (*lpddpal == NULL) return E_OUTOFMEMORY;
1652         (*lpddpal)->ref = 1;
1653         (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1654         (*lpddpal)->installed = 0;
1655         if (this->d.depth<=8) {
1656                 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1657         } else {
1658                 /* we don't want palettes in hicolor or truecolor */
1659                 (*lpddpal)->cm = 0;
1660         }
1661         return 0;
1662 }
1663
1664 static HRESULT WINAPI DGA_IDirectDraw2_CreatePalette(
1665         LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1666 ) {
1667         HRESULT res;
1668         TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1669         res = common_IDirectDraw2_CreatePalette(this,x,palent,lpddpal,lpunk);
1670         if (res != 0) return res;
1671         (*lpddpal)->lpvtbl = &dga_ddpalvt;
1672         return 0;
1673 }
1674
1675 static HRESULT WINAPI Xlib_IDirectDraw2_CreatePalette(
1676         LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1677 ) {
1678         TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",this,x,palent,lpddpal,lpunk);
1679         *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1680         if (*lpddpal == NULL) return E_OUTOFMEMORY;
1681         (*lpddpal)->ref = 1;
1682         (*lpddpal)->installed = 0;
1683
1684         (*lpddpal)->ddraw = (LPDIRECTDRAW)this;
1685         this->lpvtbl->fnAddRef(this);
1686
1687         if (this->d.depth<=8) {
1688                 (*lpddpal)->cm = TSXCreateColormap(display,this->e.xlib.drawable,DefaultVisualOfScreen(screen),AllocAll);
1689                 /* later installed ... 
1690                  * TSXInstallColormap(display,(*lpddpal)->cm);
1691                  * TSXSetWindowColormap(display,this->e.xlib.drawable,(*lpddpal)->cm);
1692                  */
1693                 TSXInstallColormap(display,(*lpddpal)->cm);
1694         } 
1695         else
1696         {
1697                 /* we don't want palettes in hicolor or truecolor */
1698                 (*lpddpal)->cm = 0;
1699         }
1700
1701         (*lpddpal)->lpvtbl = &xlib_ddpalvt;
1702         return 0;
1703 }
1704
1705 static HRESULT WINAPI DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1706 #ifdef HAVE_LIBXXF86DGA
1707         TRACE(ddraw, "(%p)->()\n",this);
1708         Sleep(1000);
1709         TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1710 #ifdef RESTORE_SIGNALS
1711         SIGNAL_InitEmulator();
1712 #endif
1713         return 0;
1714 #else /* defined(HAVE_LIBXXF86DGA) */
1715         return E_UNEXPECTED;
1716 #endif
1717 }
1718
1719 static HRESULT WINAPI Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1720         TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", this);
1721         Sleep(1000);
1722         return 0;
1723 }
1724
1725 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
1726         LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
1727 ) {
1728         TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
1729         return 0;
1730 }
1731
1732 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
1733         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", this, this->ref );
1734
1735         return ++(this->ref);
1736 }
1737
1738 static ULONG WINAPI DGA_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1739         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1740
1741 #ifdef HAVE_LIBXXF86DGA
1742         if (!--(this->ref)) {
1743                 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
1744 #ifdef RESTORE_SIGNALS
1745                 SIGNAL_InitEmulator();
1746 #endif
1747                 HeapFree(GetProcessHeap(),0,this);
1748                 return 0;
1749         }
1750 #endif /* defined(HAVE_LIBXXF86DGA) */
1751         return this->ref;
1752 }
1753
1754 static ULONG WINAPI Xlib_IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1755         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", this, this->ref );
1756
1757         if (!--(this->ref)) {
1758                 HeapFree(GetProcessHeap(),0,this);
1759                 return 0;
1760         }
1761         /* FIXME: destroy window ... */
1762         return this->ref;
1763 }
1764
1765 static HRESULT WINAPI DGA_IDirectDraw2_QueryInterface(
1766         LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1767 ) {
1768         char    xrefiid[50];
1769
1770         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1771         TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1772         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1773                 *obj = this;
1774                 this->lpvtbl->fnAddRef(this);
1775                 return 0;
1776         }
1777         if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1778                 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_ddvt;
1779                 this->lpvtbl->fnAddRef(this);
1780                 *obj = this;
1781                 return 0;
1782         }
1783         if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1784                 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&dga_dd2vt;
1785                 this->lpvtbl->fnAddRef(this);
1786                 *obj = this;
1787                 return 0;
1788         }
1789         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1790                 LPDIRECT3D      d3d;
1791
1792                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1793                 d3d->ref = 1;
1794                 d3d->ddraw = (LPDIRECTDRAW)this;
1795                 this->lpvtbl->fnAddRef(this);
1796                 d3d->lpvtbl = &d3dvt;
1797                 *obj = d3d;
1798                 return 0;
1799         }
1800         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1801                 LPDIRECT3D2     d3d;
1802
1803                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1804                 d3d->ref = 1;
1805                 d3d->ddraw = (LPDIRECTDRAW)this;
1806                 this->lpvtbl->fnAddRef(this);
1807                 d3d->lpvtbl = &d3d2vt;
1808                 *obj = d3d;
1809                 return 0;
1810         }
1811         WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1812         return OLE_E_ENUM_NOMORE;
1813 }
1814
1815 static HRESULT WINAPI Xlib_IDirectDraw2_QueryInterface(
1816         LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1817 ) {
1818         char    xrefiid[50];
1819
1820         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1821         TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1822         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1823                 *obj = this;
1824                 this->lpvtbl->fnAddRef(this);
1825                 return 0;
1826         }
1827         if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1828                 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_ddvt;
1829                 this->lpvtbl->fnAddRef(this);
1830                 *obj = this;
1831                 return 0;
1832         }
1833         if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1834                 this->lpvtbl = (LPDIRECTDRAW2_VTABLE)&xlib_dd2vt;
1835                 this->lpvtbl->fnAddRef(this);
1836                 *obj = this;
1837                 return 0;
1838         }
1839         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1840                 LPDIRECT3D      d3d;
1841
1842                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1843                 d3d->ref = 1;
1844                 d3d->ddraw = (LPDIRECTDRAW)this;
1845                 this->lpvtbl->fnAddRef(this);
1846                 d3d->lpvtbl = &d3dvt;
1847                 *obj = d3d;
1848                 return 0;
1849         }
1850         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1851                 LPDIRECT3D2     d3d;
1852
1853                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1854                 d3d->ref = 1;
1855                 d3d->ddraw = (LPDIRECTDRAW)this;
1856                 this->lpvtbl->fnAddRef(this);
1857                 d3d->lpvtbl = &d3d2vt;
1858                 *obj = d3d;
1859                 return 0;
1860         }
1861         WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1862         return OLE_E_ENUM_NOMORE;
1863 }
1864
1865 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
1866         LPDIRECTDRAW2 this,BOOL32 *status
1867 ) {
1868         TRACE(ddraw,"(%p)->(%p)\n",this,status);
1869         *status = TRUE;
1870         return 0;
1871 }
1872
1873 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
1874         LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1875 ) {
1876         DDSURFACEDESC   ddsfd;
1877
1878         TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
1879
1880         _getpixelformat(this,&(ddsfd.ddpfPixelFormat));
1881         ddsfd.dwSize = sizeof(ddsfd);
1882         ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1883         if (dwFlags & DDEDM_REFRESHRATES) {
1884                 ddsfd.dwFlags |= DDSD_REFRESHRATE;
1885                 ddsfd.x.dwRefreshRate = 60;
1886         }
1887
1888         ddsfd.dwWidth = 640;
1889         ddsfd.dwHeight = 480;
1890         ddsfd.dwBackBufferCount = 1;
1891         ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
1892
1893         if (!modescb(&ddsfd,context)) return 0;
1894
1895         ddsfd.dwWidth = 800;
1896         ddsfd.dwHeight = 600;
1897         if (!modescb(&ddsfd,context)) return 0;
1898
1899         if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
1900                 /* modeX is not standard VGA */
1901
1902                 ddsfd.dwHeight = 200;
1903                 ddsfd.dwWidth = 320;
1904                 if (!modescb(&ddsfd,context)) return 0;
1905         }
1906         return DD_OK;
1907 }
1908
1909 static HRESULT WINAPI DGA_IDirectDraw2_GetDisplayMode(
1910         LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1911 ) {
1912 #ifdef HAVE_LIBXXF86DGA
1913         TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
1914         lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1915         lpddsfd->dwHeight = screenHeight;
1916         lpddsfd->dwWidth = screenWidth;
1917         lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
1918         lpddsfd->dwBackBufferCount = 1;
1919         lpddsfd->x.dwRefreshRate = 60;
1920         lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1921         _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1922         return DD_OK;
1923 #else /* defined(HAVE_LIBXXF86DGA) */
1924         return E_UNEXPECTED;
1925 #endif /* defined(HAVE_LIBXXF86DGA) */
1926 }
1927
1928 static HRESULT WINAPI Xlib_IDirectDraw2_GetDisplayMode(
1929         LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1930 ) {
1931         TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
1932         lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1933         lpddsfd->dwHeight = screenHeight;
1934         lpddsfd->dwWidth = screenWidth;
1935         /* POOLE FIXME: Xlib */
1936         lpddsfd->lPitch = this->e.dga.fb_width*this->d.depth/8;
1937         /* END FIXME: Xlib */
1938         lpddsfd->dwBackBufferCount = 1;
1939         lpddsfd->x.dwRefreshRate = 60;
1940         lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1941         _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1942         return DD_OK;
1943 }
1944
1945 static HRESULT WINAPI IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2 this) {
1946         TRACE(ddraw,"(%p)->()\n",this);
1947         return DD_OK;
1948 }
1949
1950 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
1951         LPDIRECTDRAW2 this,LPDWORD freq
1952 ) {
1953         FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
1954         *freq = 60*100; /* 60 Hz */
1955         return 0;
1956 }
1957
1958 /* what can we directly decompress? */
1959 static HRESULT WINAPI IDirectDraw2_GetFourCCCodes(
1960         LPDIRECTDRAW2 this,LPDWORD x,LPDWORD y
1961 ) {
1962         FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
1963         return 0;
1964 }
1965
1966 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
1967         LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
1968 ) {
1969         FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
1970         return 0;
1971 }
1972
1973 static HRESULT WINAPI IDirectDraw2_Compact(
1974           LPDIRECTDRAW2 this )
1975 {
1976   FIXME(ddraw,"(%p)->()\n", this );
1977  
1978   return DD_OK;
1979 }
1980
1981
1982 /* Note: Hack so we can reuse the old functions without compiler warnings */
1983 #ifdef __GNUC__
1984 # define XCAST(fun)     (typeof(dga_ddvt.fn##fun))
1985 #else
1986 # define XCAST(fun)     (void*)
1987 #endif
1988
1989 static struct IDirectDraw_VTable dga_ddvt = {
1990         XCAST(QueryInterface)DGA_IDirectDraw2_QueryInterface,
1991         XCAST(AddRef)IDirectDraw2_AddRef,
1992         XCAST(Release)DGA_IDirectDraw2_Release,
1993         XCAST(Compact)IDirectDraw2_Compact,
1994         XCAST(CreateClipper)IDirectDraw2_CreateClipper,
1995         XCAST(CreatePalette)DGA_IDirectDraw2_CreatePalette,
1996         XCAST(CreateSurface)DGA_IDirectDraw2_CreateSurface,
1997         XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
1998         XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
1999         XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2000         XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2001         XCAST(GetCaps)DGA_IDirectDraw2_GetCaps,
2002         XCAST(GetDisplayMode)DGA_IDirectDraw2_GetDisplayMode,
2003         XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2004         XCAST(GetGDISurface)15,
2005         XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2006         XCAST(GetScanLine)17,
2007         XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2008         XCAST(Initialize)19,
2009         XCAST(RestoreDisplayMode)DGA_IDirectDraw2_RestoreDisplayMode,
2010         XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2011         DGA_IDirectDraw_SetDisplayMode,
2012         XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2013 };
2014
2015 static struct IDirectDraw_VTable xlib_ddvt = {
2016         XCAST(QueryInterface)Xlib_IDirectDraw2_QueryInterface,
2017         XCAST(AddRef)IDirectDraw2_AddRef,
2018         XCAST(Release)Xlib_IDirectDraw2_Release,
2019         XCAST(Compact)IDirectDraw2_Compact,
2020         XCAST(CreateClipper)IDirectDraw2_CreateClipper,
2021         XCAST(CreatePalette)Xlib_IDirectDraw2_CreatePalette,
2022         XCAST(CreateSurface)Xlib_IDirectDraw2_CreateSurface,
2023         XCAST(DuplicateSurface)IDirectDraw2_DuplicateSurface,
2024         XCAST(EnumDisplayModes)IDirectDraw2_EnumDisplayModes,
2025         XCAST(EnumSurfaces)IDirectDraw2_EnumSurfaces,
2026         XCAST(FlipToGDISurface)IDirectDraw2_FlipToGDISurface,
2027         XCAST(GetCaps)Xlib_IDirectDraw2_GetCaps,
2028         XCAST(GetDisplayMode)Xlib_IDirectDraw2_GetDisplayMode,
2029         XCAST(GetFourCCCodes)IDirectDraw2_GetFourCCCodes,
2030         XCAST(GetGDISurface)15,
2031         XCAST(GetMonitorFrequency)IDirectDraw2_GetMonitorFrequency,
2032         XCAST(GetScanLine)17,
2033         XCAST(GetVerticalBlankStatus)IDirectDraw2_GetVerticalBlankStatus,
2034         XCAST(Initialize)19,
2035         XCAST(RestoreDisplayMode)Xlib_IDirectDraw2_RestoreDisplayMode,
2036         XCAST(SetCooperativeLevel)IDirectDraw2_SetCooperativeLevel,
2037         Xlib_IDirectDraw_SetDisplayMode,
2038         XCAST(WaitForVerticalBlank)IDirectDraw2_WaitForVerticalBlank,
2039 };
2040
2041 /*****************************************************************************
2042  *      IDirectDraw2
2043  *
2044  */
2045
2046
2047 static HRESULT WINAPI DGA_IDirectDraw2_SetDisplayMode(
2048         LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2049 ) {
2050         return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2051 }
2052
2053 static HRESULT WINAPI Xlib_IDirectDraw2_SetDisplayMode(
2054         LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
2055 ) {
2056         return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
2057 }
2058
2059 static HRESULT WINAPI DGA_IDirectDraw2_GetAvailableVidMem(
2060         LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2061 ) {
2062         TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2063                 this,ddscaps,total,free
2064         );
2065         if (total) *total = this->e.dga.fb_memsize * 1024;
2066         if (free) *free = this->e.dga.fb_memsize * 1024;
2067         return 0;
2068 }
2069
2070 static HRESULT WINAPI Xlib_IDirectDraw2_GetAvailableVidMem(
2071         LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
2072 ) {
2073         TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
2074                 this,ddscaps,total,free
2075         );
2076         if (total) *total = 2048 * 1024;
2077         if (free) *free = 2048 * 1024;
2078         return 0;
2079 }
2080
2081 static IDirectDraw2_VTable dga_dd2vt = {
2082         DGA_IDirectDraw2_QueryInterface,
2083         IDirectDraw2_AddRef,
2084         DGA_IDirectDraw2_Release,
2085         IDirectDraw2_Compact,
2086         IDirectDraw2_CreateClipper,
2087         DGA_IDirectDraw2_CreatePalette,
2088         DGA_IDirectDraw2_CreateSurface,
2089         (void*)8,
2090         IDirectDraw2_EnumDisplayModes,
2091         IDirectDraw2_EnumSurfaces,
2092         IDirectDraw2_FlipToGDISurface,
2093         DGA_IDirectDraw2_GetCaps,
2094         DGA_IDirectDraw2_GetDisplayMode,
2095         IDirectDraw2_GetFourCCCodes,
2096         (void*)15,
2097         IDirectDraw2_GetMonitorFrequency,
2098         (void*)17,
2099         IDirectDraw2_GetVerticalBlankStatus,
2100         (void*)19,
2101         DGA_IDirectDraw2_RestoreDisplayMode,
2102         IDirectDraw2_SetCooperativeLevel,
2103         DGA_IDirectDraw2_SetDisplayMode,
2104         IDirectDraw2_WaitForVerticalBlank,
2105         DGA_IDirectDraw2_GetAvailableVidMem
2106 };
2107
2108 static struct IDirectDraw2_VTable xlib_dd2vt = {
2109         Xlib_IDirectDraw2_QueryInterface,
2110         IDirectDraw2_AddRef,
2111         Xlib_IDirectDraw2_Release,
2112         IDirectDraw2_Compact,
2113         IDirectDraw2_CreateClipper,
2114         Xlib_IDirectDraw2_CreatePalette,
2115         Xlib_IDirectDraw2_CreateSurface,
2116         (void*)8,
2117         IDirectDraw2_EnumDisplayModes,
2118         IDirectDraw2_EnumSurfaces,
2119         IDirectDraw2_FlipToGDISurface,
2120         Xlib_IDirectDraw2_GetCaps,
2121         Xlib_IDirectDraw2_GetDisplayMode,
2122         IDirectDraw2_GetFourCCCodes,
2123         (void*)15,
2124         IDirectDraw2_GetMonitorFrequency,
2125         (void*)17,
2126         IDirectDraw2_GetVerticalBlankStatus,
2127         (void*)19,
2128         Xlib_IDirectDraw2_RestoreDisplayMode,
2129         IDirectDraw2_SetCooperativeLevel,
2130         Xlib_IDirectDraw2_SetDisplayMode,
2131         IDirectDraw2_WaitForVerticalBlank,
2132         Xlib_IDirectDraw2_GetAvailableVidMem    
2133 };
2134
2135 /******************************************************************************
2136  *                              DirectDrawCreate
2137  */
2138
2139 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2140 #ifdef HAVE_LIBXXF86DGA
2141         int     memsize,banksize,width,major,minor,flags,height;
2142         char    *addr;
2143
2144         if (getuid() != 0) {
2145                 MSG("Must be root to use XF86DGA!\n");
2146                 MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
2147                 return E_UNEXPECTED;
2148         }
2149         if (!DDRAW_DGA_Available()) {
2150                 TRACE(ddraw,"No XF86DGA detected.\n");
2151                 return DDERR_GENERIC;
2152         }
2153         *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2154         (*lplpDD)->lpvtbl = &dga_ddvt;
2155         (*lplpDD)->ref = 1;
2156         TSXF86DGAQueryVersion(display,&major,&minor);
2157         TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
2158         TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
2159         if (!(flags & XF86DGADirectPresent))
2160                 MSG("direct video is NOT PRESENT.\n");
2161         TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
2162         TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2163                 addr,width,banksize,memsize
2164         );
2165         (*lplpDD)->e.dga.fb_width = width;
2166         (*lplpDD)->d.width = width;
2167         (*lplpDD)->e.dga.fb_addr = addr;
2168         (*lplpDD)->e.dga.fb_memsize = memsize;
2169         (*lplpDD)->e.dga.fb_banksize = banksize;
2170
2171         TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
2172         TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
2173         (*lplpDD)->e.dga.fb_height = screenHeight;
2174 #ifdef DIABLO_HACK
2175         (*lplpDD)->e.dga.vpmask = 1;
2176 #else
2177         (*lplpDD)->e.dga.vpmask = 0;
2178 #endif
2179
2180         /* just assume the default depth is the DGA depth too */
2181         (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2182 #ifdef RESTORE_SIGNALS
2183         SIGNAL_InitEmulator();
2184 #endif
2185         return 0;
2186 #else /* defined(HAVE_LIBXXF86DGA) */
2187         return DDERR_INVALIDDIRECTDRAWGUID;
2188 #endif /* defined(HAVE_LIBXXF86DGA) */
2189 }
2190
2191 LRESULT WINAPI Xlib_DDWndProc(HWND32 hwnd,UINT32 msg,WPARAM32 wParam,LPARAM lParam)
2192 {
2193    LRESULT ret;
2194    LPDIRECTDRAW ddraw = NULL;
2195    DWORD lastError;
2196
2197    /*FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2198
2199    SetLastError( ERROR_SUCCESS );
2200    ddraw  = (LPDIRECTDRAW)GetWindowLong32A( hwnd, ddrawXlibThisOffset );
2201    if( (!ddraw)  &&
2202        ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
2203      ) 
2204    {
2205      ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
2206    }
2207
2208    if( ddraw )
2209    {
2210       /* Perform any special direct draw functions */
2211       if (msg==WM_PAINT)
2212       {
2213         ddraw->e.xlib.paintable = 1;
2214       } 
2215
2216       /* Now let the application deal with the rest of this */
2217       if( ddraw->d.mainWindow )
2218       {
2219     
2220         /* Don't think that we actually need to call this but... 
2221            might as well be on the safe side of things... */
2222         ret = DefWindowProc32A( hwnd, msg, wParam, lParam );
2223
2224         if( !ret )
2225         {
2226           /* We didn't handle the message - give it to the application */
2227           if (ddraw && ddraw->d.mainWindow && WIN_FindWndPtr(ddraw->d.mainWindow))
2228                 ret = CallWindowProc32A( WIN_FindWndPtr( ddraw->d.mainWindow )->winproc,
2229                                    ddraw->d.mainWindow, msg, wParam, lParam );
2230         }
2231         
2232       }
2233       else
2234       {
2235         ret = DefWindowProc32A( ddraw->d.mainWindow, msg, wParam, lParam );
2236       } 
2237
2238     }
2239     else
2240     {
2241         ret = DefWindowProc32A(hwnd,msg,wParam,lParam);
2242     }
2243
2244     return ret;
2245 }
2246
2247 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
2248         WNDCLASS32A     wc;
2249         int             have_xshm = 0;
2250         WND*            pParentWindow; 
2251
2252         *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
2253         (*lplpDD)->lpvtbl = &xlib_ddvt;
2254         (*lplpDD)->ref = 1;
2255         (*lplpDD)->e.xlib.drawable = 0; /* in SetDisplayMode */
2256         (*lplpDD)->e.xlib.use_xshm = have_xshm;
2257         wc.style        = CS_GLOBALCLASS;
2258         wc.lpfnWndProc  = Xlib_DDWndProc;
2259         wc.cbClsExtra   = 0;
2260         wc.cbWndExtra   = /* Defines extra mem for window. This is used for storing this */
2261                           sizeof( LPDIRECTDRAW ); /*  ddrawXlibThisOffset */
2262
2263         /* We can be a child of the desktop since we're really important */
2264         pParentWindow   = WIN_GetDesktop();
2265         wc.hInstance    = pParentWindow ? pParentWindow->hwndSelf : 0;
2266         wc.hInstance    = 0; 
2267
2268         wc.hIcon        = 0;
2269         wc.hCursor      = (HCURSOR32)IDC_ARROW32A;
2270         wc.hbrBackground= NULL_BRUSH;
2271         wc.lpszMenuName = 0;
2272         wc.lpszClassName= "WINE_DirectDraw";
2273
2274         (*lplpDD)->e.xlib.winclass = RegisterClass32A(&wc);
2275
2276         (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
2277         (*lplpDD)->d.height = screenHeight;
2278         (*lplpDD)->d.width = screenWidth;
2279         return 0;
2280 }
2281
2282 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
2283         char    xclsid[50];
2284
2285         if (HIWORD(lpGUID))
2286                 WINE_StringFromCLSID(lpGUID,xclsid);
2287         else {
2288                 sprintf(xclsid,"<guid-%0x08x>",(int)lpGUID);
2289                 lpGUID = NULL;
2290         }
2291
2292         TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
2293
2294         if (!lpGUID) {
2295                 /* if they didn't request a particular interface, use the best
2296                  * supported one */
2297                 if (DDRAW_DGA_Available())
2298                         lpGUID = &DGA_DirectDraw_GUID;
2299                 else
2300                         lpGUID = &XLIB_DirectDraw_GUID;
2301         }
2302
2303         if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
2304                 return DGA_DirectDrawCreate(lplpDD, pUnkOuter);
2305         else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
2306                 return Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
2307
2308         fprintf(stderr,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
2309         return DDERR_INVALIDDIRECTDRAWGUID;
2310 }