Fixed ANSI compabillity.
[wine] / graphics / ddraw.c
1 /*              DirectDraw using DGA or Xlib(XSHM)
2  *
3  * Copyright 1997,1998 Marcus Meissner
4  * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5  */
6 /* XF86DGA:
7  * When DirectVideo mode is enabled you can no longer use 'normal' X 
8  * applications nor can you switch to a virtual console. Also, enabling
9  * only works, if you have switched to the screen where the application
10  * is running.
11  * Some ways to debug this stuff are:
12  * - A terminal connected to the serial port. Can be bought used for cheap.
13  *   (This is the method I am using.)
14  * - Another machine connected over some kind of network.
15  */
16
17 #include "config.h"
18
19 #ifndef X_DISPLAY_MISSING 
20
21 #include "ts_xlib.h"
22 #include "ts_xutil.h"
23
24 #ifdef HAVE_LIBXXSHM
25 #include <sys/types.h>
26 #include <sys/ipc.h>
27 #include <sys/shm.h>
28 #include "ts_xshm.h"
29 #endif /* defined(HAVE_LIBXXSHM) */
30
31 #ifdef HAVE_LIBXXF86DGA
32 #include "ts_xf86dga.h"
33 #endif /* defined(HAVE_LIBXXF86DGA) */
34
35 #ifdef HAVE_LIBXXF86VM
36 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
37    this is a crude hack to get around it */
38 #define XMD_H
39 typedef int INT32;
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
42
43 #include "x11drv.h"
44
45 #include <unistd.h>
46 #include <assert.h>
47 #include <sys/signal.h>
48 #include <fcntl.h>
49 #include <string.h>
50 #include <stdlib.h>
51
52 #include "winerror.h"
53 #include "gdi.h"
54 #include "heap.h"
55 #include "dc.h"
56 #include "win.h"
57 #include "miscemu.h"
58 #include "ddraw.h"
59 #include "d3d.h"
60 #include "debug.h"
61 #include "spy.h"
62 #include "message.h"
63 #include "options.h"
64 #include "monitor.h"
65
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "ddraw_private.h"
68 #include "d3d_private.h"
69
70 DEFAULT_DEBUG_CHANNEL(ddraw)
71
72 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
73 #undef DIABLO_HACK
74
75 /* Restore signal handlers overwritten by XF86DGA 
76  */
77 #define RESTORE_SIGNALS
78
79 /* Where do these GUIDs come from?  mkuuid.
80  * They exist solely to distinguish between the targets Wine support,
81  * and should be different than any other GUIDs in existence.
82  */
83 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
84         0xe2dcb020,
85         0xdc60,
86         0x11d1,
87         {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
88 };
89
90 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
91     0x1574a740,
92     0xdc61,
93     0x11d1,
94     {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
95 };
96
97 static struct ICOM_VTABLE(IDirectDrawSurface4)  dga_dds4vt, xlib_dds4vt;
98 static struct ICOM_VTABLE(IDirectDraw)          dga_ddvt, xlib_ddvt;
99 static struct ICOM_VTABLE(IDirectDraw2)         dga_dd2vt, xlib_dd2vt;
100 static struct ICOM_VTABLE(IDirectDraw4)         dga_dd4vt, xlib_dd4vt;
101 static struct ICOM_VTABLE(IDirectDrawClipper)   ddclipvt;
102 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt, xlib_ddpalvt;
103 static struct ICOM_VTABLE(IDirect3D)                    d3dvt;
104 static struct ICOM_VTABLE(IDirect3D2)                   d3d2vt;
105
106 #ifdef HAVE_LIBXXF86VM
107 static XF86VidModeModeInfo *orig_mode = NULL;
108 #endif
109
110 #ifdef HAVE_LIBXXSHM
111 static int XShmErrorFlag = 0;
112 #endif
113
114 BOOL
115 DDRAW_DGA_Available(void)
116 {
117 #ifdef HAVE_LIBXXF86DGA
118         int evbase, evret, fd;
119         
120         if (Options.noDGA)
121           return 0;
122    
123         /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
124         /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
125         /* others. --stephenc */
126         if ((fd = open("/dev/mem", O_RDWR)) != -1)
127           close(fd);
128
129         return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
130 #else /* defined(HAVE_LIBXXF86DGA) */
131         return 0;
132 #endif /* defined(HAVE_LIBXXF86DGA) */
133 }
134
135 /**********************************************************************/
136
137 typedef struct {
138   LPVOID lpCallback;
139   LPVOID lpContext; 
140 } DirectDrawEnumerateProcData;
141
142 /***********************************************************************
143  *              DirectDrawEnumerateExA (DDRAW.*)
144  */
145 HRESULT WINAPI DirectDrawEnumerateExA(
146   LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
147 {
148   TRACE(ddraw, "(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
149   
150   if (TRACE_ON(ddraw)) {
151     DUMP("  Flags : ");
152     if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
153       DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
154     if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
155       DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
156     if (dwFlags & DDENUM_NONDISPLAYDEVICES)
157       DUMP("DDENUM_NONDISPLAYDEVICES ");
158     DUMP("\n");
159   }
160
161   if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
162     /* For the moment, Wine does not support any 3D only accelerators */
163     return DD_OK;
164   }
165   
166   if (DDRAW_DGA_Available()) {
167     TRACE(ddraw, "Enumerating DGA interface\n");
168     if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
169       return DD_OK;
170   }
171
172   TRACE(ddraw, "Enumerating Xlib interface\n");
173   if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
174     return DD_OK;
175   
176   TRACE(ddraw, "Enumerating Default interface\n");
177   if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
178     return DD_OK;
179   
180   return DD_OK;
181 }
182
183 /***********************************************************************
184  *              DirectDrawEnumerateExW (DDRAW.*)
185  */
186
187 static BOOL CALLBACK DirectDrawEnumerateExProcW(
188         GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
189         LPVOID lpContext, HMONITOR hm)
190 {
191   DirectDrawEnumerateProcData *pEPD =
192     (DirectDrawEnumerateProcData *) lpContext;
193   LPWSTR lpDriverDescriptionW =
194     HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
195   LPWSTR lpDriverNameW =
196     HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
197
198   BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
199     lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
200
201   HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
202   HeapFree(GetProcessHeap(), 0, lpDriverNameW);
203
204   return bResult;
205 }
206
207 /**********************************************************************/
208
209 HRESULT WINAPI DirectDrawEnumerateExW(
210   LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
211 {
212   DirectDrawEnumerateProcData epd;
213   epd.lpCallback = lpCallback;
214   epd.lpContext = lpContext;
215
216   return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW, 
217                                   (LPVOID) &epd, 0);
218 }
219
220 /***********************************************************************
221  *              DirectDrawEnumerateA (DDRAW.*)
222  */
223
224 static BOOL CALLBACK DirectDrawEnumerateProcA(
225         GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName, 
226         LPVOID lpContext, HMONITOR hm)
227 {
228   DirectDrawEnumerateProcData *pEPD = 
229     (DirectDrawEnumerateProcData *) lpContext;
230   
231   return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
232     lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
233 }
234
235 /**********************************************************************/
236
237 HRESULT WINAPI DirectDrawEnumerateA(
238   LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
239 {
240   DirectDrawEnumerateProcData epd;  
241   epd.lpCallback = lpCallback;
242   epd.lpContext = lpContext;
243
244   return DirectDrawEnumerateExA(DirectDrawEnumerateProcA, 
245                                 (LPVOID) &epd, 0);
246 }
247
248 /***********************************************************************
249  *              DirectDrawEnumerateW (DDRAW.*)
250  */
251
252 static BOOL WINAPI DirectDrawEnumerateProcW(
253   GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName, 
254   LPVOID lpContext, HMONITOR hm)
255 {
256   DirectDrawEnumerateProcData *pEPD = 
257     (DirectDrawEnumerateProcData *) lpContext;
258   
259   return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
260     lpGUID, lpDriverDescription, lpDriverName, 
261     pEPD->lpContext);
262 }
263
264 /**********************************************************************/
265
266 HRESULT WINAPI DirectDrawEnumerateW(
267   LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
268 {
269   DirectDrawEnumerateProcData epd;  
270   epd.lpCallback = lpCallback;
271   epd.lpContext = lpContext;
272
273   return DirectDrawEnumerateExW(DirectDrawEnumerateProcW, 
274                                 (LPVOID) &epd, 0);
275 }
276
277 /***********************************************************************
278  *              DSoundHelp (DDRAW.?)
279  */
280
281 /* What is this doing here? */
282 HRESULT WINAPI 
283 DSoundHelp(DWORD x,DWORD y,DWORD z) {
284         FIXME(ddraw,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
285         return 0;
286 }
287
288 /******************************************************************************
289  *              internal helper functions
290  */
291 static void _dump_DDBLTFX(DWORD flagmask) {
292         int     i;
293         const struct {
294                 DWORD   mask;
295                 char    *name;
296         } flags[] = {
297 #define FE(x) { x, #x},
298                 FE(DDBLTFX_ARITHSTRETCHY)
299                 FE(DDBLTFX_MIRRORLEFTRIGHT)
300                 FE(DDBLTFX_MIRRORUPDOWN)
301                 FE(DDBLTFX_NOTEARING)
302                 FE(DDBLTFX_ROTATE180)
303                 FE(DDBLTFX_ROTATE270)
304                 FE(DDBLTFX_ROTATE90)
305                 FE(DDBLTFX_ZBUFFERRANGE)
306                 FE(DDBLTFX_ZBUFFERBASEDEST)
307         };
308         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
309            if (flags[i].mask & flagmask) {
310               DUMP("%s ",flags[i].name);
311               
312            };
313         DUMP("\n");
314         
315 }
316
317 static void _dump_DDBLTFAST(DWORD flagmask) {
318         int     i;
319         const struct {
320                 DWORD   mask;
321                 char    *name;
322         } flags[] = {
323 #define FE(x) { x, #x},
324                 FE(DDBLTFAST_NOCOLORKEY)
325                 FE(DDBLTFAST_SRCCOLORKEY)
326                 FE(DDBLTFAST_DESTCOLORKEY)
327                 FE(DDBLTFAST_WAIT)
328         };
329         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
330                 if (flags[i].mask & flagmask)
331                         DUMP("%s ",flags[i].name);
332         DUMP("\n");
333 }
334
335 static void _dump_DDBLT(DWORD flagmask) {
336         int     i;
337         const struct {
338                 DWORD   mask;
339                 char    *name;
340         } flags[] = {
341 #define FE(x) { x, #x},
342                 FE(DDBLT_ALPHADEST)
343                 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
344                 FE(DDBLT_ALPHADESTNEG)
345                 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
346                 FE(DDBLT_ALPHAEDGEBLEND)
347                 FE(DDBLT_ALPHASRC)
348                 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
349                 FE(DDBLT_ALPHASRCNEG)
350                 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
351                 FE(DDBLT_ASYNC)
352                 FE(DDBLT_COLORFILL)
353                 FE(DDBLT_DDFX)
354                 FE(DDBLT_DDROPS)
355                 FE(DDBLT_KEYDEST)
356                 FE(DDBLT_KEYDESTOVERRIDE)
357                 FE(DDBLT_KEYSRC)
358                 FE(DDBLT_KEYSRCOVERRIDE)
359                 FE(DDBLT_ROP)
360                 FE(DDBLT_ROTATIONANGLE)
361                 FE(DDBLT_ZBUFFER)
362                 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
363                 FE(DDBLT_ZBUFFERDESTOVERRIDE)
364                 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
365                 FE(DDBLT_ZBUFFERSRCOVERRIDE)
366                 FE(DDBLT_WAIT)
367                 FE(DDBLT_DEPTHFILL)
368         };
369         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
370                 if (flags[i].mask & flagmask)
371                         DUMP("%s ",flags[i].name);
372         DUMP("\n");
373 }
374
375 static void _dump_DDSCAPS(DWORD flagmask) {
376         int     i;
377         const struct {
378                 DWORD   mask;
379                 char    *name;
380         } flags[] = {
381 #define FE(x) { x, #x},
382                 FE(DDSCAPS_RESERVED1)
383                 FE(DDSCAPS_ALPHA)
384                 FE(DDSCAPS_BACKBUFFER)
385                 FE(DDSCAPS_COMPLEX)
386                 FE(DDSCAPS_FLIP)
387                 FE(DDSCAPS_FRONTBUFFER)
388                 FE(DDSCAPS_OFFSCREENPLAIN)
389                 FE(DDSCAPS_OVERLAY)
390                 FE(DDSCAPS_PALETTE)
391                 FE(DDSCAPS_PRIMARYSURFACE)
392                 FE(DDSCAPS_PRIMARYSURFACELEFT)
393                 FE(DDSCAPS_SYSTEMMEMORY)
394                 FE(DDSCAPS_TEXTURE)
395                 FE(DDSCAPS_3DDEVICE)
396                 FE(DDSCAPS_VIDEOMEMORY)
397                 FE(DDSCAPS_VISIBLE)
398                 FE(DDSCAPS_WRITEONLY)
399                 FE(DDSCAPS_ZBUFFER)
400                 FE(DDSCAPS_OWNDC)
401                 FE(DDSCAPS_LIVEVIDEO)
402                 FE(DDSCAPS_HWCODEC)
403                 FE(DDSCAPS_MODEX)
404                 FE(DDSCAPS_MIPMAP)
405                 FE(DDSCAPS_RESERVED2)
406                 FE(DDSCAPS_ALLOCONLOAD)
407                 FE(DDSCAPS_VIDEOPORT)
408                 FE(DDSCAPS_LOCALVIDMEM)
409                 FE(DDSCAPS_NONLOCALVIDMEM)
410                 FE(DDSCAPS_STANDARDVGAMODE)
411                 FE(DDSCAPS_OPTIMIZED)
412         };
413         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
414                 if (flags[i].mask & flagmask)
415                         DUMP("%s ",flags[i].name);
416         DUMP("\n");
417 }
418
419 static void _dump_DDSD(DWORD flagmask) {
420         int     i;
421         const struct {
422                 DWORD   mask;
423                 char    *name;
424         } flags[] = {
425                 FE(DDSD_CAPS)
426                 FE(DDSD_HEIGHT)
427                 FE(DDSD_WIDTH)
428                 FE(DDSD_PITCH)
429                 FE(DDSD_BACKBUFFERCOUNT)
430                 FE(DDSD_ZBUFFERBITDEPTH)
431                 FE(DDSD_ALPHABITDEPTH)
432                 FE(DDSD_PIXELFORMAT)
433                 FE(DDSD_CKDESTOVERLAY)
434                 FE(DDSD_CKDESTBLT)
435                 FE(DDSD_CKSRCOVERLAY)
436                 FE(DDSD_CKSRCBLT)
437                 FE(DDSD_MIPMAPCOUNT)
438                 FE(DDSD_REFRESHRATE)
439                 FE(DDSD_LINEARSIZE)
440                 FE(DDSD_LPSURFACE)
441         };
442         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
443                 if (flags[i].mask & flagmask)
444                         DUMP("%s ",flags[i].name);
445         DUMP("\n");
446 }
447
448 static void _dump_DDCOLORKEY(DWORD flagmask) {
449         int     i;
450         const struct {
451                 DWORD   mask;
452                 char    *name;
453         } flags[] = {
454 #define FE(x) { x, #x},
455                 FE(DDPF_ALPHAPIXELS)
456                 FE(DDPF_ALPHA)
457                 FE(DDPF_FOURCC)
458                 FE(DDPF_PALETTEINDEXED4)
459                 FE(DDPF_PALETTEINDEXEDTO8)
460                 FE(DDPF_PALETTEINDEXED8)
461                 FE(DDPF_RGB)
462                 FE(DDPF_COMPRESSED)
463                 FE(DDPF_RGBTOYUV)
464                 FE(DDPF_YUV)
465                 FE(DDPF_ZBUFFER)
466                 FE(DDPF_PALETTEINDEXED1)
467                 FE(DDPF_PALETTEINDEXED2)
468                 FE(DDPF_ZPIXELS)
469         };
470         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
471                 if (flags[i].mask & flagmask)
472                         DUMP("%s ",flags[i].name);
473         DUMP("\n");
474 }
475
476 static void _dump_paletteformat(DWORD dwFlags) {
477   int   i;
478   const struct {
479     DWORD       mask;
480     char        *name;
481   } flags[] = {
482 #define FE(x) { x, #x},
483     FE(DDPCAPS_4BIT)
484     FE(DDPCAPS_8BITENTRIES)
485     FE(DDPCAPS_8BIT)
486     FE(DDPCAPS_INITIALIZE)
487     FE(DDPCAPS_PRIMARYSURFACE)
488     FE(DDPCAPS_PRIMARYSURFACELEFT)
489     FE(DDPCAPS_ALLOW256)
490     FE(DDPCAPS_VSYNC)
491     FE(DDPCAPS_1BIT)
492     FE(DDPCAPS_2BIT)
493     FE(DDPCAPS_ALPHA)
494   };
495   for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
496     if (flags[i].mask & dwFlags)
497       DUMP("%s ",flags[i].name);
498   DUMP("\n");
499 }
500
501 static void _dump_pixelformat(LPDDPIXELFORMAT pf) {
502   DUMP("Size : %ld\n", pf->dwSize);
503   if (pf->dwFlags)
504   _dump_DDCOLORKEY(pf->dwFlags);
505   DUMP("dwFourCC : %ld\n", pf->dwFourCC);
506   DUMP("RGB bit count : %ld\n", pf->x.dwRGBBitCount);
507   DUMP("Masks : R %08lx  G %08lx  B %08lx  A %08lx\n",
508        pf->y.dwRBitMask, pf->z.dwGBitMask, pf->xx.dwBBitMask, pf->xy.dwRGBAlphaBitMask);
509 }
510
511 static void _dump_colorkeyflag(DWORD ck) {
512         int     i;
513         const struct {
514                 DWORD   mask;
515                 char    *name;
516         } flags[] = {
517 #define FE(x) { x, #x},
518           FE(DDCKEY_COLORSPACE)
519           FE(DDCKEY_DESTBLT)
520           FE(DDCKEY_DESTOVERLAY)
521           FE(DDCKEY_SRCBLT)
522           FE(DDCKEY_SRCOVERLAY)
523         };
524         for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
525                 if (flags[i].mask & ck)
526                         DUMP("%s ",flags[i].name);
527         DUMP("\n");  
528 }
529
530 /******************************************************************************
531  *              IDirectDrawSurface methods
532  *
533  * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
534  * DDS and DDS2 use those functions. (Function calls did not change (except
535  * using different DirectDrawSurfaceX version), just added flags and functions)
536  */
537 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
538     LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
539 ) {
540         ICOM_THIS(IDirectDrawSurface4Impl,iface);
541         TRACE(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
542                 This,lprect,lpddsd,flags,(DWORD)hnd);
543         if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
544             WARN(ddraw, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
545                          This,lprect,lpddsd,flags,(DWORD)hnd);
546
547         /* First, copy the Surface description */
548         *lpddsd = This->s.surface_desc;
549         TRACE(ddraw,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
550               lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
551
552         /* If asked only for a part, change the surface pointer */
553         if (lprect) {
554                 FIXME(ddraw,"   lprect: %dx%d-%dx%d\n",
555                         lprect->top,lprect->left,lprect->bottom,lprect->right
556                 );
557                 lpddsd->y.lpSurface = This->s.surface_desc.y.lpSurface +
558                         (lprect->top*This->s.surface_desc.lPitch) +
559                         (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8));
560         } else {
561                 assert(This->s.surface_desc.y.lpSurface);
562         }
563         return DD_OK;
564 }
565
566 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
567         LPDIRECTDRAWSURFACE4 iface,LPVOID surface
568 ) {
569         ICOM_THIS(IDirectDrawSurface4Impl,iface);
570         TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
571         return DD_OK;
572 }
573
574 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
575   if (This->s.ddraw->d.pixel_convert != NULL)
576     This->s.ddraw->d.pixel_convert(This->s.surface_desc.y.lpSurface,
577                                    This->t.xlib.image->data,
578                                    This->s.surface_desc.dwWidth,
579                                    This->s.surface_desc.dwHeight,
580                                    This->s.surface_desc.lPitch,
581                                    This->s.palette);
582
583 #ifdef HAVE_LIBXXSHM
584     if (This->s.ddraw->e.xlib.xshm_active)
585       TSXShmPutImage(display,
586                      This->s.ddraw->d.drawable,
587                      DefaultGCOfScreen(X11DRV_GetXScreen()),
588                      This->t.xlib.image,
589                      0, 0, 0, 0,
590                      This->t.xlib.image->width,
591                      This->t.xlib.image->height,
592                      False);
593     else
594 #endif
595         TSXPutImage(            display,
596                                 This->s.ddraw->d.drawable,
597                                 DefaultGCOfScreen(X11DRV_GetXScreen()),
598                                 This->t.xlib.image,
599                                 0, 0, 0, 0,
600                                 This->t.xlib.image->width,
601                   This->t.xlib.image->height);
602 }
603
604 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
605         LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
606 {
607         ICOM_THIS(IDirectDrawSurface4Impl,iface);
608         TRACE(ddraw,"(%p)->Unlock(%p)\n",This,surface);
609   
610         if (!This->s.ddraw->d.paintable)
611                 return DD_OK;
612
613   /* Only redraw the screen when unlocking the buffer that is on screen */
614         if ((This->t.xlib.image != NULL) &&
615             (This->s.surface_desc.ddsCaps.dwCaps & DDSCAPS_VISIBLE)) {
616           Xlib_copy_surface_on_screen(This);
617           
618         if (This->s.palette && This->s.palette->cm)
619                 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
620         }
621
622         return DD_OK;
623 }
624
625 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
626         LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
627 ) {
628         ICOM_THIS(IDirectDrawSurface4Impl,iface);
629         IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
630 #ifdef HAVE_LIBXXF86DGA
631         TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
632         if (!iflipto) {
633                 if (This->s.backbuffer)
634                         iflipto = This->s.backbuffer;
635                 else
636                         iflipto = This;
637         }
638         TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
639
640         if (iflipto->s.palette && iflipto->s.palette->cm) {
641                 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
642         }
643         while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
644         }
645         if (iflipto!=This) {
646                 int     tmp;
647                 LPVOID  ptmp;
648
649                 tmp = This->t.dga.fb_height;
650                 This->t.dga.fb_height = iflipto->t.dga.fb_height;
651                 iflipto->t.dga.fb_height = tmp;
652
653                 ptmp = This->s.surface_desc.y.lpSurface;
654                 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
655                 iflipto->s.surface_desc.y.lpSurface = ptmp;
656         }
657         return DD_OK;
658 #else /* defined(HAVE_LIBXXF86DGA) */
659         return E_UNEXPECTED;
660 #endif /* defined(HAVE_LIBXXF86DGA) */
661 }
662
663 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
664         LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
665 ) {
666         ICOM_THIS(IDirectDrawSurface4Impl,iface);
667         IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
668         TRACE(ddraw,"(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
669         if (!This->s.ddraw->d.paintable)
670                 return DD_OK;
671
672         if (!iflipto) {
673                 if (This->s.backbuffer)
674                         iflipto = This->s.backbuffer;
675                 else
676                         iflipto = This;
677         }
678   
679         Xlib_copy_surface_on_screen(This);
680         
681         if (iflipto->s.palette && iflipto->s.palette->cm) {
682           TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
683         }
684         if (iflipto!=This) {
685                 XImage *tmp;
686                 LPVOID  *surf;
687                 tmp = This->t.xlib.image;
688                 This->t.xlib.image = iflipto->t.xlib.image;
689                 iflipto->t.xlib.image = tmp;
690                 surf = This->s.surface_desc.y.lpSurface;
691                 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
692                 iflipto->s.surface_desc.y.lpSurface = surf;
693         }
694         return DD_OK;
695 }
696
697
698 /* The IDirectDrawSurface4::SetPalette method attaches the specified
699  * DirectDrawPalette object to a surface. The surface uses this palette for all
700  * subsequent operations. The palette change takes place immediately.
701  */
702 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
703         LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
704 ) {
705         ICOM_THIS(IDirectDrawSurface4Impl,iface);
706         IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
707         int i;
708         TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
709
710         if (ipal == NULL) {
711           if( This->s.palette != NULL )
712             IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
713           This->s.palette = ipal;
714
715           return DD_OK;
716         }
717         
718         if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8)) 
719         {
720                 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
721                                             DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
722
723                 if (!Options.managed)
724                         TSXInstallColormap(display,ipal->cm);
725
726                 for (i=0;i<256;i++) {
727                         XColor xc;
728
729                         xc.red = ipal->palents[i].peRed<<8;
730                         xc.blue = ipal->palents[i].peBlue<<8;
731                         xc.green = ipal->palents[i].peGreen<<8;
732                         xc.flags = DoRed|DoBlue|DoGreen;
733                         xc.pixel = i;
734                         TSXStoreColor(display,ipal->cm,&xc);
735                 }
736                 TSXInstallColormap(display,ipal->cm);
737         }
738
739         /* According to spec, we are only supposed to 
740          * AddRef if this is not the same palette.
741          */
742         if( This->s.palette != ipal )
743         {
744           if( ipal != NULL )
745             IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
746           if( This->s.palette != NULL )
747             IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
748           This->s.palette = ipal; 
749
750           /* I think that we need to attach it to all backbuffers...*/
751           if( This->s.backbuffer ) {
752              if( This->s.backbuffer->s.palette )
753                IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
754              This->s.backbuffer->s.palette = ipal;
755              if( ipal )
756                 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
757            }
758           /* Perform the refresh */
759           TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
760         }
761         return DD_OK;
762 }
763
764 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
765         LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
766 ) {
767         ICOM_THIS(IDirectDrawSurface4Impl,iface);
768         IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
769         TRACE(ddraw,"(%p)->(%p)\n",This,ipal);
770 #ifdef HAVE_LIBXXF86DGA
771         /* According to spec, we are only supposed to 
772          * AddRef if this is not the same palette.
773          */
774         if( This->s.palette != ipal )
775         {
776           if( ipal != NULL ) 
777                 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
778           if( This->s.palette != NULL )
779             IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
780           This->s.palette = ipal; 
781
782           /* I think that we need to attach it to all backbuffers...*/
783           if( This->s.backbuffer ) {
784              if( This->s.backbuffer->s.palette )
785                IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.backbuffer->s.palette );
786              This->s.backbuffer->s.palette = ipal;
787              if ( ipal )
788                IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
789           }
790           TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
791         }
792         return DD_OK;
793 #else /* defined(HAVE_LIBXXF86DGA) */
794         return E_UNEXPECTED;
795 #endif /* defined(HAVE_LIBXXF86DGA) */
796
797
798 }
799
800 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
801 {
802         int x, y;
803         LPBYTE first;
804
805         /* Do first row */
806
807 #define COLORFILL_ROW(type) { \
808         type *d = (type *) buf; \
809         for (x = 0; x < width; x++) \
810                 d[x] = (type) color; \
811         break; \
812 }
813
814         switch(bpp) {
815         case 1: COLORFILL_ROW(BYTE)
816         case 2: COLORFILL_ROW(WORD)
817         case 4: COLORFILL_ROW(DWORD)
818         default:
819         FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
820         return DDERR_UNSUPPORTED;
821         }
822
823 #undef COLORFILL_ROW
824
825         /* Now copy first row */
826         first = buf;
827         for (y = 1; y < height; y++) {
828                 buf += lPitch;
829                 memcpy(buf, first, width * bpp);
830         }
831
832         return DD_OK;
833 }
834
835 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
836         LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
837 ) {
838         ICOM_THIS(IDirectDrawSurface4Impl,iface);
839         RECT    xdst,xsrc;
840         DDSURFACEDESC   ddesc,sdesc;
841         HRESULT                 ret = DD_OK;
842         int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
843         int x, y;
844         LPBYTE dbuf, sbuf;
845
846         TRACE(ddraw,"(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
847
848         if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
849         IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
850         
851         if (TRACE_ON(ddraw)) {
852           if (rdst) TRACE(ddraw,"       destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
853           if (rsrc) TRACE(ddraw,"       srcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
854           TRACE(ddraw,"\tflags: ");
855           _dump_DDBLT(dwFlags);
856           if (dwFlags & DDBLT_DDFX) {
857             TRACE(ddraw,"       blitfx: \n");
858                 _dump_DDBLTFX(lpbltfx->dwDDFX);
859           }
860         }
861                 
862         if (rdst) {
863                 memcpy(&xdst,rdst,sizeof(xdst));
864         } else {
865                 xdst.top        = 0;
866                 xdst.bottom     = ddesc.dwHeight;
867                 xdst.left       = 0;
868                 xdst.right      = ddesc.dwWidth;
869         }
870
871         if (rsrc) {
872                 memcpy(&xsrc,rsrc,sizeof(xsrc));
873         } else {
874                 if (src) {
875                 xsrc.top        = 0;
876                 xsrc.bottom     = sdesc.dwHeight;
877                 xsrc.left       = 0;
878                 xsrc.right      = sdesc.dwWidth;
879                 } else {
880                     memset(&xsrc,0,sizeof(xsrc));
881                 }
882         }
883
884         bpp = ddesc.ddpfPixelFormat.x.dwRGBBitCount / 8;
885         srcheight = xsrc.bottom - xsrc.top;
886         srcwidth = xsrc.right - xsrc.left;
887         dstheight = xdst.bottom - xdst.top;
888         dstwidth = xdst.right - xdst.left;
889         width = (xdst.right - xdst.left) * bpp;
890         dbuf = ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
891
892         dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
893         
894         /* First, all the 'source-less' blits */
895         if (dwFlags & DDBLT_COLORFILL) {
896                 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
897                                      ddesc.lPitch, lpbltfx->b.dwFillColor);
898                 dwFlags &= ~DDBLT_COLORFILL;
899                 }
900
901         if (dwFlags & DDBLT_DEPTHFILL) {
902 #ifdef HAVE_MESAGL
903           GLboolean ztest;
904           
905           /* Clears the screen */
906           TRACE(ddraw, "        Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
907           glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
908           glGetBooleanv(GL_DEPTH_TEST, &ztest);
909           glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
910           glClear(GL_DEPTH_BUFFER_BIT);
911           glDepthMask(ztest);
912           
913           dwFlags &= ~(DDBLT_DEPTHFILL);
914 #endif HAVE_MESAGL
915         }
916         
917         if (dwFlags & DDBLT_ROP) {
918                 /* Catch some degenerate cases here */
919                 switch(lpbltfx->dwROP) {
920                         case BLACKNESS:
921                                 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
922                                 break;
923                         case 0xAA0029: /* No-op */
924                                 break;
925                         case WHITENESS:
926                                 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
927                                 break;
928                         default: 
929                                 FIXME(ddraw, "Unsupported raster op: %08lx  Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
930                                 goto error;
931             }
932                 dwFlags &= ~DDBLT_ROP;
933         }
934
935     if (dwFlags & DDBLT_DDROPS) {
936                 FIXME(ddraw, "\tDdraw Raster Ops: %08lx  Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
937         }
938
939         /* Now the 'with source' blits */
940         if (src) {
941                 LPBYTE sbase;
942                 int sx, xinc, sy, yinc;
943
944                 sbase = sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
945                 xinc = (srcwidth << 16) / dstwidth;
946                 yinc = (srcheight << 16) / dstheight;
947
948                 if (!dwFlags) {
949
950                         /* No effects, we can cheat here */
951                         if (dstwidth == srcwidth) {
952                                 if (dstheight == srcheight) {
953                                         /* No stretching in either direction.  This needs to be as fast as possible */
954                                         sbuf = sbase;
955                                         for (y = 0; y < dstheight; y++) {
956                                                 memcpy(dbuf, sbuf, width);
957                                                 sbuf += sdesc.lPitch;
958                                                 dbuf += ddesc.lPitch;
959                                         }
960         } else {
961                                         /* Stretching in Y direction only */
962                                         for (y = sy = 0; y < dstheight; y++, sy += yinc) {
963                                                 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
964                                                 memcpy(dbuf, sbuf, width);
965                                                 dbuf += ddesc.lPitch;
966                   }
967                 }
968                         } else {
969                                 /* Stretching in X direction */
970                                 int last_sy = -1;
971                                 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
972                                         sbuf = sbase + (sy >> 16) * sdesc.lPitch;
973
974                                         if ((sy >> 16) == (last_sy >> 16)) {
975                                                 /* Same as last row - copy already stretched row */
976                                                 memcpy(dbuf, dbuf - ddesc.lPitch, width);
977               } else {
978
979 #define STRETCH_ROW(type) { \
980         type *s = (type *) sbuf, *d = (type *) dbuf; \
981         for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
982                 d[x] = s[sx >> 16]; \
983         break; \
984 }
985                   
986                                                 switch(bpp) {
987                                                         case 1: STRETCH_ROW(BYTE)
988                                                         case 2: STRETCH_ROW(WORD)
989                                                         case 4: STRETCH_ROW(DWORD)
990                                                         default:
991                                                                 FIXME(ddraw, "Stretched blit not implemented for bpp %d!\n", bpp*8);
992                                                                 ret = DDERR_UNSUPPORTED;
993                                                                 goto error;
994                 }
995
996 #undef STRETCH_ROW
997
998               }
999                                         last_sy = sy;
1000                                         dbuf += ddesc.lPitch;
1001               }
1002             }
1003                 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1004                         DWORD keylow, keyhigh;
1005
1006             if (dwFlags & DDBLT_KEYSRC) {
1007                                 keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1008                                 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1009                         } else {
1010                                 /* I'm not sure if this is correct */
1011                                 FIXME(ddraw, "DDBLT_KEYDEST not fully supported yet.\n");
1012                                 keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1013                                 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1014                         }
1015
1016 #define COPYROW_COLORKEY(type) { \
1017         type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1018         for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1019                 tmp = s[sx >> 16]; \
1020                 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1021         } \
1022         break; \
1023                 }
1024                 
1025                         for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1026                                 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1027
1028                                 switch (bpp) {
1029                                         case 1: COPYROW_COLORKEY(BYTE)
1030                                         case 2: COPYROW_COLORKEY(WORD)
1031                                         case 4: COPYROW_COLORKEY(DWORD)
1032               default:
1033                                                 FIXME(ddraw, "%s color-keyed blit not implemented for bpp %d!\n",
1034                                                         (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1035                                                 ret = DDERR_UNSUPPORTED;
1036                                                 goto error;
1037               }
1038                                 dbuf += ddesc.lPitch;
1039           }
1040
1041 #undef COPYROW_COLORKEY
1042                         
1043                         dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1044
1045         }
1046         }
1047         
1048 error:
1049         
1050         if (dwFlags && FIXME_ON(ddraw)) {
1051           FIXME(ddraw,"\tUnsupported flags: ");
1052           _dump_DDBLT(dwFlags);
1053         }
1054
1055         IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1056         if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1057
1058         return DD_OK;
1059 }
1060
1061 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1062         LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1063 ) {
1064         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1065         int                             bpp, w, h, x, y;
1066         DDSURFACEDESC   ddesc,sdesc;
1067         HRESULT                 ret = DD_OK;
1068         LPBYTE                  sbuf, dbuf;
1069
1070
1071         if (TRACE_ON(ddraw)) {
1072             FIXME(ddraw,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1073                     This,dstx,dsty,src,rsrc,trans
1074             );
1075             FIXME(ddraw,"       trans:");
1076             if (FIXME_ON(ddraw))
1077               _dump_DDBLTFAST(trans);
1078             FIXME(ddraw,"       srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1079         }
1080         /* We need to lock the surfaces, or we won't get refreshes when done. */
1081         IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1082         IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1083
1084         bpp = This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8;
1085         sbuf = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1086         dbuf = ddesc.y.lpSurface + (dsty      * ddesc.lPitch) + dstx       * bpp;
1087
1088
1089         h=rsrc->bottom-rsrc->top;
1090         if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1091         if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1092         if (h<0) h=0;
1093
1094         w=rsrc->right-rsrc->left;
1095         if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1096         if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1097         if (w<0) w=0;
1098
1099         if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1100                 DWORD keylow, keyhigh;
1101                 if (trans & DDBLTFAST_SRCCOLORKEY) {
1102                         keylow  = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1103                         keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1104                 } else {
1105                         /* I'm not sure if this is correct */
1106                         FIXME(ddraw, "DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1107                         keylow  = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1108                         keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1109                 }
1110
1111 #define COPYBOX_COLORKEY(type) { \
1112         type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1113         s = sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp; \
1114         d = ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp; \
1115         for (y = 0; y < h; y++) { \
1116                 for (x = 0; x < w; x++) { \
1117                         tmp = s[x]; \
1118                         if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1119                 } \
1120                 (LPBYTE)s += sdesc.lPitch; \
1121                 (LPBYTE)d += ddesc.lPitch; \
1122         } \
1123         break; \
1124 }
1125
1126                 switch (bpp) {
1127                         case 1: COPYBOX_COLORKEY(BYTE)
1128                         case 2: COPYBOX_COLORKEY(WORD)
1129                         case 4: COPYBOX_COLORKEY(DWORD)
1130                         default:
1131                                 FIXME(ddraw, "Source color key blitting not supported for bpp %d\n", bpp*8);
1132                                 ret = DDERR_UNSUPPORTED;
1133                                 goto error;
1134         }
1135
1136 #undef COPYBOX_COLORKEY
1137
1138         } else {
1139                 int width = w * bpp;
1140
1141                 for (y = 0; y < h; y++) {
1142                         memcpy(dbuf, sbuf, width);
1143                         sbuf += sdesc.lPitch;
1144                         dbuf += ddesc.lPitch;
1145                 }
1146         }
1147
1148 error:
1149
1150         IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1151         IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1152         return ret;
1153 }
1154
1155 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1156         LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1157 ) {
1158         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1159         FIXME(ddraw,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1160                 This,ddbltbatch,x,y
1161         );
1162         return DD_OK;
1163 }
1164
1165 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1166         LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1167 ) {
1168         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1169         TRACE(ddraw,"(%p)->GetCaps(%p)\n",This,caps);
1170         caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1171         return DD_OK;
1172 }
1173
1174 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1175         LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1176 ) { 
1177         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1178                 TRACE(ddraw, "(%p)->GetSurfaceDesc(%p)\n",
1179                              This,ddsd);
1180   
1181   /* Simply copy the surface description stored in the object */
1182   *ddsd = This->s.surface_desc;
1183   
1184   if (TRACE_ON(ddraw)) {
1185     DUMP("   flags: ");
1186                 _dump_DDSD(ddsd->dwFlags);
1187     if (ddsd->dwFlags & DDSD_CAPS) {
1188       DUMP("   caps:  ");
1189       _dump_DDSCAPS(ddsd->ddsCaps.dwCaps);
1190     }
1191     if (ddsd->dwFlags & DDSD_PIXELFORMAT) {
1192       DUMP("   pixel format : \n");
1193       _dump_pixelformat(&(ddsd->ddpfPixelFormat));
1194     }
1195         }
1196
1197         return DD_OK;
1198 }
1199
1200 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1201         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1202         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1203
1204         return ++(This->ref);
1205 }
1206
1207 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1208         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1209         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1210
1211 #ifdef HAVE_LIBXXF86DGA
1212         if (!--(This->ref)) {
1213                 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1214                 /* clear out of surface list */
1215                 if (This->t.dga.fb_height == -1) {
1216                         HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1217                 } else {
1218                         This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1219                 }
1220
1221                 /* Free the backbuffer */
1222                 if (This->s.backbuffer)
1223                         IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1224
1225                 HeapFree(GetProcessHeap(),0,This);
1226                 return 0;
1227         }
1228 #endif /* defined(HAVE_LIBXXF86DGA) */
1229         return This->ref;
1230 }
1231
1232 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1233         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1234         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1235
1236         if (!--(This->ref)) {
1237                 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1238
1239                 if( This->s.backbuffer )
1240                   IDirectDrawSurface4_Release((IDirectDrawSurface4*)This->s.backbuffer);
1241
1242     if (This->t.xlib.image != NULL) {
1243       if (This->s.ddraw->d.pixel_convert != NULL) {
1244         /* In pixel conversion mode, there are two buffers to release... */
1245         HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1246         
1247 #ifdef HAVE_LIBXXSHM
1248         if (This->s.ddraw->e.xlib.xshm_active) {
1249           TSXShmDetach(display, &(This->t.xlib.shminfo));
1250           TSXDestroyImage(This->t.xlib.image);
1251           shmdt(This->t.xlib.shminfo.shmaddr);
1252         } else {
1253 #endif
1254           HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1255           This->t.xlib.image->data = NULL;
1256           TSXDestroyImage(This->t.xlib.image);
1257 #ifdef HAVE_LIBXXSHM
1258         }
1259 #endif
1260         
1261       } else {
1262                 This->t.xlib.image->data = NULL;
1263       
1264 #ifdef HAVE_LIBXXSHM
1265       if (This->s.ddraw->e.xlib.xshm_active) {
1266         TSXShmDetach(display, &(This->t.xlib.shminfo));
1267                 TSXDestroyImage(This->t.xlib.image);
1268         shmdt(This->t.xlib.shminfo.shmaddr);
1269       } else {
1270 #endif
1271               HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1272         TSXDestroyImage(This->t.xlib.image);
1273 #ifdef HAVE_LIBXXSHM    
1274       }
1275 #endif
1276       }
1277       
1278                 This->t.xlib.image = 0;
1279     } else {
1280             HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1281     }
1282
1283                 if (This->s.palette)
1284                         IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1285
1286                 HeapFree(GetProcessHeap(),0,This);
1287                 return 0;
1288         }
1289   
1290         return This->ref;
1291 }
1292
1293 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1294         LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1295 ) {
1296         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1297         TRACE(ddraw, "(%p)->GetAttachedSurface(%p,%p)\n",
1298                      This, lpddsd, lpdsf);
1299
1300         if (TRACE_ON(ddraw)) {
1301                 TRACE(ddraw,"   caps ");
1302                 _dump_DDSCAPS(lpddsd->dwCaps);
1303         }
1304
1305         if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
1306                 FIXME(ddraw,"whoops, can only handle backbuffers for now\n");
1307                 return E_FAIL;
1308         }
1309
1310         /* FIXME: should handle more than one backbuffer */
1311         *lpdsf = (LPDIRECTDRAWSURFACE4)This->s.backbuffer;
1312  
1313         if( This->s.backbuffer )
1314           IDirectDrawSurface4_AddRef( (IDirectDrawSurface4*)This->s.backbuffer );
1315
1316         return DD_OK;
1317 }
1318
1319 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1320         LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1321 ) {
1322         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1323         TRACE(ddraw,"(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1324
1325         return DDERR_ALREADYINITIALIZED;
1326 }
1327
1328 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1329         LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1330 ) {
1331         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1332         TRACE(ddraw,"(%p)->(%p)\n",This,pf);
1333
1334         *pf = This->s.surface_desc.ddpfPixelFormat;
1335         
1336         return DD_OK;
1337 }
1338
1339 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1340         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1341         FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,dwFlags);
1342         return DD_OK;
1343 }
1344
1345 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1346         LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1347 ) {
1348         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1349         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,x1,x2);
1350         return DD_OK;
1351 }
1352
1353 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1354         LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1355 ) {
1356         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1357         FIXME(ddraw,"(%p)->(%p),stub!\n",This,clipper);
1358         return DD_OK;
1359 }
1360
1361 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1362         LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1363 ) {
1364         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1365         FIXME(ddraw,"(%p)->(%p),stub!\n",This,surf);
1366
1367         IDirectDrawSurface4_AddRef(iface);
1368         
1369         /* This hack will be enough for the moment */
1370         if (This->s.backbuffer == NULL)
1371           This->s.backbuffer = (IDirectDrawSurface4Impl*)surf;
1372         return DD_OK;
1373 }
1374
1375 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1376         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1377         FIXME(ddraw,"(%p)->GetDC(%p)\n",This,lphdc);
1378         *lphdc = BeginPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1379         return DD_OK;
1380 }
1381
1382 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1383         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1384         DDSURFACEDESC   desc;
1385         DWORD x, y;
1386         
1387         FIXME(ddraw,"(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1388         EndPaint(This->s.ddraw->d.window,&This->s.ddraw->d.ps);
1389
1390         /* Well, as what the application did paint in this DC is NOT saved in the surface,
1391            I fill it with 'dummy' values to have something on the screen */
1392         IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1393         for (y = 0; y < desc.dwHeight; y++) {
1394           for (x = 0; x < desc.dwWidth; x++) {
1395             ((unsigned char *) desc.y.lpSurface)[x + y * desc.dwWidth] = (unsigned int) This + x + y;
1396           }
1397         }
1398         IDirectDrawSurface4_Unlock(iface,NULL);
1399         
1400         return DD_OK;
1401 }
1402
1403
1404 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1405         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1406         char    xrefiid[50];
1407
1408         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1409         TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
1410         
1411         /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1412          * the same interface. And IUnknown does that too of course.
1413          */
1414         if (    !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID))    ||
1415                 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID))    ||
1416                 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID))    ||
1417                 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID))     ||
1418                 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1419         ) {
1420                 *obj = This;
1421                 IDirectDrawSurface4_AddRef(iface);
1422
1423                 TRACE(ddraw, "  Creating IDirectDrawSurface interface (%p)\n", *obj);
1424                 
1425                 return S_OK;
1426         }
1427         else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1428           {
1429             /* Texture interface */
1430             *obj = d3dtexture2_create(This);
1431             IDirectDrawSurface4_AddRef(iface);
1432             
1433             TRACE(ddraw, "  Creating IDirect3DTexture2 interface (%p)\n", *obj);
1434             
1435             return S_OK;
1436           }
1437         else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1438           {
1439             /* Texture interface */
1440             *obj = d3dtexture_create(This);
1441             IDirectDrawSurface4_AddRef(iface);
1442             
1443             TRACE(ddraw, "  Creating IDirect3DTexture interface (%p)\n", *obj);
1444             
1445             return S_OK;
1446           }
1447         else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj))
1448           {
1449             /* It is the OpenGL Direct3D Device */
1450             IDirectDrawSurface4_AddRef(iface);
1451
1452             TRACE(ddraw, "  Creating IDirect3DDevice interface (%p)\n", *obj);
1453                         
1454                 return S_OK;
1455         }
1456         
1457         FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
1458         return OLE_E_ENUM_NOMORE;
1459 }
1460
1461 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1462         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1463         TRACE(ddraw,"(%p)->(), stub!\n",This);
1464         return DD_OK; /* hmm */
1465 }
1466
1467 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1468         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1469         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,context,esfcb);
1470
1471         /* For the moment, only enumerating the back buffer */
1472         if (This->s.backbuffer != NULL) {
1473           TRACE(ddraw, "Enumerating back-buffer (%p)\n", This->s.backbuffer);
1474           if (esfcb((LPDIRECTDRAWSURFACE) This->s.backbuffer, &(This->s.backbuffer->s.surface_desc), context) == DDENUMRET_CANCEL)
1475             return DD_OK;
1476         }
1477         
1478         return DD_OK;
1479 }
1480
1481 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1482         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1483         FIXME(ddraw,"(%p)->(),stub!\n",This);
1484         return DD_OK;
1485 }
1486
1487 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1488         LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey ) 
1489 {
1490         ICOM_THIS(IDirectDrawSurface4Impl,iface);
1491         TRACE(ddraw,"(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1492         if (TRACE_ON(ddraw)) {
1493           DUMP("   (0x%08lx <-> 0x%08lx)  -  ",
1494                ckey->dwColorSpaceLowValue,
1495                ckey->dwColorSpaceHighValue);
1496           _dump_colorkeyflag(dwFlags);
1497         }
1498
1499         /* If this surface was loaded as a texture, call also the texture
1500            SetColorKey callback */
1501         if (This->s.texture) {
1502           This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1503         }
1504
1505         if( dwFlags & DDCKEY_SRCBLT )
1506         {
1507            dwFlags &= ~DDCKEY_SRCBLT;
1508            This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1509            memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1510         }
1511
1512         if( dwFlags & DDCKEY_DESTBLT )
1513         {
1514            dwFlags &= ~DDCKEY_DESTBLT;
1515            This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1516            memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1517         }
1518
1519         if( dwFlags & DDCKEY_SRCOVERLAY )
1520         {
1521            dwFlags &= ~DDCKEY_SRCOVERLAY;
1522            This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1523            memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );      
1524         }
1525         
1526         if( dwFlags & DDCKEY_DESTOVERLAY )
1527         {
1528            dwFlags &= ~DDCKEY_DESTOVERLAY;
1529            This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1530            memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );     
1531         }
1532
1533         if( dwFlags )
1534         {
1535           FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1536         }
1537
1538         return DD_OK;
1539
1540 }
1541
1542 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1543         LPDIRECTDRAWSURFACE4 iface, 
1544         LPRECT lpRect )
1545 {
1546   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1547   FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpRect); 
1548
1549   return DD_OK;
1550 }
1551
1552 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1553         LPDIRECTDRAWSURFACE4 iface, 
1554         DWORD dwFlags,
1555         LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1556 {
1557   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1558   FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n",This,dwFlags,lpDDSAttachedSurface);
1559
1560   return DD_OK;
1561 }
1562
1563 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1564         LPDIRECTDRAWSURFACE4 iface,
1565         DWORD dwFlags,
1566         LPVOID lpContext,
1567         LPDDENUMSURFACESCALLBACK lpfnCallback )
1568 {
1569   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1570   FIXME(ddraw,"(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1571           lpContext, lpfnCallback );
1572
1573   return DD_OK;
1574 }
1575
1576 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1577         LPDIRECTDRAWSURFACE4 iface,
1578         LPDIRECTDRAWCLIPPER* lplpDDClipper )
1579 {
1580   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1581   FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDClipper);
1582
1583   return DD_OK;
1584 }
1585
1586 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1587         LPDIRECTDRAWSURFACE4 iface,
1588         DWORD dwFlags,
1589         LPDDCOLORKEY lpDDColorKey )
1590 {
1591   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1592   TRACE(ddraw,"(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1593
1594   if( dwFlags & DDCKEY_SRCBLT )  {
1595      dwFlags &= ~DDCKEY_SRCBLT;
1596      memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1597   }
1598
1599   if( dwFlags & DDCKEY_DESTBLT )
1600   {
1601     dwFlags &= ~DDCKEY_DESTBLT;
1602     memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1603   }
1604
1605   if( dwFlags & DDCKEY_SRCOVERLAY )
1606   {
1607     dwFlags &= ~DDCKEY_SRCOVERLAY;
1608     memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1609   }
1610
1611   if( dwFlags & DDCKEY_DESTOVERLAY )
1612   {
1613     dwFlags &= ~DDCKEY_DESTOVERLAY;
1614     memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1615   }
1616
1617   if( dwFlags )
1618   {
1619     FIXME( ddraw, "unhandled dwFlags: 0x%08lx\n", dwFlags );
1620   }
1621
1622   return DD_OK;
1623 }
1624
1625 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1626         LPDIRECTDRAWSURFACE4 iface,
1627         DWORD dwFlags ) 
1628 {
1629   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1630   FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1631
1632   return DD_OK;
1633 }
1634
1635 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1636         LPDIRECTDRAWSURFACE4 iface,
1637         LPDIRECTDRAWPALETTE* lplpDDPalette )
1638 {
1639   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1640   FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDDPalette);
1641
1642   return DD_OK;
1643 }
1644
1645 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1646         LPDIRECTDRAWSURFACE4 iface,
1647         LONG lX,
1648         LONG lY)
1649 {
1650   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1651   FIXME(ddraw,"(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1652
1653   return DD_OK;
1654 }
1655
1656 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1657         LPDIRECTDRAWSURFACE4 iface,
1658         LPRECT lpSrcRect,
1659         LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1660         LPRECT lpDestRect,
1661         DWORD dwFlags,
1662         LPDDOVERLAYFX lpDDOverlayFx )
1663 {
1664   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1665   FIXME(ddraw,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1666          lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );  
1667
1668   return DD_OK;
1669 }
1670  
1671 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1672         LPDIRECTDRAWSURFACE4 iface,
1673         DWORD dwFlags )
1674 {
1675   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1676   FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags); 
1677
1678   return DD_OK;
1679 }
1680
1681 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1682         LPDIRECTDRAWSURFACE4 iface,
1683         DWORD dwFlags,
1684         LPDIRECTDRAWSURFACE4 lpDDSReference )
1685 {
1686   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1687   FIXME(ddraw,"(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1688
1689   return DD_OK;
1690 }
1691
1692 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1693         LPDIRECTDRAWSURFACE4 iface,
1694         LPVOID* lplpDD )
1695 {
1696   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1697   FIXME(ddraw,"(%p)->(%p),stub!\n", This, lplpDD);
1698
1699   /* Not sure about that... */
1700   *lplpDD = (void *) This->s.ddraw;
1701   
1702   return DD_OK;
1703 }
1704
1705 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
1706         LPDIRECTDRAWSURFACE4 iface,
1707         DWORD dwFlags )
1708 {
1709   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1710   FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1711
1712   return DD_OK;
1713 }
1714
1715 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
1716         LPDIRECTDRAWSURFACE4 iface,
1717         DWORD dwFlags )
1718 {
1719   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1720   FIXME(ddraw,"(%p)->(0x%08lx),stub!\n", This, dwFlags);
1721
1722   return DD_OK;
1723 }
1724
1725 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
1726         LPDIRECTDRAWSURFACE4 iface,
1727         LPDDSURFACEDESC lpDDSD,
1728         DWORD dwFlags )
1729 {
1730   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1731   FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
1732
1733   return DD_OK;
1734 }
1735
1736 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1737                                                          REFGUID guidTag,
1738                                                          LPVOID lpData,
1739                                                          DWORD cbSize,
1740                                                          DWORD dwFlags) {
1741   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1742   FIXME(ddraw, "(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
1743   
1744   return DD_OK;
1745 }
1746
1747 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
1748                                                          REFGUID guidTag,
1749                                                          LPVOID lpBuffer,
1750                                                          LPDWORD lpcbBufferSize) {
1751   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1752   FIXME(ddraw, "(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
1753   
1754   return DD_OK;
1755 }
1756
1757 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
1758                                                           REFGUID guidTag)  {
1759   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1760   FIXME(ddraw, "(%p)->(%p)\n", This, guidTag);
1761   
1762   return DD_OK;
1763 }
1764
1765 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
1766                                                              LPDWORD lpValue)  {
1767   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1768   FIXME(ddraw, "(%p)->(%p)\n", This, lpValue);
1769   
1770   return DD_OK;
1771 }
1772
1773 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
1774   ICOM_THIS(IDirectDrawSurface4Impl,iface);
1775   FIXME(ddraw, "(%p)\n", This);
1776   
1777   return DD_OK;
1778 }
1779
1780 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt = {
1781         IDirectDrawSurface4Impl_QueryInterface,
1782         IDirectDrawSurface4Impl_AddRef,
1783         DGA_IDirectDrawSurface4Impl_Release,
1784         IDirectDrawSurface4Impl_AddAttachedSurface,
1785         IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1786         IDirectDrawSurface4Impl_Blt,
1787         IDirectDrawSurface4Impl_BltBatch,
1788         IDirectDrawSurface4Impl_BltFast,
1789         IDirectDrawSurface4Impl_DeleteAttachedSurface,
1790         IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1791         IDirectDrawSurface4Impl_EnumOverlayZOrders,
1792         DGA_IDirectDrawSurface4Impl_Flip,
1793         IDirectDrawSurface4Impl_GetAttachedSurface,
1794         IDirectDrawSurface4Impl_GetBltStatus,
1795         IDirectDrawSurface4Impl_GetCaps,
1796         IDirectDrawSurface4Impl_GetClipper,
1797         IDirectDrawSurface4Impl_GetColorKey,
1798         IDirectDrawSurface4Impl_GetDC,
1799         IDirectDrawSurface4Impl_GetFlipStatus,
1800         IDirectDrawSurface4Impl_GetOverlayPosition,
1801         IDirectDrawSurface4Impl_GetPalette,
1802         IDirectDrawSurface4Impl_GetPixelFormat,
1803         IDirectDrawSurface4Impl_GetSurfaceDesc,
1804         IDirectDrawSurface4Impl_Initialize,
1805         IDirectDrawSurface4Impl_IsLost,
1806         IDirectDrawSurface4Impl_Lock,
1807         IDirectDrawSurface4Impl_ReleaseDC,
1808         IDirectDrawSurface4Impl_Restore,
1809         IDirectDrawSurface4Impl_SetClipper,
1810         IDirectDrawSurface4Impl_SetColorKey,
1811         IDirectDrawSurface4Impl_SetOverlayPosition,
1812         DGA_IDirectDrawSurface4Impl_SetPalette,
1813         DGA_IDirectDrawSurface4Impl_Unlock,
1814         IDirectDrawSurface4Impl_UpdateOverlay,
1815         IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1816         IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1817         IDirectDrawSurface4Impl_GetDDInterface,
1818         IDirectDrawSurface4Impl_PageLock,
1819         IDirectDrawSurface4Impl_PageUnlock,
1820         IDirectDrawSurface4Impl_SetSurfaceDesc,
1821         IDirectDrawSurface4Impl_SetPrivateData,
1822         IDirectDrawSurface4Impl_GetPrivateData,
1823         IDirectDrawSurface4Impl_FreePrivateData,
1824         IDirectDrawSurface4Impl_GetUniquenessValue,
1825         IDirectDrawSurface4Impl_ChangeUniquenessValue
1826 };
1827
1828 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt = {
1829         IDirectDrawSurface4Impl_QueryInterface,
1830         IDirectDrawSurface4Impl_AddRef,
1831         Xlib_IDirectDrawSurface4Impl_Release,
1832         IDirectDrawSurface4Impl_AddAttachedSurface,
1833         IDirectDrawSurface4Impl_AddOverlayDirtyRect,
1834         IDirectDrawSurface4Impl_Blt,
1835         IDirectDrawSurface4Impl_BltBatch,
1836         IDirectDrawSurface4Impl_BltFast,
1837         IDirectDrawSurface4Impl_DeleteAttachedSurface,
1838         IDirectDrawSurface4Impl_EnumAttachedSurfaces,
1839         IDirectDrawSurface4Impl_EnumOverlayZOrders,
1840         Xlib_IDirectDrawSurface4Impl_Flip,
1841         IDirectDrawSurface4Impl_GetAttachedSurface,
1842         IDirectDrawSurface4Impl_GetBltStatus,
1843         IDirectDrawSurface4Impl_GetCaps,
1844         IDirectDrawSurface4Impl_GetClipper,
1845         IDirectDrawSurface4Impl_GetColorKey,
1846         IDirectDrawSurface4Impl_GetDC,
1847         IDirectDrawSurface4Impl_GetFlipStatus,
1848         IDirectDrawSurface4Impl_GetOverlayPosition,
1849         IDirectDrawSurface4Impl_GetPalette,
1850         IDirectDrawSurface4Impl_GetPixelFormat,
1851         IDirectDrawSurface4Impl_GetSurfaceDesc,
1852         IDirectDrawSurface4Impl_Initialize,
1853         IDirectDrawSurface4Impl_IsLost,
1854         IDirectDrawSurface4Impl_Lock,
1855         IDirectDrawSurface4Impl_ReleaseDC,
1856         IDirectDrawSurface4Impl_Restore,
1857         IDirectDrawSurface4Impl_SetClipper,
1858         IDirectDrawSurface4Impl_SetColorKey,
1859         IDirectDrawSurface4Impl_SetOverlayPosition,
1860         Xlib_IDirectDrawSurface4Impl_SetPalette,
1861         Xlib_IDirectDrawSurface4Impl_Unlock,
1862         IDirectDrawSurface4Impl_UpdateOverlay,
1863         IDirectDrawSurface4Impl_UpdateOverlayDisplay,
1864         IDirectDrawSurface4Impl_UpdateOverlayZOrder,
1865         IDirectDrawSurface4Impl_GetDDInterface,
1866         IDirectDrawSurface4Impl_PageLock,
1867         IDirectDrawSurface4Impl_PageUnlock,
1868         IDirectDrawSurface4Impl_SetSurfaceDesc,
1869         IDirectDrawSurface4Impl_SetPrivateData,
1870         IDirectDrawSurface4Impl_GetPrivateData,
1871         IDirectDrawSurface4Impl_FreePrivateData,
1872         IDirectDrawSurface4Impl_GetUniquenessValue,
1873         IDirectDrawSurface4Impl_ChangeUniquenessValue
1874 };
1875
1876 /******************************************************************************
1877  *                      DirectDrawCreateClipper (DDRAW.7)
1878  */
1879 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
1880                                         LPDIRECTDRAWCLIPPER *lplpDDClipper,
1881                                         LPUNKNOWN pUnkOuter)
1882 {
1883   IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
1884   TRACE(ddraw, "(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
1885
1886   *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
1887   (*ilplpDDClipper)->lpvtbl = &ddclipvt;
1888   (*ilplpDDClipper)->ref = 1;
1889
1890   return DD_OK;
1891 }
1892
1893 /******************************************************************************
1894  *                      IDirectDrawClipper
1895  */
1896 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
1897         LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
1898 ) {
1899         ICOM_THIS(IDirectDrawClipperImpl,iface);
1900         FIXME(ddraw,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
1901         return DD_OK;
1902 }
1903
1904 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
1905         ICOM_THIS(IDirectDrawClipperImpl,iface);
1906         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
1907
1908         This->ref--;
1909         if (This->ref)
1910                 return This->ref;
1911         HeapFree(GetProcessHeap(),0,This);
1912         return 0;
1913 }
1914
1915 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
1916         LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
1917 ) {
1918         ICOM_THIS(IDirectDrawClipperImpl,iface);
1919         FIXME(ddraw,"(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
1920         if (hmm) *hmm=0;
1921         return DD_OK;
1922 }
1923
1924 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
1925         LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
1926 ) {
1927         ICOM_THIS(IDirectDrawClipperImpl,iface);
1928         FIXME(ddraw,"(%p,%p,%ld),stub!\n",This,lprgn,hmm);
1929         return DD_OK;
1930 }
1931
1932 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
1933          LPDIRECTDRAWCLIPPER iface,
1934          REFIID riid,
1935          LPVOID* ppvObj )
1936 {
1937    ICOM_THIS(IDirectDrawClipperImpl,iface);
1938    FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
1939    return OLE_E_ENUM_NOMORE;
1940 }
1941
1942 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
1943 {
1944   ICOM_THIS(IDirectDrawClipperImpl,iface);
1945   TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
1946   return ++(This->ref);
1947 }
1948
1949 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
1950          LPDIRECTDRAWCLIPPER iface,
1951          HWND* HWndPtr )
1952 {
1953    ICOM_THIS(IDirectDrawClipperImpl,iface);
1954    FIXME(ddraw,"(%p)->(%p),stub!\n",This,HWndPtr);
1955    return DD_OK;
1956 }
1957
1958 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
1959          LPDIRECTDRAWCLIPPER iface,
1960          LPDIRECTDRAW lpDD,
1961          DWORD dwFlags )
1962 {
1963    ICOM_THIS(IDirectDrawClipperImpl,iface);
1964    FIXME(ddraw,"(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
1965    return DD_OK;
1966 }
1967
1968 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
1969          LPDIRECTDRAWCLIPPER iface,
1970          BOOL* lpbChanged )
1971 {
1972    ICOM_THIS(IDirectDrawClipperImpl,iface);
1973    FIXME(ddraw,"(%p)->(%p),stub!\n",This,lpbChanged);
1974    return DD_OK;
1975 }
1976
1977 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt = {
1978         IDirectDrawClipperImpl_QueryInterface,
1979         IDirectDrawClipperImpl_AddRef,
1980         IDirectDrawClipperImpl_Release,
1981         IDirectDrawClipperImpl_GetClipList,
1982         IDirectDrawClipperImpl_GetHWnd,
1983         IDirectDrawClipperImpl_Initialize,
1984         IDirectDrawClipperImpl_IsClipListChanged,
1985         IDirectDrawClipperImpl_SetClipList,
1986         IDirectDrawClipperImpl_SetHwnd
1987 };
1988
1989
1990 /******************************************************************************
1991  *                      IDirectDrawPalette
1992  */
1993 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
1994         LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
1995 ) {
1996         ICOM_THIS(IDirectDrawPaletteImpl,iface);
1997         int     i;
1998
1999         TRACE(ddraw,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2000               This,x,start,count,palent);
2001
2002         if (!This->cm) /* should not happen */ {
2003                 FIXME(ddraw,"app tried to read colormap for non-palettized mode\n");
2004                 return DDERR_GENERIC;
2005         }
2006         for (i=0;i<count;i++) {
2007                 palent[i].peRed   = This->palents[start+i].peRed;
2008                 palent[i].peBlue  = This->palents[start+i].peBlue;
2009                 palent[i].peGreen = This->palents[start+i].peGreen;
2010                 palent[i].peFlags = This->palents[start+i].peFlags;
2011
2012         }
2013         return DD_OK;
2014 }
2015
2016 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2017         LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2018 ) {
2019         ICOM_THIS(IDirectDrawPaletteImpl,iface);
2020         XColor          xc;
2021         int             i;
2022
2023         TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2024                 This,x,start,count,palent
2025         );
2026         for (i=0;i<count;i++) {
2027                 xc.red = palent[i].peRed<<8;
2028                 xc.blue = palent[i].peBlue<<8;
2029                 xc.green = palent[i].peGreen<<8;
2030                 xc.flags = DoRed|DoBlue|DoGreen;
2031                 xc.pixel = start+i;
2032
2033                 if (This->cm)
2034                     TSXStoreColor(display,This->cm,&xc);
2035
2036                 This->palents[start+i].peRed = palent[i].peRed;
2037                 This->palents[start+i].peBlue = palent[i].peBlue;
2038                 This->palents[start+i].peGreen = palent[i].peGreen;
2039                 This->palents[start+i].peFlags = palent[i].peFlags;
2040         }
2041
2042         /* Now, if we are in 'depth conversion mode', update the screen palette */
2043         if (This->ddraw->d.palette_convert != NULL)
2044           This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2045           
2046         return DD_OK;
2047 }
2048
2049 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2050         LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2051 ) {
2052 #ifdef HAVE_LIBXXF86DGA
2053         ICOM_THIS(IDirectDrawPaletteImpl,iface);
2054         XColor          xc;
2055         Colormap        cm;
2056         int             i;
2057
2058         TRACE(ddraw,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2059                 This,x,start,count,palent
2060         );
2061         if (!This->cm) /* should not happen */ {
2062                 FIXME(ddraw,"app tried to set colormap in non-palettized mode\n");
2063                 return DDERR_GENERIC;
2064         }
2065         /* FIXME: free colorcells instead of freeing whole map */
2066         cm = This->cm;
2067         This->cm = TSXCopyColormapAndFree(display,This->cm);
2068         TSXFreeColormap(display,cm);
2069
2070         for (i=0;i<count;i++) {
2071                 xc.red = palent[i].peRed<<8;
2072                 xc.blue = palent[i].peBlue<<8;
2073                 xc.green = palent[i].peGreen<<8;
2074                 xc.flags = DoRed|DoBlue|DoGreen;
2075                 xc.pixel = i+start;
2076
2077                 TSXStoreColor(display,This->cm,&xc);
2078
2079                 This->palents[start+i].peRed = palent[i].peRed;
2080                 This->palents[start+i].peBlue = palent[i].peBlue;
2081                 This->palents[start+i].peGreen = palent[i].peGreen;
2082                 This->palents[start+i].peFlags = palent[i].peFlags;
2083         }
2084         TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2085         return DD_OK;
2086 #else /* defined(HAVE_LIBXXF86DGA) */
2087         return E_UNEXPECTED;
2088 #endif /* defined(HAVE_LIBXXF86DGA) */
2089 }
2090
2091 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2092         ICOM_THIS(IDirectDrawPaletteImpl,iface);
2093         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2094         if (!--(This->ref)) {
2095                 if (This->cm) {
2096                         TSXFreeColormap(display,This->cm);
2097                         This->cm = 0;
2098                 }
2099                 HeapFree(GetProcessHeap(),0,This);
2100                 return 0;
2101         }
2102         return This->ref;
2103 }
2104
2105 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2106         ICOM_THIS(IDirectDrawPaletteImpl,iface);
2107
2108         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2109         return ++(This->ref);
2110 }
2111
2112 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2113         LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2114 ) {
2115         ICOM_THIS(IDirectDrawPaletteImpl,iface);
2116         TRACE(ddraw,"(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2117
2118         return DDERR_ALREADYINITIALIZED;
2119 }
2120
2121 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2122          LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2123 {
2124    ICOM_THIS(IDirectDrawPaletteImpl,iface);
2125    FIXME( ddraw, "(%p)->(%p) stub.\n", This, lpdwCaps );
2126    return DD_OK;
2127
2128
2129 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2130         LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj ) 
2131 {
2132   ICOM_THIS(IDirectDrawPaletteImpl,iface);
2133   char    xrefiid[50];
2134
2135   WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2136   FIXME(ddraw,"(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2137
2138   return S_OK;
2139 }
2140
2141 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt = {
2142         IDirectDrawPaletteImpl_QueryInterface,
2143         IDirectDrawPaletteImpl_AddRef,
2144         IDirectDrawPaletteImpl_Release,
2145         IDirectDrawPaletteImpl_GetCaps,
2146         IDirectDrawPaletteImpl_GetEntries,
2147         IDirectDrawPaletteImpl_Initialize,
2148         DGA_IDirectDrawPaletteImpl_SetEntries
2149 };
2150
2151 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt = {
2152         IDirectDrawPaletteImpl_QueryInterface,
2153         IDirectDrawPaletteImpl_AddRef,
2154         IDirectDrawPaletteImpl_Release,
2155         IDirectDrawPaletteImpl_GetCaps,
2156         IDirectDrawPaletteImpl_GetEntries,
2157         IDirectDrawPaletteImpl_Initialize,
2158         Xlib_IDirectDrawPaletteImpl_SetEntries
2159 };
2160
2161 /*******************************************************************************
2162  *                              IDirect3D
2163  */
2164 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2165         LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2166 ) {
2167         ICOM_THIS(IDirect3DImpl,iface);
2168         /* FIXME: Not sure if this is correct */
2169         char    xrefiid[50];
2170
2171         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2172         TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2173         if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2174             (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2175             (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2176                 *obj = This->ddraw;
2177                 IDirect3D_AddRef(iface);
2178
2179                 TRACE(ddraw, "  Creating IDirectDrawX interface (%p)\n", *obj);
2180                 
2181                 return S_OK;
2182         }
2183         if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2184             (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2185                 *obj = This;
2186                 IDirect3D_AddRef(iface);
2187
2188                 TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
2189
2190                 return S_OK;
2191         }
2192         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2193                 IDirect3D2Impl*  d3d;
2194
2195                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2196                 d3d->ref = 1;
2197                 d3d->ddraw = This->ddraw;
2198                 IDirect3D_AddRef(iface);
2199                 d3d->lpvtbl = &d3d2vt;
2200                 *obj = d3d;
2201
2202                 TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
2203
2204                 return S_OK;
2205         }
2206         FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2207         return OLE_E_ENUM_NOMORE;
2208 }
2209
2210 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2211         ICOM_THIS(IDirect3DImpl,iface);
2212         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2213
2214         return ++(This->ref);
2215 }
2216
2217 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2218 {
2219         ICOM_THIS(IDirect3DImpl,iface);
2220         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2221
2222         if (!--(This->ref)) {
2223                 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2224                 HeapFree(GetProcessHeap(),0,This);
2225                 return 0;
2226         }
2227         return This->ref;
2228 }
2229
2230 static HRESULT WINAPI IDirect3DImpl_Initialize(
2231          LPDIRECT3D iface, REFIID refiid )
2232 {
2233   ICOM_THIS(IDirect3DImpl,iface);
2234   /* FIXME: Not sure if this is correct */
2235   char    xrefiid[50];
2236
2237   WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2238   FIXME(ddraw,"(%p)->(%s):stub.\n",This,xrefiid);
2239   
2240   return DDERR_ALREADYINITIALIZED;
2241 }
2242
2243 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2244                                             LPD3DENUMDEVICESCALLBACK cb,
2245                                             LPVOID context) {
2246   ICOM_THIS(IDirect3DImpl,iface);
2247   FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2248
2249   /* Call functions defined in d3ddevices.c */
2250   if (!d3d_OpenGL_dx3(cb, context))
2251     return DD_OK;
2252
2253   return DD_OK;
2254 }
2255
2256 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2257                                             LPDIRECT3DLIGHT *lplight,
2258                                             IUnknown *lpunk)
2259 {
2260   ICOM_THIS(IDirect3DImpl,iface);
2261   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2262   
2263   /* Call the creation function that is located in d3dlight.c */
2264   *lplight = d3dlight_create_dx3(This);
2265   
2266   return DD_OK;
2267 }
2268
2269 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2270                                                LPDIRECT3DMATERIAL *lpmaterial,
2271                                                IUnknown *lpunk)
2272 {
2273   ICOM_THIS(IDirect3DImpl,iface);
2274   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2275
2276   /* Call the creation function that is located in d3dviewport.c */
2277   *lpmaterial = d3dmaterial_create(This);
2278   
2279   return DD_OK;
2280 }
2281
2282 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2283                                                LPDIRECT3DVIEWPORT *lpviewport,
2284                                                IUnknown *lpunk)
2285 {
2286   ICOM_THIS(IDirect3DImpl,iface);
2287   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2288   
2289   /* Call the creation function that is located in d3dviewport.c */
2290   *lpviewport = d3dviewport_create(This);
2291   
2292   return DD_OK;
2293 }
2294
2295 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2296                                            LPD3DFINDDEVICESEARCH lpfinddevsrc,
2297                                            LPD3DFINDDEVICERESULT lpfinddevrst)
2298 {
2299   ICOM_THIS(IDirect3DImpl,iface);
2300   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2301   
2302   return DD_OK;
2303 }
2304
2305 static ICOM_VTABLE(IDirect3D) d3dvt = {
2306         IDirect3DImpl_QueryInterface,
2307         IDirect3DImpl_AddRef,
2308         IDirect3DImpl_Release,
2309         IDirect3DImpl_Initialize,
2310         IDirect3DImpl_EnumDevices,
2311         IDirect3DImpl_CreateLight,
2312         IDirect3DImpl_CreateMaterial,
2313         IDirect3DImpl_CreateViewport,
2314         IDirect3DImpl_FindDevice
2315 };
2316
2317 /*******************************************************************************
2318  *                              IDirect3D2
2319  */
2320 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2321         LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {  
2322         ICOM_THIS(IDirect3D2Impl,iface);
2323
2324         /* FIXME: Not sure if this is correct */
2325         char    xrefiid[50];
2326
2327         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2328         TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
2329         if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2330             (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2331             (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2332                 *obj = This->ddraw;
2333                 IDirect3D2_AddRef(iface);
2334
2335                 TRACE(ddraw, "  Creating IDirectDrawX interface (%p)\n", *obj);
2336                 
2337                 return S_OK;
2338         }
2339         if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2340             (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2341                 *obj = This;
2342                 IDirect3D2_AddRef(iface);
2343
2344                 TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
2345
2346                 return S_OK;
2347         }
2348         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2349                 IDirect3DImpl*  d3d;
2350
2351                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2352                 d3d->ref = 1;
2353                 d3d->ddraw = This->ddraw;
2354                 IDirect3D2_AddRef(iface);
2355                 d3d->lpvtbl = &d3dvt;
2356                 *obj = d3d;
2357
2358                 TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
2359
2360                 return S_OK;
2361         }
2362         FIXME(ddraw,"(%p):interface for IID %s NOT found!\n",This,xrefiid);
2363         return OLE_E_ENUM_NOMORE;
2364 }
2365
2366 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2367         ICOM_THIS(IDirect3D2Impl,iface);
2368         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
2369
2370         return ++(This->ref);
2371 }
2372
2373 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2374         ICOM_THIS(IDirect3D2Impl,iface);
2375         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
2376
2377         if (!--(This->ref)) {
2378                 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2379                 HeapFree(GetProcessHeap(),0,This);
2380                 return 0;
2381         }
2382         return This->ref;
2383 }
2384
2385 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2386         LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2387 ) {
2388         ICOM_THIS(IDirect3D2Impl,iface);
2389         FIXME(ddraw,"(%p)->(%p,%p),stub!\n",This,cb,context);
2390
2391         /* Call functions defined in d3ddevices.c */
2392         if (!d3d_OpenGL(cb, context))
2393           return DD_OK;
2394
2395         return DD_OK;
2396 }
2397
2398 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2399                                              LPDIRECT3DLIGHT *lplight,
2400                                              IUnknown *lpunk)
2401 {
2402   ICOM_THIS(IDirect3D2Impl,iface);
2403   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2404
2405   /* Call the creation function that is located in d3dlight.c */
2406   *lplight = d3dlight_create(This);
2407   
2408         return DD_OK;
2409 }
2410
2411 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2412                                                 LPDIRECT3DMATERIAL2 *lpmaterial,
2413                                                 IUnknown *lpunk)
2414 {
2415   ICOM_THIS(IDirect3D2Impl,iface);
2416   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2417
2418   /* Call the creation function that is located in d3dviewport.c */
2419   *lpmaterial = d3dmaterial2_create(This);
2420
2421   return DD_OK;
2422 }
2423
2424 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2425                                                 LPDIRECT3DVIEWPORT2 *lpviewport,
2426                                                 IUnknown *lpunk)
2427 {
2428   ICOM_THIS(IDirect3D2Impl,iface);
2429   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2430   
2431   /* Call the creation function that is located in d3dviewport.c */
2432   *lpviewport = d3dviewport2_create(This);
2433   
2434   return DD_OK;
2435 }
2436
2437 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2438                                             LPD3DFINDDEVICESEARCH lpfinddevsrc,
2439                                             LPD3DFINDDEVICERESULT lpfinddevrst)
2440 {
2441   ICOM_THIS(IDirect3D2Impl,iface);
2442   TRACE(ddraw, "(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2443
2444   return DD_OK;
2445 }
2446
2447 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2448                                               REFCLSID rguid,
2449                                               LPDIRECTDRAWSURFACE surface,
2450                                               LPDIRECT3DDEVICE2 *device)
2451 {
2452   ICOM_THIS(IDirect3D2Impl,iface);
2453   char  xbuf[50];
2454   
2455   WINE_StringFromCLSID(rguid,xbuf);
2456   FIXME(ddraw,"(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2457
2458   if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2459     IDirect3D2_AddRef(iface);
2460     return DD_OK;
2461 }
2462
2463   return DDERR_INVALIDPARAMS;
2464 }
2465
2466 static ICOM_VTABLE(IDirect3D2) d3d2vt = {
2467         IDirect3D2Impl_QueryInterface,
2468         IDirect3D2Impl_AddRef,
2469         IDirect3D2Impl_Release,
2470         IDirect3D2Impl_EnumDevices,
2471         IDirect3D2Impl_CreateLight,
2472         IDirect3D2Impl_CreateMaterial,
2473         IDirect3D2Impl_CreateViewport,
2474         IDirect3D2Impl_FindDevice,
2475         IDirect3D2Impl_CreateDevice
2476 };
2477
2478 /*******************************************************************************
2479  *                              IDirectDraw
2480  */
2481
2482 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2483  * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2484  */
2485 static INT ddrawXlibThisOffset = 0;
2486
2487 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2488                                                LPDDSURFACEDESC lpddsd,
2489                                                IDirectDrawSurfaceImpl* lpdsf)
2490 {
2491   int bpp;
2492   
2493   /* The surface was already allocated when entering in this function */
2494   TRACE(ddraw,"using system memory for a surface (%p)\n", lpdsf);
2495
2496   if (lpddsd->dwFlags & DDSD_ZBUFFERBITDEPTH) {
2497     /* This is a Z Buffer */
2498     TRACE(ddraw, "Creating Z-Buffer of %ld bit depth\n", lpddsd->x.dwZBufferBitDepth);
2499     bpp = lpddsd->x.dwZBufferBitDepth / 8;
2500   } else {
2501     /* This is a standard image */
2502   if (!(lpddsd->dwFlags & DDSD_PIXELFORMAT)) {
2503     /* No pixel format => use DirectDraw's format */
2504     lpddsd->ddpfPixelFormat = This->d.directdraw_pixelformat;
2505     lpddsd->dwFlags |= DDSD_PIXELFORMAT;
2506   }  else {
2507     /* To check what the program wants */
2508     if (TRACE_ON(ddraw)) {
2509       _dump_pixelformat(&(lpddsd->ddpfPixelFormat));
2510     }
2511   }
2512
2513   if (lpddsd->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) {
2514     bpp = 1;
2515   } else {
2516   bpp = lpddsd->ddpfPixelFormat.x.dwRGBBitCount / 8;
2517   }
2518   }
2519
2520   /* Copy the surface description */
2521   lpdsf->s.surface_desc = *lpddsd;
2522   
2523   lpdsf->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE;
2524   lpdsf->s.surface_desc.y.lpSurface = (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpddsd->dwWidth * lpddsd->dwHeight * bpp);
2525   lpdsf->s.surface_desc.lPitch = lpddsd->dwWidth * bpp;
2526   
2527   return DD_OK;
2528 }
2529
2530 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2531         LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2532 ) {
2533 #ifdef HAVE_LIBXXF86DGA
2534         ICOM_THIS(IDirectDraw2Impl,iface);
2535         IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2536         int     i;
2537
2538         TRACE(ddraw, "(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2539         if (TRACE_ON(ddraw)) {
2540                 DUMP("   w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2541                 _dump_DDSD(lpddsd->dwFlags);
2542                 DUMP("   caps ");
2543                 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2544         }
2545
2546         *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2547         IDirectDraw2_AddRef(iface);
2548         
2549         (*ilpdsf)->ref = 1;
2550         (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2551         (*ilpdsf)->s.ddraw = This;
2552         (*ilpdsf)->s.palette = NULL;
2553         (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2554
2555         if (!(lpddsd->dwFlags & DDSD_WIDTH))
2556           lpddsd->dwWidth  = This->d.width;
2557         if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2558           lpddsd->dwHeight = This->d.height;
2559         
2560         /* Check if this a 'primary surface' or not */
2561         if ((lpddsd->dwFlags & DDSD_CAPS) &&
2562             (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2563
2564           /* This is THE primary surface => there is DGA-specific code */
2565           /* First, store the surface description */
2566           (*ilpdsf)->s.surface_desc = *lpddsd;
2567           
2568           /* Find a viewport */
2569                 for (i=0;i<32;i++)
2570                         if (!(This->e.dga.vpmask & (1<<i)))
2571                                 break;
2572                 TRACE(ddraw,"using viewport %d for a primary surface\n",i);
2573                 /* if i == 32 or maximum ... return error */
2574                 This->e.dga.vpmask|=(1<<i);
2575           (*ilpdsf)->s.surface_desc.y.lpSurface =
2576             This->e.dga.fb_addr+((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2577                 (*ilpdsf)->t.dga.fb_height = i*This->e.dga.fb_height;
2578           (*ilpdsf)->s.surface_desc.lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
2579           lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch;
2580
2581           /* Add flags if there were not present */
2582           (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2583           (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2584           (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2585           TRACE(ddraw,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2586           /* We put our surface always in video memory */
2587           (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2588           (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2589         (*ilpdsf)->s.backbuffer = NULL;
2590           
2591         if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2592                 IDirectDrawSurface4Impl*        back;
2593
2594                 if (lpddsd->dwBackBufferCount>1)
2595                         FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2596
2597             (*ilpdsf)->s.backbuffer = back =
2598               (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2599                 IDirectDraw2_AddRef(iface);
2600                 back->ref = 1;
2601                 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2602                 for (i=0;i<32;i++)
2603                         if (!(This->e.dga.vpmask & (1<<i)))
2604                                 break;
2605                 TRACE(ddraw,"using viewport %d for backbuffer\n",i);
2606                 /* if i == 32 or maximum ... return error */
2607                 This->e.dga.vpmask|=(1<<i);
2608                 back->t.dga.fb_height = i*This->e.dga.fb_height;
2609
2610             /* Copy the surface description from the front buffer */
2611             back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2612             /* Change the parameters that are not the same */
2613             back->s.surface_desc.y.lpSurface = This->e.dga.fb_addr+
2614               ((i*This->e.dga.fb_height)*This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2615                 back->s.ddraw = This;
2616                 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2617                                             * one! */
2618
2619             /* Add relevant info to front and back buffers */
2620             (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2621             back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2622             back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2623             back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2624             back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2625           }
2626         } else {
2627           /* There is no DGA-specific code here...
2628              Go to the common surface creation function */
2629           return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2630         }
2631         
2632         return DD_OK;
2633 #else /* defined(HAVE_LIBXXF86DGA) */
2634         return E_UNEXPECTED;
2635 #endif /* defined(HAVE_LIBXXF86DGA) */
2636 }
2637
2638 #ifdef HAVE_LIBXXSHM
2639 /* Error handlers for Image creation */
2640 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2641   XShmErrorFlag = 1;
2642   return 0;
2643 }
2644
2645 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2646   XImage *img;
2647   int (*WineXHandler)(Display *, XErrorEvent *);
2648
2649     img = TSXShmCreateImage(display,
2650                             DefaultVisualOfScreen(X11DRV_GetXScreen()),
2651                             This->d.pixmap_depth,
2652                             ZPixmap,
2653                             NULL,
2654                             &(lpdsf->t.xlib.shminfo),
2655                             lpdsf->s.surface_desc.dwWidth,
2656                             lpdsf->s.surface_desc.dwHeight);
2657     
2658   if (img == NULL) {
2659     MSG("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2660     This->e.xlib.xshm_active = 0;
2661       return NULL;
2662   }
2663
2664     lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2665     if (lpdsf->t.xlib.shminfo.shmid < 0) {
2666     MSG("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2667     This->e.xlib.xshm_active = 0;
2668       TSXDestroyImage(img);
2669       return NULL;
2670     }
2671
2672     lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2673       
2674     if (img->data == (char *) -1) {
2675     MSG("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2676     This->e.xlib.xshm_active = 0;
2677       TSXDestroyImage(img);
2678       shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2679       return NULL;
2680     }
2681     lpdsf->t.xlib.shminfo.readOnly = False;
2682       
2683   /* This is where things start to get trickier....
2684      First, we flush the current X connections to be sure to catch all non-XShm related
2685      errors */
2686     TSXSync(display, False);
2687   /* Then we enter in the non-thread safe part of the tests */
2688   EnterCriticalSection( &X11DRV_CritSection );
2689   
2690   /* Reset the error flag, sets our new error handler and try to attach the surface */
2691   XShmErrorFlag = 0;
2692   WineXHandler = XSetErrorHandler(XShmErrorHandler);
2693   XShmAttach(display, &(lpdsf->t.xlib.shminfo));
2694   XSync(display, False);
2695
2696   /* Check the error flag */
2697   if (XShmErrorFlag) {
2698     /* An error occured */
2699     XFlush(display);
2700     XShmErrorFlag = 0;
2701     XDestroyImage(img);
2702     shmdt(lpdsf->t.xlib.shminfo.shmaddr);
2703     shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2704     XSetErrorHandler(WineXHandler);
2705
2706     MSG("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
2707     This->e.xlib.xshm_active = 0;
2708     
2709     /* Leave the critical section */
2710     LeaveCriticalSection( &X11DRV_CritSection );
2711
2712     return NULL;
2713   }
2714
2715   /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2716      but it may be a bit overkill.... */
2717   XSetErrorHandler(WineXHandler);
2718   LeaveCriticalSection( &X11DRV_CritSection );
2719   
2720     shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2721
2722     if (This->d.pixel_convert != NULL) {
2723       lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2724                                                     lpdsf->s.surface_desc.dwWidth *
2725                                                     lpdsf->s.surface_desc.dwHeight *
2726                                                     (This->d.directdraw_pixelformat.x.dwRGBBitCount));
2727     } else {
2728     lpdsf->s.surface_desc.y.lpSurface = img->data;
2729     }
2730
2731   return img;
2732 }
2733 #endif /* HAVE_LIBXXSHM */
2734
2735 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2736   XImage *img = NULL;
2737   void *img_data;
2738
2739 #ifdef HAVE_LIBXXSHM
2740   if (This->e.xlib.xshm_active) {
2741     img = create_xshmimage(This, lpdsf);
2742   }
2743     
2744   if (img == NULL) {
2745 #endif
2746     /* Allocate surface memory */
2747     lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2748                                                   lpdsf->s.surface_desc.dwWidth *
2749                                                   lpdsf->s.surface_desc.dwHeight *
2750                                                   (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8));
2751     
2752     if (This->d.pixel_convert != NULL) {
2753       img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
2754                            lpdsf->s.surface_desc.dwWidth *
2755                            lpdsf->s.surface_desc.dwHeight *
2756                            (This->d.screen_pixelformat.x.dwRGBBitCount / 8));
2757     } else {
2758       img_data = lpdsf->s.surface_desc.y.lpSurface;
2759     }
2760       
2761     /* In this case, create an XImage */
2762     img =
2763       TSXCreateImage(display,
2764                      DefaultVisualOfScreen(X11DRV_GetXScreen()),
2765                      This->d.pixmap_depth,
2766                      ZPixmap,
2767                      0,
2768                      img_data,
2769                      lpdsf->s.surface_desc.dwWidth,
2770                      lpdsf->s.surface_desc.dwHeight,
2771                      32,
2772                      lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
2773                      );
2774     
2775 #ifdef HAVE_LIBXXSHM
2776   }
2777 #endif
2778   if (This->d.pixel_convert != NULL) {
2779     lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
2780   } else {
2781   lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
2782   }
2783   
2784   return img;
2785 }
2786
2787 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
2788         LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2789 ) {
2790         ICOM_THIS(IDirectDraw2Impl,iface);
2791         IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2792         TRACE(ddraw, "(%p)->CreateSurface(%p,%p,%p)\n",
2793                      This,lpddsd,ilpdsf,lpunk);
2794
2795         if (TRACE_ON(ddraw)) {
2796                 DUMP("   w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
2797                 _dump_DDSD(lpddsd->dwFlags);
2798                 DUMP("   caps ");
2799                 _dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
2800         }
2801
2802         *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurfaceImpl));
2803
2804         IDirectDraw2_AddRef(iface);
2805         (*ilpdsf)->s.ddraw             = This;
2806         (*ilpdsf)->ref                 = 1;
2807         (*ilpdsf)->lpvtbl              = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
2808         (*ilpdsf)->s.palette = NULL;
2809         (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
2810
2811         if (!(lpddsd->dwFlags & DDSD_WIDTH))
2812                 lpddsd->dwWidth  = This->d.width;
2813         if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2814                 lpddsd->dwHeight = This->d.height;
2815
2816         /* Check if this a 'primary surface' or not */
2817   if ((lpddsd->dwFlags & DDSD_CAPS) && 
2818             (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2819     XImage *img;
2820       
2821     TRACE(ddraw,"using standard XImage for a primary surface (%p)\n", *ilpdsf);
2822
2823           /* First, store the surface description */
2824           (*ilpdsf)->s.surface_desc = *lpddsd;
2825           
2826     /* Create the XImage */
2827     img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
2828     if (img == NULL)
2829       return DDERR_OUTOFMEMORY;
2830     (*ilpdsf)->t.xlib.image = img;
2831
2832           /* Add flags if there were not present */
2833           (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2834           (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2835           (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2836           (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2837           (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2838           (*ilpdsf)->s.backbuffer = NULL;
2839     
2840     /* Check for backbuffers */
2841         if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2842                 IDirectDrawSurface4Impl*        back;
2843       XImage *img;
2844
2845                 if (lpddsd->dwBackBufferCount>1)
2846                         FIXME(ddraw,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
2847
2848       (*ilpdsf)->s.backbuffer = back =
2849         (IDirectDrawSurface4Impl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface4Impl));
2850
2851       TRACE(ddraw,"allocated back-buffer (%p)\n", back);
2852       
2853                 IDirectDraw2_AddRef(iface);
2854                 back->s.ddraw = This;
2855
2856                 back->ref = 1;
2857                 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
2858             /* Copy the surface description from the front buffer */
2859             back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2860
2861       /* Create the XImage */
2862       img = create_ximage(This, back);
2863       if (img == NULL)
2864         return DDERR_OUTOFMEMORY;
2865       back->t.xlib.image = img;
2866       
2867                 back->s.backbuffer = NULL; /* does not have a backbuffer, it is
2868                                             * one! */
2869
2870             /* Add relevant info to front and back buffers */
2871             (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_FRONTBUFFER;
2872             back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2873             back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2874             back->s.surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_VISIBLE;
2875             back->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
2876         }
2877         } else {
2878           /* There is no Xlib-specific code here...
2879              Go to the common surface creation function */
2880           return common_off_screen_CreateSurface(This, lpddsd, *ilpdsf);
2881   }
2882   
2883         return DD_OK;
2884 }
2885
2886 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
2887         LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
2888 ) {
2889         ICOM_THIS(IDirectDraw2Impl,iface);
2890         FIXME(ddraw,"(%p)->(%p,%p) simply copies\n",This,src,dst);
2891         *dst = src; /* FIXME */
2892         return DD_OK;
2893 }
2894
2895 /* 
2896  * The Xlib Implementation tries to use the passed hwnd as drawing window,
2897  * even when the approbiate bitmasks are not specified.
2898  */
2899 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
2900         LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
2901 ) {
2902         ICOM_THIS(IDirectDraw2Impl,iface);
2903         int     i;
2904         const struct {
2905                 int     mask;
2906                 char    *name;
2907         } flagmap[] = {
2908                 FE(DDSCL_FULLSCREEN)
2909                 FE(DDSCL_ALLOWREBOOT)
2910                 FE(DDSCL_NOWINDOWCHANGES)
2911                 FE(DDSCL_NORMAL)
2912                 FE(DDSCL_ALLOWMODEX)
2913                 FE(DDSCL_EXCLUSIVE)
2914                 FE(DDSCL_SETFOCUSWINDOW)
2915                 FE(DDSCL_SETDEVICEWINDOW)
2916                 FE(DDSCL_CREATEDEVICEWINDOW)
2917         };
2918
2919         FIXME(ddraw,"(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
2920         if(TRACE_ON(ddraw)){
2921           dbg_decl_str(ddraw, 512);
2922           for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
2923             if (flagmap[i].mask & cooplevel)
2924               dsprintf(ddraw, "%s ", flagmap[i].name);
2925           TRACE(ddraw," cooperative level %s\n", dbg_str(ddraw));
2926         }
2927         This->d.mainWindow = hwnd;
2928
2929         /* This will be overwritten in the case of Full Screen mode.
2930            Windowed games could work with that :-) */
2931         if (hwnd)
2932         {
2933             WND *tmpWnd = WIN_FindWndPtr(hwnd);
2934             This->d.drawable  = X11DRV_WND_GetXWindow(tmpWnd);
2935             WIN_ReleaseWndPtr(tmpWnd);
2936         }
2937
2938         return DD_OK;
2939 }
2940
2941 /* Small helper to either use the cooperative window or create a new 
2942  * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2943  */
2944 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
2945         RECT    rect;
2946
2947         /* Do not destroy the application supplied cooperative window */
2948         if (This->d.window && This->d.window != This->d.mainWindow) {
2949                 DestroyWindow(This->d.window);
2950                 This->d.window = 0;
2951         }
2952         /* Sanity check cooperative window before assigning it to drawing. */
2953         if (    IsWindow(This->d.mainWindow) &&
2954                 IsWindowVisible(This->d.mainWindow)
2955         ) {
2956                 GetWindowRect(This->d.mainWindow,&rect);
2957                 if (((rect.right-rect.left) >= This->d.width)   &&
2958                     ((rect.bottom-rect.top) >= This->d.height)
2959                 )
2960                         This->d.window = This->d.mainWindow;
2961         }
2962         /* ... failed, create new one. */
2963         if (!This->d.window) {
2964             This->d.window = CreateWindowExA(
2965                     0,
2966                     "WINE_DirectDraw",
2967                     "WINE_DirectDraw",
2968                     WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
2969                     0,0,
2970                     This->d.width,
2971                     This->d.height,
2972                     0,
2973                     0,
2974                     0,
2975                     NULL
2976             );
2977             /*Store THIS with the window. We'll use it in the window procedure*/
2978             SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
2979             ShowWindow(This->d.window,TRUE);
2980             UpdateWindow(This->d.window);
2981         }
2982         SetFocus(This->d.window);
2983 }
2984
2985 static int _common_depth_to_pixelformat(DWORD depth, DDPIXELFORMAT *pixelformat, DDPIXELFORMAT *screen_pixelformat, int *pix_depth) {
2986   XVisualInfo *vi;
2987   XPixmapFormatValues *pf;
2988   XVisualInfo vt;
2989   int nvisuals, npixmap, i;
2990   int match = 0;
2991
2992   vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
2993   pf = XListPixmapFormats(display, &npixmap);
2994   
2995   for (i = 0; i < npixmap; i++) {
2996     if (pf[i].bits_per_pixel == depth) {
2997       int j;
2998       
2999       for (j = 0; j < nvisuals; j++) {
3000         if (vi[j].depth == pf[i].depth) {
3001           pixelformat->dwSize = sizeof(*pixelformat);
3002           if (depth == 8) {
3003             pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3004             pixelformat->y.dwRBitMask = 0;
3005             pixelformat->z.dwGBitMask = 0;
3006             pixelformat->xx.dwBBitMask = 0;
3007           } else {
3008             pixelformat->dwFlags = DDPF_RGB;
3009             pixelformat->y.dwRBitMask = vi[j].red_mask;
3010             pixelformat->z.dwGBitMask = vi[j].green_mask;
3011             pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3012           }
3013           pixelformat->dwFourCC = 0;
3014           pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3015           pixelformat->xy.dwRGBAlphaBitMask= 0;
3016
3017           *screen_pixelformat = *pixelformat;
3018           
3019           if (pix_depth != NULL)
3020             *pix_depth = vi[j].depth;
3021           
3022           match = 1;
3023           
3024           break;
3025         }
3026       }
3027
3028       if (j == nvisuals)
3029         ERR(ddraw, "No visual corresponding to pixmap format !\n");
3030     }
3031   }
3032
3033   if ((match == 0) && (depth == 8)) {
3034     pixelformat->dwSize = sizeof(*pixelformat);
3035     pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3036     pixelformat->dwFourCC = 0;
3037     pixelformat->x.dwRGBBitCount = 8;
3038     pixelformat->y.dwRBitMask = 0;
3039     pixelformat->z.dwGBitMask = 0;
3040     pixelformat->xx.dwBBitMask = 0;
3041     pixelformat->xy.dwRGBAlphaBitMask= 0;    
3042     
3043     /* In that case, find a visual to emulate the 8 bpp format */
3044     for (i = 0; i < npixmap; i++) {
3045       if (pf[i].bits_per_pixel >= depth) {
3046         int j;
3047         
3048         for (j = 0; j < nvisuals; j++) {
3049           if (vi[j].depth == pf[i].depth) {
3050             screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3051             screen_pixelformat->dwFlags = DDPF_RGB;
3052             screen_pixelformat->dwFourCC = 0;
3053             screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3054             screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3055             screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3056             screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3057             screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3058
3059             if (pix_depth != NULL)
3060               *pix_depth = vi[j].depth;
3061             
3062             match = 2;
3063             
3064             break;
3065           }
3066         }
3067         
3068         if (j == nvisuals)
3069           ERR(ddraw, "No visual corresponding to pixmap format !\n");
3070       }
3071     }
3072   }
3073   
3074   TSXFree(vi);
3075   TSXFree(pf);
3076
3077   return match;
3078 }
3079
3080 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3081         LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3082 ) {
3083 #ifdef HAVE_LIBXXF86DGA
3084         ICOM_THIS(IDirectDrawImpl,iface);
3085         int     i,mode_count;
3086
3087         TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3088
3089         /* We hope getting the asked for depth */
3090         if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != 1) {
3091           /* I.e. no visual found or emulated */
3092                 ERR(ddraw,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3093                 return DDERR_UNSUPPORTEDMODE;
3094         }
3095         
3096         if (This->d.width < width) {
3097                 ERR(ddraw,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3098                 return DDERR_UNSUPPORTEDMODE;
3099         }
3100         This->d.width   = width;
3101         This->d.height  = height;
3102
3103         /* adjust fb_height, so we don't overlap */
3104         if (This->e.dga.fb_height < height)
3105                 This->e.dga.fb_height = height;
3106         _common_IDirectDrawImpl_SetDisplayMode(This);
3107
3108 #ifdef HAVE_LIBXXF86VM
3109         {
3110             XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3111             XF86VidModeModeLine mod_tmp;
3112             /* int dotclock_tmp; */
3113
3114             /* save original video mode and set fullscreen if available*/
3115             orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));  
3116             TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3117             orig_mode->hdisplay = mod_tmp.hdisplay; 
3118             orig_mode->hsyncstart = mod_tmp.hsyncstart;
3119             orig_mode->hsyncend = mod_tmp.hsyncend; 
3120             orig_mode->htotal = mod_tmp.htotal;
3121             orig_mode->vdisplay = mod_tmp.vdisplay; 
3122             orig_mode->vsyncstart = mod_tmp.vsyncstart;
3123             orig_mode->vsyncend = mod_tmp.vsyncend; 
3124             orig_mode->vtotal = mod_tmp.vtotal;
3125             orig_mode->flags = mod_tmp.flags; 
3126             orig_mode->private = mod_tmp.private;
3127             
3128             TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3129             for (i=0;i<mode_count;i++)
3130             {
3131                 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3132                 {
3133                     vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3134                     *vidmode = *(all_modes[i]);
3135                     break;
3136                 } else
3137                     TSXFree(all_modes[i]->private);
3138             }
3139             for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3140             TSXFree(all_modes);
3141
3142             if (!vidmode)
3143                 WARN(ddraw, "Fullscreen mode not available!\n");
3144
3145             if (vidmode)
3146               {
3147                 TRACE(ddraw,"SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3148                 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3149 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3150                 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3151 #endif
3152               }
3153         }
3154 #endif
3155
3156         /* FIXME: this function OVERWRITES several signal handlers. 
3157          * can we save them? and restore them later? In a way that
3158          * it works for the library too?
3159          */
3160         TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3161 #ifdef DIABLO_HACK
3162         TSXF86DGASetViewPort(display,DefaultScreen(display),0,This->e.dga.fb_height);
3163 #else
3164         TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3165 #endif
3166
3167 #ifdef RESTORE_SIGNALS
3168         SIGNAL_InitHandlers();
3169 #endif
3170         return DD_OK;
3171 #else /* defined(HAVE_LIBXXF86DGA) */
3172         return E_UNEXPECTED;
3173 #endif /* defined(HAVE_LIBXXF86DGA) */
3174 }
3175
3176 /* *************************************
3177       16 / 15 bpp to palettized 8 bpp
3178    ************************************* */
3179 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3180   unsigned char  *c_src = (unsigned char  *) src;
3181   unsigned short *c_dst = (unsigned short *) dst;
3182   int x, y;
3183
3184   if (palette != NULL) {
3185     unsigned short *pal = (unsigned short *) palette->screen_palents;
3186
3187     for (y = 0; y < height; y++) {
3188       for (x = 0; x < width; x++) {
3189         c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3190       }
3191     }
3192   } else {
3193     WARN(ddraw, "No palette set...\n");
3194     memset(dst, 0, width * height * 2);
3195   }
3196 }
3197 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3198   int i;
3199   unsigned short *pal = (unsigned short *) screen_palette;
3200   
3201   for (i = 0; i < count; i++)
3202     pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3203                       ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3204                       ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3205 }
3206 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3207   int i;
3208   unsigned short *pal = (unsigned short *) screen_palette;
3209   
3210   for (i = 0; i < count; i++)
3211     pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3212                       ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3213                       ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3214 }
3215
3216 /* *************************************
3217       24 / 32 bpp to palettized 8 bpp
3218    ************************************* */
3219 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3220   unsigned char  *c_src = (unsigned char  *) src;
3221   unsigned int *c_dst = (unsigned int *) dst;
3222   int x, y;
3223
3224   if (palette != NULL) {
3225     unsigned int *pal = (unsigned int *) palette->screen_palents;
3226     
3227     for (y = 0; y < height; y++) {
3228       for (x = 0; x < width; x++) {
3229         c_dst[x + y * width] = pal[c_src[x + y * pitch]];
3230       }
3231     }
3232   } else {
3233     WARN(ddraw, "No palette set...\n");
3234     memset(dst, 0, width * height * 4);
3235   }
3236 }
3237 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3238   int i;
3239   unsigned int *pal = (unsigned int *) screen_palette;
3240   
3241   for (i = 0; i < count; i++)
3242     pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3243                       (((unsigned int) palent[i].peGreen) << 8) |
3244                       ((unsigned int) palent[i].peBlue));
3245 }
3246
3247 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3248         LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3249 ) {
3250         ICOM_THIS(IDirectDrawImpl,iface);
3251         char    buf[200];
3252         WND *tmpWnd;
3253
3254         TRACE(ddraw, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3255                       This, width, height, depth);
3256
3257         switch (_common_depth_to_pixelformat(depth,
3258                                              &(This->d.directdraw_pixelformat),
3259                                              &(This->d.screen_pixelformat),
3260                                              &(This->d.pixmap_depth))) {
3261         case 0:
3262           sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3263           MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3264           return DDERR_UNSUPPORTEDMODE;
3265
3266         case 1:
3267           /* No convertion */
3268           This->d.pixel_convert = NULL;
3269           This->d.palette_convert = NULL;
3270           break;
3271
3272         case 2: {
3273           int found = 0;
3274
3275           WARN(ddraw, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3276           
3277           /* Set the depth convertion routines */
3278           switch (This->d.screen_pixelformat.x.dwRGBBitCount) {
3279           case 16:
3280             if ((This->d.screen_pixelformat.y.dwRBitMask == 0xF800) &&
3281                 (This->d.screen_pixelformat.z.dwGBitMask == 0x07E0) &&
3282                 (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3283               /* 16 bpp */
3284               found = 1;
3285               
3286               This->d.pixel_convert = pixel_convert_16_to_8;
3287               This->d.palette_convert = palette_convert_16_to_8;
3288             } else if ((This->d.screen_pixelformat.y.dwRBitMask == 0x7C00) &&
3289                        (This->d.screen_pixelformat.z.dwGBitMask == 0x03E0) &&
3290                        (This->d.screen_pixelformat.xx.dwBBitMask == 0x001F)) {
3291               /* 15 bpp */
3292               found = 1;
3293
3294               This->d.pixel_convert = pixel_convert_16_to_8;
3295               This->d.palette_convert = palette_convert_15_to_8;
3296             }
3297             break;
3298             
3299           case 24:
3300             /* Not handled yet :/ */
3301             found = 0;
3302                         break;
3303             
3304           case 32:
3305             if ((This->d.screen_pixelformat.y.dwRBitMask ==  0xFF0000) &&
3306                 (This->d.screen_pixelformat.z.dwGBitMask ==  0x00FF00) &&
3307                 (This->d.screen_pixelformat.xx.dwBBitMask == 0x0000FF)) {
3308               /* 24 bpp */
3309               found = 1;
3310
3311               This->d.pixel_convert = pixel_convert_32_to_8;
3312               This->d.palette_convert = palette_convert_24_to_8;
3313             }
3314               break;
3315           }
3316
3317           if (!found) {
3318                 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3319                 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3320                 return DDERR_UNSUPPORTEDMODE;
3321           }
3322         } break;
3323         }
3324
3325         This->d.width   = width;
3326         This->d.height  = height;
3327
3328         _common_IDirectDrawImpl_SetDisplayMode(This);
3329
3330         tmpWnd = WIN_FindWndPtr(This->d.window);
3331         This->d.paintable = 1;
3332         This->d.drawable  = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3333         /* We don't have a context for this window. Host off the desktop */
3334
3335         if( !This->d.drawable )
3336         {
3337            This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3338             WIN_ReleaseDesktop();
3339         }
3340         WIN_ReleaseWndPtr(tmpWnd);
3341         return DD_OK;
3342 }
3343
3344 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3345         LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3346 ) {
3347 #ifdef HAVE_LIBXXF86DGA
3348         ICOM_THIS(IDirectDraw2Impl,iface);
3349         TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3350         caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3351         caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
3352         caps1->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
3353         if (caps2) {
3354                 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3355                 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);              /* we can do anything */
3356                 caps2->ddsCaps.dwCaps = 0xffffffff;     /* we can do anything */
3357         }
3358         return DD_OK;
3359 #else /* defined(HAVE_LIBXXF86DGA) */
3360         return E_UNEXPECTED;
3361 #endif /* defined(HAVE_LIBXXF86DGA) */
3362 }
3363
3364 static void fill_caps(LPDDCAPS caps) {
3365   /* This function tries to fill the capabilities of Wine's DDraw implementation.
3366      Need to be fixed, though.. */
3367   if (caps == NULL)
3368     return;
3369
3370   caps->dwSize = sizeof(*caps);
3371   caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL |
3372     DDCAPS_CANBLTSYSMEM |  DDCAPS_COLORKEY | DDCAPS_PALETTE;
3373   caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3374   caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3375   caps->dwFXCaps = 0;
3376   caps->dwFXAlphaCaps = 0;
3377   caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3378   caps->dwSVCaps = 0;
3379   caps->dwZBufferBitDepths = DDBD_16;
3380   /* I put here 8 Mo so that D3D applications will believe they have enough memory
3381      to put textures in video memory.
3382      BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3383      for example) ? */
3384   caps->dwVidMemTotal = 8192 * 1024;
3385   caps->dwVidMemFree = 8192 * 1024;
3386   /* These are all the supported capabilities of the surfaces */
3387   caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3388     DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3389       DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3390         DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3391 #ifdef HAVE_MESAGL
3392   caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3393   caps->dwCaps2 |=  DDCAPS2_NO2DDURING3DSCENE;
3394   caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3395 #endif
3396 }
3397
3398 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3399         LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3400 )  {
3401         ICOM_THIS(IDirectDraw2Impl,iface);
3402         TRACE(ddraw,"(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3403
3404         /* Put the same caps for the two capabilities */
3405         fill_caps(caps1);
3406         fill_caps(caps2);
3407
3408         return DD_OK;
3409 }
3410
3411 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3412         LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3413 ) {
3414         ICOM_THIS(IDirectDraw2Impl,iface);
3415         IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3416         FIXME(ddraw,"(%p)->(%08lx,%p,%p),stub!\n",
3417                 This,x,ilpddclip,lpunk
3418         );
3419         *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3420         (*ilpddclip)->ref = 1;
3421         (*ilpddclip)->lpvtbl = &ddclipvt;
3422         return DD_OK;
3423 }
3424
3425 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3426         IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3427 ) {
3428         int size = 0;
3429           
3430         if (TRACE_ON(ddraw))
3431           _dump_paletteformat(dwFlags);
3432         
3433         *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3434         if (*lpddpal == NULL) return E_OUTOFMEMORY;
3435         (*lpddpal)->ref = 1;
3436         (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3437         (*lpddpal)->installed = 0;
3438
3439           if (dwFlags & DDPCAPS_1BIT)
3440             size = 2;
3441           else if (dwFlags & DDPCAPS_2BIT)
3442             size = 4;
3443           else if (dwFlags & DDPCAPS_4BIT)
3444             size = 16;
3445           else if (dwFlags & DDPCAPS_8BIT)
3446             size = 256;
3447           else
3448             ERR(ddraw, "unhandled palette format\n");
3449         *psize = size;
3450         
3451         if (palent)
3452         {
3453           /* Now, if we are in 'depth conversion mode', create the screen palette */
3454           if (This->d.palette_convert != NULL)      
3455             This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3456
3457           memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3458         } else if (This->d.palette_convert != NULL) {
3459           /* In that case, put all 0xFF */
3460           memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3461         }
3462         
3463         return DD_OK;
3464 }
3465
3466 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3467         LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3468 ) {
3469         ICOM_THIS(IDirectDraw2Impl,iface);
3470         IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3471         HRESULT res;
3472         int xsize = 0,i;
3473
3474         TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3475         res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3476         if (res != 0) return res;
3477         (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3478         if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3479                 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3480         } else {
3481                 FIXME(ddraw,"why are we doing CreatePalette in hi/truecolor?\n");
3482                 (*ilpddpal)->cm = 0;
3483         }
3484         if (((*ilpddpal)->cm)&&xsize) {
3485           for (i=0;i<xsize;i++) {
3486                   XColor xc;
3487
3488                   xc.red = (*ilpddpal)->palents[i].peRed<<8;
3489                   xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3490                   xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3491                   xc.flags = DoRed|DoBlue|DoGreen;
3492                   xc.pixel = i;
3493                   TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3494           }
3495         }
3496         return DD_OK;
3497 }
3498
3499 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3500         LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3501 ) {
3502         ICOM_THIS(IDirectDraw2Impl,iface);
3503         IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3504         int xsize;
3505         HRESULT res;
3506
3507         TRACE(ddraw,"(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3508         res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3509         if (res != 0) return res;
3510         (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3511         return DD_OK;
3512 }
3513
3514 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3515 #ifdef HAVE_LIBXXF86DGA
3516         ICOM_THIS(IDirectDraw2Impl,iface);
3517         TRACE(ddraw, "(%p)->()\n",This);
3518         Sleep(1000);
3519         TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3520 #ifdef RESTORE_SIGNALS
3521         SIGNAL_InitHandlers();
3522 #endif
3523         return DD_OK;
3524 #else /* defined(HAVE_LIBXXF86DGA) */
3525         return E_UNEXPECTED;
3526 #endif
3527 }
3528
3529 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3530         ICOM_THIS(IDirectDraw2Impl,iface);
3531         TRACE(ddraw, "(%p)->RestoreDisplayMode()\n", This);
3532         Sleep(1000);
3533         return DD_OK;
3534 }
3535
3536 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3537         LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3538 ) {
3539         ICOM_THIS(IDirectDraw2Impl,iface);
3540         TRACE(ddraw,"(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3541         return DD_OK;
3542 }
3543
3544 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3545         ICOM_THIS(IDirectDraw2Impl,iface);
3546         TRACE( ddraw, "(%p)->() incrementing from %lu.\n", This, This->ref );
3547
3548         return ++(This->ref);
3549 }
3550
3551 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3552         ICOM_THIS(IDirectDraw2Impl,iface);
3553         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3554
3555 #ifdef HAVE_LIBXXF86DGA
3556         if (!--(This->ref)) {
3557                 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3558                 if (This->d.window && (This->d.mainWindow != This->d.window))
3559                         DestroyWindow(This->d.window);
3560 #ifdef HAVE_LIBXXF86VM
3561                 if (orig_mode) {
3562                         TSXF86VidModeSwitchToMode(
3563                                 display,
3564                                 DefaultScreen(display),
3565                                 orig_mode);
3566                         if (orig_mode->privsize)
3567                                 TSXFree(orig_mode->private);            
3568                         free(orig_mode);
3569                         orig_mode = NULL;
3570                 }
3571 #endif
3572                 
3573 #ifdef RESTORE_SIGNALS
3574                 SIGNAL_InitHandlers();
3575 #endif
3576                 HeapFree(GetProcessHeap(),0,This);
3577                 return 0;
3578         }
3579 #endif /* defined(HAVE_LIBXXF86DGA) */
3580         return This->ref;
3581 }
3582
3583 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3584         ICOM_THIS(IDirectDraw2Impl,iface);
3585         TRACE( ddraw, "(%p)->() decrementing from %lu.\n", This, This->ref );
3586
3587         if (!--(This->ref)) {
3588                 if (This->d.window && (This->d.mainWindow != This->d.window))
3589                         DestroyWindow(This->d.window);
3590                 HeapFree(GetProcessHeap(),0,This);
3591                 return 0;
3592         }
3593         /* FIXME: destroy window ... */
3594         return This->ref;
3595 }
3596
3597 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3598         LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3599 ) {
3600         ICOM_THIS(IDirectDraw2Impl,iface);
3601         char    xrefiid[50];
3602
3603         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3604         TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3605         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3606                 *obj = This;
3607                 IDirectDraw2_AddRef(iface);
3608
3609                 TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
3610                 
3611                 return S_OK;
3612         }
3613         if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3614                 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
3615                 IDirectDraw2_AddRef(iface);
3616                 *obj = This;
3617
3618                 TRACE(ddraw, "  Creating IDirectDraw interface (%p)\n", *obj);
3619                 
3620                 return S_OK;
3621         }
3622         if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3623                 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
3624                 IDirectDraw2_AddRef(iface);
3625                 *obj = This;
3626
3627                 TRACE(ddraw, "  Creating IDirectDraw2 interface (%p)\n", *obj);
3628
3629                 return S_OK;
3630         }
3631         if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3632                 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
3633                 IDirectDraw2_AddRef(iface);
3634                 *obj = This;
3635
3636                 TRACE(ddraw, "  Creating IDirectDraw4 interface (%p)\n", *obj);
3637
3638                 return S_OK;
3639         }
3640         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3641                 IDirect3DImpl* d3d;
3642
3643                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3644                 d3d->ref = 1;
3645                 d3d->ddraw = (IDirectDrawImpl*)This;
3646                 IDirectDraw2_AddRef(iface);
3647                 d3d->lpvtbl = &d3dvt;
3648                 *obj = d3d;
3649
3650                 TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
3651                 
3652                 return S_OK;
3653         }
3654         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
3655                 IDirect3D2Impl* d3d;
3656
3657                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3658                 d3d->ref = 1;
3659                 d3d->ddraw = (IDirectDrawImpl*)This;
3660                 IDirectDraw2_AddRef(iface);
3661                 d3d->lpvtbl = &d3d2vt;
3662                 *obj = d3d;
3663
3664                 TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
3665                 
3666                 return S_OK;
3667         }
3668         WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3669         return OLE_E_ENUM_NOMORE;
3670 }
3671
3672 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
3673         LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3674 ) {
3675         ICOM_THIS(IDirectDraw2Impl,iface);
3676         char    xrefiid[50];
3677
3678         WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3679         TRACE(ddraw,"(%p)->(%s,%p)\n",This,xrefiid,obj);
3680         if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3681                 *obj = This;
3682                 IDirectDraw2_AddRef(iface);
3683
3684                 TRACE(ddraw, "  Creating IUnknown interface (%p)\n", *obj);
3685                 
3686                 return S_OK;
3687         }
3688         if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
3689                 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
3690                 IDirectDraw2_AddRef(iface);
3691                 *obj = This;
3692
3693                 TRACE(ddraw, "  Creating IDirectDraw interface (%p)\n", *obj);
3694                 
3695                 return S_OK;
3696         }
3697         if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
3698                 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
3699                 IDirectDraw2_AddRef(iface);
3700                 *obj = This;
3701
3702                 TRACE(ddraw, "  Creating IDirectDraw2 interface (%p)\n", *obj);
3703                 
3704                 return S_OK;
3705         }
3706         if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
3707                 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
3708                 IDirectDraw2_AddRef(iface);
3709                 *obj = This;
3710
3711                 TRACE(ddraw, "  Creating IDirectDraw4 interface (%p)\n", *obj);
3712
3713                 return S_OK;
3714         }
3715         if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
3716                 IDirect3DImpl* d3d;
3717
3718                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3719                 d3d->ref = 1;
3720                 d3d->ddraw = (IDirectDrawImpl*)This;
3721                 IDirectDraw2_AddRef(iface);
3722                 d3d->lpvtbl = &d3dvt;
3723                 *obj = d3d;
3724
3725                 TRACE(ddraw, "  Creating IDirect3D interface (%p)\n", *obj);
3726
3727                 return S_OK;
3728         }
3729         if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
3730                 IDirect3D2Impl* d3d;
3731
3732                 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
3733                 d3d->ref = 1;
3734                 d3d->ddraw = (IDirectDrawImpl*)This;
3735                 IDirectDraw2_AddRef(iface);
3736                 d3d->lpvtbl = &d3d2vt;
3737                 *obj = d3d;
3738
3739                 TRACE(ddraw, "  Creating IDirect3D2 interface (%p)\n", *obj);
3740
3741                 return S_OK;
3742         }
3743         WARN(ddraw,"(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
3744         return OLE_E_ENUM_NOMORE;
3745 }
3746
3747 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
3748         LPDIRECTDRAW2 iface,BOOL *status
3749 ) {
3750         ICOM_THIS(IDirectDraw2Impl,iface);
3751         TRACE(ddraw,"(%p)->(%p)\n",This,status);
3752         *status = TRUE;
3753         return DD_OK;
3754 }
3755
3756 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
3757         LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3758 ) {
3759         ICOM_THIS(IDirectDraw2Impl,iface);
3760         DDSURFACEDESC   ddsfd;
3761         static struct {
3762                 int w,h;
3763         } modes[5] = { /* some of the usual modes */
3764                 {512,384},
3765                 {640,400},
3766                 {640,480},
3767                 {800,600},
3768                 {1024,768},
3769         };
3770         static int depths[4] = {8,16,24,32};
3771         int     i,j;
3772
3773         TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3774         ddsfd.dwSize = sizeof(ddsfd);
3775         ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3776         if (dwFlags & DDEDM_REFRESHRATES) {
3777                 ddsfd.dwFlags |= DDSD_REFRESHRATE;
3778                 ddsfd.x.dwRefreshRate = 60;
3779         }
3780
3781         for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
3782                 ddsfd.dwBackBufferCount = 1;
3783                 ddsfd.ddpfPixelFormat.dwFourCC  = 0;
3784                 ddsfd.ddpfPixelFormat.dwFlags   = DDPF_RGB;
3785                 ddsfd.ddpfPixelFormat.x.dwRGBBitCount   = depths[i];
3786                 /* FIXME: those masks would have to be set in depth > 8 */
3787                 if (depths[i]==8) {
3788                 ddsfd.ddpfPixelFormat.y.dwRBitMask      = 0;
3789                 ddsfd.ddpfPixelFormat.z.dwGBitMask      = 0;
3790                 ddsfd.ddpfPixelFormat.xx.dwBBitMask     = 0;
3791                 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3792                         ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
3793                         ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
3794                 } else {
3795                   ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3796                   
3797                   /* FIXME: We should query those from X itself */
3798                   switch (depths[i]) {
3799                   case 16:
3800                     ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
3801                     ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
3802                     ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
3803                     break;
3804                   case 24:
3805                     ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3806                     ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3807                     ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3808                     break;
3809                   case 32:
3810                     ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
3811                     ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
3812                     ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
3813                     break;
3814                   }
3815                 }
3816
3817                 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3818                 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3819                 TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3820                 if (!modescb(&ddsfd,context)) return DD_OK;
3821
3822                 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
3823                         ddsfd.dwWidth   = modes[j].w;
3824                         ddsfd.dwHeight  = modes[j].h;
3825                         TRACE(ddraw," enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
3826                         if (!modescb(&ddsfd,context)) return DD_OK;
3827                 }
3828
3829                 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3830                         /* modeX is not standard VGA */
3831
3832                         ddsfd.dwHeight = 200;
3833                         ddsfd.dwWidth = 320;
3834                         TRACE(ddraw," enumerating (320x200x%d)\n",depths[i]);
3835                         if (!modescb(&ddsfd,context)) return DD_OK;
3836                 }
3837         }
3838         return DD_OK;
3839 }
3840
3841 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
3842         LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
3843 ) {
3844   ICOM_THIS(IDirectDraw2Impl,iface);
3845   XVisualInfo *vi;
3846   XPixmapFormatValues *pf;
3847   XVisualInfo vt;
3848   int nvisuals, npixmap, i;
3849   int send_mode;
3850   int has_8bpp = 0;
3851   DDSURFACEDESC ddsfd;
3852   static struct {
3853     int w,h;
3854   } modes[] = { /* some of the usual modes */
3855     {512,384},
3856     {640,400},
3857     {640,480},
3858     {800,600},
3859     {1024,768},
3860     {1280,1024}
3861   };
3862   DWORD maxWidth, maxHeight;
3863
3864   TRACE(ddraw,"(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
3865   ddsfd.dwSize = sizeof(ddsfd);
3866   ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
3867   if (dwFlags & DDEDM_REFRESHRATES) {
3868     ddsfd.dwFlags |= DDSD_REFRESHRATE;
3869     ddsfd.x.dwRefreshRate = 60;
3870   }
3871   maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3872   maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3873   
3874   vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3875   pf = XListPixmapFormats(display, &npixmap);
3876
3877   i = 0;
3878   send_mode = 0;
3879   while (i < npixmap) {
3880     if ((has_8bpp == 0) && (pf[i].depth == 8)) {
3881       /* Special case of a 8bpp depth */
3882       has_8bpp = 1;
3883       send_mode = 1;
3884
3885       ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
3886       ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3887       ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
3888       ddsfd.ddpfPixelFormat.dwFourCC = 0;
3889       ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
3890       ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
3891       ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
3892       ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
3893       ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3894     } else if (pf[i].depth > 8) {
3895       int j;
3896       
3897       /* All the 'true color' depths (15, 16 and 24)
3898          First, find the corresponding visual to extract the bit masks */
3899       for (j = 0; j < nvisuals; j++) {
3900         if (vi[j].depth == pf[i].depth) {
3901           ddsfd.ddsCaps.dwCaps = 0;
3902           ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
3903           ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
3904           ddsfd.ddpfPixelFormat.dwFourCC = 0;
3905           ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
3906           ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
3907           ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
3908           ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
3909           ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
3910
3911           send_mode = 1;
3912           break;
3913         }
3914       }
3915       
3916       if (j == nvisuals)
3917         ERR(ddraw, "Did not find visual corresponding the the pixmap format !\n");
3918     } else {
3919       send_mode = 0;
3920     }
3921
3922     if (send_mode) {
3923       int mode;
3924
3925       if (TRACE_ON(ddraw)) {
3926         TRACE(ddraw, "Enumerating with pixel format : \n");
3927         _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
3928       }
3929       
3930       for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
3931         /* Do not enumerate modes we cannot handle anyway */
3932         if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
3933           break;
3934
3935         ddsfd.dwWidth = modes[mode].w;
3936         ddsfd.dwHeight = modes[mode].h;
3937         
3938         /* Now, send the mode description to the application */
3939         TRACE(ddraw, " - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
3940         if (!modescb(&ddsfd, context))
3941           goto exit_enum;
3942       }
3943
3944       if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
3945         /* modeX is not standard VGA */
3946         ddsfd.dwWidth = 320;
3947         ddsfd.dwHeight = 200;
3948         if (!modescb(&ddsfd, context))
3949           goto exit_enum;
3950       }
3951     }
3952
3953     /* Hack to always enumerate a 8bpp depth */
3954     i++;
3955     if ((i == npixmap) && (has_8bpp == 0)) {
3956       i--;
3957       pf[i].depth = 8;
3958     }
3959   }
3960   
3961  exit_enum:
3962   TSXFree(vi);
3963   TSXFree(pf);
3964
3965   return DD_OK;
3966 }
3967
3968 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
3969         LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3970 ) {
3971 #ifdef HAVE_LIBXXF86DGA
3972         ICOM_THIS(IDirectDraw2Impl,iface);
3973         TRACE(ddraw,"(%p)->(%p)\n",This,lpddsfd);
3974         lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3975         lpddsfd->dwHeight = This->d.height;
3976         lpddsfd->dwWidth = This->d.width;
3977         lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3978         lpddsfd->dwBackBufferCount = 1;
3979         lpddsfd->x.dwRefreshRate = 60;
3980         lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
3981         lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
3982         return DD_OK;
3983 #else /* defined(HAVE_LIBXXF86DGA) */
3984         return E_UNEXPECTED;
3985 #endif /* defined(HAVE_LIBXXF86DGA) */
3986 }
3987
3988 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
3989         LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
3990 ) {
3991         ICOM_THIS(IDirectDraw2Impl,iface);
3992         TRACE(ddraw,"(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
3993         lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
3994         lpddsfd->dwHeight = This->d.height;
3995         lpddsfd->dwWidth = This->d.width;
3996         lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
3997         lpddsfd->dwBackBufferCount = 1;
3998         lpddsfd->x.dwRefreshRate = 60;
3999         lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4000         lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4001         return DD_OK;
4002 }
4003
4004 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4005         ICOM_THIS(IDirectDraw2Impl,iface);
4006         TRACE(ddraw,"(%p)->()\n",This);
4007         return DD_OK;
4008 }
4009
4010 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4011         LPDIRECTDRAW2 iface,LPDWORD freq
4012 ) {
4013         ICOM_THIS(IDirectDraw2Impl,iface);
4014         FIXME(ddraw,"(%p)->(%p) returns 60 Hz always\n",This,freq);
4015         *freq = 60*100; /* 60 Hz */
4016         return DD_OK;
4017 }
4018
4019 /* what can we directly decompress? */
4020 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4021         LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4022 ) {
4023         ICOM_THIS(IDirectDraw2Impl,iface);
4024         FIXME(ddraw,"(%p,%p,%p), stub\n",This,x,y);
4025         return DD_OK;
4026 }
4027
4028 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4029         LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4030 ) {
4031   ICOM_THIS(IDirectDraw2Impl,iface);
4032   FIXME(ddraw,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4033   return DD_OK;
4034 }
4035
4036 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4037           LPDIRECTDRAW2 iface )
4038 {
4039   ICOM_THIS(IDirectDraw2Impl,iface);
4040   FIXME(ddraw,"(%p)->()\n", This );
4041  
4042   return DD_OK;
4043 }
4044
4045 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4046                                                  LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4047   ICOM_THIS(IDirectDraw2Impl,iface);
4048   FIXME(ddraw,"(%p)->(%p)\n", This, lplpGDIDDSSurface);
4049
4050   return DD_OK;
4051 }
4052
4053 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4054                                                LPDWORD lpdwScanLine) {
4055   ICOM_THIS(IDirectDraw2Impl,iface);
4056   FIXME(ddraw,"(%p)->(%p)\n", This, lpdwScanLine);
4057
4058   return DD_OK;
4059 }
4060
4061 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4062                                               GUID *lpGUID) {
4063   ICOM_THIS(IDirectDraw2Impl,iface);
4064   FIXME(ddraw,"(%p)->(%p)\n", This, lpGUID);
4065   
4066   return DD_OK;
4067 }
4068
4069 /* Note: Hack so we can reuse the old functions without compiler warnings */
4070 #ifdef __GNUC__
4071 # define XCAST(fun)     (typeof(dga_ddvt.fn##fun))
4072 #else
4073 # define XCAST(fun)     (void*)
4074 #endif
4075
4076 static ICOM_VTABLE(IDirectDraw) dga_ddvt = {
4077         XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4078         XCAST(AddRef)IDirectDraw2Impl_AddRef,
4079         XCAST(Release)DGA_IDirectDraw2Impl_Release,
4080         XCAST(Compact)IDirectDraw2Impl_Compact,
4081         XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4082         XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4083         XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4084         XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4085         XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4086         XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4087         XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4088         XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4089         XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4090         XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4091         XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4092         XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4093         XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4094         XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4095         XCAST(Initialize)IDirectDraw2Impl_Initialize,
4096         XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4097         XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4098         DGA_IDirectDrawImpl_SetDisplayMode,
4099         XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4100 };
4101
4102 static ICOM_VTABLE(IDirectDraw) xlib_ddvt = {
4103         XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4104         XCAST(AddRef)IDirectDraw2Impl_AddRef,
4105         XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4106         XCAST(Compact)IDirectDraw2Impl_Compact,
4107         XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4108         XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4109         XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4110         XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4111         XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4112         XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4113         XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4114         XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4115         XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4116         XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4117         XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4118         XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4119         XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4120         XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4121         XCAST(Initialize)IDirectDraw2Impl_Initialize,
4122         XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4123         XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4124         Xlib_IDirectDrawImpl_SetDisplayMode,
4125         XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4126 };
4127
4128 #undef XCAST
4129
4130 /*****************************************************************************
4131  *      IDirectDraw2
4132  *
4133  */
4134
4135
4136 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4137         LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4138 ) {
4139         return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4140 }
4141
4142 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4143         LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4144 ) {
4145         return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4146 }
4147
4148 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4149         LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4150 ) {
4151         ICOM_THIS(IDirectDraw2Impl,iface);
4152         TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4153                 This,ddscaps,total,free
4154         );
4155         if (total) *total = This->e.dga.fb_memsize * 1024;
4156         if (free) *free = This->e.dga.fb_memsize * 1024;
4157         return DD_OK;
4158 }
4159
4160 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4161         LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4162 ) {
4163         ICOM_THIS(IDirectDraw2Impl,iface);
4164         TRACE(ddraw,"(%p)->(%p,%p,%p)\n",
4165                 This,ddscaps,total,free
4166         );
4167         if (total) *total = 2048 * 1024;
4168         if (free) *free = 2048 * 1024;
4169         return DD_OK;
4170 }
4171
4172 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt = {
4173         DGA_IDirectDraw2Impl_QueryInterface,
4174         IDirectDraw2Impl_AddRef,
4175         DGA_IDirectDraw2Impl_Release,
4176         IDirectDraw2Impl_Compact,
4177         IDirectDraw2Impl_CreateClipper,
4178         DGA_IDirectDraw2Impl_CreatePalette,
4179         DGA_IDirectDraw2Impl_CreateSurface,
4180         IDirectDraw2Impl_DuplicateSurface,
4181         DGA_IDirectDraw2Impl_EnumDisplayModes,
4182         IDirectDraw2Impl_EnumSurfaces,
4183         IDirectDraw2Impl_FlipToGDISurface,
4184         DGA_IDirectDraw2Impl_GetCaps,
4185         DGA_IDirectDraw2Impl_GetDisplayMode,
4186         IDirectDraw2Impl_GetFourCCCodes,
4187         IDirectDraw2Impl_GetGDISurface,
4188         IDirectDraw2Impl_GetMonitorFrequency,
4189         IDirectDraw2Impl_GetScanLine,
4190         IDirectDraw2Impl_GetVerticalBlankStatus,
4191         IDirectDraw2Impl_Initialize,
4192         DGA_IDirectDraw2Impl_RestoreDisplayMode,
4193         IDirectDraw2Impl_SetCooperativeLevel,
4194         DGA_IDirectDraw2Impl_SetDisplayMode,
4195         IDirectDraw2Impl_WaitForVerticalBlank,
4196         DGA_IDirectDraw2Impl_GetAvailableVidMem
4197 };
4198
4199 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt = {
4200         Xlib_IDirectDraw2Impl_QueryInterface,
4201         IDirectDraw2Impl_AddRef,
4202         Xlib_IDirectDraw2Impl_Release,
4203         IDirectDraw2Impl_Compact,
4204         IDirectDraw2Impl_CreateClipper,
4205         Xlib_IDirectDraw2Impl_CreatePalette,
4206         Xlib_IDirectDraw2Impl_CreateSurface,
4207         IDirectDraw2Impl_DuplicateSurface,
4208         Xlib_IDirectDraw2Impl_EnumDisplayModes,
4209         IDirectDraw2Impl_EnumSurfaces,
4210         IDirectDraw2Impl_FlipToGDISurface,
4211         Xlib_IDirectDraw2Impl_GetCaps,
4212         Xlib_IDirectDraw2Impl_GetDisplayMode,
4213         IDirectDraw2Impl_GetFourCCCodes,
4214         IDirectDraw2Impl_GetGDISurface,
4215         IDirectDraw2Impl_GetMonitorFrequency,
4216         IDirectDraw2Impl_GetScanLine,
4217         IDirectDraw2Impl_GetVerticalBlankStatus,
4218         IDirectDraw2Impl_Initialize,
4219         Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4220         IDirectDraw2Impl_SetCooperativeLevel,
4221         Xlib_IDirectDraw2Impl_SetDisplayMode,
4222         IDirectDraw2Impl_WaitForVerticalBlank,
4223         Xlib_IDirectDraw2Impl_GetAvailableVidMem        
4224 };
4225
4226 /*****************************************************************************
4227  *      IDirectDraw4
4228  *
4229  */
4230
4231 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4232                                                     HDC hdc,
4233                                                     LPDIRECTDRAWSURFACE *lpDDS) {
4234   ICOM_THIS(IDirectDraw4Impl,iface);
4235   FIXME(ddraw, "(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4236
4237   return DD_OK;
4238 }
4239
4240 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4241   ICOM_THIS(IDirectDraw4Impl,iface);
4242   FIXME(ddraw, "(%p)->()\n", This);
4243
4244   return DD_OK;
4245 }
4246
4247 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4248   ICOM_THIS(IDirectDraw4Impl,iface);
4249   FIXME(ddraw, "(%p)->()\n", This);
4250
4251   return DD_OK;
4252 }
4253
4254 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4255                                                        LPDDDEVICEIDENTIFIER lpdddi,
4256                                                        DWORD dwFlags) {
4257   ICOM_THIS(IDirectDraw4Impl,iface);
4258   FIXME(ddraw, "(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4259   
4260   return DD_OK;
4261 }
4262
4263 #ifdef __GNUC__
4264 # define XCAST(fun)     (typeof(dga_dd4vt.fn##fun))
4265 #else
4266 # define XCAST(fun)     (void*)
4267 #endif
4268
4269
4270 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt = {
4271         XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4272         XCAST(AddRef)IDirectDraw2Impl_AddRef,
4273         XCAST(Release)DGA_IDirectDraw2Impl_Release,
4274         XCAST(Compact)IDirectDraw2Impl_Compact,
4275         XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4276         XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4277         XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4278         XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4279         XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4280         XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4281         XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4282         XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4283         XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4284         XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4285         XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4286         XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4287         XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4288         XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4289         XCAST(Initialize)IDirectDraw2Impl_Initialize,
4290         XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4291         XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4292         XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4293         XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4294         XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4295         IDirectDraw4Impl_GetSurfaceFromDC,
4296         IDirectDraw4Impl_RestoreAllSurfaces,
4297         IDirectDraw4Impl_TestCooperativeLevel,
4298         IDirectDraw4Impl_GetDeviceIdentifier
4299 };
4300
4301 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt = {
4302         XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4303         XCAST(AddRef)IDirectDraw2Impl_AddRef,
4304         XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4305         XCAST(Compact)IDirectDraw2Impl_Compact,
4306         XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4307         XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4308         XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4309         XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4310         XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4311         XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4312         XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4313         XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4314         XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4315         XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4316         XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4317         XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4318         XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4319         XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4320         XCAST(Initialize)IDirectDraw2Impl_Initialize,
4321         XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4322         XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4323         XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4324         XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4325         XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4326         IDirectDraw4Impl_GetSurfaceFromDC,
4327         IDirectDraw4Impl_RestoreAllSurfaces,
4328         IDirectDraw4Impl_TestCooperativeLevel,
4329         IDirectDraw4Impl_GetDeviceIdentifier
4330 };
4331
4332 #undef XCAST
4333
4334 /******************************************************************************
4335  *                              DirectDrawCreate
4336  */
4337
4338 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4339 {
4340    LRESULT ret;
4341    IDirectDrawImpl* ddraw = NULL;
4342    DWORD lastError;
4343
4344    /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4345
4346    SetLastError( ERROR_SUCCESS );
4347    ddraw  = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4348    if( (!ddraw)  &&
4349        ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4350      ) 
4351    {
4352      ERR( ddraw, "Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4353    }
4354
4355    if( ddraw )
4356    {
4357       /* Perform any special direct draw functions */
4358       if (msg==WM_PAINT)
4359         ddraw->d.paintable = 1;
4360
4361       /* Now let the application deal with the rest of this */
4362       if( ddraw->d.mainWindow )
4363       {
4364     
4365         /* Don't think that we actually need to call this but... 
4366            might as well be on the safe side of things... */
4367
4368         /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4369            it should be the procedures of our fake window that gets called
4370            instead of those of the window provided by the application.
4371            And with this patch, mouse clicks work with Monkey Island III
4372              - Lionel */
4373         ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4374
4375         if( !ret )
4376         {
4377           WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4378           /* We didn't handle the message - give it to the application */
4379           if (ddraw && ddraw->d.mainWindow && tmpWnd)
4380           {
4381                 ret = CallWindowProcA(tmpWnd->winproc,
4382                                    ddraw->d.mainWindow, msg, wParam, lParam );
4383           }
4384           WIN_ReleaseWndPtr(tmpWnd);
4385
4386         }
4387         
4388       } else {
4389         ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4390       } 
4391
4392     }
4393     else
4394     {
4395         ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4396     }
4397
4398     return ret;
4399 }
4400
4401 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4402 #ifdef HAVE_LIBXXF86DGA
4403         IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4404         int     memsize,banksize,width,major,minor,flags,height;
4405         char    *addr;
4406         int     fd;                     
4407         int     depth;
4408
4409         /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4410         if ((fd = open("/dev/mem", O_RDWR)) != -1)
4411           close(fd);
4412         
4413         if (fd  == -1) {
4414           MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4415           MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4416           return E_UNEXPECTED;
4417         }
4418         if (!DDRAW_DGA_Available()) {
4419                 TRACE(ddraw,"No XF86DGA detected.\n");
4420                 return DDERR_GENERIC;
4421         }
4422         *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4423         (*ilplpDD)->lpvtbl = &dga_ddvt;
4424         (*ilplpDD)->ref = 1;
4425         TSXF86DGAQueryVersion(display,&major,&minor);
4426         TRACE(ddraw,"XF86DGA is version %d.%d\n",major,minor);
4427         TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4428         if (!(flags & XF86DGADirectPresent))
4429                 MSG("direct video is NOT PRESENT.\n");
4430         TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4431         TRACE(ddraw,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4432                 addr,width,banksize,memsize
4433         );
4434         (*ilplpDD)->e.dga.fb_width = width;
4435         (*ilplpDD)->d.width = width;
4436         (*ilplpDD)->e.dga.fb_addr = addr;
4437         (*ilplpDD)->e.dga.fb_memsize = memsize;
4438         (*ilplpDD)->e.dga.fb_banksize = banksize;
4439
4440         TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4441         TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4442         (*ilplpDD)->e.dga.fb_height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4443 #ifdef DIABLO_HACK
4444         (*ilplpDD)->e.dga.vpmask = 1;
4445 #else
4446         (*ilplpDD)->e.dga.vpmask = 0;
4447 #endif
4448
4449         /* just assume the default depth is the DGA depth too */
4450         depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4451         _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4452 #ifdef RESTORE_SIGNALS
4453         SIGNAL_InitHandlers();
4454 #endif
4455
4456         return DD_OK;
4457 #else /* defined(HAVE_LIBXXF86DGA) */
4458         return DDERR_INVALIDDIRECTDRAWGUID;
4459 #endif /* defined(HAVE_LIBXXF86DGA) */
4460 }
4461
4462 BOOL
4463 DDRAW_XSHM_Available(void)
4464    {
4465 #ifdef HAVE_LIBXXSHM
4466   if (TSXShmQueryExtension(display))
4467       {
4468       int major, minor;
4469       Bool shpix;
4470
4471       if (TSXShmQueryVersion(display, &major, &minor, &shpix))
4472         return 1;
4473       else
4474         return 0;
4475     }
4476     else
4477     return 0;
4478 #else
4479   return 0;
4480 #endif
4481 }
4482
4483 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4484         IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4485         int depth;
4486
4487         *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4488         (*ilplpDD)->lpvtbl = &xlib_ddvt;
4489         (*ilplpDD)->ref = 1;
4490         (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4491
4492         /* At DirectDraw creation, the depth is the default depth */
4493         depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4494         _common_depth_to_pixelformat(depth,
4495                                      &((*ilplpDD)->d.directdraw_pixelformat),
4496                                      &((*ilplpDD)->d.screen_pixelformat),
4497                                      &((*ilplpDD)->d.pixmap_depth));
4498         (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4499         (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4500
4501 #ifdef HAVE_LIBXXSHM
4502         /* Test if XShm is available. */
4503         if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
4504           TRACE(ddraw, "Using XShm extension.\n");
4505 #endif
4506         
4507         return DD_OK;
4508 }
4509
4510 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
4511         IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4512         char    xclsid[50];
4513         WNDCLASSA       wc;
4514         /* WND*            pParentWindow; */
4515         HRESULT ret;
4516
4517         if (HIWORD(lpGUID))
4518                 WINE_StringFromCLSID(lpGUID,xclsid);
4519         else {
4520                 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
4521                 lpGUID = NULL;
4522         }
4523
4524         TRACE(ddraw,"(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
4525
4526         if ((!lpGUID) ||
4527             (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4528             (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4529             (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4530                 /* if they didn't request a particular interface, use the best
4531                  * supported one */
4532                 if (DDRAW_DGA_Available())
4533                         lpGUID = &DGA_DirectDraw_GUID;
4534                 else
4535                         lpGUID = &XLIB_DirectDraw_GUID;
4536         }
4537
4538         wc.style        = CS_GLOBALCLASS;
4539         wc.lpfnWndProc  = Xlib_DDWndProc;
4540         wc.cbClsExtra   = 0;
4541         wc.cbWndExtra   = /* Defines extra mem for window. This is used for storing this */
4542                           sizeof( LPDIRECTDRAW ); /*  ddrawXlibThisOffset */
4543
4544         /* We can be a child of the desktop since we're really important */
4545         /*
4546          This code is not useful since hInstance is forced to 0 afterward
4547         pParentWindow   = WIN_GetDesktop();
4548         wc.hInstance    = pParentWindow ? pParentWindow->hwndSelf : 0;
4549         */
4550         wc.hInstance    = 0; 
4551
4552         
4553         wc.hIcon        = 0;
4554         wc.hCursor      = (HCURSOR)IDC_ARROWA;
4555         wc.hbrBackground= NULL_BRUSH;
4556         wc.lpszMenuName = 0;
4557         wc.lpszClassName= "WINE_DirectDraw";
4558         RegisterClassA(&wc);
4559
4560         if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
4561                 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
4562         else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
4563                 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
4564         else
4565           goto err;
4566
4567
4568         (*ilplpDD)->d.winclass = RegisterClassA(&wc);
4569         return ret;
4570
4571       err:
4572         ERR(ddraw, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
4573         return DDERR_INVALIDDIRECTDRAWGUID;
4574 }
4575
4576
4577 #else /* !defined(X_DISPLAY_MISSING) */
4578
4579 #include "windef.h"
4580
4581 #define DD_OK 0
4582
4583 typedef void *LPGUID;
4584 typedef void *LPUNKNOWN;
4585 typedef void *LPDIRECTDRAW;
4586 typedef void *LPDIRECTDRAWCLIPPER;
4587 typedef void *LPDDENUMCALLBACKA;
4588 typedef void *LPDDENUMCALLBACKEXA;
4589 typedef void *LPDDENUMCALLBACKEXW;
4590 typedef void *LPDDENUMCALLBACKW;
4591
4592 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z) 
4593 {
4594   return DD_OK;
4595 }
4596
4597 HRESULT WINAPI DirectDrawCreate(
4598   LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) 
4599 {
4600   return DD_OK;
4601 }
4602
4603 HRESULT WINAPI DirectDrawCreateClipper(
4604   DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
4605 {
4606   return DD_OK;
4607 }
4608
4609 HRESULT WINAPI DirectDrawEnumerateA(
4610   LPDDENUMCALLBACKA lpCallback, LPVOID lpContext) 
4611 {
4612   return DD_OK;
4613 }
4614
4615 HRESULT WINAPI DirectDrawEnumerateExA(
4616   LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
4617 {
4618   return DD_OK;
4619 }
4620
4621 HRESULT WINAPI DirectDrawEnumerateExW(
4622   LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
4623 {
4624   return DD_OK;
4625 }
4626
4627 HRESULT WINAPI DirectDrawEnumerateW(
4628   LPDDENUMCALLBACKW lpCallback, LPVOID lpContext) 
4629 {
4630   return DD_OK;
4631 }
4632
4633 #endif /* !defined(X_DISPLAY_MISSING) */
4634
4635
4636 /*******************************************************************************
4637  * DirectDraw ClassFactory
4638  *
4639  *  Heavily inspired (well, can you say completely copied :-) ) from DirectSound
4640  *
4641  */
4642 typedef struct
4643 {
4644     /* IUnknown fields */
4645     ICOM_VTABLE(IClassFactory)* lpvtbl;
4646     DWORD                       ref;
4647 } IClassFactoryImpl;
4648
4649 static HRESULT WINAPI 
4650 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
4651         ICOM_THIS(IClassFactoryImpl,iface);
4652         char buf[80];
4653
4654         if (HIWORD(riid))
4655             WINE_StringFromCLSID(riid,buf);
4656         else
4657             sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4658         FIXME(ddraw,"(%p)->(%s,%p),stub!\n",This,buf,ppobj);
4659         return E_NOINTERFACE;
4660 }
4661
4662 static ULONG WINAPI
4663 DDCF_AddRef(LPCLASSFACTORY iface) {
4664         ICOM_THIS(IClassFactoryImpl,iface);
4665         return ++(This->ref);
4666 }
4667
4668 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
4669         ICOM_THIS(IClassFactoryImpl,iface);
4670         /* static class, won't be  freed */
4671         return --(This->ref);
4672 }
4673
4674 static HRESULT WINAPI DDCF_CreateInstance(
4675         LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
4676 ) {
4677         ICOM_THIS(IClassFactoryImpl,iface);
4678         char buf[80];
4679
4680         WINE_StringFromCLSID(riid,buf);
4681         TRACE(ddraw,"(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
4682         if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
4683             (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
4684             (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
4685                 /* FIXME: reuse already created DirectDraw if present? */
4686                 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
4687         }
4688         return E_NOINTERFACE;
4689 }
4690
4691 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
4692         ICOM_THIS(IClassFactoryImpl,iface);
4693         FIXME(ddraw,"(%p)->(%d),stub!\n",This,dolock);
4694         return S_OK;
4695 }
4696
4697 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl = {
4698         DDCF_QueryInterface,
4699         DDCF_AddRef,
4700         DDCF_Release,
4701         DDCF_CreateInstance,
4702         DDCF_LockServer
4703 };
4704 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
4705
4706 /*******************************************************************************
4707  * DllGetClassObject [DDRAW.13]
4708  * Retrieves class object from a DLL object
4709  *
4710  * NOTES
4711  *    Docs say returns STDAPI
4712  *
4713  * PARAMS
4714  *    rclsid [I] CLSID for the class object
4715  *    riid   [I] Reference to identifier of interface for class object
4716  *    ppv    [O] Address of variable to receive interface pointer for riid
4717  *
4718  * RETURNS
4719  *    Success: S_OK
4720  *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
4721  *             E_UNEXPECTED
4722  */
4723 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
4724 {
4725     char buf[80],xbuf[80];
4726
4727     if (HIWORD(rclsid))
4728         WINE_StringFromCLSID(rclsid,xbuf);
4729     else
4730         sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
4731     if (HIWORD(riid))
4732         WINE_StringFromCLSID(riid,buf);
4733     else
4734         sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
4735     WINE_StringFromCLSID(riid,xbuf);
4736     TRACE(ddraw, "(%p,%p,%p)\n", xbuf, buf, ppv);
4737     if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
4738         *ppv = (LPVOID)&DDRAW_CF;
4739         IClassFactory_AddRef((IClassFactory*)*ppv);
4740     return S_OK;
4741     }
4742     FIXME(ddraw, "(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
4743     return E_NOINTERFACE;
4744 }
4745
4746
4747 /*******************************************************************************
4748  * DllCanUnloadNow [DDRAW.12]  Determines whether the DLL is in use.
4749  *
4750  * RETURNS
4751  *    Success: S_OK
4752  *    Failure: S_FALSE
4753  */
4754 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
4755 {
4756     FIXME(ddraw, "(void): stub\n");
4757     return S_FALSE;
4758 }