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