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