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