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