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