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