Release 980614
[wine] / graphics / ddraw.c
1 /*              DirectDraw using DGA
2  *
3  * Copyright 1997,1998 Marcus Meissner
4  */
5 /* When DirectVideo mode is enabled you can no longer use 'normal' X 
6  * applications nor can you switch to a virtual console. Also, enabling
7  * only works, if you have switched to the screen where the application
8  * is running.
9  * Some ways to debug this stuff are:
10  * - A terminal connected to the serial port. Can be bought used for cheap.
11  *   (This is the method I am using.)
12  * - Another machine connected over some kind of network.
13  */
14 /* Progress on following programs:
15  *
16  * - Diablo [640x480x8]:
17  *   The movies play. The game doesn't work, it somehow tries to write
18  *   into 2 lines _BEFORE_ the start of the surface. Don't know why.
19  *
20  * - WingCommander 4 / Win95 Patch [640x480x8]:
21  *   The intromovie plays, in 8 bit mode (to reconfigure wc4, run wine
22  *   "wc4w.exe -I"). The 16bit mode looks broken, but I think this is due to
23  *   my Matrox Mystique which uses 565 (rgb) colorweight instead of the usual
24  *   555. Specifying it in DDPIXELFORMAT didn't help.
25  *   Requires to be run in 640x480xdepth mode (doesn't seem to heed
26  *   DDSURFACEDESC.lPitch). You can fly the first mission with Maniac, but
27  *   it crashes as soon as you arrive at Blue Point Station...
28  *
29  * - Monkey Island 3 [640x480x8]:
30  *   Goes to the easy/hard selection screen, then hangs due to MT problems.
31  * 
32  * - DiscWorld 2 [640x480x8]:
33  *   [Crashes with 'cli' in released version. Yes. Privileged instructions
34  *    in 32bit code. Will they ever learn...]
35  *   Plays through nearly all intro movies. Sound and animation skip a lot of
36  *   stuff (possible DirectSound problem).
37  * 
38  * - XvT [640x480x16]:
39  *   Shows the splash screen, then fails with missing Joystick.
40  *
41  * - Tomb Raider 2 Demo (using 8 bit renderer) [640x480x8]:
42  *   Playable. Sound is weird.
43  *
44  * - WingCommander Prophecy Demo (using software renderer) [640x480x16]:
45  *   [Crashes with an invalid opcode (outb) in the release version.]
46  *   Plays intromovie, hangs in selection screen (no keyboard input, probably
47  *   DirectInput problem).
48  */
49
50 #include "config.h"
51 #include <unistd.h>
52 #include <assert.h>
53 #include "ts_xlib.h"
54 #include <sys/signal.h>
55
56 #include "windows.h"
57 #include "winerror.h"
58 #include "interfaces.h"
59 #include "gdi.h"
60 #include "heap.h"
61 #include "ldt.h"
62 #include "dc.h"
63 #include "win.h"
64 #include "miscemu.h"
65 #include "ddraw.h"
66 #include "d3d.h"
67 #include "debug.h"
68
69 #ifdef HAVE_LIBXXF86DGA
70 #include <X11/extensions/xf86dga.h>
71 #endif
72
73 /* restore signal handlers overwritten by XF86DGA 
74  * this is a define, for it will only work in emulator mode
75  */
76 #undef RESTORE_SIGNALS
77
78 static struct IDirectDrawSurface3_VTable        dds3vt;
79 static struct IDirectDrawSurface2_VTable        dds2vt;
80 static struct IDirectDrawSurface_VTable         ddsvt;
81 static struct IDirectDraw_VTable                ddvt;
82 static struct IDirectDraw2_VTable               dd2vt;
83 static struct IDirect3D_VTable                  d3dvt;
84 static struct IDirect3D2_VTable                 d3d2vt;
85
86
87 HRESULT WINAPI
88 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
89         /* we have just one display driver right now ... */
90         ddenumproc(0,"WINE Display","display",data);
91         return 0;
92 }
93
94 HRESULT WINAPI 
95 DSoundHelp(DWORD x,DWORD y,DWORD z) {
96         FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
97         return 0;
98 }
99
100
101 #ifdef HAVE_LIBXXF86DGA
102
103 /******************************************************************************
104  *              internal helper functions
105  */
106 static void _dump_DDBLTFX(DWORD flagmask) {
107         int     i;
108         const struct {
109                 DWORD   mask;
110                 char    *name;
111         } flags[] = {
112 #define FE(x) { x, #x},
113                 FE(DDBLTFX_ARITHSTRETCHY)
114                 FE(DDBLTFX_MIRRORLEFTRIGHT)
115                 FE(DDBLTFX_MIRRORUPDOWN)
116                 FE(DDBLTFX_NOTEARING)
117                 FE(DDBLTFX_ROTATE180)
118                 FE(DDBLTFX_ROTATE270)
119                 FE(DDBLTFX_ROTATE90)
120                 FE(DDBLTFX_ZBUFFERRANGE)
121                 FE(DDBLTFX_ZBUFFERBASEDEST)
122         };
123         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
124            if (flags[i].mask & flagmask) {
125               DUMP("%s ",flags[i].name);
126               
127            };
128         DUMP("\n");
129         
130 }
131
132 static void _dump_DDBLTFAST(DWORD flagmask) {
133         int     i;
134         const struct {
135                 DWORD   mask;
136                 char    *name;
137         } flags[] = {
138 #define FE(x) { x, #x},
139                 FE(DDBLTFAST_NOCOLORKEY)
140                 FE(DDBLTFAST_SRCCOLORKEY)
141                 FE(DDBLTFAST_DESTCOLORKEY)
142                 FE(DDBLTFAST_WAIT)
143         };
144         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
145                 if (flags[i].mask & flagmask)
146                         DUMP("%s ",flags[i].name);
147         DUMP("\n");
148 }
149
150 static void _dump_DDBLT(DWORD flagmask) {
151         int     i;
152         const struct {
153                 DWORD   mask;
154                 char    *name;
155         } flags[] = {
156 #define FE(x) { x, #x},
157                 FE(DDBLT_ALPHADEST)
158                 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
159                 FE(DDBLT_ALPHADESTNEG)
160                 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
161                 FE(DDBLT_ALPHAEDGEBLEND)
162                 FE(DDBLT_ALPHASRC)
163                 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
164                 FE(DDBLT_ALPHASRCNEG)
165                 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
166                 FE(DDBLT_ASYNC)
167                 FE(DDBLT_COLORFILL)
168                 FE(DDBLT_DDFX)
169                 FE(DDBLT_DDROPS)
170                 FE(DDBLT_KEYDEST)
171                 FE(DDBLT_KEYDESTOVERRIDE)
172                 FE(DDBLT_KEYSRC)
173                 FE(DDBLT_KEYSRCOVERRIDE)
174                 FE(DDBLT_ROP)
175                 FE(DDBLT_ROTATIONANGLE)
176                 FE(DDBLT_ZBUFFER)
177                 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
178                 FE(DDBLT_ZBUFFERDESTOVERRIDE)
179                 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
180                 FE(DDBLT_ZBUFFERSRCOVERRIDE)
181                 FE(DDBLT_WAIT)
182                 FE(DDBLT_DEPTHFILL)
183         };
184         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
185                 if (flags[i].mask & flagmask)
186                         DUMP("%s ",flags[i].name);
187 }
188
189 static void _dump_DDSCAPS(DWORD flagmask) {
190         int     i;
191         const struct {
192                 DWORD   mask;
193                 char    *name;
194         } flags[] = {
195 #define FE(x) { x, #x},
196                 FE(DDSCAPS_RESERVED1)
197                 FE(DDSCAPS_ALPHA)
198                 FE(DDSCAPS_BACKBUFFER)
199                 FE(DDSCAPS_COMPLEX)
200                 FE(DDSCAPS_FLIP)
201                 FE(DDSCAPS_FRONTBUFFER)
202                 FE(DDSCAPS_OFFSCREENPLAIN)
203                 FE(DDSCAPS_OVERLAY)
204                 FE(DDSCAPS_PALETTE)
205                 FE(DDSCAPS_PRIMARYSURFACE)
206                 FE(DDSCAPS_PRIMARYSURFACELEFT)
207                 FE(DDSCAPS_SYSTEMMEMORY)
208                 FE(DDSCAPS_TEXTURE)
209                 FE(DDSCAPS_3DDEVICE)
210                 FE(DDSCAPS_VIDEOMEMORY)
211                 FE(DDSCAPS_VISIBLE)
212                 FE(DDSCAPS_WRITEONLY)
213                 FE(DDSCAPS_ZBUFFER)
214                 FE(DDSCAPS_OWNDC)
215                 FE(DDSCAPS_LIVEVIDEO)
216                 FE(DDSCAPS_HWCODEC)
217                 FE(DDSCAPS_MODEX)
218                 FE(DDSCAPS_MIPMAP)
219                 FE(DDSCAPS_RESERVED2)
220                 FE(DDSCAPS_ALLOCONLOAD)
221                 FE(DDSCAPS_VIDEOPORT)
222                 FE(DDSCAPS_LOCALVIDMEM)
223                 FE(DDSCAPS_NONLOCALVIDMEM)
224                 FE(DDSCAPS_STANDARDVGAMODE)
225                 FE(DDSCAPS_OPTIMIZED)
226         };
227         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
228                 if (flags[i].mask & flagmask)
229                         DUMP("%s ",flags[i].name);
230         DUMP("\n");
231 }
232
233 void _dump_DDCAPS(DWORD flagmask) {
234         int     i;
235         const struct {
236                 DWORD   mask;
237                 char    *name;
238 } flags[] = {
239 #define FE(x) { x, #x},
240                 FE(DDCAPS_3D)
241                 FE(DDCAPS_ALIGNBOUNDARYDEST)
242                 FE(DDCAPS_ALIGNSIZEDEST)
243                 FE(DDCAPS_ALIGNBOUNDARYSRC)
244                 FE(DDCAPS_ALIGNSIZESRC)
245                 FE(DDCAPS_ALIGNSTRIDE)
246                 FE(DDCAPS_BLT)
247                 FE(DDCAPS_BLTQUEUE)
248                 FE(DDCAPS_BLTFOURCC)
249                 FE(DDCAPS_BLTSTRETCH)
250                 FE(DDCAPS_GDI)
251                 FE(DDCAPS_OVERLAY)
252                 FE(DDCAPS_OVERLAYCANTCLIP)
253                 FE(DDCAPS_OVERLAYFOURCC)
254                 FE(DDCAPS_OVERLAYSTRETCH)
255                 FE(DDCAPS_PALETTE)
256                 FE(DDCAPS_PALETTEVSYNC)
257                 FE(DDCAPS_READSCANLINE)
258                 FE(DDCAPS_STEREOVIEW)
259                 FE(DDCAPS_VBI)
260                 FE(DDCAPS_ZBLTS)
261                 FE(DDCAPS_ZOVERLAYS)
262                 FE(DDCAPS_COLORKEY)
263                 FE(DDCAPS_ALPHA)
264                 FE(DDCAPS_COLORKEYHWASSIST)
265                 FE(DDCAPS_NOHARDWARE)
266                 FE(DDCAPS_BLTCOLORFILL)
267                 FE(DDCAPS_BANKSWITCHED)
268                 FE(DDCAPS_BLTDEPTHFILL)
269                 FE(DDCAPS_CANCLIP)
270                 FE(DDCAPS_CANCLIPSTRETCHED)
271                 FE(DDCAPS_CANBLTSYSMEM)
272         };
273         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
274                 if (flags[i].mask & flagmask)
275                         DUMP("%s ",flags[i].name);
276         DUMP("\n");
277 }
278
279 static void _dump_DDSD(DWORD flagmask) {
280         int     i;
281         const struct {
282                 DWORD   mask;
283                 char    *name;
284         } flags[] = {
285                 FE(DDSD_CAPS)
286                 FE(DDSD_HEIGHT)
287                 FE(DDSD_WIDTH)
288                 FE(DDSD_PITCH)
289                 FE(DDSD_BACKBUFFERCOUNT)
290                 FE(DDSD_ZBUFFERBITDEPTH)
291                 FE(DDSD_ALPHABITDEPTH)
292                 FE(DDSD_PIXELFORMAT)
293                 FE(DDSD_CKDESTOVERLAY)
294                 FE(DDSD_CKDESTBLT)
295                 FE(DDSD_CKSRCOVERLAY)
296                 FE(DDSD_CKSRCBLT)
297                 FE(DDSD_MIPMAPCOUNT)
298                 FE(DDSD_REFRESHRATE)
299                 FE(DDSD_LINEARSIZE)
300                 FE(DDSD_LPSURFACE)
301         };
302         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
303                 if (flags[i].mask & flagmask)
304                         DUMP("%s ",flags[i].name);
305         DUMP("\n");
306 }
307
308 static int _getpixelformat(LPDIRECTDRAW ddraw,LPDDPIXELFORMAT pf) {
309         static XVisualInfo      *vi;
310         XVisualInfo             vt;
311         int                     nitems;
312
313         if (!vi)
314                 vi = TSXGetVisualInfo(display,VisualNoMask,&vt,&nitems);
315
316         pf->dwFourCC = 0;
317         if (ddraw->d.depth==8) {
318                 pf->dwFlags             = DDPF_RGB|DDPF_PALETTEINDEXED8;
319                 pf->x.dwRGBBitCount     = 8;
320                 pf->y.dwRBitMask        = 0;
321                 pf->z.dwGBitMask        = 0;
322                 pf->xx.dwBBitMask       = 0;
323                 pf->xy.dwRGBAlphaBitMask= 0;
324                 return 0;
325         }
326         if (ddraw->d.depth==16) {
327                 pf->dwFlags             = DDPF_RGB;
328                 pf->x.dwRGBBitCount     = 16;
329                 pf->y.dwRBitMask        = vi[0].red_mask;
330                 pf->z.dwGBitMask        = vi[0].green_mask;
331                 pf->xx.dwBBitMask       = vi[0].blue_mask;
332                 pf->xy.dwRGBAlphaBitMask= 0;
333                 return 0;
334         }
335         FIXME(ddraw,"_getpixelformat:oops?\n");
336         return DDERR_GENERIC;
337 }
338
339 /******************************************************************************
340  *                      IDirectDrawSurface
341  */
342
343 static HRESULT WINAPI IDirectDrawSurface_Lock(
344     LPDIRECTDRAWSURFACE this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
345 ) {
346         TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
347                 this,lprect,lpddsd,flags,(DWORD)hnd);
348         if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
349             WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
350                          this,lprect,lpddsd,flags,(DWORD)hnd);
351
352         if (lprect) {
353                 TRACE(ddraw,"   lprect: %dx%d-%dx%d\n",
354                         lprect->top,lprect->left,lprect->bottom,lprect->right
355                 );
356                 lpddsd->y.lpSurface =   this->s.surface+
357                                         (lprect->top*this->s.lpitch)+
358                                         (lprect->left*(this->s.ddraw->d.depth/8));
359         } else
360                 lpddsd->y.lpSurface = this->s.surface;
361         lpddsd->dwFlags = DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_LPSURFACE;
362         lpddsd->dwWidth         = this->s.width;
363         lpddsd->dwHeight        = this->s.height;
364         lpddsd->lPitch          = this->s.lpitch;
365         _getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
366         return 0;
367 }
368
369 static HRESULT WINAPI IDirectDrawSurface_Unlock(
370         LPDIRECTDRAWSURFACE this,LPVOID surface
371 ) {
372         TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
373         return 0;
374 }
375
376 static HRESULT WINAPI IDirectDrawSurface_Flip(
377         LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE flipto,DWORD dwFlags
378 ) {
379         TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
380         if (!flipto) {
381                 if (this->s.backbuffer)
382                         flipto = this->s.backbuffer;
383                 else
384                         flipto = this;
385         }
386         XF86DGASetViewPort(display,DefaultScreen(display),0,flipto->s.fb_height);
387         if (flipto->s.palette && flipto->s.palette->cm)
388                 XF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
389         while (!XF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
390         }
391         if (flipto!=this) {
392                 int     tmp;
393                 LPVOID  ptmp;
394
395                 tmp = this->s.fb_height;
396                 this->s.fb_height = flipto->s.fb_height;
397                 flipto->s.fb_height = tmp;
398
399                 ptmp = this->s.surface;
400                 this->s.surface = flipto->s.surface;
401                 flipto->s.surface = ptmp;
402         }
403         return 0;
404 }
405
406 static HRESULT WINAPI IDirectDrawSurface_SetPalette(
407         LPDIRECTDRAWSURFACE this,LPDIRECTDRAWPALETTE pal
408 ) {
409         TRACE(ddraw,"(%p)->SetPalette(%p)\n",this,pal);
410         this->s.palette = pal; /* probably addref it too */
411         return 0;
412 }
413
414 static HRESULT WINAPI IDirectDrawSurface_Blt(
415         LPDIRECTDRAWSURFACE this,LPRECT32 rdst,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
416 ) {
417         RECT32  xdst,xsrc;
418         int     i,j;
419
420         if (rdst)
421                 memcpy(&xdst,rdst,sizeof(xdst));
422         else {
423                 xdst.top        = 0;
424                 xdst.bottom     = this->s.height;
425                 xdst.left       = 0;
426                 xdst.right      = this->s.width;
427         }
428         if (rsrc)
429                 memcpy(&xsrc,rsrc,sizeof(xsrc));
430         else if (src) {
431                 xsrc.top        = 0;
432                 xsrc.bottom     = src->s.height;
433                 xsrc.left       = 0;
434                 xsrc.right      = src->s.width;
435         }
436
437         if (dwFlags & DDBLT_COLORFILL) {
438                 int     bpp = this->s.ddraw->d.depth/8;
439                 LPBYTE  xline,xpixel;
440
441                 xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
442                 for (i=xdst.top;i<xdst.bottom;i++) {
443                         xpixel = xline+bpp*xdst.left;
444
445                         for (j=xdst.left;j<xdst.right;j++) {
446                                 /* FIXME: this only works on little endian
447                                  * architectures, where DWORD starts with low
448                                  * byte first!
449                                  */
450                                 memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
451                                 xpixel += bpp;
452                         }
453                         xline += this->s.lpitch;
454                 }
455                 dwFlags &= ~(DDBLT_COLORFILL);
456         }
457         dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
458         if (    (xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
459                 (xsrc.left==0) && (xsrc.right  ==this->s.width) &&
460                 (xdst.top ==0) && (xdst.bottom ==this->s.height) &&
461                 (xdst.left==0) && (xdst.right  ==this->s.width)  &&
462                 !dwFlags
463         ) {
464                 memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
465                 return 0;
466         }
467         if (dwFlags) {
468                 FIXME(ddraw,"(%p)->(%p,%p,%p,%08lx,%p),stub!\n",
469                         this,rdst,src,rsrc,dwFlags,lpbltfx
470                 );
471                 if (rdst) TRACE(ddraw," destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
472                 if (rsrc) TRACE(ddraw," srcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
473                 TRACE(ddraw,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
474         }
475         if (dwFlags & DDBLT_DDFX) {
476                 TRACE(ddraw,"   blitfx: \n");_dump_DDBLTFX(lpbltfx->dwDDFX);
477         }
478         return 0;
479 }
480
481 static HRESULT WINAPI IDirectDrawSurface_BltFast(
482         LPDIRECTDRAWSURFACE this,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD trans
483 ) {
484         int     i,bpp;
485         if (TRACE_ON(ddraw)) {
486             FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx),stub!\n",
487                     this,dstx,dsty,src,rsrc,trans
488             );
489             TRACE(ddraw,"       trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
490             TRACE(ddraw,"       srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
491         }
492         bpp = this->s.ddraw->d.depth/8;
493         for (i=0;i<rsrc->bottom-rsrc->top;i++) {
494                 memcpy( this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
495                         src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
496                         (rsrc->right-rsrc->left)*bpp
497                 );
498         }
499         return 0;
500 }
501
502 static HRESULT WINAPI IDirectDrawSurface_BltBatch(
503         LPDIRECTDRAWSURFACE this,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
504 ) {
505         TRACE(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
506                 this,ddbltbatch,x,y
507         );
508         return 0;
509 }
510
511 static HRESULT WINAPI IDirectDrawSurface_GetCaps(
512         LPDIRECTDRAWSURFACE this,LPDDSCAPS caps
513 ) {
514         TRACE(ddraw,"(%p)->GetCaps(%p)\n",this,caps);
515         caps->dwCaps = DDCAPS_PALETTE; /* probably more */
516         return 0;
517 }
518
519 static HRESULT WINAPI IDirectDrawSurface_GetSurfaceDesc(
520         LPDIRECTDRAWSURFACE this,LPDDSURFACEDESC ddsd
521 ) { 
522         if (TRACE_ON(ddraw)) {
523                 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
524                              this,ddsd);
525                 fprintf(stderr,"        flags: ");
526                 _dump_DDSD(ddsd->dwFlags);
527                 fprintf(stderr,"\n");
528         }
529
530         ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
531         ddsd->ddsCaps.dwCaps    = DDSCAPS_PALETTE;
532         ddsd->dwBackBufferCount = 1;
533         ddsd->dwHeight          = this->s.height;
534         ddsd->dwWidth           = this->s.width;
535         ddsd->lPitch            = this->s.lpitch;
536         if (this->s.backbuffer)
537                 ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
538         _getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
539         
540         return 0;
541 }
542
543 static ULONG WINAPI IDirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE this) {
544         TRACE(ddraw,"(%p)->AddRef()\n",this);
545         return ++(this->ref);
546 }
547
548 static ULONG WINAPI IDirectDrawSurface_Release(LPDIRECTDRAWSURFACE this) {
549         TRACE(ddraw,"(%p)->Release()\n",this);
550         if (!--(this->ref)) {
551                 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
552                 /* clear out of surface list */
553                 if (this->s.fb_height == -1) {
554                         HeapFree(GetProcessHeap(),0,this->s.surface);
555                 } else {
556                         this->s.ddraw->d.vpmask &= ~(1<<(this->s.fb_height/this->s.ddraw->d.fb_height));
557                 }
558                 HeapFree(GetProcessHeap(),0,this);
559                 return 0;
560         }
561         return this->ref;
562 }
563
564 static HRESULT WINAPI IDirectDrawSurface_GetAttachedSurface(
565         LPDIRECTDRAWSURFACE this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE *lpdsf
566 ) {
567         TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
568                      this, lpddsd, lpdsf);
569         if (TRACE_ON(ddraw)) {
570                 TRACE(ddraw,"   caps ");
571                 _dump_DDSCAPS(lpddsd->dwCaps);
572         }
573         if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
574                 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
575                 return E_FAIL;
576         }
577         /* FIXME: should handle more than one backbuffer */
578         *lpdsf = this->s.backbuffer;
579         return 0;
580 }
581
582 static HRESULT WINAPI IDirectDrawSurface_Initialize(
583         LPDIRECTDRAWSURFACE this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
584 ) {
585         return DDERR_ALREADYINITIALIZED;
586 }
587
588 static HRESULT WINAPI IDirectDrawSurface_GetPixelFormat(
589         LPDIRECTDRAWSURFACE this,LPDDPIXELFORMAT pf
590 ) {
591         return _getpixelformat(this->s.ddraw,pf);
592 }
593
594 static HRESULT WINAPI IDirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE this,DWORD dwFlags) {
595         FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",
596                 this,dwFlags
597         );
598         return 0;
599 }
600
601 static HRESULT WINAPI IDirectDrawSurface_GetOverlayPosition(
602         LPDIRECTDRAWSURFACE this,LPLONG x1,LPLONG x2
603 ) {
604         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",
605                 this,x1,x2
606         );
607         return 0;
608 }
609
610 static HRESULT WINAPI IDirectDrawSurface_SetClipper(
611         LPDIRECTDRAWSURFACE this,LPDIRECTDRAWCLIPPER clipper
612 ) {
613         FIXME(ddraw,"(%p)->(%p),stub!\n",this,clipper);
614         return 0;
615 }
616
617 static HRESULT WINAPI IDirectDrawSurface_AddAttachedSurface(
618         LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE surf
619 ) {
620         FIXME(ddraw,"(%p)->(%p),stub!\n",this,surf);
621         this->s.backbuffer = surf;
622         return 0;
623 }
624
625 static HRESULT WINAPI IDirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE this,HDC32* lphdc) {
626         FIXME(ddraw,"(%p)->GetDC(%p),stub!\n",this,lphdc);
627         return 0;
628 }
629
630 static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE this,REFIID refiid,LPVOID *obj) {
631         char    xrefiid[50];
632
633         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
634         TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
635         
636         /* thats version 3 (DirectX 5) */
637         if (    !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID_IDirectDrawSurface3))) {
638                 this->lpvtbl->fnAddRef(this);
639                 this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds3vt;
640                 *obj = this;
641                 return 0;
642         }
643         /* thats version 2 (DirectX 3) */
644         if (    !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID_IDirectDrawSurface2))) {
645                 this->lpvtbl->fnAddRef(this);
646                 this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds2vt;
647                 *obj = this;
648                 return 0;
649         }
650         /* thats us */
651         if (!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID_IDirectDrawSurface))) {
652                 this->lpvtbl->fnAddRef(this);
653                 *obj = this;
654                 return 0;
655         }
656         WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
657         return OLE_E_ENUM_NOMORE;
658 }
659
660 static HRESULT WINAPI IDirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE this) {
661         return 0; /* hmm */
662 }
663
664 static struct IDirectDrawSurface_VTable ddsvt = {
665         IDirectDrawSurface_QueryInterface,
666         IDirectDrawSurface_AddRef,
667         IDirectDrawSurface_Release,
668         IDirectDrawSurface_AddAttachedSurface,
669         (void*)5,
670         IDirectDrawSurface_Blt,
671         IDirectDrawSurface_BltBatch,
672         IDirectDrawSurface_BltFast,
673         (void*)9,
674         (void*)10,
675         (void*)11,
676         IDirectDrawSurface_Flip,
677         IDirectDrawSurface_GetAttachedSurface,
678         IDirectDrawSurface_GetBltStatus,
679         IDirectDrawSurface_GetCaps,
680         (void*)16,
681         (void*)17,
682         IDirectDrawSurface_GetDC,
683         (void*)19,
684         IDirectDrawSurface_GetOverlayPosition,
685         (void*)21,
686         IDirectDrawSurface_GetPixelFormat,
687         IDirectDrawSurface_GetSurfaceDesc,
688         IDirectDrawSurface_Initialize,
689         IDirectDrawSurface_IsLost,
690         IDirectDrawSurface_Lock,
691         (void*)27,
692         (void*)28,
693         IDirectDrawSurface_SetClipper,
694         (void*)30,
695         (void*)31,
696         IDirectDrawSurface_SetPalette,
697         IDirectDrawSurface_Unlock,
698         (void*)34,
699         (void*)35,
700         (void*)36,
701 };
702
703 /******************************************************************************
704  *                      IDirectDrawSurface2
705  *
706  * calls IDirectDrawSurface methods where possible
707  */
708 static HRESULT WINAPI IDirectDrawSurface2_Lock(
709     LPDIRECTDRAWSURFACE2 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
710 ) {
711         return IDirectDrawSurface_Lock((LPDIRECTDRAWSURFACE)this,lprect,lpddsd,flags,hnd);
712 }
713
714 static HRESULT WINAPI IDirectDrawSurface2_Unlock(
715         LPDIRECTDRAWSURFACE2 this,LPVOID surface
716 ) {
717         TRACE(ddraw,"(%p)->Unlock(%p)\n",this,surface);
718         return 0;
719 }
720
721 static HRESULT WINAPI IDirectDrawSurface2_SetPalette(
722         LPDIRECTDRAWSURFACE2 this,LPDIRECTDRAWPALETTE pal
723 ) {
724         return IDirectDrawSurface_SetPalette((LPDIRECTDRAWSURFACE)this,pal);
725 }
726
727 static ULONG WINAPI IDirectDrawSurface2_AddRef(LPDIRECTDRAWSURFACE2 this) {
728         TRACE(ddraw,"(%p)->AddRef()\n",this);
729         return ++(this->ref);
730 }
731
732 static ULONG WINAPI IDirectDrawSurface2_Release(LPDIRECTDRAWSURFACE2 this) {
733         return IDirectDrawSurface_Release((LPDIRECTDRAWSURFACE)this);
734 }
735
736 static HRESULT WINAPI IDirectDrawSurface2_GetAttachedSurface(
737         LPDIRECTDRAWSURFACE2 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE2 *lpdsf
738 ) {
739         HRESULT ret = IDirectDrawSurface_GetAttachedSurface((LPDIRECTDRAWSURFACE)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf);
740
741         if (!ret)
742                 (*lpdsf)->lpvtbl = &dds2vt;
743         return ret;
744 }
745
746 static HRESULT WINAPI IDirectDrawSurface2_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
747         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
748         return 0;
749 }
750
751 static HRESULT WINAPI IDirectDrawSurface2_QueryInterface(
752         LPDIRECTDRAWSURFACE2 this,REFIID riid,LPVOID *ppobj
753 ) {
754         return IDirectDrawSurface_QueryInterface((LPDIRECTDRAWSURFACE)this,riid,ppobj);
755 }
756
757 static HRESULT WINAPI IDirectDrawSurface2_IsLost(LPDIRECTDRAWSURFACE2 this) {
758         return 0; /* hmm */
759 }
760
761
762 static struct IDirectDrawSurface2_VTable dds2vt = {
763         IDirectDrawSurface2_QueryInterface,
764         IDirectDrawSurface2_AddRef,
765         IDirectDrawSurface2_Release,
766         (void*)4,
767         (void*)5,
768         (void*)6/*IDirectDrawSurface_Blt*/,
769         (void*)7/*IDirectDrawSurface_BltBatch*/,
770         (void*)8,
771         (void*)9,
772         IDirectDrawSurface2_EnumAttachedSurfaces,
773         (void*)11,
774         (void*)12,
775         IDirectDrawSurface2_GetAttachedSurface,
776         (void*)14,
777         (void*)15/*IDirectDrawSurface_GetCaps*/,
778         (void*)16,
779         (void*)17,
780         (void*)18,
781         (void*)19,
782         (void*)20,
783         (void*)21,
784         (void*)22,
785         (void*)23/*IDirectDrawSurface_GetSurfaceDesc*/,
786         (void*)24,
787         IDirectDrawSurface2_IsLost,
788         IDirectDrawSurface2_Lock,
789         (void*)27,
790         (void*)28,
791         (void*)29,
792         (void*)30,
793         (void*)31,
794         IDirectDrawSurface2_SetPalette,
795         IDirectDrawSurface2_Unlock,
796         (void*)34,
797         (void*)35,
798         (void*)36,
799         (void*)37,
800         (void*)38,
801         (void*)39,
802 };
803
804 /******************************************************************************
805  *                      IDirectDrawSurface3
806  */
807 static HRESULT WINAPI IDirectDrawSurface3_SetPalette(
808         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
809 ) {
810         return IDirectDrawSurface_SetPalette((LPDIRECTDRAWSURFACE)this,pal);
811 }
812
813 static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
814         LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
815 ) {
816         return _getpixelformat(this->s.ddraw,pf);
817 }
818
819 static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
820         LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
821 ) {
822         HRESULT ret = IDirectDrawSurface_GetAttachedSurface((LPDIRECTDRAWSURFACE)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf);
823
824         if (!ret)
825                 (*lpdsf)->lpvtbl = &dds3vt;
826         return ret;
827 }
828
829 static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
830         TRACE(ddraw,"(%p)->AddRef()\n",this);
831         return ++(this->ref);
832 }
833
834 static ULONG WINAPI IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
835         TRACE(ddraw,"(%p)->Release()\n",this);
836         if (!--(this->ref)) {
837                 this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
838                 this->s.ddraw->d.vpmask &= ~(1<<(this->s.fb_height/this->s.ddraw->d.fb_height));
839                 HeapFree(GetProcessHeap(),0,this);
840                 return 0;
841         }
842         return this->ref;
843 }
844
845 static HRESULT WINAPI IDirectDrawSurface3_Blt(
846         LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,
847         LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
848 ) {
849         return IDirectDrawSurface_Blt((LPDIRECTDRAWSURFACE)this,rdst,(LPDIRECTDRAWSURFACE)src,rsrc,dwFlags,lpbltfx);
850 }
851
852 static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
853         return 0; /* hmm */
854 }
855
856 static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
857         return 0;
858 }
859
860 static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(
861         LPDIRECTDRAWSURFACE3 this,DWORD dwflags
862 ) {
863         return IDirectDrawSurface_GetBltStatus((LPDIRECTDRAWSURFACE)this,dwflags);
864 }
865
866 static HRESULT WINAPI IDirectDrawSurface3_Flip(
867         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
868 ) {
869         return IDirectDrawSurface_Flip((LPDIRECTDRAWSURFACE)this,(LPDIRECTDRAWSURFACE)flipto,dwFlags);
870 }
871
872 static HRESULT WINAPI IDirectDrawSurface3_Lock(
873     LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
874 ) {
875         return IDirectDrawSurface_Lock((LPDIRECTDRAWSURFACE)this,lprect,lpddsd,flags,hnd); 
876 }
877
878 static HRESULT WINAPI IDirectDrawSurface3_Unlock(
879         LPDIRECTDRAWSURFACE3 this,LPVOID surface
880 ) {
881         return IDirectDrawSurface_Unlock((LPDIRECTDRAWSURFACE)this,surface);
882 }
883
884 static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
885         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,context,esfcb);
886         return 0;
887 }
888
889 static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
890         LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
891 ) {
892         return IDirectDrawSurface_SetClipper((LPDIRECTDRAWSURFACE)this,clipper);
893 }
894
895 static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(
896         LPDIRECTDRAWSURFACE3 this,REFIID riid,LPVOID *ppobj
897 ) {
898         return IDirectDrawSurface_QueryInterface((LPDIRECTDRAWSURFACE)this,riid,ppobj);
899 }
900
901 static struct IDirectDrawSurface3_VTable dds3vt = {
902         IDirectDrawSurface3_QueryInterface,
903         IDirectDrawSurface3_AddRef,
904         IDirectDrawSurface3_Release,
905         (void*)4,
906         (void*)5,
907         IDirectDrawSurface3_Blt,
908         (void*)7,
909         (void*)8,
910         (void*)9,
911         IDirectDrawSurface3_EnumAttachedSurfaces,
912         (void*)11,
913         IDirectDrawSurface3_Flip,
914         IDirectDrawSurface3_GetAttachedSurface,
915         IDirectDrawSurface3_GetBltStatus,
916         (void*)15,
917         (void*)16,
918         (void*)17,
919         (void*)18,
920         (void*)19,
921         (void*)20,
922         (void*)21,
923         IDirectDrawSurface3_GetPixelFormat,
924         (void*)23,
925         (void*)24,
926         IDirectDrawSurface3_IsLost,
927         IDirectDrawSurface3_Lock,
928         (void*)27,
929         IDirectDrawSurface3_Restore,
930         IDirectDrawSurface3_SetClipper,
931         (void*)30,
932         (void*)31,
933         IDirectDrawSurface3_SetPalette,
934         IDirectDrawSurface3_Unlock,
935         (void*)34,
936         (void*)35,
937         (void*)36,
938         (void*)37,
939         (void*)38,
940         (void*)39,
941         (void*)40,
942 };
943
944
945 /******************************************************************************
946  *                      IDirectDrawClipper
947  */
948 static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
949         LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
950 ) {
951         FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
952         return 0;
953 }
954
955 static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
956         this->ref--;
957         if (this->ref)
958                 return this->ref;
959         HeapFree(GetProcessHeap(),0,this);
960         return 0;
961 }
962
963 static HRESULT WINAPI IDirectDrawClipper_GetClipList(
964         LPDIRECTDRAWCLIPPER this,LPRECT32 rects,LPRGNDATA lprgn,LPDWORD hmm
965 ) {
966         FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",this,rects,lprgn,hmm);
967         if (hmm) *hmm=0;
968         return 0;
969 }
970
971 static struct IDirectDrawClipper_VTable ddclipvt = {
972         (void*)1,
973         (void*)2,
974         IDirectDrawClipper_Release,
975         IDirectDrawClipper_GetClipList,
976         (void*)5,
977         (void*)6,
978         (void*)7,
979         (void*)8,
980         IDirectDrawClipper_SetHwnd
981 };
982
983 /******************************************************************************
984  *                      IDirectDrawPalette
985  */
986 static HRESULT WINAPI IDirectDrawPalette_GetEntries(
987         LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
988 ) {
989         int     i;
990
991         FIXME(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p),stub!\n",
992                 this,x,start,end,palent
993         );
994         for (i=start;i<end;i++) {
995                 palent[i-start].peRed = i;
996                 palent[i-start].peGreen = i;
997                 palent[i-start].peBlue = i;
998         }
999         return 0;
1000 }
1001
1002 static HRESULT WINAPI IDirectDrawPalette_SetEntries(
1003         LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
1004 ) {
1005         XColor          xc;
1006         int             i;
1007
1008         TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1009                 this,x,start,end,palent
1010         );
1011         if (!this->cm) /* should not happen */ {
1012                 ERR(ddraw,"no colormap in SetEntries???\n");
1013                 return DDERR_GENERIC;
1014         }
1015 /* FIXME: free colorcells instead of freeing whole map */
1016         TSXFreeColormap(display,this->cm);
1017         this->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1018         if (start>0) {
1019                 xc.red = xc.blue = xc.green = 0; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 0; TSXStoreColor(display,this->cm,&xc);
1020                 this->palents[0].peRed = 0;
1021                 this->palents[0].peBlue = 0;
1022                 this->palents[0].peGreen = 0;
1023         }
1024         if (end<256) {
1025                 xc.red = xc.blue = xc.green = 0xffff; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 255; TSXStoreColor(display,this->cm,&xc);
1026                 this->palents[255].peRed = 255;
1027                 this->palents[255].peBlue = 255;
1028                 this->palents[255].peGreen = 255;
1029         }
1030         for (i=start;i<end;i++) {
1031                 xc.red = palent[i-start].peRed<<8;
1032                 xc.blue = palent[i-start].peBlue<<8;
1033                 xc.green = palent[i-start].peGreen<<8;
1034                 xc.flags = DoRed|DoBlue|DoGreen;
1035                 xc.pixel = i;
1036                 TSXStoreColor(display,this->cm,&xc);
1037                 this->palents[i].peRed = palent[i-start].peRed;
1038                 this->palents[i].peBlue = palent[i-start].peBlue;
1039                 this->palents[i].peGreen = palent[i-start].peGreen;
1040         }
1041
1042 /* Insomnia's (Stea Greene's) Mods Start Here */
1043 /* FIXME: Still should free individual cells, but this fixes loss of */
1044 /*        unchange sections of old palette */
1045
1046         for (i=0;i<start;i++) {
1047                 xc.red = this->palents[i].peRed<<8;
1048                 xc.blue = this->palents[i].peBlue<<8;
1049                 xc.green = this->palents[i].peGreen<<8;
1050                 xc.flags = DoRed|DoBlue|DoGreen;
1051                 xc.pixel = i;
1052                 TSXStoreColor(display,this->cm,&xc);
1053         }
1054         for (i=end;i<256;i++) {
1055                 xc.red = this->palents[i].peRed<<8;
1056                 xc.blue = this->palents[i].peBlue<<8;
1057                 xc.green = this->palents[i].peGreen<<8;
1058                 xc.flags = DoRed|DoBlue|DoGreen;
1059                 xc.pixel = i;
1060                 TSXStoreColor(display,this->cm,&xc);
1061         }
1062 /* End Insomnia's Mods */
1063
1064         XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
1065         return 0;
1066 }
1067
1068 static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
1069         if (!--(this->ref)) {
1070                 if (this->cm) {
1071                         TSXFreeColormap(display,this->cm);
1072                         this->cm = 0;
1073                 }
1074                 HeapFree(GetProcessHeap(),0,this);
1075                 return 0;
1076         }
1077         return this->ref;
1078 }
1079
1080 static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
1081         return ++(this->ref);
1082 }
1083
1084 static HRESULT WINAPI IDirectDrawPalette_Initialize(
1085         LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
1086 ) {
1087         return DDERR_ALREADYINITIALIZED;
1088 }
1089
1090 static struct IDirectDrawPalette_VTable ddpalvt = {
1091         (void*)1,
1092         IDirectDrawPalette_AddRef,
1093         IDirectDrawPalette_Release,
1094         (void*)4,
1095         IDirectDrawPalette_GetEntries,
1096         IDirectDrawPalette_Initialize,
1097         IDirectDrawPalette_SetEntries
1098 };
1099
1100 /*******************************************************************************
1101  *                              IDirect3D
1102  */
1103 static struct IDirect3D_VTable d3dvt = {
1104         (void*)1,
1105         (void*)2,
1106         (void*)3,
1107         (void*)4,
1108         (void*)5,
1109         (void*)6,
1110         (void*)7,
1111         (void*)8,
1112         (void*)9,
1113 };
1114
1115 /*******************************************************************************
1116  *                              IDirect3D2
1117  */
1118 static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
1119         this->ref--;
1120         if (!this->ref) {
1121                 this->ddraw->lpvtbl->fnRelease(this->ddraw);
1122                 HeapFree(GetProcessHeap(),0,this);
1123                 return 0;
1124         }
1125         return this->ref;
1126 }
1127
1128 static HRESULT WINAPI IDirect3D2_EnumDevices(
1129         LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
1130 ) {
1131         D3DDEVICEDESC   d1,d2;
1132
1133         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",this,cb,context);
1134         d1.dwSize       = sizeof(d1);
1135         d1.dwFlags      = 0;
1136
1137         d2.dwSize       = sizeof(d2);
1138         d2.dwFlags      = 0;
1139         cb(&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
1140         return 0;
1141 }
1142
1143 static struct IDirect3D2_VTable d3d2vt = {
1144         (void*)1,
1145         (void*)2,
1146         IDirect3D2_Release,
1147         IDirect3D2_EnumDevices,
1148         (void*)5,
1149         (void*)6,
1150         (void*)7,
1151         (void*)8,
1152         (void*)9,
1153 };
1154
1155 /*******************************************************************************
1156  *                              IDirectDraw
1157  */
1158 static HRESULT WINAPI IDirectDraw_CreateSurface(
1159         LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1160 ) {
1161         int     i;
1162
1163         TRACE(ddraw, "(%p)->(%p,%p,%p)\n",
1164                      this,lpddsd,lpdsf,lpunk);
1165         if (TRACE_ON(ddraw)) {
1166                 DUMP("[w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
1167                 _dump_DDSD(lpddsd->dwFlags);
1168                 fprintf(stderr,"caps ");
1169                 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
1170                 fprintf(stderr,"]\n");
1171         }
1172
1173         *lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1174         this->lpvtbl->fnAddRef(this);
1175         (*lpdsf)->ref = 1;
1176         (*lpdsf)->lpvtbl = &ddsvt;
1177         if (    (lpddsd->dwFlags & DDSD_CAPS) && 
1178                 (lpddsd->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN)
1179         ) {
1180                 if (!(lpddsd->dwFlags & DDSD_WIDTH))
1181                         lpddsd->dwWidth = this->d.fb_width;
1182                 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
1183                         lpddsd->dwWidth = this->d.fb_height;
1184                 (*lpdsf)->s.surface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth*lpddsd->dwHeight*this->d.depth/8);
1185                 (*lpdsf)->s.fb_height = -1;
1186                 (*lpdsf)->s.lpitch = lpddsd->dwWidth*this->d.depth/8;
1187                 TRACE(ddraw,"using system memory for a primary surface\n");
1188         } else {
1189                 for (i=0;i<32;i++)
1190                         if (!(this->d.vpmask & (1<<i)))
1191                                 break;
1192                 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
1193                 /* if i == 32 or maximum ... return error */
1194                 this->d.vpmask|=(1<<i);
1195                 (*lpdsf)->s.surface = this->d.fb_addr+((i*this->d.fb_height)*this->d.fb_width*this->d.depth/8);
1196                 (*lpdsf)->s.fb_height = i*this->d.fb_height;
1197                 (*lpdsf)->s.lpitch = this->d.fb_width*this->d.depth/8;
1198         }
1199
1200         lpddsd->lPitch = (*lpdsf)->s.lpitch;
1201
1202         (*lpdsf)->s.width = this->d.width;
1203         (*lpdsf)->s.height = this->d.height;
1204         (*lpdsf)->s.ddraw = this;
1205         (*lpdsf)->s.backbuffer = NULL;
1206         if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
1207                 LPDIRECTDRAWSURFACE     back;
1208
1209                 if (lpddsd->dwBackBufferCount>1)
1210                         FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
1211
1212                 (*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
1213                 this->lpvtbl->fnAddRef(this);
1214                 back->ref = 1;
1215                 back->lpvtbl = &ddsvt;
1216                 for (i=0;i<32;i++)
1217                         if (!(this->d.vpmask & (1<<i)))
1218                                 break;
1219                 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
1220                 /* if i == 32 or maximum ... return error */
1221                 this->d.vpmask|=(1<<i);
1222                 back->s.surface = this->d.fb_addr+((i*this->d.fb_height)*this->d.fb_width*this->d.depth/8);
1223                 back->s.fb_height = i*this->d.fb_height;
1224
1225                 back->s.width = this->d.width;
1226                 back->s.height = this->d.height;
1227                 back->s.ddraw = this;
1228                 back->s.lpitch = this->d.fb_width*this->d.depth/8;
1229                 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
1230                                           * one! */
1231         }
1232         return 0;
1233 }
1234
1235 static HRESULT WINAPI IDirectDraw_DuplicateSurface(
1236         LPDIRECTDRAW this,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
1237 ) {
1238         FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",this,src,dst);
1239         *dst = src; /* FIXME */
1240         return 0;
1241 }
1242
1243 static HRESULT WINAPI IDirectDraw_SetCooperativeLevel(
1244         LPDIRECTDRAW this,HWND32 hwnd,DWORD cooplevel
1245 ) {
1246         int     i;
1247         const struct {
1248                 int     mask;
1249                 char    *name;
1250         } flagmap[] = {
1251                 FE(DDSCL_FULLSCREEN)
1252                 FE(DDSCL_ALLOWREBOOT)
1253                 FE(DDSCL_NOWINDOWCHANGES)
1254                 FE(DDSCL_NORMAL)
1255                 FE(DDSCL_ALLOWMODEX)
1256                 FE(DDSCL_EXCLUSIVE)
1257                 FE(DDSCL_SETFOCUSWINDOW)
1258                 FE(DDSCL_SETDEVICEWINDOW)
1259                 FE(DDSCL_CREATEDEVICEWINDOW)
1260         };
1261
1262         TRACE(ddraw,"(%p)->(%08lx,%08lx)\n",
1263                 this,(DWORD)hwnd,cooplevel
1264         );
1265         if(TRACE_ON(ddraw)){
1266           dbg_decl_str(ddraw, 512);
1267           for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
1268             if (flagmap[i].mask & cooplevel)
1269               dsprintf(ddraw, "%s ", flagmap[i].name);
1270           TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
1271         }
1272         this->d.mainwindow = hwnd;
1273         return 0;
1274 }
1275
1276
1277 static HRESULT WINAPI IDirectDraw_SetDisplayMode(
1278         LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
1279 ) {
1280         int     i,*depths,depcount;
1281
1282         TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n",
1283                       this, width, height, depth);
1284
1285         depths = TSXListDepths(display,DefaultScreen(display),&depcount);
1286         for (i=0;i<depcount;i++)
1287                 if (depths[i]==depth)
1288                         break;
1289         TSXFree(depths);
1290         if (i==depcount) {/* not found */
1291                 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
1292                 return DDERR_UNSUPPORTEDMODE;
1293         }
1294         if (this->d.fb_width < width) {
1295                 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,this->d.fb_width);
1296                 return DDERR_UNSUPPORTEDMODE;
1297         }
1298         this->d.width   = width;
1299         this->d.height  = height;
1300         /* adjust fb_height, so we don't overlap */
1301         if (this->d.fb_height < height)
1302                 this->d.fb_height = height;
1303         this->d.depth   = depth;
1304
1305         /* FIXME: this function OVERWRITES several signal handlers. 
1306          * can we save them? and restore them later? In a way that
1307          * it works for the library too?
1308          */
1309         XF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
1310 /*
1311         XF86DGASetViewPort(display,DefaultScreen(display),0,this->d.fb_height);
1312  */
1313
1314 #ifdef RESTORE_SIGNALS
1315         SIGNAL_InitEmulator();
1316 #endif
1317         return 0;
1318 }
1319
1320 static HRESULT WINAPI IDirectDraw_GetCaps(
1321         LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
1322 )  {
1323         TRACE(ddraw,"(%p)->(%p,%p)\n",this,caps1,caps2);
1324         caps1->dwVidMemTotal = this->d.fb_memsize;
1325         caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
1326         caps1->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
1327         if (caps2) {
1328                 caps2->dwVidMemTotal = this->d.fb_memsize;
1329                 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
1330                 caps2->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
1331         }
1332         return 0;
1333 }
1334
1335 static HRESULT WINAPI IDirectDraw_CreateClipper(
1336         LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1337 ) {
1338         FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
1339                 this,x,lpddclip,lpunk
1340         );
1341         *lpddclip = (LPDIRECTDRAWCLIPPER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipper));
1342         (*lpddclip)->ref = 1;
1343         (*lpddclip)->lpvtbl = &ddclipvt;
1344         return 0;
1345 }
1346
1347 static HRESULT WINAPI IDirectDraw_CreatePalette(
1348         LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1349 ) {
1350         TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",
1351                 this,x,palent,lpddpal,lpunk
1352         );
1353         *lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
1354         (*lpddpal)->ref = 1;
1355         (*lpddpal)->lpvtbl = &ddpalvt;
1356         (*lpddpal)->ddraw = this;
1357         if (this->d.depth<=8) {
1358                 (*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
1359         } else /* we don't want palettes in hicolor or truecolor */
1360                 (*lpddpal)->cm = 0;
1361
1362         return 0;
1363 }
1364
1365 static HRESULT WINAPI IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
1366         TRACE(ddraw, "(%p)->()\n", 
1367                       this);
1368         Sleep(1000);
1369         XF86DGADirectVideo(display,DefaultScreen(display),0);
1370 #ifdef RESTORE_SIGNALS
1371         SIGNAL_InitEmulator();
1372 #endif
1373         return 0;
1374 }
1375
1376
1377 static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank(
1378         LPDIRECTDRAW this,DWORD x,HANDLE32 h
1379 ) {
1380         TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",this,x,h);
1381         return 0;
1382 }
1383
1384 static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) {
1385         return ++(this->ref);
1386 }
1387
1388 static ULONG WINAPI IDirectDraw_Release(LPDIRECTDRAW this) {
1389         if (!--(this->ref)) {
1390                 XF86DGADirectVideo(display,DefaultScreen(display),0);
1391 #ifdef RESTORE_SIGNALS
1392                 SIGNAL_InitEmulator();
1393 #endif
1394                 HeapFree(GetProcessHeap(),0,this);
1395                 return 0;
1396         }
1397         return this->ref;
1398 }
1399
1400 static HRESULT WINAPI IDirectDraw_QueryInterface(
1401         LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
1402 ) {
1403         char    xrefiid[50];
1404
1405         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1406         TRACE(ddraw,"(%p)->(%s,%p)\n",this,xrefiid,obj);
1407         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
1408                 *obj = this;
1409                 this->lpvtbl->fnAddRef(this);
1410                 return 0;
1411         }
1412         if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
1413                 *obj = this;
1414                 this->lpvtbl->fnAddRef(this);
1415                 return 0;
1416         }
1417         if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
1418                 this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dd2vt;
1419                 this->lpvtbl->fnAddRef(this);
1420                 *obj = this;
1421                 return 0;
1422         }
1423         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
1424                 LPDIRECT3D      d3d;
1425
1426                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1427                 d3d->ref = 1;
1428                 d3d->ddraw = this;
1429                 this->lpvtbl->fnAddRef(this);
1430                 d3d->lpvtbl = &d3dvt;
1431                 *obj = d3d;
1432                 return 0;
1433         }
1434         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
1435                 LPDIRECT3D2     d3d;
1436
1437                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
1438                 d3d->ref = 1;
1439                 d3d->ddraw = this;
1440                 this->lpvtbl->fnAddRef(this);
1441                 d3d->lpvtbl = &d3d2vt;
1442                 *obj = d3d;
1443                 return 0;
1444         }
1445         WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
1446         return OLE_E_ENUM_NOMORE;
1447 }
1448
1449 static HRESULT WINAPI IDirectDraw_GetVerticalBlankStatus(
1450         LPDIRECTDRAW this,BOOL32 *status
1451 ) {
1452         TRACE(ddraw,"(%p)->(%p)\n",this,status);
1453         *status = TRUE;
1454         return 0;
1455 }
1456
1457 static HRESULT WINAPI IDirectDraw_EnumDisplayModes(
1458         LPDIRECTDRAW this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1459 ) {
1460         DDSURFACEDESC   ddsfd;
1461
1462         TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
1463
1464
1465         _getpixelformat(this,&(ddsfd.ddpfPixelFormat));
1466         ddsfd.dwSize = sizeof(ddsfd);
1467         ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1468         if (dwFlags & DDEDM_REFRESHRATES) {
1469                 ddsfd.dwFlags |= DDSD_REFRESHRATE;
1470                 ddsfd.x.dwRefreshRate = 60;
1471         }
1472
1473         ddsfd.dwWidth = 640;
1474         ddsfd.dwHeight = 480;
1475         ddsfd.dwBackBufferCount = 1;
1476         ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
1477
1478         if (!modescb(&ddsfd,context)) return 0;
1479
1480         ddsfd.dwWidth = 800;
1481         ddsfd.dwHeight = 600;
1482         if (!modescb(&ddsfd,context)) return 0;
1483
1484         if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
1485                 /* modeX is not standard VGA */
1486
1487                 ddsfd.dwHeight = 200;
1488                 ddsfd.dwWidth = 320;
1489                 if (!modescb(&ddsfd,context)) return 0;
1490         }
1491         return DD_OK;
1492 }
1493
1494 static HRESULT WINAPI IDirectDraw_GetDisplayMode(
1495         LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
1496 ) {
1497         TRACE(ddraw,"(%p)->(%p)\n",this,lpddsfd);
1498         lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
1499         lpddsfd->dwHeight = screenHeight;
1500         lpddsfd->dwWidth = screenWidth;
1501         lpddsfd->lPitch = this->d.fb_width*this->d.depth/8;
1502         lpddsfd->dwBackBufferCount = 1;
1503         lpddsfd->x.dwRefreshRate = 60;
1504         lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
1505         _getpixelformat(this,&(lpddsfd->ddpfPixelFormat));
1506         return DD_OK;
1507 }
1508
1509 static HRESULT WINAPI IDirectDraw_FlipToGDISurface(LPDIRECTDRAW this) {
1510         TRACE(ddraw,"(%p)->()\n",this);
1511         return DD_OK;
1512 }
1513
1514 static HRESULT WINAPI IDirectDraw_GetMonitorFrequency(
1515         LPDIRECTDRAW this,LPDWORD freq
1516 ) {
1517         FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",this,freq);
1518         *freq = 60*100; /* 60 Hz */
1519         return 0;
1520 }
1521
1522 /* what can we directly decompress? */
1523 static HRESULT WINAPI IDirectDraw_GetFourCCCodes(
1524         LPDIRECTDRAW this,LPDWORD x,LPDWORD y
1525 ) {
1526         FIXME(ddraw,"(%p,%p,%p), stub\n",this,x,y);
1527         return 0;
1528 }
1529
1530 static IDirectDraw_VTable ddvt = {
1531         IDirectDraw_QueryInterface,
1532         IDirectDraw_AddRef,
1533         IDirectDraw_Release,
1534         (void*)4,
1535         IDirectDraw_CreateClipper,
1536         IDirectDraw_CreatePalette,
1537         IDirectDraw_CreateSurface,
1538         IDirectDraw_DuplicateSurface,
1539         IDirectDraw_EnumDisplayModes,
1540         (void*)10,
1541         IDirectDraw_FlipToGDISurface,
1542         IDirectDraw_GetCaps,
1543         IDirectDraw_GetDisplayMode,
1544         IDirectDraw_GetFourCCCodes,
1545         (void*)15,
1546         IDirectDraw_GetMonitorFrequency,
1547         (void*)17,
1548         IDirectDraw_GetVerticalBlankStatus,
1549         (void*)19,
1550         IDirectDraw_RestoreDisplayMode,
1551         IDirectDraw_SetCooperativeLevel,
1552         IDirectDraw_SetDisplayMode,
1553         IDirectDraw_WaitForVerticalBlank,
1554 };
1555
1556 /*****************************************************************************
1557  *      IDirectDraw2
1558  *
1559  */
1560 static HRESULT WINAPI IDirectDraw2_CreateClipper(
1561         LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
1562 ) {
1563         return IDirectDraw_CreateClipper((LPDIRECTDRAW)this,x,lpddclip,lpunk);
1564 }
1565
1566 static HRESULT WINAPI IDirectDraw2_CreateSurface(
1567         LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
1568 ) {
1569         return IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk);
1570 }
1571
1572 static HRESULT WINAPI IDirectDraw2_QueryInterface(
1573         LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
1574 ) {
1575         return IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
1576 }
1577
1578 static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
1579         return IDirectDraw_AddRef((LPDIRECTDRAW)this);
1580 }
1581
1582 static ULONG WINAPI IDirectDraw2_Release(LPDIRECTDRAW2 this) {
1583         return IDirectDraw_Release((LPDIRECTDRAW)this);
1584 }
1585
1586 static HRESULT WINAPI IDirectDraw2_GetCaps(
1587         LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
1588 )  {
1589         return IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2);
1590 }
1591
1592 static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
1593         LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x
1594 ) {
1595         return IDirectDraw_SetCooperativeLevel((LPDIRECTDRAW)this,hwnd,x);
1596 }
1597
1598 static HRESULT WINAPI IDirectDraw2_CreatePalette(
1599         LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
1600 ) {
1601         return IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
1602 }
1603
1604
1605 static HRESULT WINAPI IDirectDraw2_SetDisplayMode(
1606         LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
1607 ) {
1608         TRACE(ddraw,"(%p)->(%ld,%ld,%ld,%08lx,%08lx)\n",
1609                       this, width, height, depth, xx, yy);
1610
1611         return IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
1612 }
1613
1614 static HRESULT WINAPI IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
1615         return IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this);
1616 }
1617
1618 static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
1619         LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
1620 ) {
1621         FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
1622         return 0;
1623 }
1624
1625 static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
1626         LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
1627 ) {
1628         return IDirectDraw_EnumDisplayModes((LPDIRECTDRAW)this,dwFlags,lpddsfd,context,modescb);
1629 }
1630
1631 static HRESULT WINAPI IDirectDraw2_GetDisplayMode(
1632         LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
1633 ) {
1634         return IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd);
1635 }
1636
1637 static HRESULT WINAPI IDirectDraw2_GetAvailableVidMem(
1638         LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
1639 ) {
1640         TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
1641                 this,ddscaps,total,free
1642         );
1643         if (total) *total = this->d.fb_memsize * 1024;
1644         if (free) *free = this->d.fb_memsize * 1024;
1645         return 0;
1646 }
1647
1648 static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
1649         LPDIRECTDRAW2 this,LPDWORD freq
1650 ) {
1651         return IDirectDraw_GetMonitorFrequency((LPDIRECTDRAW)this,freq);
1652 }
1653
1654 static HRESULT WINAPI IDirectDraw2_GetVerticalBlankStatus(
1655         LPDIRECTDRAW2 this,BOOL32 *status
1656 ) {
1657         return IDirectDraw_GetVerticalBlankStatus((LPDIRECTDRAW)this,status);
1658 }
1659
1660 static HRESULT WINAPI IDirectDraw2_WaitForVerticalBlank(
1661         LPDIRECTDRAW2 this,DWORD x,HANDLE32 h
1662 ) {
1663         return IDirectDraw_WaitForVerticalBlank((LPDIRECTDRAW)this,x,h);
1664 }
1665
1666 static IDirectDraw2_VTable dd2vt = {
1667         IDirectDraw2_QueryInterface,
1668         IDirectDraw2_AddRef,
1669         IDirectDraw2_Release,
1670         (void*)4,
1671         IDirectDraw2_CreateClipper,
1672         IDirectDraw2_CreatePalette,
1673         IDirectDraw2_CreateSurface,
1674         (void*)8,
1675         IDirectDraw2_EnumDisplayModes,
1676         IDirectDraw2_EnumSurfaces,
1677         (void*)11,
1678         IDirectDraw2_GetCaps,
1679         IDirectDraw2_GetDisplayMode,
1680         (void*)14,
1681         (void*)15,
1682         IDirectDraw2_GetMonitorFrequency,
1683         (void*)17,
1684         IDirectDraw2_GetVerticalBlankStatus,
1685         (void*)19,
1686         IDirectDraw2_RestoreDisplayMode,
1687         IDirectDraw2_SetCooperativeLevel,
1688         IDirectDraw2_SetDisplayMode,
1689         IDirectDraw2_WaitForVerticalBlank,
1690         IDirectDraw2_GetAvailableVidMem
1691         
1692 };
1693
1694 /******************************************************************************
1695  *                              DirectDrawCreate
1696  */
1697
1698 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1699
1700         char    xclsid[50];
1701         int     memsize,banksize,width,evbase,evret,major,minor,flags,height;
1702         char    *addr;
1703
1704         if (lpGUID)
1705                 WINE_StringFromCLSID(lpGUID,xclsid);
1706         else
1707                 strcpy(xclsid,"<null>");
1708
1709         TRACE(ddraw,"(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
1710         if (getuid()) {
1711                 MSG("Must be root to use XF86DGA!\n");
1712                 MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1713                 return E_UNEXPECTED;
1714         }
1715         *lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
1716         (*lplpDD)->lpvtbl = &ddvt;
1717         (*lplpDD)->ref = 1;
1718         if (!XF86DGAQueryExtension(display,&evbase,&evret)) {
1719                 MSG("Wine DirectDraw: No XF86DGA detected.\n");
1720                 return 0;
1721         }
1722         XF86DGAQueryVersion(display,&major,&minor);
1723         TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
1724         XF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
1725         if (!(flags & XF86DGADirectPresent))
1726                 MSG("direct video is NOT ENABLED.\n");
1727         XF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
1728         TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
1729                 addr,width,banksize,memsize
1730         );
1731         (*lplpDD)->d.fb_width = width;
1732         (*lplpDD)->d.fb_addr = addr;
1733         (*lplpDD)->d.fb_memsize = memsize;
1734         (*lplpDD)->d.fb_banksize = banksize;
1735
1736         XF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
1737         XF86DGASetViewPort(display,DefaultScreen(display),0,0);
1738         (*lplpDD)->d.vp_width = width;
1739         (*lplpDD)->d.vp_height = height;
1740         (*lplpDD)->d.fb_height = screenHeight;
1741         (*lplpDD)->d.vpmask = 0;
1742
1743         /* just assume the default depth is the DGA depth too */
1744         (*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
1745 #ifdef RESTORE_SIGNALS
1746         SIGNAL_InitEmulator();
1747 #endif
1748         return 0;
1749 }
1750 #else
1751
1752 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
1753         MessageBox32A(0,"WINE DirectDraw needs the XF86DGA extensions compiled in. (libXxf86dga.a).","WINE DirectDraw",MB_OK|MB_ICONSTOP);
1754         return E_OUTOFMEMORY;
1755 }
1756 #endif