- fixed the creation of back-buffers in DGA mode
[wine.git] / graphics / ddraw.c
blob45a453440ec56cda3114ed4a6f41d4375c47793e
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)
76 /* Get the number of bytes per pixel for a given surface */
77 #define GET_BPP(desc) (desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? \
78 1 : \
79 desc.ddpfPixelFormat.x.dwRGBBitCount / 8)
81 /* Where do these GUIDs come from? mkuuid.
82 * They exist solely to distinguish between the targets Wine support,
83 * and should be different than any other GUIDs in existence.
85 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
86 0xe2dcb020,
87 0xdc60,
88 0x11d1,
89 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
92 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
93 0x1574a740,
94 0xdc61,
95 0x11d1,
96 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
99 #ifdef HAVE_LIBXXF86DGA
100 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
101 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
102 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
103 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
104 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
105 #endif /* defined(HAVE_LIBXXF86DGA) */
107 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
108 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
109 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
110 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
111 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
113 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
114 static struct ICOM_VTABLE(IDirect3D) d3dvt;
115 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
117 /* This is for mode-emulation */
119 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
120 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
121 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
122 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
123 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
124 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
125 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
127 typedef struct {
128 unsigned short bpp;
129 unsigned short depth;
130 unsigned int rmask;
131 unsigned int gmask;
132 unsigned int bmask;
133 } ConvertMode;
135 typedef struct {
136 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
137 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
138 } ConvertFuncs;
140 typedef struct {
141 ConvertMode screen, dest;
142 ConvertFuncs funcs;
143 } Convert;
145 static Convert ModeEmulations[] = {
146 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
147 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
148 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
149 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
150 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
153 #ifdef HAVE_LIBXXF86VM
154 static XF86VidModeModeInfo *orig_mode = NULL;
155 #endif
157 #ifdef HAVE_LIBXXSHM
158 static int XShmErrorFlag = 0;
159 #endif
161 static BOOL
162 DDRAW_DGA_Available(void)
164 #ifdef HAVE_LIBXXF86DGA
165 int evbase, evret, fd;
167 if (Options.noDGA)
168 return 0;
170 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
171 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
172 /* others. --stephenc */
173 if ((fd = open("/dev/mem", O_RDWR)) != -1)
174 close(fd);
176 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
177 #else /* defined(HAVE_LIBXXF86DGA) */
178 return 0;
179 #endif /* defined(HAVE_LIBXXF86DGA) */
182 /**********************************************************************/
184 typedef struct {
185 LPVOID lpCallback;
186 LPVOID lpContext;
187 } DirectDrawEnumerateProcData;
189 /***********************************************************************
190 * DirectDrawEnumerateExA (DDRAW.*)
192 HRESULT WINAPI DirectDrawEnumerateExA(
193 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
195 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
197 if (TRACE_ON(ddraw)) {
198 DPRINTF(" Flags : ");
199 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
200 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
201 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
202 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
203 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
204 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
205 DPRINTF("\n");
208 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
209 /* For the moment, Wine does not support any 3D only accelerators */
210 return DD_OK;
213 if (DDRAW_DGA_Available()) {
214 TRACE("Enumerating DGA interface\n");
215 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
216 return DD_OK;
219 TRACE("Enumerating Xlib interface\n");
220 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
221 return DD_OK;
223 TRACE("Enumerating Default interface\n");
224 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
225 return DD_OK;
227 return DD_OK;
230 /***********************************************************************
231 * DirectDrawEnumerateExW (DDRAW.*)
234 static BOOL CALLBACK DirectDrawEnumerateExProcW(
235 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
236 LPVOID lpContext, HMONITOR hm)
238 DirectDrawEnumerateProcData *pEPD =
239 (DirectDrawEnumerateProcData *) lpContext;
240 LPWSTR lpDriverDescriptionW =
241 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
242 LPWSTR lpDriverNameW =
243 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
245 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
246 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
248 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
249 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
251 return bResult;
254 /**********************************************************************/
256 HRESULT WINAPI DirectDrawEnumerateExW(
257 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
259 DirectDrawEnumerateProcData epd;
260 epd.lpCallback = (LPVOID) lpCallback;
261 epd.lpContext = lpContext;
263 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
264 (LPVOID) &epd, 0);
267 /***********************************************************************
268 * DirectDrawEnumerateA (DDRAW.*)
271 static BOOL CALLBACK DirectDrawEnumerateProcA(
272 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
273 LPVOID lpContext, HMONITOR hm)
275 DirectDrawEnumerateProcData *pEPD =
276 (DirectDrawEnumerateProcData *) lpContext;
278 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
279 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
282 /**********************************************************************/
284 HRESULT WINAPI DirectDrawEnumerateA(
285 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
287 DirectDrawEnumerateProcData epd;
288 epd.lpCallback = (LPVOID) lpCallback;
289 epd.lpContext = lpContext;
291 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
292 (LPVOID) &epd, 0);
295 /***********************************************************************
296 * DirectDrawEnumerateW (DDRAW.*)
299 static BOOL WINAPI DirectDrawEnumerateProcW(
300 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
301 LPVOID lpContext, HMONITOR hm)
303 DirectDrawEnumerateProcData *pEPD =
304 (DirectDrawEnumerateProcData *) lpContext;
306 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
307 lpGUID, lpDriverDescription, lpDriverName,
308 pEPD->lpContext);
311 /**********************************************************************/
313 HRESULT WINAPI DirectDrawEnumerateW(
314 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
316 DirectDrawEnumerateProcData epd;
317 epd.lpCallback = (LPVOID) lpCallback;
318 epd.lpContext = lpContext;
320 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
321 (LPVOID) &epd, 0);
324 /***********************************************************************
325 * DSoundHelp (DDRAW.?)
328 /* What is this doing here? */
329 HRESULT WINAPI
330 DSoundHelp(DWORD x,DWORD y,DWORD z) {
331 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
332 return 0;
335 /******************************************************************************
336 * internal helper functions
338 static void _dump_DDBLTFX(DWORD flagmask) {
339 int i;
340 const struct {
341 DWORD mask;
342 char *name;
343 } flags[] = {
344 #define FE(x) { x, #x},
345 FE(DDBLTFX_ARITHSTRETCHY)
346 FE(DDBLTFX_MIRRORLEFTRIGHT)
347 FE(DDBLTFX_MIRRORUPDOWN)
348 FE(DDBLTFX_NOTEARING)
349 FE(DDBLTFX_ROTATE180)
350 FE(DDBLTFX_ROTATE270)
351 FE(DDBLTFX_ROTATE90)
352 FE(DDBLTFX_ZBUFFERRANGE)
353 FE(DDBLTFX_ZBUFFERBASEDEST)
354 #undef FE
356 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
357 if (flags[i].mask & flagmask) {
358 DPRINTF("%s ",flags[i].name);
361 DPRINTF("\n");
365 static void _dump_DDBLTFAST(DWORD flagmask) {
366 int i;
367 const struct {
368 DWORD mask;
369 char *name;
370 } flags[] = {
371 #define FE(x) { x, #x},
372 FE(DDBLTFAST_NOCOLORKEY)
373 FE(DDBLTFAST_SRCCOLORKEY)
374 FE(DDBLTFAST_DESTCOLORKEY)
375 FE(DDBLTFAST_WAIT)
376 #undef FE
378 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
379 if (flags[i].mask & flagmask)
380 DPRINTF("%s ",flags[i].name);
381 DPRINTF("\n");
384 static void _dump_DDBLT(DWORD flagmask) {
385 int i;
386 const struct {
387 DWORD mask;
388 char *name;
389 } flags[] = {
390 #define FE(x) { x, #x},
391 FE(DDBLT_ALPHADEST)
392 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
393 FE(DDBLT_ALPHADESTNEG)
394 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
395 FE(DDBLT_ALPHAEDGEBLEND)
396 FE(DDBLT_ALPHASRC)
397 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
398 FE(DDBLT_ALPHASRCNEG)
399 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
400 FE(DDBLT_ASYNC)
401 FE(DDBLT_COLORFILL)
402 FE(DDBLT_DDFX)
403 FE(DDBLT_DDROPS)
404 FE(DDBLT_KEYDEST)
405 FE(DDBLT_KEYDESTOVERRIDE)
406 FE(DDBLT_KEYSRC)
407 FE(DDBLT_KEYSRCOVERRIDE)
408 FE(DDBLT_ROP)
409 FE(DDBLT_ROTATIONANGLE)
410 FE(DDBLT_ZBUFFER)
411 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
412 FE(DDBLT_ZBUFFERDESTOVERRIDE)
413 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
414 FE(DDBLT_ZBUFFERSRCOVERRIDE)
415 FE(DDBLT_WAIT)
416 FE(DDBLT_DEPTHFILL)
417 #undef FE
419 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
420 if (flags[i].mask & flagmask)
421 DPRINTF("%s ",flags[i].name);
422 DPRINTF("\n");
425 static void _dump_DDSCAPS(void *in) {
426 int i;
427 const struct {
428 DWORD mask;
429 char *name;
430 } flags[] = {
431 #define FE(x) { x, #x},
432 FE(DDSCAPS_RESERVED1)
433 FE(DDSCAPS_ALPHA)
434 FE(DDSCAPS_BACKBUFFER)
435 FE(DDSCAPS_COMPLEX)
436 FE(DDSCAPS_FLIP)
437 FE(DDSCAPS_FRONTBUFFER)
438 FE(DDSCAPS_OFFSCREENPLAIN)
439 FE(DDSCAPS_OVERLAY)
440 FE(DDSCAPS_PALETTE)
441 FE(DDSCAPS_PRIMARYSURFACE)
442 FE(DDSCAPS_PRIMARYSURFACELEFT)
443 FE(DDSCAPS_SYSTEMMEMORY)
444 FE(DDSCAPS_TEXTURE)
445 FE(DDSCAPS_3DDEVICE)
446 FE(DDSCAPS_VIDEOMEMORY)
447 FE(DDSCAPS_VISIBLE)
448 FE(DDSCAPS_WRITEONLY)
449 FE(DDSCAPS_ZBUFFER)
450 FE(DDSCAPS_OWNDC)
451 FE(DDSCAPS_LIVEVIDEO)
452 FE(DDSCAPS_HWCODEC)
453 FE(DDSCAPS_MODEX)
454 FE(DDSCAPS_MIPMAP)
455 FE(DDSCAPS_RESERVED2)
456 FE(DDSCAPS_ALLOCONLOAD)
457 FE(DDSCAPS_VIDEOPORT)
458 FE(DDSCAPS_LOCALVIDMEM)
459 FE(DDSCAPS_NONLOCALVIDMEM)
460 FE(DDSCAPS_STANDARDVGAMODE)
461 FE(DDSCAPS_OPTIMIZED)
462 #undef FE
464 DWORD flagmask = *((DWORD *) in);
465 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
466 if (flags[i].mask & flagmask)
467 DPRINTF("%s ",flags[i].name);
470 static void _dump_pixelformat_flag(DWORD flagmask) {
471 int i;
472 const struct {
473 DWORD mask;
474 char *name;
475 } flags[] = {
476 #define FE(x) { x, #x},
477 FE(DDPF_ALPHAPIXELS)
478 FE(DDPF_ALPHA)
479 FE(DDPF_FOURCC)
480 FE(DDPF_PALETTEINDEXED4)
481 FE(DDPF_PALETTEINDEXEDTO8)
482 FE(DDPF_PALETTEINDEXED8)
483 FE(DDPF_RGB)
484 FE(DDPF_COMPRESSED)
485 FE(DDPF_RGBTOYUV)
486 FE(DDPF_YUV)
487 FE(DDPF_ZBUFFER)
488 FE(DDPF_PALETTEINDEXED1)
489 FE(DDPF_PALETTEINDEXED2)
490 FE(DDPF_ZPIXELS)
491 #undef FE
493 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
494 if (flags[i].mask & flagmask)
495 DPRINTF("%s ",flags[i].name);
498 static void _dump_paletteformat(DWORD dwFlags) {
499 int i;
500 const struct {
501 DWORD mask;
502 char *name;
503 } flags[] = {
504 #define FE(x) { x, #x},
505 FE(DDPCAPS_4BIT)
506 FE(DDPCAPS_8BITENTRIES)
507 FE(DDPCAPS_8BIT)
508 FE(DDPCAPS_INITIALIZE)
509 FE(DDPCAPS_PRIMARYSURFACE)
510 FE(DDPCAPS_PRIMARYSURFACELEFT)
511 FE(DDPCAPS_ALLOW256)
512 FE(DDPCAPS_VSYNC)
513 FE(DDPCAPS_1BIT)
514 FE(DDPCAPS_2BIT)
515 FE(DDPCAPS_ALPHA)
516 #undef FE
518 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
519 if (flags[i].mask & dwFlags)
520 DPRINTF("%s ",flags[i].name);
521 DPRINTF("\n");
524 static void _dump_pixelformat(void *in) {
525 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
526 char *cmd;
528 DPRINTF("( ");
529 _dump_pixelformat_flag(pf->dwFlags);
530 if (pf->dwFlags & DDPF_FOURCC) {
531 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
533 if (pf->dwFlags & DDPF_RGB) {
534 DPRINTF(", RGB bits: %ld, ", pf->x.dwRGBBitCount);
535 switch (pf->x.dwRGBBitCount) {
536 case 4:
537 cmd = "%1lx";
538 break;
539 case 8:
540 cmd = "%02lx";
541 break;
542 case 16:
543 cmd = "%04lx";
544 break;
545 case 24:
546 cmd = "%06lx";
547 break;
548 case 32:
549 cmd = "%08lx";
550 break;
551 default:
552 ERR("Unexpected bit depth !\n");
553 cmd = "%d";
555 DPRINTF(" R "); DPRINTF(cmd, pf->y.dwRBitMask);
556 DPRINTF(" G "); DPRINTF(cmd, pf->z.dwGBitMask);
557 DPRINTF(" B "); DPRINTF(cmd, pf->xx.dwBBitMask);
558 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
559 DPRINTF(" A "); DPRINTF(cmd, pf->xy.dwRGBAlphaBitMask);
561 if (pf->dwFlags & DDPF_ZPIXELS) {
562 DPRINTF(" Z "); DPRINTF(cmd, pf->xy.dwRGBZBitMask);
565 if (pf->dwFlags & DDPF_ZBUFFER) {
566 DPRINTF(", Z bits : %ld", pf->x.dwZBufferBitDepth);
568 if (pf->dwFlags & DDPF_ALPHA) {
569 DPRINTF(", Alpha bits : %ld", pf->x.dwAlphaBitDepth);
571 DPRINTF(")");
574 static void _dump_colorkeyflag(DWORD ck) {
575 int i;
576 const struct {
577 DWORD mask;
578 char *name;
579 } flags[] = {
580 #define FE(x) { x, #x},
581 FE(DDCKEY_COLORSPACE)
582 FE(DDCKEY_DESTBLT)
583 FE(DDCKEY_DESTOVERLAY)
584 FE(DDCKEY_SRCBLT)
585 FE(DDCKEY_SRCOVERLAY)
586 #undef FE
588 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
589 if (flags[i].mask & ck)
590 DPRINTF("%s ",flags[i].name);
593 static void _dump_DWORD(void *in) {
594 DPRINTF("%ld", *((DWORD *) in));
596 static void _dump_PTR(void *in) {
597 DPRINTF("%p", *((void **) in));
599 static void _dump_DDCOLORKEY(void *in) {
600 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
602 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
605 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
606 int i;
607 struct {
608 DWORD mask;
609 char *name;
610 void (*func)(void *);
611 void *elt;
612 } flags[16], *fe = flags;
613 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
614 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
615 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
616 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
617 FE(DDSD_PITCH, _dump_DWORD, lPitch);
618 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
619 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, x.dwZBufferBitDepth);
620 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
621 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
622 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
623 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
624 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
625 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
626 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, x.dwMipMapCount);
627 FE(DDSD_REFRESHRATE, _dump_DWORD, x.dwRefreshRate);
628 FE(DDSD_LINEARSIZE, _dump_DWORD, y.dwLinearSize);
629 FE(DDSD_LPSURFACE, _dump_PTR, y.lpSurface);
630 #undef FE
632 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
633 if (flags[i].mask & lpddsd->dwFlags) {
634 DPRINTF(" - %s : ",flags[i].name);
635 flags[i].func(flags[i].elt);
636 DPRINTF("\n");
641 /******************************************************************************
642 * IDirectDrawSurface methods
644 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
645 * DDS and DDS2 use those functions. (Function calls did not change (except
646 * using different DirectDrawSurfaceX version), just added flags and functions)
649 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
650 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
652 ICOM_THIS(IDirectDrawSurface4Impl,iface);
653 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
654 This,lprect,lpddsd,flags,(DWORD)hnd);
655 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
656 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
657 This,lprect,lpddsd,flags,(DWORD)hnd);
659 /* First, copy the Surface description */
660 *lpddsd = This->s.surface_desc;
661 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
662 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
664 /* If asked only for a part, change the surface pointer */
665 if (lprect) {
666 TRACE(" lprect: %dx%d-%dx%d\n",
667 lprect->top,lprect->left,lprect->bottom,lprect->right
669 if ((lprect->top < 0) ||
670 (lprect->left < 0) ||
671 (lprect->bottom < 0) ||
672 (lprect->right < 0)) {
673 ERR(" Negative values in LPRECT !!!\n");
674 return DDERR_INVALIDPARAMS;
677 lpddsd->y.lpSurface = (LPVOID) ((char *) This->s.surface_desc.y.lpSurface +
678 (lprect->top*This->s.surface_desc.lPitch) +
679 (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8)));
680 } else {
681 assert(This->s.surface_desc.y.lpSurface);
683 return DD_OK;
686 #ifdef HAVE_LIBXXF86DGA
687 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
688 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
690 ICOM_THIS(IDirectDrawSurface4Impl,iface);
691 TRACE("(%p)->Unlock(%p)\n",This,surface);
692 return DD_OK;
694 #endif /* defined(HAVE_LIBXXF86DGA) */
696 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
697 if (This->s.ddraw->d.pixel_convert != NULL)
698 This->s.ddraw->d.pixel_convert(This->s.surface_desc.y.lpSurface,
699 This->t.xlib.image->data,
700 This->s.surface_desc.dwWidth,
701 This->s.surface_desc.dwHeight,
702 This->s.surface_desc.lPitch,
703 This->s.palette);
705 #ifdef HAVE_LIBXXSHM
706 if (This->s.ddraw->e.xlib.xshm_active)
707 TSXShmPutImage(display,
708 This->s.ddraw->d.drawable,
709 DefaultGCOfScreen(X11DRV_GetXScreen()),
710 This->t.xlib.image,
711 0, 0, 0, 0,
712 This->t.xlib.image->width,
713 This->t.xlib.image->height,
714 False);
715 else
716 #endif
717 TSXPutImage( display,
718 This->s.ddraw->d.drawable,
719 DefaultGCOfScreen(X11DRV_GetXScreen()),
720 This->t.xlib.image,
721 0, 0, 0, 0,
722 This->t.xlib.image->width,
723 This->t.xlib.image->height);
726 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
727 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
729 ICOM_THIS(IDirectDrawSurface4Impl,iface);
730 TRACE("(%p)->Unlock(%p)\n",This,surface);
732 if (!This->s.ddraw->d.paintable)
733 return DD_OK;
735 /* Only redraw the screen when unlocking the buffer that is on screen */
736 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
737 Xlib_copy_surface_on_screen(This);
739 if (This->s.palette && This->s.palette->cm)
740 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
742 return DD_OK;
745 static IDirectDrawSurface4Impl* _common_find_flipto(
746 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
748 int i,j,flipable=0;
749 struct _surface_chain *chain = This->s.chain;
751 /* if there was no override flipto, look for current backbuffer */
752 if (!flipto) {
753 /* walk the flip chain looking for backbuffer */
754 for (i=0;i<chain->nrofsurfaces;i++) {
755 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
756 flipable++;
757 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
758 flipto = chain->surfaces[i];
760 /* sanity checks ... */
761 if (!flipto) {
762 if (flipable>1) {
763 for (i=0;i<chain->nrofsurfaces;i++)
764 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
765 break;
766 if (i==chain->nrofsurfaces) {
767 /* we do not have a frontbuffer either */
768 for (i=0;i<chain->nrofsurfaces;i++)
769 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
770 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
771 break;
773 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
774 int k = j % chain->nrofsurfaces;
775 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
776 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
777 flipto = chain->surfaces[k];
778 break;
783 if (!flipto)
784 flipto = This;
786 TRACE("flipping to %p\n",flipto);
788 return flipto;
791 #ifdef HAVE_LIBXXF86DGA
792 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
793 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
795 ICOM_THIS(IDirectDrawSurface4Impl,iface);
796 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
797 DWORD xheight;
798 LPBYTE surf;
800 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
801 iflipto = _common_find_flipto(This,iflipto);
803 /* and flip! */
804 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
805 if (iflipto->s.palette && iflipto->s.palette->cm)
806 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
807 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
810 /* We need to switch the lowlevel surfaces, for DGA this is: */
812 /* The height within the framebuffer */
813 xheight = This->t.dga.fb_height;
814 This->t.dga.fb_height = iflipto->t.dga.fb_height;
815 iflipto->t.dga.fb_height = xheight;
817 /* And the assciated surface pointer */
818 surf = This->s.surface_desc.y.lpSurface;
819 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
820 iflipto->s.surface_desc.y.lpSurface = surf;
822 return DD_OK;
824 #endif /* defined(HAVE_LIBXXF86DGA) */
826 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
827 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
829 ICOM_THIS(IDirectDrawSurface4Impl,iface);
830 XImage *image;
831 LPBYTE surf;
832 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
834 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
835 iflipto = _common_find_flipto(This,iflipto);
837 #if defined(HAVE_MESAGL) && 0 /* does not work */
838 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
839 TRACE(" - OpenGL flip\n");
840 ENTER_GL();
841 glXSwapBuffers(display, This->s.ddraw->d.drawable);
842 LEAVE_GL();
844 return DD_OK;
846 #endif /* defined(HAVE_MESAGL) */
848 if (!This->s.ddraw->d.paintable)
849 return DD_OK;
851 /* We need to switch the lowlevel surfaces, for xlib this is: */
852 /* The surface pointer */
853 surf = This->s.surface_desc.y.lpSurface;
854 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
855 iflipto->s.surface_desc.y.lpSurface = surf;
856 /* the associated ximage */
857 image = This->t.xlib.image;
858 This->t.xlib.image = iflipto->t.xlib.image;
859 iflipto->t.xlib.image = image;
861 Xlib_copy_surface_on_screen(This);
863 if (iflipto->s.palette && iflipto->s.palette->cm)
864 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
865 return DD_OK;
868 /* The IDirectDrawSurface4::SetPalette method attaches the specified
869 * DirectDrawPalette object to a surface. The surface uses this palette for all
870 * subsequent operations. The palette change takes place immediately.
872 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
873 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
875 ICOM_THIS(IDirectDrawSurface4Impl,iface);
876 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
877 int i;
878 TRACE("(%p)->(%p)\n",This,ipal);
880 if (ipal == NULL) {
881 if( This->s.palette != NULL )
882 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
883 This->s.palette = ipal;
885 return DD_OK;
888 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
890 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
891 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
893 if (!Options.managed)
894 TSXInstallColormap(display,ipal->cm);
896 for (i=0;i<256;i++) {
897 XColor xc;
899 xc.red = ipal->palents[i].peRed<<8;
900 xc.blue = ipal->palents[i].peBlue<<8;
901 xc.green = ipal->palents[i].peGreen<<8;
902 xc.flags = DoRed|DoBlue|DoGreen;
903 xc.pixel = i;
904 TSXStoreColor(display,ipal->cm,&xc);
906 TSXInstallColormap(display,ipal->cm);
909 /* According to spec, we are only supposed to
910 * AddRef if this is not the same palette.
912 if( This->s.palette != ipal )
914 if( ipal != NULL )
915 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
916 if( This->s.palette != NULL )
917 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
918 This->s.palette = ipal;
919 /* Perform the refresh */
920 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
922 return DD_OK;
925 #ifdef HAVE_LIBXXF86DGA
926 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
927 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
929 ICOM_THIS(IDirectDrawSurface4Impl,iface);
930 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
931 TRACE("(%p)->(%p)\n",This,ipal);
933 /* According to spec, we are only supposed to
934 * AddRef if this is not the same palette.
936 if( This->s.palette != ipal )
938 if( ipal != NULL )
939 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
940 if( This->s.palette != NULL )
941 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
942 This->s.palette = ipal;
943 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
945 return DD_OK;
947 #endif /* defined(HAVE_LIBXXF86DGA) */
949 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
951 int x, y;
952 LPBYTE first;
954 /* Do first row */
956 #define COLORFILL_ROW(type) { \
957 type *d = (type *) buf; \
958 for (x = 0; x < width; x++) \
959 d[x] = (type) color; \
960 break; \
963 switch(bpp) {
964 case 1: COLORFILL_ROW(BYTE)
965 case 2: COLORFILL_ROW(WORD)
966 case 4: COLORFILL_ROW(DWORD)
967 default:
968 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
969 return DDERR_UNSUPPORTED;
972 #undef COLORFILL_ROW
974 /* Now copy first row */
975 first = buf;
976 for (y = 1; y < height; y++) {
977 buf += lPitch;
978 memcpy(buf, first, width * bpp);
981 return DD_OK;
984 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
985 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
987 ICOM_THIS(IDirectDrawSurface4Impl,iface);
988 RECT xdst,xsrc;
989 DDSURFACEDESC ddesc,sdesc;
990 HRESULT ret = DD_OK;
991 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
992 int x, y;
993 LPBYTE dbuf, sbuf;
995 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
997 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
998 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1000 if (TRACE_ON(ddraw)) {
1001 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1002 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1003 TRACE("\tflags: ");
1004 _dump_DDBLT(dwFlags);
1005 if (dwFlags & DDBLT_DDFX) {
1006 TRACE("\tblitfx: ");
1007 _dump_DDBLTFX(lpbltfx->dwDDFX);
1011 if (rdst) {
1012 memcpy(&xdst,rdst,sizeof(xdst));
1013 } else {
1014 xdst.top = 0;
1015 xdst.bottom = ddesc.dwHeight;
1016 xdst.left = 0;
1017 xdst.right = ddesc.dwWidth;
1020 if (rsrc) {
1021 memcpy(&xsrc,rsrc,sizeof(xsrc));
1022 } else {
1023 if (src) {
1024 xsrc.top = 0;
1025 xsrc.bottom = sdesc.dwHeight;
1026 xsrc.left = 0;
1027 xsrc.right = sdesc.dwWidth;
1028 } else {
1029 memset(&xsrc,0,sizeof(xsrc));
1033 bpp = GET_BPP(ddesc);
1034 srcheight = xsrc.bottom - xsrc.top;
1035 srcwidth = xsrc.right - xsrc.left;
1036 dstheight = xdst.bottom - xdst.top;
1037 dstwidth = xdst.right - xdst.left;
1038 width = (xdst.right - xdst.left) * bpp;
1039 dbuf = (BYTE *) ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1041 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1043 /* First, all the 'source-less' blits */
1044 if (dwFlags & DDBLT_COLORFILL) {
1045 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1046 ddesc.lPitch, lpbltfx->b.dwFillColor);
1047 dwFlags &= ~DDBLT_COLORFILL;
1050 if (dwFlags & DDBLT_DEPTHFILL) {
1051 #ifdef HAVE_MESAGL
1052 GLboolean ztest;
1054 /* Clears the screen */
1055 TRACE(" Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
1056 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1057 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1058 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1059 glClear(GL_DEPTH_BUFFER_BIT);
1060 glDepthMask(ztest);
1062 dwFlags &= ~(DDBLT_DEPTHFILL);
1063 #endif /* defined(HAVE_MESAGL) */
1066 if (dwFlags & DDBLT_ROP) {
1067 /* Catch some degenerate cases here */
1068 switch(lpbltfx->dwROP) {
1069 case BLACKNESS:
1070 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1071 break;
1072 case 0xAA0029: /* No-op */
1073 break;
1074 case WHITENESS:
1075 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1076 break;
1077 default:
1078 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
1079 goto error;
1081 dwFlags &= ~DDBLT_ROP;
1084 if (dwFlags & DDBLT_DDROPS) {
1085 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
1088 /* Now the 'with source' blits */
1089 if (src) {
1090 LPBYTE sbase;
1091 int sx, xinc, sy, yinc;
1093 sbase = (BYTE *) sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1094 xinc = (srcwidth << 16) / dstwidth;
1095 yinc = (srcheight << 16) / dstheight;
1097 if (!dwFlags) {
1099 /* No effects, we can cheat here */
1100 if (dstwidth == srcwidth) {
1101 if (dstheight == srcheight) {
1102 /* No stretching in either direction. This needs to be as fast as possible */
1103 sbuf = sbase;
1104 for (y = 0; y < dstheight; y++) {
1105 memcpy(dbuf, sbuf, width);
1106 sbuf += sdesc.lPitch;
1107 dbuf += ddesc.lPitch;
1109 } else {
1110 /* Stretching in Y direction only */
1111 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1112 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1113 memcpy(dbuf, sbuf, width);
1114 dbuf += ddesc.lPitch;
1117 } else {
1118 /* Stretching in X direction */
1119 int last_sy = -1;
1120 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1121 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1123 if ((sy >> 16) == (last_sy >> 16)) {
1124 /* Same as last row - copy already stretched row */
1125 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1126 } else {
1128 #define STRETCH_ROW(type) { \
1129 type *s = (type *) sbuf, *d = (type *) dbuf; \
1130 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1131 d[x] = s[sx >> 16]; \
1132 break; }
1134 switch(bpp) {
1135 case 1: STRETCH_ROW(BYTE)
1136 case 2: STRETCH_ROW(WORD)
1137 case 4: STRETCH_ROW(DWORD)
1138 default:
1139 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1140 ret = DDERR_UNSUPPORTED;
1141 goto error;
1144 #undef STRETCH_ROW
1147 last_sy = sy;
1148 dbuf += ddesc.lPitch;
1151 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1152 DWORD keylow, keyhigh;
1154 if (dwFlags & DDBLT_KEYSRC) {
1155 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1156 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1157 } else {
1158 /* I'm not sure if this is correct */
1159 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1160 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1161 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1165 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1166 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1168 #define COPYROW_COLORKEY(type) { \
1169 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1170 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1171 tmp = s[sx >> 16]; \
1172 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1174 break; }
1176 switch (bpp) {
1177 case 1: COPYROW_COLORKEY(BYTE)
1178 case 2: COPYROW_COLORKEY(WORD)
1179 case 4: COPYROW_COLORKEY(DWORD)
1180 default:
1181 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1182 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1183 ret = DDERR_UNSUPPORTED;
1184 goto error;
1186 dbuf += ddesc.lPitch;
1189 #undef COPYROW_COLORKEY
1191 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1196 error:
1198 if (dwFlags && FIXME_ON(ddraw)) {
1199 FIXME("\tUnsupported flags: ");
1200 _dump_DDBLT(dwFlags);
1203 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1204 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1206 return DD_OK;
1209 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1210 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1212 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1213 int bpp, w, h, x, y;
1214 DDSURFACEDESC ddesc,sdesc;
1215 HRESULT ret = DD_OK;
1216 LPBYTE sbuf, dbuf;
1219 if (TRACE_ON(ddraw)) {
1220 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1221 This,dstx,dsty,src,rsrc,trans
1223 FIXME(" trans:");
1224 if (FIXME_ON(ddraw))
1225 _dump_DDBLTFAST(trans);
1226 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1228 /* We need to lock the surfaces, or we won't get refreshes when done. */
1229 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1230 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1232 bpp = GET_BPP(This->s.surface_desc);
1233 sbuf = (BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1234 dbuf = (BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1237 h=rsrc->bottom-rsrc->top;
1238 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1239 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1240 if (h<0) h=0;
1242 w=rsrc->right-rsrc->left;
1243 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1244 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1245 if (w<0) w=0;
1247 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1248 DWORD keylow, keyhigh;
1249 if (trans & DDBLTFAST_SRCCOLORKEY) {
1250 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1251 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1252 } else {
1253 /* I'm not sure if this is correct */
1254 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1255 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1256 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1259 #define COPYBOX_COLORKEY(type) { \
1260 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1261 s = (type *) ((BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1262 d = (type *) ((BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1263 for (y = 0; y < h; y++) { \
1264 for (x = 0; x < w; x++) { \
1265 tmp = s[x]; \
1266 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1268 (LPBYTE)s += sdesc.lPitch; \
1269 (LPBYTE)d += ddesc.lPitch; \
1271 break; \
1274 switch (bpp) {
1275 case 1: COPYBOX_COLORKEY(BYTE)
1276 case 2: COPYBOX_COLORKEY(WORD)
1277 case 4: COPYBOX_COLORKEY(DWORD)
1278 default:
1279 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1280 ret = DDERR_UNSUPPORTED;
1281 goto error;
1284 #undef COPYBOX_COLORKEY
1286 } else {
1287 int width = w * bpp;
1289 for (y = 0; y < h; y++) {
1290 memcpy(dbuf, sbuf, width);
1291 sbuf += sdesc.lPitch;
1292 dbuf += ddesc.lPitch;
1296 error:
1298 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1299 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1300 return ret;
1303 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1304 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1306 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1307 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1308 This,ddbltbatch,x,y
1310 return DD_OK;
1313 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1314 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1316 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1317 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1318 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1319 return DD_OK;
1322 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1323 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1324 ) {
1325 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1326 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1328 /* Simply copy the surface description stored in the object */
1329 *ddsd = This->s.surface_desc;
1331 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1333 return DD_OK;
1336 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1337 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1338 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1339 return ++(This->ref);
1342 #ifdef HAVE_LIBXXF86DGA
1343 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1344 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1346 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1348 if (--(This->ref))
1349 return This->ref;
1351 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1352 /* clear out of surface list */
1353 if (This->t.dga.fb_height == -1)
1354 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1355 else
1356 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1358 /* Free the DIBSection (if any) */
1359 if (This->s.hdc != 0) {
1360 SelectObject(This->s.hdc, This->s.holdbitmap);
1361 DeleteDC(This->s.hdc);
1362 DeleteObject(This->s.DIBsection);
1365 HeapFree(GetProcessHeap(),0,This);
1366 return 0;
1368 #endif /* defined(HAVE_LIBXXF86DGA) */
1370 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1371 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1373 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1375 if (--(This->ref))
1376 return This->ref;
1378 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1380 if (This->t.xlib.image != NULL) {
1381 if (This->s.ddraw->d.pixel_convert != NULL) {
1382 /* In pixel conversion mode, there are 2 buffers to release. */
1383 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1385 #ifdef HAVE_LIBXXSHM
1386 if (This->s.ddraw->e.xlib.xshm_active) {
1387 TSXShmDetach(display, &(This->t.xlib.shminfo));
1388 TSXDestroyImage(This->t.xlib.image);
1389 shmdt(This->t.xlib.shminfo.shmaddr);
1390 } else {
1391 #endif
1392 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1393 This->t.xlib.image->data = NULL;
1394 TSXDestroyImage(This->t.xlib.image);
1395 #ifdef HAVE_LIBXXSHM
1397 #endif
1398 } else {
1399 This->t.xlib.image->data = NULL;
1401 #ifdef HAVE_LIBXXSHM
1402 if (This->s.ddraw->e.xlib.xshm_active) {
1403 TSXShmDetach(display, &(This->t.xlib.shminfo));
1404 TSXDestroyImage(This->t.xlib.image);
1405 shmdt(This->t.xlib.shminfo.shmaddr);
1406 } else {
1407 #endif
1408 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1409 TSXDestroyImage(This->t.xlib.image);
1410 #ifdef HAVE_LIBXXSHM
1412 #endif
1414 This->t.xlib.image = 0;
1415 } else {
1416 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1419 if (This->s.palette)
1420 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1422 /* Free the DIBSection (if any) */
1423 if (This->s.hdc != 0) {
1424 SelectObject(This->s.hdc, This->s.holdbitmap);
1425 DeleteDC(This->s.hdc);
1426 DeleteObject(This->s.DIBsection);
1429 HeapFree(GetProcessHeap(),0,This);
1430 return 0;
1433 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1434 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1436 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1437 int i,found = 0,xstart;
1438 struct _surface_chain *chain;
1440 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1441 if (TRACE_ON(ddraw)) {
1442 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1444 chain = This->s.chain;
1445 if (!chain)
1446 return DDERR_NOTFOUND;
1448 for (i=0;i<chain->nrofsurfaces;i++)
1449 if (chain->surfaces[i] == This)
1450 break;
1452 xstart = i;
1453 for (i=0;i<chain->nrofsurfaces;i++) {
1454 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1455 #if 0
1456 if (found) /* may not find the same caps twice, (doc) */
1457 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1458 #endif
1459 found = (i+1)+xstart;
1462 if (!found)
1463 return DDERR_NOTFOUND;
1464 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1465 /* FIXME: AddRef? */
1466 TRACE("found %p\n",*lpdsf);
1467 return DD_OK;
1470 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1471 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1473 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1474 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1476 return DDERR_ALREADYINITIALIZED;
1479 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1480 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1482 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1483 TRACE("(%p)->(%p)\n",This,pf);
1485 *pf = This->s.surface_desc.ddpfPixelFormat;
1486 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1487 return DD_OK;
1490 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1491 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1492 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1493 return DD_OK;
1496 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1497 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1499 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1500 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1501 return DD_OK;
1504 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1505 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1507 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1508 FIXME("(%p)->(%p),stub!\n",This,clipper);
1509 return DD_OK;
1512 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1513 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1515 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1516 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1517 int i;
1518 struct _surface_chain *chain;
1520 IDirectDrawSurface4_AddRef(iface);
1522 FIXME("(%p)->(%p)\n",This,surf);
1523 chain = This->s.chain;
1525 if (chain) {
1526 for (i=0;i<chain->nrofsurfaces;i++)
1527 if (chain->surfaces[i] == isurf)
1528 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1529 } else {
1530 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1531 chain->nrofsurfaces = 1;
1532 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1533 chain->surfaces[0] = This;
1534 This->s.chain = chain;
1537 if (chain->surfaces)
1538 chain->surfaces = HeapReAlloc(
1539 GetProcessHeap(),
1541 chain->surfaces,
1542 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1544 else
1545 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1546 isurf->s.chain = chain;
1547 chain->surfaces[chain->nrofsurfaces++] = isurf;
1548 return DD_OK;
1551 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1552 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1553 DDSURFACEDESC desc;
1554 BITMAPINFO *b_info;
1555 UINT usage;
1557 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1559 /* Creates a DIB Section of the same size / format as the surface */
1560 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1562 if (This->s.hdc == 0) {
1563 switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
1564 case 16:
1565 case 32:
1566 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1567 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1568 break;
1569 #endif
1571 case 24:
1572 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1573 break;
1575 default:
1576 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1577 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.x.dwRGBBitCount));
1578 break;
1581 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1582 b_info->bmiHeader.biWidth = desc.dwWidth;
1583 b_info->bmiHeader.biHeight = desc.dwHeight;
1584 b_info->bmiHeader.biPlanes = 1;
1585 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.x.dwRGBBitCount;
1586 #if 0
1587 if ((desc.ddpfPixelFormat.x.dwRGBBitCount != 16) &&
1588 (desc.ddpfPixelFormat.x.dwRGBBitCount != 32))
1589 #endif
1590 b_info->bmiHeader.biCompression = BI_RGB;
1591 #if 0
1592 else
1593 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1594 #endif
1595 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.x.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1596 b_info->bmiHeader.biXPelsPerMeter = 0;
1597 b_info->bmiHeader.biYPelsPerMeter = 0;
1598 b_info->bmiHeader.biClrUsed = 0;
1599 b_info->bmiHeader.biClrImportant = 0;
1601 switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
1602 case 16:
1603 case 32:
1604 #if 0
1606 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1608 usage = 0;
1609 masks[0] = desc.ddpfPixelFormat.y.dwRBitMask;
1610 masks[1] = desc.ddpfPixelFormat.z.dwGBitMask;
1611 masks[2] = desc.ddpfPixelFormat.xx.dwBBitMask;
1613 break;
1614 #endif
1615 case 24:
1616 /* Nothing to do */
1617 usage = DIB_RGB_COLORS;
1618 break;
1620 default: {
1621 int i;
1623 /* Fill the palette */
1624 usage = DIB_RGB_COLORS;
1626 if (This->s.palette == NULL) {
1627 ERR("Bad palette !!!\n");
1628 } else {
1629 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1630 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1632 for (i=0;i<(1<<desc.ddpfPixelFormat.x.dwRGBBitCount);i++) {
1633 rgb[i].rgbBlue = pent[i].peBlue;
1634 rgb[i].rgbRed = pent[i].peRed;
1635 rgb[i].rgbGreen = pent[i].peGreen;
1639 break;
1641 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1642 b_info,
1643 usage,
1644 &(This->s.bitmap_data),
1648 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1649 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1651 /* b_info is not useful anymore */
1652 HeapFree(GetProcessHeap(), 0, b_info);
1654 /* Create the DC */
1655 This->s.hdc = CreateCompatibleDC(0);
1656 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1659 /* Copy our surface in the DIB section */
1660 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1661 memcpy(This->s.bitmap_data,desc.y.lpSurface,desc.lPitch*desc.dwHeight);
1662 else
1663 /* TODO */
1664 FIXME("This case has to be done :/\n");
1666 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1667 *lphdc = This->s.hdc;
1669 return DD_OK;
1672 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1673 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1675 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1676 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1677 /* Copy the DIB section to our surface */
1678 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1679 memcpy(This->s.surface_desc.y.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1680 } else {
1681 /* TODO */
1682 FIXME("This case has to be done :/\n");
1684 /* Unlock the surface */
1685 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.y.lpSurface);
1686 return DD_OK;
1689 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1690 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1691 char xrefiid[50];
1693 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1694 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
1696 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1697 * the same interface. And IUnknown does that too of course.
1699 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1700 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1701 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1702 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1703 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1705 *obj = This;
1706 IDirectDrawSurface4_AddRef(iface);
1708 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1709 return S_OK;
1711 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1713 /* Texture interface */
1714 *obj = d3dtexture2_create(This);
1715 IDirectDrawSurface4_AddRef(iface);
1716 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1717 return S_OK;
1719 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1721 /* Texture interface */
1722 *obj = d3dtexture_create(This);
1723 IDirectDrawSurface4_AddRef(iface);
1725 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1727 return S_OK;
1729 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1730 /* It is the OpenGL Direct3D Device */
1731 IDirectDrawSurface4_AddRef(iface);
1732 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1733 return S_OK;
1736 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
1737 return OLE_E_ENUM_NOMORE;
1740 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1741 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1742 TRACE("(%p)->(), stub!\n",This);
1743 return DD_OK; /* hmm */
1746 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1747 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1748 int i;
1749 struct _surface_chain *chain = This->s.chain;
1751 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1752 for (i=0;i<chain->nrofsurfaces;i++) {
1753 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1754 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1755 return DD_OK; /* FIXME: return value correct? */
1757 return DD_OK;
1760 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1761 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1762 FIXME("(%p)->(),stub!\n",This);
1763 return DD_OK;
1766 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1767 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1769 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1770 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1771 if (TRACE_ON(ddraw)) {
1772 _dump_colorkeyflag(dwFlags);
1773 DPRINTF(" : ");
1774 _dump_DDCOLORKEY((void *) ckey);
1775 DPRINTF("\n");
1778 /* If this surface was loaded as a texture, call also the texture
1779 SetColorKey callback */
1780 if (This->s.texture) {
1781 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1784 if( dwFlags & DDCKEY_SRCBLT )
1786 dwFlags &= ~DDCKEY_SRCBLT;
1787 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1788 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1791 if( dwFlags & DDCKEY_DESTBLT )
1793 dwFlags &= ~DDCKEY_DESTBLT;
1794 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1795 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1798 if( dwFlags & DDCKEY_SRCOVERLAY )
1800 dwFlags &= ~DDCKEY_SRCOVERLAY;
1801 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1802 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1805 if( dwFlags & DDCKEY_DESTOVERLAY )
1807 dwFlags &= ~DDCKEY_DESTOVERLAY;
1808 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1809 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1812 if( dwFlags )
1814 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1817 return DD_OK;
1821 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1822 LPDIRECTDRAWSURFACE4 iface,
1823 LPRECT lpRect )
1825 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1826 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1828 return DD_OK;
1831 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1832 LPDIRECTDRAWSURFACE4 iface,
1833 DWORD dwFlags,
1834 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1836 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1837 int i;
1838 struct _surface_chain *chain;
1840 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
1841 chain = This->s.chain;
1842 for (i=0;i<chain->nrofsurfaces;i++) {
1843 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
1844 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
1846 chain->surfaces[i]->s.chain = NULL;
1847 memcpy( chain->surfaces+i,
1848 chain->surfaces+(i+1),
1849 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
1851 chain->surfaces = HeapReAlloc(
1852 GetProcessHeap(),
1854 chain->surfaces,
1855 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
1857 chain->nrofsurfaces--;
1858 return DD_OK;
1861 return DD_OK;
1864 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1865 LPDIRECTDRAWSURFACE4 iface,
1866 DWORD dwFlags,
1867 LPVOID lpContext,
1868 LPDDENUMSURFACESCALLBACK lpfnCallback )
1870 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1871 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1872 lpContext, lpfnCallback );
1874 return DD_OK;
1877 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1878 LPDIRECTDRAWSURFACE4 iface,
1879 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1881 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1882 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
1884 return DD_OK;
1887 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1888 LPDIRECTDRAWSURFACE4 iface,
1889 DWORD dwFlags,
1890 LPDDCOLORKEY lpDDColorKey )
1892 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1893 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1895 if( dwFlags & DDCKEY_SRCBLT ) {
1896 dwFlags &= ~DDCKEY_SRCBLT;
1897 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1900 if( dwFlags & DDCKEY_DESTBLT )
1902 dwFlags &= ~DDCKEY_DESTBLT;
1903 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1906 if( dwFlags & DDCKEY_SRCOVERLAY )
1908 dwFlags &= ~DDCKEY_SRCOVERLAY;
1909 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1912 if( dwFlags & DDCKEY_DESTOVERLAY )
1914 dwFlags &= ~DDCKEY_DESTOVERLAY;
1915 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1918 if( dwFlags )
1920 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1923 return DD_OK;
1926 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1927 LPDIRECTDRAWSURFACE4 iface,
1928 DWORD dwFlags )
1930 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1931 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1933 return DD_OK;
1936 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1937 LPDIRECTDRAWSURFACE4 iface,
1938 LPDIRECTDRAWPALETTE* lplpDDPalette )
1940 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1941 FIXME("(%p)->(%p),stub!\n", This, lplpDDPalette);
1943 return DD_OK;
1946 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1947 LPDIRECTDRAWSURFACE4 iface,
1948 LONG lX,
1949 LONG lY)
1951 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1952 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1954 return DD_OK;
1957 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1958 LPDIRECTDRAWSURFACE4 iface,
1959 LPRECT lpSrcRect,
1960 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1961 LPRECT lpDestRect,
1962 DWORD dwFlags,
1963 LPDDOVERLAYFX lpDDOverlayFx )
1965 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1966 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1967 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1969 return DD_OK;
1972 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1973 LPDIRECTDRAWSURFACE4 iface,
1974 DWORD dwFlags )
1976 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1977 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1979 return DD_OK;
1982 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1983 LPDIRECTDRAWSURFACE4 iface,
1984 DWORD dwFlags,
1985 LPDIRECTDRAWSURFACE4 lpDDSReference )
1987 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1988 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1990 return DD_OK;
1993 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1994 LPDIRECTDRAWSURFACE4 iface,
1995 LPVOID* lplpDD )
1997 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1998 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2000 /* Not sure about that... */
2001 *lplpDD = (void *) This->s.ddraw;
2003 return DD_OK;
2006 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2007 LPDIRECTDRAWSURFACE4 iface,
2008 DWORD dwFlags )
2010 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2011 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2013 return DD_OK;
2016 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2017 LPDIRECTDRAWSURFACE4 iface,
2018 DWORD dwFlags )
2020 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2021 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2023 return DD_OK;
2026 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2027 LPDIRECTDRAWSURFACE4 iface,
2028 LPDDSURFACEDESC lpDDSD,
2029 DWORD dwFlags )
2031 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2032 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2034 return DD_OK;
2037 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2038 REFGUID guidTag,
2039 LPVOID lpData,
2040 DWORD cbSize,
2041 DWORD dwFlags) {
2042 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2043 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2045 return DD_OK;
2048 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2049 REFGUID guidTag,
2050 LPVOID lpBuffer,
2051 LPDWORD lpcbBufferSize) {
2052 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2053 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2055 return DD_OK;
2058 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2059 REFGUID guidTag) {
2060 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2061 FIXME("(%p)->(%p)\n", This, guidTag);
2063 return DD_OK;
2066 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2067 LPDWORD lpValue) {
2068 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2069 FIXME("(%p)->(%p)\n", This, lpValue);
2071 return DD_OK;
2074 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2075 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2076 FIXME("(%p)\n", This);
2078 return DD_OK;
2081 #ifdef HAVE_LIBXXF86DGA
2082 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2084 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2085 IDirectDrawSurface4Impl_QueryInterface,
2086 IDirectDrawSurface4Impl_AddRef,
2087 DGA_IDirectDrawSurface4Impl_Release,
2088 IDirectDrawSurface4Impl_AddAttachedSurface,
2089 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2090 IDirectDrawSurface4Impl_Blt,
2091 IDirectDrawSurface4Impl_BltBatch,
2092 IDirectDrawSurface4Impl_BltFast,
2093 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2094 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2095 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2096 DGA_IDirectDrawSurface4Impl_Flip,
2097 IDirectDrawSurface4Impl_GetAttachedSurface,
2098 IDirectDrawSurface4Impl_GetBltStatus,
2099 IDirectDrawSurface4Impl_GetCaps,
2100 IDirectDrawSurface4Impl_GetClipper,
2101 IDirectDrawSurface4Impl_GetColorKey,
2102 IDirectDrawSurface4Impl_GetDC,
2103 IDirectDrawSurface4Impl_GetFlipStatus,
2104 IDirectDrawSurface4Impl_GetOverlayPosition,
2105 IDirectDrawSurface4Impl_GetPalette,
2106 IDirectDrawSurface4Impl_GetPixelFormat,
2107 IDirectDrawSurface4Impl_GetSurfaceDesc,
2108 IDirectDrawSurface4Impl_Initialize,
2109 IDirectDrawSurface4Impl_IsLost,
2110 IDirectDrawSurface4Impl_Lock,
2111 IDirectDrawSurface4Impl_ReleaseDC,
2112 IDirectDrawSurface4Impl_Restore,
2113 IDirectDrawSurface4Impl_SetClipper,
2114 IDirectDrawSurface4Impl_SetColorKey,
2115 IDirectDrawSurface4Impl_SetOverlayPosition,
2116 DGA_IDirectDrawSurface4Impl_SetPalette,
2117 DGA_IDirectDrawSurface4Impl_Unlock,
2118 IDirectDrawSurface4Impl_UpdateOverlay,
2119 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2120 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2121 IDirectDrawSurface4Impl_GetDDInterface,
2122 IDirectDrawSurface4Impl_PageLock,
2123 IDirectDrawSurface4Impl_PageUnlock,
2124 IDirectDrawSurface4Impl_SetSurfaceDesc,
2125 IDirectDrawSurface4Impl_SetPrivateData,
2126 IDirectDrawSurface4Impl_GetPrivateData,
2127 IDirectDrawSurface4Impl_FreePrivateData,
2128 IDirectDrawSurface4Impl_GetUniquenessValue,
2129 IDirectDrawSurface4Impl_ChangeUniquenessValue
2131 #endif /* defined(HAVE_LIBXXF86DGA) */
2133 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2135 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2136 IDirectDrawSurface4Impl_QueryInterface,
2137 IDirectDrawSurface4Impl_AddRef,
2138 Xlib_IDirectDrawSurface4Impl_Release,
2139 IDirectDrawSurface4Impl_AddAttachedSurface,
2140 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2141 IDirectDrawSurface4Impl_Blt,
2142 IDirectDrawSurface4Impl_BltBatch,
2143 IDirectDrawSurface4Impl_BltFast,
2144 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2145 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2146 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2147 Xlib_IDirectDrawSurface4Impl_Flip,
2148 IDirectDrawSurface4Impl_GetAttachedSurface,
2149 IDirectDrawSurface4Impl_GetBltStatus,
2150 IDirectDrawSurface4Impl_GetCaps,
2151 IDirectDrawSurface4Impl_GetClipper,
2152 IDirectDrawSurface4Impl_GetColorKey,
2153 IDirectDrawSurface4Impl_GetDC,
2154 IDirectDrawSurface4Impl_GetFlipStatus,
2155 IDirectDrawSurface4Impl_GetOverlayPosition,
2156 IDirectDrawSurface4Impl_GetPalette,
2157 IDirectDrawSurface4Impl_GetPixelFormat,
2158 IDirectDrawSurface4Impl_GetSurfaceDesc,
2159 IDirectDrawSurface4Impl_Initialize,
2160 IDirectDrawSurface4Impl_IsLost,
2161 IDirectDrawSurface4Impl_Lock,
2162 IDirectDrawSurface4Impl_ReleaseDC,
2163 IDirectDrawSurface4Impl_Restore,
2164 IDirectDrawSurface4Impl_SetClipper,
2165 IDirectDrawSurface4Impl_SetColorKey,
2166 IDirectDrawSurface4Impl_SetOverlayPosition,
2167 Xlib_IDirectDrawSurface4Impl_SetPalette,
2168 Xlib_IDirectDrawSurface4Impl_Unlock,
2169 IDirectDrawSurface4Impl_UpdateOverlay,
2170 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2171 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2172 IDirectDrawSurface4Impl_GetDDInterface,
2173 IDirectDrawSurface4Impl_PageLock,
2174 IDirectDrawSurface4Impl_PageUnlock,
2175 IDirectDrawSurface4Impl_SetSurfaceDesc,
2176 IDirectDrawSurface4Impl_SetPrivateData,
2177 IDirectDrawSurface4Impl_GetPrivateData,
2178 IDirectDrawSurface4Impl_FreePrivateData,
2179 IDirectDrawSurface4Impl_GetUniquenessValue,
2180 IDirectDrawSurface4Impl_ChangeUniquenessValue
2183 /******************************************************************************
2184 * DirectDrawCreateClipper (DDRAW.7)
2186 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2187 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2188 LPUNKNOWN pUnkOuter)
2190 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2191 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2193 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2194 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
2195 (*ilplpDDClipper)->ref = 1;
2197 return DD_OK;
2200 /******************************************************************************
2201 * IDirectDrawClipper
2203 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2204 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
2206 ICOM_THIS(IDirectDrawClipperImpl,iface);
2207 FIXME("(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
2208 return DD_OK;
2211 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2212 ICOM_THIS(IDirectDrawClipperImpl,iface);
2213 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2215 This->ref--;
2216 if (This->ref)
2217 return This->ref;
2218 HeapFree(GetProcessHeap(),0,This);
2219 return 0;
2222 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2223 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2225 ICOM_THIS(IDirectDrawClipperImpl,iface);
2226 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2227 if (hmm) *hmm=0;
2228 return DD_OK;
2231 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2232 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2234 ICOM_THIS(IDirectDrawClipperImpl,iface);
2235 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2236 return DD_OK;
2239 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2240 LPDIRECTDRAWCLIPPER iface,
2241 REFIID riid,
2242 LPVOID* ppvObj )
2244 ICOM_THIS(IDirectDrawClipperImpl,iface);
2245 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2246 return OLE_E_ENUM_NOMORE;
2249 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2251 ICOM_THIS(IDirectDrawClipperImpl,iface);
2252 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2253 return ++(This->ref);
2256 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2257 LPDIRECTDRAWCLIPPER iface,
2258 HWND* HWndPtr )
2260 ICOM_THIS(IDirectDrawClipperImpl,iface);
2261 FIXME("(%p)->(%p),stub!\n",This,HWndPtr);
2262 return DD_OK;
2265 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2266 LPDIRECTDRAWCLIPPER iface,
2267 LPDIRECTDRAW lpDD,
2268 DWORD dwFlags )
2270 ICOM_THIS(IDirectDrawClipperImpl,iface);
2271 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2272 return DD_OK;
2275 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2276 LPDIRECTDRAWCLIPPER iface,
2277 BOOL* lpbChanged )
2279 ICOM_THIS(IDirectDrawClipperImpl,iface);
2280 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2281 return DD_OK;
2284 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2286 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2287 IDirectDrawClipperImpl_QueryInterface,
2288 IDirectDrawClipperImpl_AddRef,
2289 IDirectDrawClipperImpl_Release,
2290 IDirectDrawClipperImpl_GetClipList,
2291 IDirectDrawClipperImpl_GetHWnd,
2292 IDirectDrawClipperImpl_Initialize,
2293 IDirectDrawClipperImpl_IsClipListChanged,
2294 IDirectDrawClipperImpl_SetClipList,
2295 IDirectDrawClipperImpl_SetHwnd
2299 /******************************************************************************
2300 * IDirectDrawPalette
2302 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2303 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2305 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2306 int i;
2308 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2309 This,x,start,count,palent);
2311 /* No palette created and not in depth-convertion mode -> BUG ! */
2312 if ((This->cm == None) &&
2313 (This->ddraw->d.palette_convert == NULL))
2315 FIXME("app tried to read colormap for non-palettized mode\n");
2316 return DDERR_GENERIC;
2318 for (i=0;i<count;i++) {
2319 palent[i].peRed = This->palents[start+i].peRed;
2320 palent[i].peBlue = This->palents[start+i].peBlue;
2321 palent[i].peGreen = This->palents[start+i].peGreen;
2322 palent[i].peFlags = This->palents[start+i].peFlags;
2325 return DD_OK;
2328 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2329 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2331 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2332 XColor xc;
2333 int i;
2335 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2336 This,x,start,count,palent
2338 for (i=0;i<count;i++) {
2339 xc.red = palent[i].peRed<<8;
2340 xc.blue = palent[i].peBlue<<8;
2341 xc.green = palent[i].peGreen<<8;
2342 xc.flags = DoRed|DoBlue|DoGreen;
2343 xc.pixel = start+i;
2345 if (This->cm)
2346 TSXStoreColor(display,This->cm,&xc);
2348 This->palents[start+i].peRed = palent[i].peRed;
2349 This->palents[start+i].peBlue = palent[i].peBlue;
2350 This->palents[start+i].peGreen = palent[i].peGreen;
2351 This->palents[start+i].peFlags = palent[i].peFlags;
2354 /* Now, if we are in 'depth conversion mode', update the screen palette */
2355 /* FIXME: we need to update the image or we won't get palette fading. */
2356 if (This->ddraw->d.palette_convert != NULL)
2357 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2359 return DD_OK;
2362 #ifdef HAVE_LIBXXF86DGA
2363 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2364 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2366 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2367 XColor xc;
2368 Colormap cm;
2369 int i;
2371 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2372 This,x,start,count,palent
2374 if (!This->cm) /* should not happen */ {
2375 FIXME("app tried to set colormap in non-palettized mode\n");
2376 return DDERR_GENERIC;
2378 /* FIXME: free colorcells instead of freeing whole map */
2379 cm = This->cm;
2380 This->cm = TSXCopyColormapAndFree(display,This->cm);
2381 TSXFreeColormap(display,cm);
2383 for (i=0;i<count;i++) {
2384 xc.red = palent[i].peRed<<8;
2385 xc.blue = palent[i].peBlue<<8;
2386 xc.green = palent[i].peGreen<<8;
2387 xc.flags = DoRed|DoBlue|DoGreen;
2388 xc.pixel = i+start;
2390 TSXStoreColor(display,This->cm,&xc);
2392 This->palents[start+i].peRed = palent[i].peRed;
2393 This->palents[start+i].peBlue = palent[i].peBlue;
2394 This->palents[start+i].peGreen = palent[i].peGreen;
2395 This->palents[start+i].peFlags = palent[i].peFlags;
2397 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2398 return DD_OK;
2400 #endif /* defined(HAVE_LIBXXF86DGA) */
2402 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2403 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2404 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2405 if (!--(This->ref)) {
2406 if (This->cm) {
2407 TSXFreeColormap(display,This->cm);
2408 This->cm = 0;
2410 HeapFree(GetProcessHeap(),0,This);
2411 return 0;
2413 return This->ref;
2416 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2417 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2419 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2420 return ++(This->ref);
2423 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2424 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2426 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2427 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2429 return DDERR_ALREADYINITIALIZED;
2432 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2433 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2435 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2436 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2437 return DD_OK;
2440 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2441 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2443 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2444 char xrefiid[50];
2446 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2447 FIXME("(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2449 return S_OK;
2452 #ifdef HAVE_LIBXXF86DGA
2453 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2455 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2456 IDirectDrawPaletteImpl_QueryInterface,
2457 IDirectDrawPaletteImpl_AddRef,
2458 IDirectDrawPaletteImpl_Release,
2459 IDirectDrawPaletteImpl_GetCaps,
2460 IDirectDrawPaletteImpl_GetEntries,
2461 IDirectDrawPaletteImpl_Initialize,
2462 DGA_IDirectDrawPaletteImpl_SetEntries
2464 #endif /* defined(HAVE_LIBXXF86DGA) */
2466 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2468 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2469 IDirectDrawPaletteImpl_QueryInterface,
2470 IDirectDrawPaletteImpl_AddRef,
2471 IDirectDrawPaletteImpl_Release,
2472 IDirectDrawPaletteImpl_GetCaps,
2473 IDirectDrawPaletteImpl_GetEntries,
2474 IDirectDrawPaletteImpl_Initialize,
2475 Xlib_IDirectDrawPaletteImpl_SetEntries
2478 /*******************************************************************************
2479 * IDirect3D
2481 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2482 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2484 ICOM_THIS(IDirect3DImpl,iface);
2485 /* FIXME: Not sure if this is correct */
2486 char xrefiid[50];
2488 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2489 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2490 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2491 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2492 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2493 *obj = This->ddraw;
2494 IDirect3D_AddRef(iface);
2496 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2498 return S_OK;
2500 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2501 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2502 *obj = This;
2503 IDirect3D_AddRef(iface);
2505 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2507 return S_OK;
2509 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2510 IDirect3D2Impl* d3d;
2512 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2513 d3d->ref = 1;
2514 d3d->ddraw = This->ddraw;
2515 IDirect3D_AddRef(iface);
2516 d3d->lpvtbl = &d3d2vt;
2517 *obj = d3d;
2519 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2521 return S_OK;
2523 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2524 return OLE_E_ENUM_NOMORE;
2527 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2528 ICOM_THIS(IDirect3DImpl,iface);
2529 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2531 return ++(This->ref);
2534 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2536 ICOM_THIS(IDirect3DImpl,iface);
2537 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2539 if (!--(This->ref)) {
2540 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2541 HeapFree(GetProcessHeap(),0,This);
2542 return 0;
2544 return This->ref;
2547 static HRESULT WINAPI IDirect3DImpl_Initialize(
2548 LPDIRECT3D iface, REFIID refiid )
2550 ICOM_THIS(IDirect3DImpl,iface);
2551 /* FIXME: Not sure if this is correct */
2552 char xrefiid[50];
2554 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2555 FIXME("(%p)->(%s):stub.\n",This,xrefiid);
2557 return DDERR_ALREADYINITIALIZED;
2560 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2561 LPD3DENUMDEVICESCALLBACK cb,
2562 LPVOID context) {
2563 ICOM_THIS(IDirect3DImpl,iface);
2564 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2566 /* Call functions defined in d3ddevices.c */
2567 if (!d3d_OpenGL_dx3(cb, context))
2568 return DD_OK;
2570 return DD_OK;
2573 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2574 LPDIRECT3DLIGHT *lplight,
2575 IUnknown *lpunk)
2577 ICOM_THIS(IDirect3DImpl,iface);
2578 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2580 /* Call the creation function that is located in d3dlight.c */
2581 *lplight = d3dlight_create_dx3(This);
2583 return DD_OK;
2586 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2587 LPDIRECT3DMATERIAL *lpmaterial,
2588 IUnknown *lpunk)
2590 ICOM_THIS(IDirect3DImpl,iface);
2591 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2593 /* Call the creation function that is located in d3dviewport.c */
2594 *lpmaterial = d3dmaterial_create(This);
2596 return DD_OK;
2599 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2600 LPDIRECT3DVIEWPORT *lpviewport,
2601 IUnknown *lpunk)
2603 ICOM_THIS(IDirect3DImpl,iface);
2604 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2606 /* Call the creation function that is located in d3dviewport.c */
2607 *lpviewport = d3dviewport_create(This);
2609 return DD_OK;
2612 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2613 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2614 LPD3DFINDDEVICERESULT lpfinddevrst)
2616 ICOM_THIS(IDirect3DImpl,iface);
2617 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2619 return DD_OK;
2622 static ICOM_VTABLE(IDirect3D) d3dvt =
2624 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2625 IDirect3DImpl_QueryInterface,
2626 IDirect3DImpl_AddRef,
2627 IDirect3DImpl_Release,
2628 IDirect3DImpl_Initialize,
2629 IDirect3DImpl_EnumDevices,
2630 IDirect3DImpl_CreateLight,
2631 IDirect3DImpl_CreateMaterial,
2632 IDirect3DImpl_CreateViewport,
2633 IDirect3DImpl_FindDevice
2636 /*******************************************************************************
2637 * IDirect3D2
2639 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2640 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2641 ICOM_THIS(IDirect3D2Impl,iface);
2643 /* FIXME: Not sure if this is correct */
2644 char xrefiid[50];
2646 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2647 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2648 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2649 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2650 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2651 *obj = This->ddraw;
2652 IDirect3D2_AddRef(iface);
2654 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2656 return S_OK;
2658 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2659 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2660 *obj = This;
2661 IDirect3D2_AddRef(iface);
2663 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2665 return S_OK;
2667 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2668 IDirect3DImpl* d3d;
2670 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2671 d3d->ref = 1;
2672 d3d->ddraw = This->ddraw;
2673 IDirect3D2_AddRef(iface);
2674 d3d->lpvtbl = &d3dvt;
2675 *obj = d3d;
2677 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2679 return S_OK;
2681 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2682 return OLE_E_ENUM_NOMORE;
2685 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2686 ICOM_THIS(IDirect3D2Impl,iface);
2687 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2689 return ++(This->ref);
2692 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2693 ICOM_THIS(IDirect3D2Impl,iface);
2694 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2696 if (!--(This->ref)) {
2697 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2698 HeapFree(GetProcessHeap(),0,This);
2699 return 0;
2701 return This->ref;
2704 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2705 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2707 ICOM_THIS(IDirect3D2Impl,iface);
2708 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2710 /* Call functions defined in d3ddevices.c */
2711 if (!d3d_OpenGL(cb, context))
2712 return DD_OK;
2714 return DD_OK;
2717 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2718 LPDIRECT3DLIGHT *lplight,
2719 IUnknown *lpunk)
2721 ICOM_THIS(IDirect3D2Impl,iface);
2722 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2724 /* Call the creation function that is located in d3dlight.c */
2725 *lplight = d3dlight_create(This);
2727 return DD_OK;
2730 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2731 LPDIRECT3DMATERIAL2 *lpmaterial,
2732 IUnknown *lpunk)
2734 ICOM_THIS(IDirect3D2Impl,iface);
2735 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2737 /* Call the creation function that is located in d3dviewport.c */
2738 *lpmaterial = d3dmaterial2_create(This);
2740 return DD_OK;
2743 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2744 LPDIRECT3DVIEWPORT2 *lpviewport,
2745 IUnknown *lpunk)
2747 ICOM_THIS(IDirect3D2Impl,iface);
2748 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2750 /* Call the creation function that is located in d3dviewport.c */
2751 *lpviewport = d3dviewport2_create(This);
2753 return DD_OK;
2756 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2757 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2758 LPD3DFINDDEVICERESULT lpfinddevrst)
2760 ICOM_THIS(IDirect3D2Impl,iface);
2761 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2763 return DD_OK;
2766 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2767 REFCLSID rguid,
2768 LPDIRECTDRAWSURFACE surface,
2769 LPDIRECT3DDEVICE2 *device)
2771 ICOM_THIS(IDirect3D2Impl,iface);
2772 char xbuf[50];
2774 WINE_StringFromCLSID(rguid,xbuf);
2775 FIXME("(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2777 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2778 IDirect3D2_AddRef(iface);
2779 return DD_OK;
2782 return DDERR_INVALIDPARAMS;
2785 static ICOM_VTABLE(IDirect3D2) d3d2vt =
2787 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2788 IDirect3D2Impl_QueryInterface,
2789 IDirect3D2Impl_AddRef,
2790 IDirect3D2Impl_Release,
2791 IDirect3D2Impl_EnumDevices,
2792 IDirect3D2Impl_CreateLight,
2793 IDirect3D2Impl_CreateMaterial,
2794 IDirect3D2Impl_CreateViewport,
2795 IDirect3D2Impl_FindDevice,
2796 IDirect3D2Impl_CreateDevice
2799 /*******************************************************************************
2800 * IDirectDraw
2803 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2804 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2806 static INT ddrawXlibThisOffset = 0;
2808 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2809 IDirectDrawSurfaceImpl* lpdsf)
2811 int bpp;
2813 /* The surface was already allocated when entering in this function */
2814 TRACE("using system memory for a surface (%p) \n", lpdsf);
2816 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
2817 /* This is a Z Buffer */
2818 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.x.dwZBufferBitDepth);
2819 bpp = lpdsf->s.surface_desc.x.dwZBufferBitDepth / 8;
2820 } else {
2821 /* This is a standard image */
2822 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
2823 /* No pixel format => use DirectDraw's format */
2824 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2825 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
2828 bpp = GET_BPP(lpdsf->s.surface_desc);
2831 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
2832 /* The surface was preallocated : seems that we have nothing to do :-) */
2833 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
2836 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
2837 lpdsf->s.surface_desc.y.lpSurface =
2838 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
2839 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
2841 return DD_OK;
2844 #ifdef HAVE_LIBXXF86DGA
2845 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2846 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2848 ICOM_THIS(IDirectDraw2Impl,iface);
2849 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2850 int i, fbheight = This->e.dga.fb_height;
2852 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2853 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
2855 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
2856 GetProcessHeap(),
2857 HEAP_ZERO_MEMORY,
2858 sizeof(IDirectDrawSurfaceImpl)
2860 IDirectDraw2_AddRef(iface);
2862 (*ilpdsf)->ref = 1;
2863 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2864 (*ilpdsf)->s.ddraw = This;
2865 (*ilpdsf)->s.palette = NULL;
2866 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2868 /* Copy the surface description */
2869 (*ilpdsf)->s.surface_desc = *lpddsd;
2871 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2872 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2873 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2874 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2876 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
2878 /* Check if this a 'primary surface' or not */
2879 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2880 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2881 /* This is THE primary surface => there is DGA-specific code */
2883 /* First, store the surface description */
2884 (*ilpdsf)->s.surface_desc = *lpddsd;
2886 /* Find a viewport */
2887 for (i=0;i<32;i++)
2888 if (!(This->e.dga.vpmask & (1<<i)))
2889 break;
2890 TRACE("using viewport %d for a primary surface\n",i);
2891 /* if i == 32 or maximum ... return error */
2892 This->e.dga.vpmask|=(1<<i);
2893 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
2894 This->e.dga.fb_width*
2895 (This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2897 (*ilpdsf)->s.surface_desc.y.lpSurface =
2898 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2900 (*ilpdsf)->t.dga.fb_height = i*fbheight;
2902 /* Add flags if there were not present */
2903 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2904 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2905 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2906 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2907 /* We put our surface always in video memory */
2908 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2909 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2910 (*ilpdsf)->s.chain = NULL;
2912 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2913 IDirectDrawSurface4Impl* back;
2914 int bbc;
2916 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
2917 int i;
2919 back = (IDirectDrawSurface4Impl*)HeapAlloc(
2920 GetProcessHeap(),
2921 HEAP_ZERO_MEMORY,
2922 sizeof(IDirectDrawSurface4Impl)
2924 IDirectDraw2_AddRef(iface);
2925 back->ref = 1;
2926 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2927 for (i=0;i<32;i++)
2928 if (!(This->e.dga.vpmask & (1<<i)))
2929 break;
2930 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
2931 /* if i == 32 or maximum ... return error */
2932 This->e.dga.vpmask|=(1<<i);
2933 back->t.dga.fb_height = i*fbheight;
2934 /* Copy the surface description from the front buffer */
2935 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2936 /* Change the parameters that are not the same */
2937 back->s.surface_desc.y.lpSurface =
2938 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2940 back->s.ddraw = This;
2941 /* Add relevant info to front and back buffers */
2942 /* FIXME: backbuffer/frontbuffer handling broken here, but
2943 * will be fixed up in _Flip().
2945 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
2946 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
2947 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2948 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
2949 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
2952 } else {
2953 /* There is no DGA-specific code here...
2954 Go to the common surface creation function */
2955 return common_off_screen_CreateSurface(This, *ilpdsf);
2957 return DD_OK;
2959 #endif /* defined(HAVE_LIBXXF86DGA) */
2961 #ifdef HAVE_LIBXXSHM
2962 /* Error handlers for Image creation */
2963 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2964 XShmErrorFlag = 1;
2965 return 0;
2968 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2969 XImage *img;
2970 int (*WineXHandler)(Display *, XErrorEvent *);
2972 img = TSXShmCreateImage(display,
2973 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2974 This->d.pixmap_depth,
2975 ZPixmap,
2976 NULL,
2977 &(lpdsf->t.xlib.shminfo),
2978 lpdsf->s.surface_desc.dwWidth,
2979 lpdsf->s.surface_desc.dwHeight
2982 if (img == NULL) {
2983 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2984 This->e.xlib.xshm_active = 0;
2985 return NULL;
2988 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2989 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2990 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2991 This->e.xlib.xshm_active = 0;
2992 TSXDestroyImage(img);
2993 return NULL;
2996 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2998 if (img->data == (char *) -1) {
2999 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3000 This->e.xlib.xshm_active = 0;
3001 TSXDestroyImage(img);
3002 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3003 return NULL;
3005 lpdsf->t.xlib.shminfo.readOnly = False;
3007 /* This is where things start to get trickier....
3008 * First, we flush the current X connections to be sure to catch all
3009 * non-XShm related errors
3011 TSXSync(display, False);
3012 /* Then we enter in the non-thread safe part of the tests */
3013 EnterCriticalSection( &X11DRV_CritSection );
3015 /* Reset the error flag, sets our new error handler and try to attach
3016 * the surface
3018 XShmErrorFlag = 0;
3019 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3020 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3021 XSync(display, False);
3023 /* Check the error flag */
3024 if (XShmErrorFlag) {
3025 /* An error occured */
3026 XFlush(display);
3027 XShmErrorFlag = 0;
3028 XDestroyImage(img);
3029 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3030 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3031 XSetErrorHandler(WineXHandler);
3033 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3034 This->e.xlib.xshm_active = 0;
3036 /* Leave the critical section */
3037 LeaveCriticalSection( &X11DRV_CritSection );
3038 return NULL;
3040 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3041 * this works, but it may be a bit overkill....
3043 XSetErrorHandler(WineXHandler);
3044 LeaveCriticalSection( &X11DRV_CritSection );
3046 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3048 if (This->d.pixel_convert != NULL) {
3049 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(
3050 GetProcessHeap(),
3051 HEAP_ZERO_MEMORY,
3052 lpdsf->s.surface_desc.dwWidth *
3053 lpdsf->s.surface_desc.dwHeight *
3054 (This->d.directdraw_pixelformat.x.dwRGBBitCount)
3056 } else {
3057 lpdsf->s.surface_desc.y.lpSurface = img->data;
3059 return img;
3061 #endif /* HAVE_LIBXXSHM */
3063 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3064 XImage *img = NULL;
3065 void *img_data;
3067 #ifdef HAVE_LIBXXSHM
3068 if (This->e.xlib.xshm_active)
3069 img = create_xshmimage(This, lpdsf);
3071 if (img == NULL) {
3072 #endif
3073 /* Allocate surface memory */
3074 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(
3075 GetProcessHeap(),HEAP_ZERO_MEMORY,
3076 lpdsf->s.surface_desc.dwWidth *
3077 lpdsf->s.surface_desc.dwHeight *
3078 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8)
3081 if (This->d.pixel_convert != NULL) {
3082 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3083 lpdsf->s.surface_desc.dwWidth *
3084 lpdsf->s.surface_desc.dwHeight *
3085 (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
3087 } else {
3088 img_data = lpdsf->s.surface_desc.y.lpSurface;
3091 /* In this case, create an XImage */
3092 img = TSXCreateImage(display,
3093 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3094 This->d.pixmap_depth,
3095 ZPixmap,
3097 img_data,
3098 lpdsf->s.surface_desc.dwWidth,
3099 lpdsf->s.surface_desc.dwHeight,
3101 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
3103 #ifdef HAVE_LIBXXSHM
3105 #endif
3106 if (This->d.pixel_convert != NULL) {
3107 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
3108 } else {
3109 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3111 return img;
3114 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3115 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3117 ICOM_THIS(IDirectDraw2Impl,iface);
3118 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3120 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3122 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3124 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3125 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3128 IDirectDraw2_AddRef(iface);
3130 (*ilpdsf)->s.ddraw = This;
3131 (*ilpdsf)->ref = 1;
3132 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3133 (*ilpdsf)->s.palette = NULL;
3134 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3136 /* Copy the surface description */
3137 (*ilpdsf)->s.surface_desc = *lpddsd;
3139 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3140 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3141 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3142 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3143 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3145 /* Check if this a 'primary surface' or not */
3146 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3147 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3148 XImage *img;
3150 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3151 /* Create the XImage */
3152 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3153 if (img == NULL)
3154 return DDERR_OUTOFMEMORY;
3155 (*ilpdsf)->t.xlib.image = img;
3157 /* Add flags if there were not present */
3158 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3159 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3160 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3161 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3162 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3164 /* Check for backbuffers */
3165 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3166 IDirectDrawSurface4Impl* back;
3167 XImage *img;
3168 int i;
3170 for (i=lpddsd->dwBackBufferCount;i--;) {
3171 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3172 GetProcessHeap(),HEAP_ZERO_MEMORY,
3173 sizeof(IDirectDrawSurface4Impl)
3176 TRACE("allocated back-buffer (%p)\n", back);
3178 IDirectDraw2_AddRef(iface);
3179 back->s.ddraw = This;
3181 back->ref = 1;
3182 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3183 /* Copy the surface description from the front buffer */
3184 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3186 /* Create the XImage */
3187 img = create_ximage(This, back);
3188 if (img == NULL)
3189 return DDERR_OUTOFMEMORY;
3190 back->t.xlib.image = img;
3192 /* Add relevant info to front and back buffers */
3193 /* FIXME: backbuffer/frontbuffer handling broken here, but
3194 * will be fixed up in _Flip().
3196 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3197 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3198 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3199 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3200 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3203 } else {
3204 /* There is no Xlib-specific code here...
3205 Go to the common surface creation function */
3206 return common_off_screen_CreateSurface(This, *ilpdsf);
3208 return DD_OK;
3211 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3212 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3214 ICOM_THIS(IDirectDraw2Impl,iface);
3215 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3216 *dst = src; /* FIXME */
3217 return DD_OK;
3221 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3222 * even when the approbiate bitmasks are not specified.
3224 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3225 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3227 ICOM_THIS(IDirectDraw2Impl,iface);
3229 int i;
3230 const struct {
3231 int mask;
3232 char *name;
3233 } flagmap[] = {
3234 #define FE(x) { x, #x},
3235 FE(DDSCL_FULLSCREEN)
3236 FE(DDSCL_ALLOWREBOOT)
3237 FE(DDSCL_NOWINDOWCHANGES)
3238 FE(DDSCL_NORMAL)
3239 FE(DDSCL_ALLOWMODEX)
3240 FE(DDSCL_EXCLUSIVE)
3241 FE(DDSCL_SETFOCUSWINDOW)
3242 FE(DDSCL_SETDEVICEWINDOW)
3243 FE(DDSCL_CREATEDEVICEWINDOW)
3244 #undef FE
3248 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3249 This->d.mainWindow = hwnd;
3251 /* This will be overwritten in the case of Full Screen mode.
3252 Windowed games could work with that :-) */
3253 if (hwnd)
3255 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3256 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3257 WIN_ReleaseWndPtr(tmpWnd);
3259 if( !This->d.drawable ) {
3260 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3261 WIN_ReleaseDesktop();
3263 TRACE("Setting drawable to %ld\n", This->d.drawable);
3266 return DD_OK;
3269 /* Small helper to either use the cooperative window or create a new
3270 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3272 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3273 RECT rect;
3275 /* Do not destroy the application supplied cooperative window */
3276 if (This->d.window && This->d.window != This->d.mainWindow) {
3277 DestroyWindow(This->d.window);
3278 This->d.window = 0;
3280 /* Sanity check cooperative window before assigning it to drawing. */
3281 if ( IsWindow(This->d.mainWindow) &&
3282 IsWindowVisible(This->d.mainWindow)
3284 /* if it does not fit, resize the cooperative window.
3285 * and hope the app likes it
3287 GetWindowRect(This->d.mainWindow,&rect);
3288 if ((((rect.right-rect.left) >= This->d.width) &&
3289 ((rect.bottom-rect.top) >= This->d.height))
3291 This->d.window = This->d.mainWindow;
3292 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3296 /* ... failed, create new one. */
3297 if (!This->d.window) {
3298 This->d.window = CreateWindowExA(
3300 "WINE_DirectDraw",
3301 "WINE_DirectDraw",
3302 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3303 0,0,
3304 This->d.width,
3305 This->d.height,
3309 NULL
3311 /*Store THIS with the window. We'll use it in the window procedure*/
3312 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3313 ShowWindow(This->d.window,TRUE);
3314 UpdateWindow(This->d.window);
3316 SetFocus(This->d.window);
3319 static int _common_depth_to_pixelformat(DWORD depth,
3320 DDPIXELFORMAT *pixelformat,
3321 DDPIXELFORMAT *screen_pixelformat,
3322 int *pix_depth) {
3323 XVisualInfo *vi;
3324 XPixmapFormatValues *pf;
3325 XVisualInfo vt;
3326 int nvisuals, npixmap, i;
3327 int match = 0;
3328 int index = -2;
3330 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3331 pf = XListPixmapFormats(display, &npixmap);
3333 for (i = 0; i < npixmap; i++) {
3334 if (pf[i].depth == depth) {
3335 int j;
3337 for (j = 0; j < nvisuals; j++) {
3338 if (vi[j].depth == pf[i].depth) {
3339 pixelformat->dwSize = sizeof(*pixelformat);
3340 if (depth == 8) {
3341 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3342 pixelformat->y.dwRBitMask = 0;
3343 pixelformat->z.dwGBitMask = 0;
3344 pixelformat->xx.dwBBitMask = 0;
3345 } else {
3346 pixelformat->dwFlags = DDPF_RGB;
3347 pixelformat->y.dwRBitMask = vi[j].red_mask;
3348 pixelformat->z.dwGBitMask = vi[j].green_mask;
3349 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3351 pixelformat->dwFourCC = 0;
3352 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3353 pixelformat->xy.dwRGBAlphaBitMask= 0;
3355 *screen_pixelformat = *pixelformat;
3357 if (pix_depth != NULL)
3358 *pix_depth = vi[j].depth;
3360 match = 1;
3361 index = -1;
3363 goto clean_up_and_exit;
3367 ERR("No visual corresponding to pixmap format !\n");
3371 if (match == 0) {
3372 /* We try now to find an emulated mode */
3373 int c;
3375 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3376 if (ModeEmulations[c].dest.depth == depth) {
3377 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3378 for (i = 0; i < npixmap; i++) {
3379 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3380 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3381 int j;
3383 for (j = 0; j < nvisuals; j++) {
3384 if (vi[j].depth == pf[i].depth) {
3385 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3386 screen_pixelformat->dwFlags = DDPF_RGB;
3387 screen_pixelformat->dwFourCC = 0;
3388 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3389 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3390 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3391 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3392 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3394 pixelformat->dwSize = sizeof(*pixelformat);
3395 pixelformat->dwFourCC = 0;
3396 if (depth == 8) {
3397 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3398 pixelformat->x.dwRGBBitCount = 8;
3399 pixelformat->y.dwRBitMask = 0;
3400 pixelformat->z.dwGBitMask = 0;
3401 pixelformat->xx.dwBBitMask = 0;
3402 } else {
3403 pixelformat->dwFlags = DDPF_RGB;
3404 pixelformat->x.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3405 pixelformat->y.dwRBitMask = ModeEmulations[c].dest.rmask;
3406 pixelformat->z.dwGBitMask = ModeEmulations[c].dest.gmask;
3407 pixelformat->xx.dwBBitMask = ModeEmulations[c].dest.bmask;
3409 pixelformat->xy.dwRGBAlphaBitMask= 0;
3411 if (pix_depth != NULL)
3412 *pix_depth = vi[j].depth;
3414 match = 2;
3415 index = c;
3417 goto clean_up_and_exit;
3420 ERR("No visual corresponding to pixmap format !\n");
3428 clean_up_and_exit:
3429 TSXFree(vi);
3430 TSXFree(pf);
3432 return index;
3435 #ifdef HAVE_LIBXXF86DGA
3436 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3437 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3439 ICOM_THIS(IDirectDrawImpl,iface);
3440 int i,mode_count;
3442 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3444 /* We hope getting the asked for depth */
3445 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3446 /* I.e. no visual found or emulated */
3447 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3448 return DDERR_UNSUPPORTEDMODE;
3451 if (This->d.width < width) {
3452 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3453 return DDERR_UNSUPPORTEDMODE;
3455 This->d.width = width;
3456 This->d.height = height;
3458 /* adjust fb_height, so we don't overlap */
3459 if (This->e.dga.fb_height < height)
3460 This->e.dga.fb_height = height;
3461 _common_IDirectDrawImpl_SetDisplayMode(This);
3463 #ifdef HAVE_LIBXXF86VM
3465 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3466 XF86VidModeModeLine mod_tmp;
3467 /* int dotclock_tmp; */
3469 /* save original video mode and set fullscreen if available*/
3470 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3471 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3472 orig_mode->hdisplay = mod_tmp.hdisplay;
3473 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3474 orig_mode->hsyncend = mod_tmp.hsyncend;
3475 orig_mode->htotal = mod_tmp.htotal;
3476 orig_mode->vdisplay = mod_tmp.vdisplay;
3477 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3478 orig_mode->vsyncend = mod_tmp.vsyncend;
3479 orig_mode->vtotal = mod_tmp.vtotal;
3480 orig_mode->flags = mod_tmp.flags;
3481 orig_mode->private = mod_tmp.private;
3483 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3484 for (i=0;i<mode_count;i++)
3486 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3488 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3489 *vidmode = *(all_modes[i]);
3490 break;
3491 } else
3492 TSXFree(all_modes[i]->private);
3494 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3495 TSXFree(all_modes);
3497 if (!vidmode)
3498 WARN("Fullscreen mode not available!\n");
3500 if (vidmode)
3502 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3503 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3504 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3505 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3506 #endif
3509 #endif
3511 /* FIXME: this function OVERWRITES several signal handlers.
3512 * can we save them? and restore them later? In a way that
3513 * it works for the library too?
3515 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3516 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3518 #ifdef RESTORE_SIGNALS
3519 EXC_InitHandlers();
3520 #endif
3521 return DD_OK;
3523 #endif /* defined(HAVE_LIBXXF86DGA) */
3525 /* *************************************
3526 16 / 15 bpp to palettized 8 bpp
3527 ************************************* */
3528 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3529 unsigned char *c_src = (unsigned char *) src;
3530 unsigned short *c_dst = (unsigned short *) dst;
3531 int y;
3533 if (palette != NULL) {
3534 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3536 for (y = height; y--; ) {
3537 #if defined(__i386__) && defined(__GNUC__)
3538 /* gcc generates slightly inefficient code for the the copy / lookup,
3539 * it generates one excess memory access (to pal) per pixel. Since
3540 * we know that pal is not modified by the memory write we can
3541 * put it into a register and reduce the number of memory accesses
3542 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3543 * (This is not guaranteed to be the fastest method.)
3545 __asm__ __volatile__(
3546 "xor %%eax,%%eax\n"
3547 "1:\n"
3548 " lodsb\n"
3549 " movw (%%edx,%%eax,2),%%ax\n"
3550 " stosw\n"
3551 " xor %%eax,%%eax\n"
3552 " loop 1b\n"
3553 : "=S" (c_src), "=D" (c_dst)
3554 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3555 : "eax", "cc", "memory"
3557 c_src+=(pitch-width);
3558 #else
3559 unsigned char * srclineend = c_src+width;
3560 while (c_src < srclineend)
3561 *c_dst++ = pal[*c_src++];
3562 c_src+=(pitch-width);
3563 #endif
3565 } else {
3566 WARN("No palette set...\n");
3567 memset(dst, 0, width * height * 2);
3570 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3571 int i;
3572 unsigned short *pal = (unsigned short *) screen_palette;
3574 for (i = 0; i < count; i++)
3575 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3576 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3577 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3579 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3580 int i;
3581 unsigned short *pal = (unsigned short *) screen_palette;
3583 for (i = 0; i < count; i++)
3584 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3585 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3586 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3589 /* *************************************
3590 24 to palettized 8 bpp
3591 ************************************* */
3592 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3593 unsigned char *c_src = (unsigned char *) src;
3594 unsigned char *c_dst = (unsigned char *) dst;
3595 int y;
3597 if (palette != NULL) {
3598 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3600 for (y = height; y--; ) {
3601 unsigned char * srclineend = c_src+width;
3602 while (c_src < srclineend ) {
3603 register long pixel = pal[*c_src++];
3604 *c_dst++ = pixel;
3605 *c_dst++ = pixel>>8;
3606 *c_dst++ = pixel>>16;
3608 c_src+=(pitch-width);
3610 } else {
3611 WARN("No palette set...\n");
3612 memset(dst, 0, width * height * 4);
3615 /* *************************************
3616 32 bpp to palettized 8 bpp
3617 ************************************* */
3618 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3619 unsigned char *c_src = (unsigned char *) src;
3620 unsigned int *c_dst = (unsigned int *) dst;
3621 int y;
3623 if (palette != NULL) {
3624 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3626 for (y = height; y--; ) {
3627 #if defined(__i386__) && defined(__GNUC__)
3628 /* See comment in pixel_convert_16_to_8 */
3629 __asm__ __volatile__(
3630 "xor %%eax,%%eax\n"
3631 "1:\n"
3632 " lodsb\n"
3633 " movl (%%edx,%%eax,4),%%eax\n"
3634 " stosl\n"
3635 " xor %%eax,%%eax\n"
3636 " loop 1b\n"
3637 : "=S" (c_src), "=D" (c_dst)
3638 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3639 : "eax", "cc", "memory"
3641 c_src+=(pitch-width);
3642 #else
3643 unsigned char * srclineend = c_src+width;
3644 while (c_src < srclineend )
3645 *c_dst++ = pal[*c_src++];
3646 c_src+=(pitch-width);
3647 #endif
3649 } else {
3650 WARN("No palette set...\n");
3651 memset(dst, 0, width * height * 4);
3655 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3656 int i;
3657 unsigned int *pal = (unsigned int *) screen_palette;
3659 for (i = 0; i < count; i++)
3660 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3661 (((unsigned int) palent[i].peGreen) << 8) |
3662 ((unsigned int) palent[i].peBlue));
3665 /* *************************************
3666 32 bpp to 16 bpp
3667 ************************************* */
3668 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3669 unsigned short *c_src = (unsigned short *) src;
3670 unsigned int *c_dst = (unsigned int *) dst;
3671 int y;
3673 for (y = height; y--; ) {
3674 unsigned short * srclineend = c_src+width;
3675 while (c_src < srclineend ) {
3676 *c_dst++ = (((*c_src & 0xF800) << 8) |
3677 ((*c_src & 0x07E0) << 5) |
3678 ((*c_src & 0x001F) << 3));
3679 c_src++;
3681 c_src+=((pitch/2)-width);
3686 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3687 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3689 ICOM_THIS(IDirectDrawImpl,iface);
3690 char buf[200];
3691 WND *tmpWnd;
3692 int c;
3694 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3695 This, width, height, depth);
3697 switch ((c = _common_depth_to_pixelformat(depth,
3698 &(This->d.directdraw_pixelformat),
3699 &(This->d.screen_pixelformat),
3700 &(This->d.pixmap_depth)))) {
3701 case -2:
3702 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3703 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3704 return DDERR_UNSUPPORTEDMODE;
3706 case -1:
3707 /* No convertion */
3708 This->d.pixel_convert = NULL;
3709 This->d.palette_convert = NULL;
3710 break;
3712 default:
3713 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3715 /* Set the depth convertion routines */
3716 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
3717 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
3720 This->d.width = width;
3721 This->d.height = height;
3723 _common_IDirectDrawImpl_SetDisplayMode(This);
3725 tmpWnd = WIN_FindWndPtr(This->d.window);
3726 This->d.paintable = 1;
3727 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3728 WIN_ReleaseWndPtr(tmpWnd);
3730 /* We don't have a context for this window. Host off the desktop */
3731 if( !This->d.drawable )
3733 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3734 WIN_ReleaseDesktop();
3736 TRACE("Setting drawable to %ld\n", This->d.drawable);
3738 return DD_OK;
3741 #ifdef HAVE_LIBXXF86DGA
3742 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3743 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3745 ICOM_THIS(IDirectDraw2Impl,iface);
3746 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3747 if (!caps1 && !caps2)
3748 return DDERR_INVALIDPARAMS;
3749 if (caps1) {
3750 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3751 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3752 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3754 if (caps2) {
3755 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3756 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3757 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3759 return DD_OK;
3761 #endif /* defined(HAVE_LIBXXF86DGA) */
3763 static void fill_caps(LPDDCAPS caps) {
3764 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3765 Need to be fixed, though.. */
3766 if (caps == NULL)
3767 return;
3769 caps->dwSize = sizeof(*caps);
3770 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
3771 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3772 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3773 caps->dwFXCaps = 0;
3774 caps->dwFXAlphaCaps = 0;
3775 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3776 caps->dwSVCaps = 0;
3777 caps->dwZBufferBitDepths = DDBD_16;
3778 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3779 to put textures in video memory.
3780 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3781 for example) ? */
3782 caps->dwVidMemTotal = 8192 * 1024;
3783 caps->dwVidMemFree = 8192 * 1024;
3784 /* These are all the supported capabilities of the surfaces */
3785 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3786 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3787 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3788 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3789 #ifdef HAVE_MESAGL
3790 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3791 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3792 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3793 #endif
3796 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3797 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3799 ICOM_THIS(IDirectDraw2Impl,iface);
3800 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3802 /* Put the same caps for the two capabilities */
3803 fill_caps(caps1);
3804 fill_caps(caps2);
3806 return DD_OK;
3809 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3810 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3812 ICOM_THIS(IDirectDraw2Impl,iface);
3813 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3814 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
3815 This,x,ilpddclip,lpunk
3817 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3818 (*ilpddclip)->ref = 1;
3819 (*ilpddclip)->lpvtbl = &ddclipvt;
3820 return DD_OK;
3823 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3824 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3826 int size = 0;
3828 if (TRACE_ON(ddraw))
3829 _dump_paletteformat(dwFlags);
3831 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3832 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3833 (*lpddpal)->ref = 1;
3834 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3835 (*lpddpal)->installed = 0;
3837 if (dwFlags & DDPCAPS_1BIT)
3838 size = 2;
3839 else if (dwFlags & DDPCAPS_2BIT)
3840 size = 4;
3841 else if (dwFlags & DDPCAPS_4BIT)
3842 size = 16;
3843 else if (dwFlags & DDPCAPS_8BIT)
3844 size = 256;
3845 else
3846 ERR("unhandled palette format\n");
3847 *psize = size;
3849 if (palent)
3851 /* Now, if we are in 'depth conversion mode', create the screen palette */
3852 if (This->d.palette_convert != NULL)
3853 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3855 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3856 } else if (This->d.palette_convert != NULL) {
3857 /* In that case, put all 0xFF */
3858 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3861 return DD_OK;
3864 #ifdef HAVE_LIBXXF86DGA
3865 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3866 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3868 ICOM_THIS(IDirectDraw2Impl,iface);
3869 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3870 HRESULT res;
3871 int xsize = 0,i;
3873 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3874 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3875 if (res != 0) return res;
3876 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3877 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3878 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3879 } else {
3880 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
3881 (*ilpddpal)->cm = 0;
3883 if (((*ilpddpal)->cm)&&xsize) {
3884 for (i=0;i<xsize;i++) {
3885 XColor xc;
3887 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3888 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3889 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3890 xc.flags = DoRed|DoBlue|DoGreen;
3891 xc.pixel = i;
3892 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3895 return DD_OK;
3897 #endif /* defined(HAVE_LIBXXF86DGA) */
3899 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3900 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3902 ICOM_THIS(IDirectDraw2Impl,iface);
3903 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3904 int xsize;
3905 HRESULT res;
3907 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3908 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3909 if (res != 0) return res;
3910 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3911 return DD_OK;
3914 #ifdef HAVE_LIBXXF86DGA
3915 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3916 ICOM_THIS(IDirectDraw2Impl,iface);
3917 TRACE("(%p)->()\n",This);
3918 Sleep(1000);
3919 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3920 #ifdef RESTORE_SIGNALS
3921 EXC_InitHandlers();
3922 #endif
3923 return DD_OK;
3925 #endif /* defined(HAVE_LIBXXF86DGA) */
3927 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3928 ICOM_THIS(IDirectDraw2Impl,iface);
3929 TRACE("(%p)->RestoreDisplayMode()\n", This);
3930 Sleep(1000);
3931 return DD_OK;
3934 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3935 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3937 ICOM_THIS(IDirectDraw2Impl,iface);
3938 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3939 return DD_OK;
3942 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3943 ICOM_THIS(IDirectDraw2Impl,iface);
3944 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
3946 return ++(This->ref);
3949 #ifdef HAVE_LIBXXF86DGA
3950 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3951 ICOM_THIS(IDirectDraw2Impl,iface);
3952 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
3954 if (!--(This->ref)) {
3955 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3956 if (This->d.window && (This->d.mainWindow != This->d.window))
3957 DestroyWindow(This->d.window);
3958 #ifdef HAVE_LIBXXF86VM
3959 if (orig_mode) {
3960 TSXF86VidModeSwitchToMode(
3961 display,
3962 DefaultScreen(display),
3963 orig_mode);
3964 if (orig_mode->privsize)
3965 TSXFree(orig_mode->private);
3966 free(orig_mode);
3967 orig_mode = NULL;
3969 #endif
3971 #ifdef RESTORE_SIGNALS
3972 EXC_InitHandlers();
3973 #endif
3974 HeapFree(GetProcessHeap(),0,This);
3975 return 0;
3977 return This->ref;
3979 #endif /* defined(HAVE_LIBXXF86DGA) */
3981 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3982 ICOM_THIS(IDirectDraw2Impl,iface);
3983 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
3985 if (!--(This->ref)) {
3986 if (This->d.window && (This->d.mainWindow != This->d.window))
3987 DestroyWindow(This->d.window);
3988 HeapFree(GetProcessHeap(),0,This);
3989 return 0;
3991 /* FIXME: destroy window ... */
3992 return This->ref;
3995 #ifdef HAVE_LIBXXF86DGA
3996 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3997 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3999 ICOM_THIS(IDirectDraw2Impl,iface);
4000 char xrefiid[50];
4002 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4003 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4004 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
4005 *obj = This;
4006 IDirectDraw2_AddRef(iface);
4008 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4010 return S_OK;
4012 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
4013 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4014 IDirectDraw2_AddRef(iface);
4015 *obj = This;
4017 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4019 return S_OK;
4021 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
4022 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4023 IDirectDraw2_AddRef(iface);
4024 *obj = This;
4026 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4028 return S_OK;
4030 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
4031 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4032 IDirectDraw2_AddRef(iface);
4033 *obj = This;
4035 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4037 return S_OK;
4039 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
4040 IDirect3DImpl* d3d;
4042 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4043 d3d->ref = 1;
4044 d3d->ddraw = (IDirectDrawImpl*)This;
4045 IDirectDraw2_AddRef(iface);
4046 d3d->lpvtbl = &d3dvt;
4047 *obj = d3d;
4049 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4051 return S_OK;
4053 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
4054 IDirect3D2Impl* d3d;
4056 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4057 d3d->ref = 1;
4058 d3d->ddraw = (IDirectDrawImpl*)This;
4059 IDirectDraw2_AddRef(iface);
4060 d3d->lpvtbl = &d3d2vt;
4061 *obj = d3d;
4063 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4065 return S_OK;
4067 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4068 return OLE_E_ENUM_NOMORE;
4070 #endif /* defined(HAVE_LIBXXF86DGA) */
4072 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4073 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4075 ICOM_THIS(IDirectDraw2Impl,iface);
4076 char xrefiid[50];
4078 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4079 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4080 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
4081 *obj = This;
4082 IDirectDraw2_AddRef(iface);
4084 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4086 return S_OK;
4088 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
4089 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4090 IDirectDraw2_AddRef(iface);
4091 *obj = This;
4093 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4095 return S_OK;
4097 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
4098 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4099 IDirectDraw2_AddRef(iface);
4100 *obj = This;
4102 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4104 return S_OK;
4106 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
4107 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4108 IDirectDraw2_AddRef(iface);
4109 *obj = This;
4111 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4113 return S_OK;
4115 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
4116 IDirect3DImpl* d3d;
4118 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4119 d3d->ref = 1;
4120 d3d->ddraw = (IDirectDrawImpl*)This;
4121 IDirectDraw2_AddRef(iface);
4122 d3d->lpvtbl = &d3dvt;
4123 *obj = d3d;
4125 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4127 return S_OK;
4129 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
4130 IDirect3D2Impl* d3d;
4132 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4133 d3d->ref = 1;
4134 d3d->ddraw = (IDirectDrawImpl*)This;
4135 IDirectDraw2_AddRef(iface);
4136 d3d->lpvtbl = &d3d2vt;
4137 *obj = d3d;
4139 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4141 return S_OK;
4143 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4144 return OLE_E_ENUM_NOMORE;
4147 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4148 LPDIRECTDRAW2 iface,BOOL *status
4150 ICOM_THIS(IDirectDraw2Impl,iface);
4151 TRACE("(%p)->(%p)\n",This,status);
4152 *status = TRUE;
4153 return DD_OK;
4156 #ifdef HAVE_LIBXXF86DGA
4157 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4158 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4160 ICOM_THIS(IDirectDraw2Impl,iface);
4161 DDSURFACEDESC ddsfd;
4162 static struct {
4163 int w,h;
4164 } modes[5] = { /* some of the usual modes */
4165 {512,384},
4166 {640,400},
4167 {640,480},
4168 {800,600},
4169 {1024,768},
4171 static int depths[4] = {8,16,24,32};
4172 int i,j;
4174 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4175 ddsfd.dwSize = sizeof(ddsfd);
4176 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4177 if (dwFlags & DDEDM_REFRESHRATES) {
4178 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4179 ddsfd.x.dwRefreshRate = 60;
4182 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4183 ddsfd.dwBackBufferCount = 1;
4184 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4185 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4186 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
4187 /* FIXME: those masks would have to be set in depth > 8 */
4188 if (depths[i]==8) {
4189 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4190 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4191 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4192 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4193 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4194 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4195 } else {
4196 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4198 /* FIXME: We should query those from X itself */
4199 switch (depths[i]) {
4200 case 16:
4201 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
4202 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
4203 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
4204 break;
4205 case 24:
4206 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4207 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4208 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4209 break;
4210 case 32:
4211 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4212 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4213 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4214 break;
4218 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4219 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4220 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4221 if (!modescb(&ddsfd,context)) return DD_OK;
4223 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4224 ddsfd.dwWidth = modes[j].w;
4225 ddsfd.dwHeight = modes[j].h;
4226 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4227 if (!modescb(&ddsfd,context)) return DD_OK;
4230 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4231 /* modeX is not standard VGA */
4233 ddsfd.dwHeight = 200;
4234 ddsfd.dwWidth = 320;
4235 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4236 if (!modescb(&ddsfd,context)) return DD_OK;
4239 return DD_OK;
4241 #endif /* defined(HAVE_LIBXXF86DGA) */
4243 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4244 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4246 ICOM_THIS(IDirectDraw2Impl,iface);
4247 XVisualInfo *vi;
4248 XPixmapFormatValues *pf;
4249 XVisualInfo vt;
4250 int nvisuals, npixmap, i, emu;
4251 int has_mode[] = { 0, 0, 0, 0 };
4252 int has_depth[] = { 8, 15, 16, 24 };
4253 DDSURFACEDESC ddsfd;
4254 static struct {
4255 int w,h;
4256 } modes[] = { /* some of the usual modes */
4257 {512,384},
4258 {640,400},
4259 {640,480},
4260 {800,600},
4261 {1024,768},
4262 {1280,1024}
4264 DWORD maxWidth, maxHeight;
4266 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4267 ddsfd.dwSize = sizeof(ddsfd);
4268 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4269 if (dwFlags & DDEDM_REFRESHRATES) {
4270 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4271 ddsfd.x.dwRefreshRate = 60;
4273 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4274 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4276 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4277 pf = XListPixmapFormats(display, &npixmap);
4279 i = 0;
4280 emu = 0;
4281 while ((i < npixmap) ||
4282 (emu != 4)) {
4283 int mode_index;
4284 int send_mode = 0;
4285 int j;
4287 if (i < npixmap) {
4288 for (j = 0; j < 4; j++) {
4289 if (has_depth[j] == pf[i].depth) {
4290 mode_index = j;
4291 break;
4294 if (j == 4) {
4295 i++;
4296 continue;
4300 if (has_mode[mode_index] == 0) {
4301 if (mode_index == 0) {
4302 send_mode = 1;
4304 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4305 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4306 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4307 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4308 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
4309 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4310 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4311 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4312 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4314 has_mode[mode_index] = 1;
4315 } else {
4316 /* All the 'true color' depths (15, 16 and 24)
4317 First, find the corresponding visual to extract the bit masks */
4318 for (j = 0; j < nvisuals; j++) {
4319 if (vi[j].depth == pf[i].depth) {
4320 ddsfd.ddsCaps.dwCaps = 0;
4321 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4322 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4323 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4324 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
4325 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
4326 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
4327 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
4328 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4330 send_mode = 1;
4331 has_mode[mode_index] = 1;
4332 break;
4336 if (j == nvisuals)
4337 ERR("Did not find visual corresponding the the pixmap format !\n");
4341 i++;
4342 } else {
4343 /* Now to emulated modes */
4344 if (has_mode[emu] == 0) {
4345 int c;
4346 int l;
4347 int depth = has_depth[emu];
4349 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4350 if (ModeEmulations[c].dest.depth == depth) {
4351 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4352 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4353 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4354 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4355 int j;
4356 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4357 if ((vi[j].depth == pf[l].depth) &&
4358 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4359 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4360 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4361 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4362 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4363 if (depth == 8) {
4364 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4365 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
4366 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4367 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4368 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4369 } else {
4370 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4371 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4372 ddsfd.ddpfPixelFormat.y.dwRBitMask = ModeEmulations[c].dest.rmask;
4373 ddsfd.ddpfPixelFormat.z.dwGBitMask = ModeEmulations[c].dest.gmask;
4374 ddsfd.ddpfPixelFormat.xx.dwBBitMask = ModeEmulations[c].dest.bmask;
4376 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4377 send_mode = 1;
4380 if (send_mode == 0)
4381 ERR("No visual corresponding to pixmap format !\n");
4389 emu++;
4392 if (send_mode) {
4393 int mode;
4395 if (TRACE_ON(ddraw)) {
4396 TRACE("Enumerating with pixel format : \n");
4397 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4398 DPRINTF("\n");
4401 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4402 /* Do not enumerate modes we cannot handle anyway */
4403 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4404 break;
4406 ddsfd.dwWidth = modes[mode].w;
4407 ddsfd.dwHeight = modes[mode].h;
4409 /* Now, send the mode description to the application */
4410 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4411 if (!modescb(&ddsfd, context))
4412 goto exit_enum;
4415 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4416 /* modeX is not standard VGA */
4417 ddsfd.dwWidth = 320;
4418 ddsfd.dwHeight = 200;
4419 if (!modescb(&ddsfd, context))
4420 goto exit_enum;
4425 exit_enum:
4426 TSXFree(vi);
4427 TSXFree(pf);
4429 return DD_OK;
4432 #ifdef HAVE_LIBXXF86DGA
4433 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4434 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4436 ICOM_THIS(IDirectDraw2Impl,iface);
4437 TRACE("(%p)->(%p)\n",This,lpddsfd);
4438 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4439 lpddsfd->dwHeight = This->d.height;
4440 lpddsfd->dwWidth = This->d.width;
4441 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4442 lpddsfd->dwBackBufferCount = 1;
4443 lpddsfd->x.dwRefreshRate = 60;
4444 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4445 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4446 return DD_OK;
4448 #endif /* defined(HAVE_LIBXXF86DGA) */
4450 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4451 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4453 ICOM_THIS(IDirectDraw2Impl,iface);
4454 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4455 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4456 lpddsfd->dwHeight = This->d.height;
4457 lpddsfd->dwWidth = This->d.width;
4458 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4459 lpddsfd->dwBackBufferCount = 1;
4460 lpddsfd->x.dwRefreshRate = 60;
4461 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4462 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4463 return DD_OK;
4466 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4467 ICOM_THIS(IDirectDraw2Impl,iface);
4468 TRACE("(%p)->()\n",This);
4469 return DD_OK;
4472 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4473 LPDIRECTDRAW2 iface,LPDWORD freq
4475 ICOM_THIS(IDirectDraw2Impl,iface);
4476 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4477 *freq = 60*100; /* 60 Hz */
4478 return DD_OK;
4481 /* what can we directly decompress? */
4482 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4483 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4485 ICOM_THIS(IDirectDraw2Impl,iface);
4486 FIXME("(%p,%p,%p), stub\n",This,x,y);
4487 return DD_OK;
4490 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4491 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4493 ICOM_THIS(IDirectDraw2Impl,iface);
4494 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4495 return DD_OK;
4498 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4499 LPDIRECTDRAW2 iface )
4501 ICOM_THIS(IDirectDraw2Impl,iface);
4502 FIXME("(%p)->()\n", This );
4504 return DD_OK;
4507 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4508 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4509 ICOM_THIS(IDirectDraw2Impl,iface);
4510 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4512 return DD_OK;
4515 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4516 LPDWORD lpdwScanLine) {
4517 ICOM_THIS(IDirectDraw2Impl,iface);
4518 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4520 return DD_OK;
4523 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4524 GUID *lpGUID) {
4525 ICOM_THIS(IDirectDraw2Impl,iface);
4526 FIXME("(%p)->(%p)\n", This, lpGUID);
4528 return DD_OK;
4531 #ifdef HAVE_LIBXXF86DGA
4533 /* Note: Hack so we can reuse the old functions without compiler warnings */
4534 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4535 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4536 #else
4537 # define XCAST(fun) (void *)
4538 #endif
4540 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4542 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4543 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4544 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4545 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4546 XCAST(Compact)IDirectDraw2Impl_Compact,
4547 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4548 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4549 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4550 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4551 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4552 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4553 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4554 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4555 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4556 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4557 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4558 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4559 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4560 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4561 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4562 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4563 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4564 DGA_IDirectDrawImpl_SetDisplayMode,
4565 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4568 #undef XCAST
4570 #endif /* defined(HAVE_LIBXXF86DGA) */
4572 /* Note: Hack so we can reuse the old functions without compiler warnings */
4573 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4574 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4575 #else
4576 # define XCAST(fun) (void *)
4577 #endif
4579 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4581 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4582 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4583 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4584 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4585 XCAST(Compact)IDirectDraw2Impl_Compact,
4586 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4587 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4588 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4589 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4590 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4591 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4592 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4593 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4594 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4595 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4596 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4597 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4598 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4599 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4600 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4601 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4602 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4603 Xlib_IDirectDrawImpl_SetDisplayMode,
4604 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4607 #undef XCAST
4609 /*****************************************************************************
4610 * IDirectDraw2
4615 #ifdef HAVE_LIBXXF86DGA
4616 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4617 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4619 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4621 #endif /* defined(HAVE_LIBXXF86DGA) */
4623 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4624 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4626 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4629 #ifdef HAVE_LIBXXF86DGA
4630 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4631 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4633 ICOM_THIS(IDirectDraw2Impl,iface);
4634 TRACE("(%p)->(%p,%p,%p)\n",
4635 This,ddscaps,total,free
4637 if (total) *total = This->e.dga.fb_memsize * 1024;
4638 if (free) *free = This->e.dga.fb_memsize * 1024;
4639 return DD_OK;
4641 #endif /* defined(HAVE_LIBXXF86DGA) */
4643 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4644 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4646 ICOM_THIS(IDirectDraw2Impl,iface);
4647 TRACE("(%p)->(%p,%p,%p)\n",
4648 This,ddscaps,total,free
4650 if (total) *total = 2048 * 1024;
4651 if (free) *free = 2048 * 1024;
4652 return DD_OK;
4655 #ifdef HAVE_LIBXXF86DGA
4656 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4658 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4659 DGA_IDirectDraw2Impl_QueryInterface,
4660 IDirectDraw2Impl_AddRef,
4661 DGA_IDirectDraw2Impl_Release,
4662 IDirectDraw2Impl_Compact,
4663 IDirectDraw2Impl_CreateClipper,
4664 DGA_IDirectDraw2Impl_CreatePalette,
4665 DGA_IDirectDraw2Impl_CreateSurface,
4666 IDirectDraw2Impl_DuplicateSurface,
4667 DGA_IDirectDraw2Impl_EnumDisplayModes,
4668 IDirectDraw2Impl_EnumSurfaces,
4669 IDirectDraw2Impl_FlipToGDISurface,
4670 DGA_IDirectDraw2Impl_GetCaps,
4671 DGA_IDirectDraw2Impl_GetDisplayMode,
4672 IDirectDraw2Impl_GetFourCCCodes,
4673 IDirectDraw2Impl_GetGDISurface,
4674 IDirectDraw2Impl_GetMonitorFrequency,
4675 IDirectDraw2Impl_GetScanLine,
4676 IDirectDraw2Impl_GetVerticalBlankStatus,
4677 IDirectDraw2Impl_Initialize,
4678 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4679 IDirectDraw2Impl_SetCooperativeLevel,
4680 DGA_IDirectDraw2Impl_SetDisplayMode,
4681 IDirectDraw2Impl_WaitForVerticalBlank,
4682 DGA_IDirectDraw2Impl_GetAvailableVidMem
4684 #endif /* defined(HAVE_LIBXXF86DGA) */
4686 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4688 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4689 Xlib_IDirectDraw2Impl_QueryInterface,
4690 IDirectDraw2Impl_AddRef,
4691 Xlib_IDirectDraw2Impl_Release,
4692 IDirectDraw2Impl_Compact,
4693 IDirectDraw2Impl_CreateClipper,
4694 Xlib_IDirectDraw2Impl_CreatePalette,
4695 Xlib_IDirectDraw2Impl_CreateSurface,
4696 IDirectDraw2Impl_DuplicateSurface,
4697 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4698 IDirectDraw2Impl_EnumSurfaces,
4699 IDirectDraw2Impl_FlipToGDISurface,
4700 Xlib_IDirectDraw2Impl_GetCaps,
4701 Xlib_IDirectDraw2Impl_GetDisplayMode,
4702 IDirectDraw2Impl_GetFourCCCodes,
4703 IDirectDraw2Impl_GetGDISurface,
4704 IDirectDraw2Impl_GetMonitorFrequency,
4705 IDirectDraw2Impl_GetScanLine,
4706 IDirectDraw2Impl_GetVerticalBlankStatus,
4707 IDirectDraw2Impl_Initialize,
4708 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4709 IDirectDraw2Impl_SetCooperativeLevel,
4710 Xlib_IDirectDraw2Impl_SetDisplayMode,
4711 IDirectDraw2Impl_WaitForVerticalBlank,
4712 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4715 /*****************************************************************************
4716 * IDirectDraw4
4720 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4721 HDC hdc,
4722 LPDIRECTDRAWSURFACE *lpDDS) {
4723 ICOM_THIS(IDirectDraw4Impl,iface);
4724 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4726 return DD_OK;
4729 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4730 ICOM_THIS(IDirectDraw4Impl,iface);
4731 FIXME("(%p)->()\n", This);
4733 return DD_OK;
4736 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4737 ICOM_THIS(IDirectDraw4Impl,iface);
4738 FIXME("(%p)->()\n", This);
4740 return DD_OK;
4743 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4744 LPDDDEVICEIDENTIFIER lpdddi,
4745 DWORD dwFlags) {
4746 ICOM_THIS(IDirectDraw4Impl,iface);
4747 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4749 return DD_OK;
4752 #ifdef HAVE_LIBXXF86DGA
4754 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4755 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4756 #else
4757 # define XCAST(fun) (void*)
4758 #endif
4760 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
4762 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4763 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4764 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4765 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4766 XCAST(Compact)IDirectDraw2Impl_Compact,
4767 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4768 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4769 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4770 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4771 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4772 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4773 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4774 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4775 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4776 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4777 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4778 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4779 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4780 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4781 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4782 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4783 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4784 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4785 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4786 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4787 IDirectDraw4Impl_GetSurfaceFromDC,
4788 IDirectDraw4Impl_RestoreAllSurfaces,
4789 IDirectDraw4Impl_TestCooperativeLevel,
4790 IDirectDraw4Impl_GetDeviceIdentifier
4793 #undef XCAST
4795 #endif /* defined(HAVE_LIBXXF86DGA) */
4797 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4798 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
4799 #else
4800 # define XCAST(fun) (void*)
4801 #endif
4803 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
4805 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4806 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4807 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4808 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4809 XCAST(Compact)IDirectDraw2Impl_Compact,
4810 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4811 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4812 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4813 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4814 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4815 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4816 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4817 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4818 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4819 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4820 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4821 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4822 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4823 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4824 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4825 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4826 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4827 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4828 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4829 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4830 IDirectDraw4Impl_GetSurfaceFromDC,
4831 IDirectDraw4Impl_RestoreAllSurfaces,
4832 IDirectDraw4Impl_TestCooperativeLevel,
4833 IDirectDraw4Impl_GetDeviceIdentifier
4836 #undef XCAST
4838 /******************************************************************************
4839 * DirectDrawCreate
4842 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4844 LRESULT ret;
4845 IDirectDrawImpl* ddraw = NULL;
4846 DWORD lastError;
4848 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4850 SetLastError( ERROR_SUCCESS );
4851 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4852 if( (!ddraw) &&
4853 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4856 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4859 if( ddraw )
4861 /* Perform any special direct draw functions */
4862 if (msg==WM_PAINT)
4863 ddraw->d.paintable = 1;
4865 /* Now let the application deal with the rest of this */
4866 if( ddraw->d.mainWindow )
4869 /* Don't think that we actually need to call this but...
4870 might as well be on the safe side of things... */
4872 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4873 it should be the procedures of our fake window that gets called
4874 instead of those of the window provided by the application.
4875 And with this patch, mouse clicks work with Monkey Island III
4876 - Lionel */
4877 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4879 if( !ret )
4881 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4882 /* We didn't handle the message - give it to the application */
4883 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4885 ret = CallWindowProcA(tmpWnd->winproc,
4886 ddraw->d.mainWindow, msg, wParam, lParam );
4888 WIN_ReleaseWndPtr(tmpWnd);
4892 } else {
4893 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4897 else
4899 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4902 return ret;
4905 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4906 #ifdef HAVE_LIBXXF86DGA
4907 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4908 int memsize,banksize,width,major,minor,flags,height;
4909 char *addr;
4910 int fd;
4911 int depth;
4913 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4914 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4915 close(fd);
4917 if (fd == -1) {
4918 MESSAGE("Must be able to access /dev/mem to use XF86DGA!\n");
4919 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4920 return E_UNEXPECTED;
4922 if (!DDRAW_DGA_Available()) {
4923 TRACE("No XF86DGA detected.\n");
4924 return DDERR_GENERIC;
4926 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4927 (*ilplpDD)->lpvtbl = &dga_ddvt;
4928 (*ilplpDD)->ref = 1;
4929 TSXF86DGAQueryVersion(display,&major,&minor);
4930 TRACE("XF86DGA is version %d.%d\n",major,minor);
4931 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4932 if (!(flags & XF86DGADirectPresent))
4933 MESSAGE("direct video is NOT PRESENT.\n");
4934 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4935 (*ilplpDD)->e.dga.fb_width = width;
4936 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4937 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4938 (*ilplpDD)->e.dga.fb_height = height;
4939 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4940 addr,width,banksize,memsize
4942 TRACE("viewport height: %d\n",height);
4944 /* Get the screen dimensions as seen by Wine.
4945 In that case, it may be better to ignore the -desktop mode and return the
4946 real screen size => print a warning */
4947 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4948 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4949 if (((*ilplpDD)->d.height != height) ||
4950 ((*ilplpDD)->d.width != width))
4951 WARN("You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4952 (*ilplpDD)->e.dga.fb_addr = addr;
4953 (*ilplpDD)->e.dga.fb_memsize = memsize;
4954 (*ilplpDD)->e.dga.fb_banksize = banksize;
4955 (*ilplpDD)->e.dga.vpmask = 0;
4957 /* just assume the default depth is the DGA depth too */
4958 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4959 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4960 #ifdef RESTORE_SIGNALS
4961 EXC_InitHandlers();
4962 #endif
4964 return DD_OK;
4965 #else /* defined(HAVE_LIBXXF86DGA) */
4966 return DDERR_INVALIDDIRECTDRAWGUID;
4967 #endif /* defined(HAVE_LIBXXF86DGA) */
4970 static BOOL
4971 DDRAW_XSHM_Available(void)
4973 #ifdef HAVE_LIBXXSHM
4974 if (TSXShmQueryExtension(display))
4976 int major, minor;
4977 Bool shpix;
4979 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
4980 (Options.noXSHM != 1))
4981 return 1;
4982 else
4983 return 0;
4985 else
4986 return 0;
4987 #else
4988 return 0;
4989 #endif
4992 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4993 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4994 int depth;
4996 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4997 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4998 (*ilplpDD)->ref = 1;
4999 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5001 /* At DirectDraw creation, the depth is the default depth */
5002 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5003 _common_depth_to_pixelformat(depth,
5004 &((*ilplpDD)->d.directdraw_pixelformat),
5005 &((*ilplpDD)->d.screen_pixelformat),
5006 &((*ilplpDD)->d.pixmap_depth));
5007 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5008 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5010 #ifdef HAVE_LIBXXSHM
5011 /* Test if XShm is available. */
5012 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
5013 TRACE("Using XShm extension.\n");
5014 #endif
5016 return DD_OK;
5019 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5020 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5021 char xclsid[50];
5022 WNDCLASSA wc;
5023 /* WND* pParentWindow; */
5024 HRESULT ret;
5026 if (HIWORD(lpGUID))
5027 WINE_StringFromCLSID(lpGUID,xclsid);
5028 else {
5029 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5030 lpGUID = NULL;
5033 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5035 if ((!lpGUID) ||
5036 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
5037 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
5038 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
5039 /* if they didn't request a particular interface, use the best
5040 * supported one */
5041 if (DDRAW_DGA_Available())
5042 lpGUID = &DGA_DirectDraw_GUID;
5043 else
5044 lpGUID = &XLIB_DirectDraw_GUID;
5047 wc.style = CS_GLOBALCLASS;
5048 wc.lpfnWndProc = Xlib_DDWndProc;
5049 wc.cbClsExtra = 0;
5050 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5051 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5053 /* We can be a child of the desktop since we're really important */
5055 This code is not useful since hInstance is forced to 0 afterward
5056 pParentWindow = WIN_GetDesktop();
5057 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5059 wc.hInstance = 0;
5062 wc.hIcon = 0;
5063 wc.hCursor = (HCURSOR)IDC_ARROWA;
5064 wc.hbrBackground= NULL_BRUSH;
5065 wc.lpszMenuName = 0;
5066 wc.lpszClassName= "WINE_DirectDraw";
5067 RegisterClassA(&wc);
5069 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
5070 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5071 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
5072 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5073 else
5074 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 ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
5132 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
5133 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
5134 /* FIXME: reuse already created DirectDraw if present? */
5135 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5137 return E_NOINTERFACE;
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 (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
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 E_NOINTERFACE;
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 E_NOINTERFACE;
5273 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5275 return DD_OK;
5278 #endif /* !defined(X_DISPLAY_MISSING) */