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