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