- Added a new option 'noxshm'
[wine/multimedia.git] / graphics / ddraw.c
blobeeee9e9a70a1e6f83ff54f14a6421a71418727ba
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997-1999 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
10 * is running.
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
17 #include "config.h"
19 #ifndef X_DISPLAY_MISSING
21 #include "ts_xlib.h"
22 #include "ts_xutil.h"
24 #ifdef HAVE_LIBXXSHM
25 #include <sys/types.h>
26 #include <sys/ipc.h>
27 #include <sys/shm.h>
28 #include "ts_xshm.h"
29 #endif /* defined(HAVE_LIBXXSHM) */
31 #ifdef HAVE_LIBXXF86DGA
32 #include "ts_xf86dga.h"
33 #endif /* defined(HAVE_LIBXXF86DGA) */
35 #ifdef HAVE_LIBXXF86VM
36 #include "ts_xf86vmode.h"
37 #endif /* defined(HAVE_LIBXXF86VM) */
39 #include "x11drv.h"
41 #include <unistd.h>
42 #include <assert.h>
43 #include <sys/signal.h>
44 #include <fcntl.h>
45 #include <string.h>
46 #include <stdlib.h>
48 #include "winerror.h"
49 #include "gdi.h"
50 #include "heap.h"
51 #include "dc.h"
52 #include "win.h"
53 #include "wine/exception.h"
54 #include "ddraw.h"
55 #include "d3d.h"
56 #include "debugtools.h"
57 #include "spy.h"
58 #include "message.h"
59 #include "options.h"
60 #include "monitor.h"
62 /* This for all the enumeration and creation of D3D-related objects */
63 #include "ddraw_private.h"
64 #include "d3d_private.h"
66 DEFAULT_DEBUG_CHANNEL(ddraw)
68 /* Restore signal handlers overwritten by XF86DGA
70 #define RESTORE_SIGNALS
72 /* Get DDSCAPS of surface (shortcutmacro) */
73 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
76 /* Get the number of bytes per pixel for a given surface */
77 #define GET_BPP(desc) (desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? \
78 1 : \
79 desc.ddpfPixelFormat.x.dwRGBBitCount / 8)
81 /* Where do these GUIDs come from? mkuuid.
82 * They exist solely to distinguish between the targets Wine support,
83 * and should be different than any other GUIDs in existence.
85 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
86 0xe2dcb020,
87 0xdc60,
88 0x11d1,
89 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
92 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
93 0x1574a740,
94 0xdc61,
95 0x11d1,
96 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
99 #ifdef HAVE_LIBXXF86DGA
100 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
101 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
102 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
103 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
104 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
105 #endif /* defined(HAVE_LIBXXF86DGA) */
107 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
108 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
109 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
110 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
111 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
113 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
114 static struct ICOM_VTABLE(IDirect3D) d3dvt;
115 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
117 /* This is for mode-emulation */
119 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
120 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
121 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
122 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
123 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
124 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
125 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
127 typedef struct {
128 unsigned short bpp;
129 unsigned short depth;
130 unsigned int rmask;
131 unsigned int gmask;
132 unsigned int bmask;
133 } ConvertMode;
135 typedef struct {
136 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
137 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
138 } ConvertFuncs;
140 typedef struct {
141 ConvertMode screen, dest;
142 ConvertFuncs funcs;
143 } Convert;
145 static Convert ModeEmulations[] = {
146 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
147 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
148 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
149 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
150 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
153 #ifdef HAVE_LIBXXF86VM
154 static XF86VidModeModeInfo *orig_mode = NULL;
155 #endif
157 #ifdef HAVE_LIBXXSHM
158 static int XShmErrorFlag = 0;
159 #endif
161 BOOL
162 DDRAW_DGA_Available(void)
164 #ifdef HAVE_LIBXXF86DGA
165 int evbase, evret, fd;
167 if (Options.noDGA)
168 return 0;
170 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
171 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
172 /* others. --stephenc */
173 if ((fd = open("/dev/mem", O_RDWR)) != -1)
174 close(fd);
176 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
177 #else /* defined(HAVE_LIBXXF86DGA) */
178 return 0;
179 #endif /* defined(HAVE_LIBXXF86DGA) */
182 /**********************************************************************/
184 typedef struct {
185 LPVOID lpCallback;
186 LPVOID lpContext;
187 } DirectDrawEnumerateProcData;
189 /***********************************************************************
190 * DirectDrawEnumerateExA (DDRAW.*)
192 HRESULT WINAPI DirectDrawEnumerateExA(
193 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
195 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
197 if (TRACE_ON(ddraw)) {
198 DPRINTF(" Flags : ");
199 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
200 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
201 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
202 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
203 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
204 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
205 DPRINTF("\n");
208 if (dwFlags & DDENUM_NONDISPLAYDEVICES) {
209 /* For the moment, Wine does not support any 3D only accelerators */
210 return DD_OK;
213 if (DDRAW_DGA_Available()) {
214 TRACE("Enumerating DGA interface\n");
215 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
216 return DD_OK;
219 TRACE("Enumerating Xlib interface\n");
220 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
221 return DD_OK;
223 TRACE("Enumerating Default interface\n");
224 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
225 return DD_OK;
227 return DD_OK;
230 /***********************************************************************
231 * DirectDrawEnumerateExW (DDRAW.*)
234 static BOOL CALLBACK DirectDrawEnumerateExProcW(
235 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
236 LPVOID lpContext, HMONITOR hm)
238 DirectDrawEnumerateProcData *pEPD =
239 (DirectDrawEnumerateProcData *) lpContext;
240 LPWSTR lpDriverDescriptionW =
241 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
242 LPWSTR lpDriverNameW =
243 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
245 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
246 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
248 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
249 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
251 return bResult;
254 /**********************************************************************/
256 HRESULT WINAPI DirectDrawEnumerateExW(
257 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
259 DirectDrawEnumerateProcData epd;
260 epd.lpCallback = (LPVOID) lpCallback;
261 epd.lpContext = lpContext;
263 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
264 (LPVOID) &epd, 0);
267 /***********************************************************************
268 * DirectDrawEnumerateA (DDRAW.*)
271 static BOOL CALLBACK DirectDrawEnumerateProcA(
272 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
273 LPVOID lpContext, HMONITOR hm)
275 DirectDrawEnumerateProcData *pEPD =
276 (DirectDrawEnumerateProcData *) lpContext;
278 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
279 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
282 /**********************************************************************/
284 HRESULT WINAPI DirectDrawEnumerateA(
285 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
287 DirectDrawEnumerateProcData epd;
288 epd.lpCallback = (LPVOID) lpCallback;
289 epd.lpContext = lpContext;
291 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
292 (LPVOID) &epd, 0);
295 /***********************************************************************
296 * DirectDrawEnumerateW (DDRAW.*)
299 static BOOL WINAPI DirectDrawEnumerateProcW(
300 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
301 LPVOID lpContext, HMONITOR hm)
303 DirectDrawEnumerateProcData *pEPD =
304 (DirectDrawEnumerateProcData *) lpContext;
306 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
307 lpGUID, lpDriverDescription, lpDriverName,
308 pEPD->lpContext);
311 /**********************************************************************/
313 HRESULT WINAPI DirectDrawEnumerateW(
314 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
316 DirectDrawEnumerateProcData epd;
317 epd.lpCallback = (LPVOID) lpCallback;
318 epd.lpContext = lpContext;
320 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
321 (LPVOID) &epd, 0);
324 /***********************************************************************
325 * DSoundHelp (DDRAW.?)
328 /* What is this doing here? */
329 HRESULT WINAPI
330 DSoundHelp(DWORD x,DWORD y,DWORD z) {
331 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
332 return 0;
335 /******************************************************************************
336 * internal helper functions
338 static void _dump_DDBLTFX(DWORD flagmask) {
339 int i;
340 const struct {
341 DWORD mask;
342 char *name;
343 } flags[] = {
344 #define FE(x) { x, #x},
345 FE(DDBLTFX_ARITHSTRETCHY)
346 FE(DDBLTFX_MIRRORLEFTRIGHT)
347 FE(DDBLTFX_MIRRORUPDOWN)
348 FE(DDBLTFX_NOTEARING)
349 FE(DDBLTFX_ROTATE180)
350 FE(DDBLTFX_ROTATE270)
351 FE(DDBLTFX_ROTATE90)
352 FE(DDBLTFX_ZBUFFERRANGE)
353 FE(DDBLTFX_ZBUFFERBASEDEST)
354 #undef FE
356 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
357 if (flags[i].mask & flagmask) {
358 DPRINTF("%s ",flags[i].name);
361 DPRINTF("\n");
365 static void _dump_DDBLTFAST(DWORD flagmask) {
366 int i;
367 const struct {
368 DWORD mask;
369 char *name;
370 } flags[] = {
371 #define FE(x) { x, #x},
372 FE(DDBLTFAST_NOCOLORKEY)
373 FE(DDBLTFAST_SRCCOLORKEY)
374 FE(DDBLTFAST_DESTCOLORKEY)
375 FE(DDBLTFAST_WAIT)
376 #undef FE
378 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
379 if (flags[i].mask & flagmask)
380 DPRINTF("%s ",flags[i].name);
381 DPRINTF("\n");
384 static void _dump_DDBLT(DWORD flagmask) {
385 int i;
386 const struct {
387 DWORD mask;
388 char *name;
389 } flags[] = {
390 #define FE(x) { x, #x},
391 FE(DDBLT_ALPHADEST)
392 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
393 FE(DDBLT_ALPHADESTNEG)
394 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
395 FE(DDBLT_ALPHAEDGEBLEND)
396 FE(DDBLT_ALPHASRC)
397 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
398 FE(DDBLT_ALPHASRCNEG)
399 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
400 FE(DDBLT_ASYNC)
401 FE(DDBLT_COLORFILL)
402 FE(DDBLT_DDFX)
403 FE(DDBLT_DDROPS)
404 FE(DDBLT_KEYDEST)
405 FE(DDBLT_KEYDESTOVERRIDE)
406 FE(DDBLT_KEYSRC)
407 FE(DDBLT_KEYSRCOVERRIDE)
408 FE(DDBLT_ROP)
409 FE(DDBLT_ROTATIONANGLE)
410 FE(DDBLT_ZBUFFER)
411 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
412 FE(DDBLT_ZBUFFERDESTOVERRIDE)
413 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
414 FE(DDBLT_ZBUFFERSRCOVERRIDE)
415 FE(DDBLT_WAIT)
416 FE(DDBLT_DEPTHFILL)
417 #undef FE
419 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
420 if (flags[i].mask & flagmask)
421 DPRINTF("%s ",flags[i].name);
422 DPRINTF("\n");
425 static void _dump_DDSCAPS(void *in) {
426 int i;
427 const struct {
428 DWORD mask;
429 char *name;
430 } flags[] = {
431 #define FE(x) { x, #x},
432 FE(DDSCAPS_RESERVED1)
433 FE(DDSCAPS_ALPHA)
434 FE(DDSCAPS_BACKBUFFER)
435 FE(DDSCAPS_COMPLEX)
436 FE(DDSCAPS_FLIP)
437 FE(DDSCAPS_FRONTBUFFER)
438 FE(DDSCAPS_OFFSCREENPLAIN)
439 FE(DDSCAPS_OVERLAY)
440 FE(DDSCAPS_PALETTE)
441 FE(DDSCAPS_PRIMARYSURFACE)
442 FE(DDSCAPS_PRIMARYSURFACELEFT)
443 FE(DDSCAPS_SYSTEMMEMORY)
444 FE(DDSCAPS_TEXTURE)
445 FE(DDSCAPS_3DDEVICE)
446 FE(DDSCAPS_VIDEOMEMORY)
447 FE(DDSCAPS_VISIBLE)
448 FE(DDSCAPS_WRITEONLY)
449 FE(DDSCAPS_ZBUFFER)
450 FE(DDSCAPS_OWNDC)
451 FE(DDSCAPS_LIVEVIDEO)
452 FE(DDSCAPS_HWCODEC)
453 FE(DDSCAPS_MODEX)
454 FE(DDSCAPS_MIPMAP)
455 FE(DDSCAPS_RESERVED2)
456 FE(DDSCAPS_ALLOCONLOAD)
457 FE(DDSCAPS_VIDEOPORT)
458 FE(DDSCAPS_LOCALVIDMEM)
459 FE(DDSCAPS_NONLOCALVIDMEM)
460 FE(DDSCAPS_STANDARDVGAMODE)
461 FE(DDSCAPS_OPTIMIZED)
462 #undef FE
464 DWORD flagmask = *((DWORD *) in);
465 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
466 if (flags[i].mask & flagmask)
467 DPRINTF("%s ",flags[i].name);
470 static void _dump_pixelformat_flag(DWORD flagmask) {
471 int i;
472 const struct {
473 DWORD mask;
474 char *name;
475 } flags[] = {
476 #define FE(x) { x, #x},
477 FE(DDPF_ALPHAPIXELS)
478 FE(DDPF_ALPHA)
479 FE(DDPF_FOURCC)
480 FE(DDPF_PALETTEINDEXED4)
481 FE(DDPF_PALETTEINDEXEDTO8)
482 FE(DDPF_PALETTEINDEXED8)
483 FE(DDPF_RGB)
484 FE(DDPF_COMPRESSED)
485 FE(DDPF_RGBTOYUV)
486 FE(DDPF_YUV)
487 FE(DDPF_ZBUFFER)
488 FE(DDPF_PALETTEINDEXED1)
489 FE(DDPF_PALETTEINDEXED2)
490 FE(DDPF_ZPIXELS)
491 #undef FE
493 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
494 if (flags[i].mask & flagmask)
495 DPRINTF("%s ",flags[i].name);
498 static void _dump_paletteformat(DWORD dwFlags) {
499 int i;
500 const struct {
501 DWORD mask;
502 char *name;
503 } flags[] = {
504 #define FE(x) { x, #x},
505 FE(DDPCAPS_4BIT)
506 FE(DDPCAPS_8BITENTRIES)
507 FE(DDPCAPS_8BIT)
508 FE(DDPCAPS_INITIALIZE)
509 FE(DDPCAPS_PRIMARYSURFACE)
510 FE(DDPCAPS_PRIMARYSURFACELEFT)
511 FE(DDPCAPS_ALLOW256)
512 FE(DDPCAPS_VSYNC)
513 FE(DDPCAPS_1BIT)
514 FE(DDPCAPS_2BIT)
515 FE(DDPCAPS_ALPHA)
516 #undef FE
518 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
519 if (flags[i].mask & dwFlags)
520 DPRINTF("%s ",flags[i].name);
521 DPRINTF("\n");
524 static void _dump_pixelformat(void *in) {
525 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
526 char *cmd;
528 DPRINTF("( ");
529 _dump_pixelformat_flag(pf->dwFlags);
530 if (pf->dwFlags & DDPF_FOURCC) {
531 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
533 if (pf->dwFlags & DDPF_RGB) {
534 DPRINTF(", RGB bits: %ld, ", pf->x.dwRGBBitCount);
535 switch (pf->x.dwRGBBitCount) {
536 case 4:
537 cmd = "%1lx";
538 break;
539 case 8:
540 cmd = "%02lx";
541 break;
542 case 16:
543 cmd = "%04lx";
544 break;
545 case 24:
546 cmd = "%06lx";
547 break;
548 case 32:
549 cmd = "%08lx";
550 break;
551 default:
552 ERR("Unexpected bit depth !\n");
553 cmd = "%d";
555 DPRINTF(" R "); DPRINTF(cmd, pf->y.dwRBitMask);
556 DPRINTF(" G "); DPRINTF(cmd, pf->z.dwGBitMask);
557 DPRINTF(" B "); DPRINTF(cmd, pf->xx.dwBBitMask);
558 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
559 DPRINTF(" A "); DPRINTF(cmd, pf->xy.dwRGBAlphaBitMask);
561 if (pf->dwFlags & DDPF_ZPIXELS) {
562 DPRINTF(" Z "); DPRINTF(cmd, pf->xy.dwRGBZBitMask);
565 if (pf->dwFlags & DDPF_ZBUFFER) {
566 DPRINTF(", Z bits : %ld", pf->x.dwZBufferBitDepth);
568 if (pf->dwFlags & DDPF_ALPHA) {
569 DPRINTF(", Alpha bits : %ld", pf->x.dwAlphaBitDepth);
571 DPRINTF(")");
574 static void _dump_colorkeyflag(DWORD ck) {
575 int i;
576 const struct {
577 DWORD mask;
578 char *name;
579 } flags[] = {
580 #define FE(x) { x, #x},
581 FE(DDCKEY_COLORSPACE)
582 FE(DDCKEY_DESTBLT)
583 FE(DDCKEY_DESTOVERLAY)
584 FE(DDCKEY_SRCBLT)
585 FE(DDCKEY_SRCOVERLAY)
586 #undef FE
588 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
589 if (flags[i].mask & ck)
590 DPRINTF("%s ",flags[i].name);
593 static void _dump_DWORD(void *in) {
594 DPRINTF("%ld", *((DWORD *) in));
596 static void _dump_PTR(void *in) {
597 DPRINTF("%p", *((void **) in));
599 static void _dump_DDCOLORKEY(void *in) {
600 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
602 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
605 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
606 int i;
607 const struct {
608 DWORD mask;
609 char *name;
610 void (*func)(void *);
611 void *elt;
612 } flags[] = {
613 #define FE(x,func,elt) { x, #x, func, (void *) &(lpddsd->elt)}
614 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps),
615 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight),
616 FE(DDSD_WIDTH, _dump_DWORD, dwWidth),
617 FE(DDSD_PITCH, _dump_DWORD, lPitch),
618 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount),
619 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, x.dwZBufferBitDepth),
620 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth),
621 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat),
622 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay),
623 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt),
624 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay),
625 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt),
626 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, x.dwMipMapCount),
627 FE(DDSD_REFRESHRATE, _dump_DWORD, x.dwRefreshRate),
628 FE(DDSD_LINEARSIZE, _dump_DWORD, y.dwLinearSize),
629 FE(DDSD_LPSURFACE, _dump_PTR, y.lpSurface)
630 #undef FE
632 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
633 if (flags[i].mask & lpddsd->dwFlags) {
634 DPRINTF(" - %s : ",flags[i].name);
635 flags[i].func(flags[i].elt);
636 DPRINTF("\n");
641 /******************************************************************************
642 * IDirectDrawSurface methods
644 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
645 * DDS and DDS2 use those functions. (Function calls did not change (except
646 * using different DirectDrawSurfaceX version), just added flags and functions)
649 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
650 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
652 ICOM_THIS(IDirectDrawSurface4Impl,iface);
653 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
654 This,lprect,lpddsd,flags,(DWORD)hnd);
655 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
656 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
657 This,lprect,lpddsd,flags,(DWORD)hnd);
659 /* First, copy the Surface description */
660 *lpddsd = This->s.surface_desc;
661 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
662 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
664 /* If asked only for a part, change the surface pointer */
665 if (lprect) {
666 FIXME(" lprect: %dx%d-%dx%d\n",
667 lprect->top,lprect->left,lprect->bottom,lprect->right
669 lpddsd->y.lpSurface = (LPVOID) ((char *) This->s.surface_desc.y.lpSurface +
670 (lprect->top*This->s.surface_desc.lPitch) +
671 (lprect->left*(This->s.surface_desc.ddpfPixelFormat.x.dwRGBBitCount / 8)));
672 } else {
673 assert(This->s.surface_desc.y.lpSurface);
675 return DD_OK;
678 #ifdef HAVE_LIBXXF86DGA
679 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
680 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
682 ICOM_THIS(IDirectDrawSurface4Impl,iface);
683 TRACE("(%p)->Unlock(%p)\n",This,surface);
684 return DD_OK;
686 #endif /* defined(HAVE_LIBXXF86DGA) */
688 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
689 if (This->s.ddraw->d.pixel_convert != NULL)
690 This->s.ddraw->d.pixel_convert(This->s.surface_desc.y.lpSurface,
691 This->t.xlib.image->data,
692 This->s.surface_desc.dwWidth,
693 This->s.surface_desc.dwHeight,
694 This->s.surface_desc.lPitch,
695 This->s.palette);
697 #ifdef HAVE_LIBXXSHM
698 if (This->s.ddraw->e.xlib.xshm_active)
699 TSXShmPutImage(display,
700 This->s.ddraw->d.drawable,
701 DefaultGCOfScreen(X11DRV_GetXScreen()),
702 This->t.xlib.image,
703 0, 0, 0, 0,
704 This->t.xlib.image->width,
705 This->t.xlib.image->height,
706 False);
707 else
708 #endif
709 TSXPutImage( display,
710 This->s.ddraw->d.drawable,
711 DefaultGCOfScreen(X11DRV_GetXScreen()),
712 This->t.xlib.image,
713 0, 0, 0, 0,
714 This->t.xlib.image->width,
715 This->t.xlib.image->height);
718 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
719 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
721 ICOM_THIS(IDirectDrawSurface4Impl,iface);
722 TRACE("(%p)->Unlock(%p)\n",This,surface);
724 if (!This->s.ddraw->d.paintable)
725 return DD_OK;
727 /* Only redraw the screen when unlocking the buffer that is on screen */
728 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
729 Xlib_copy_surface_on_screen(This);
731 if (This->s.palette && This->s.palette->cm)
732 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
734 return DD_OK;
737 static IDirectDrawSurface4Impl* _common_find_flipto(
738 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
740 int i,j,flipable=0;
741 struct _surface_chain *chain = This->s.chain;
743 /* if there was no override flipto, look for current backbuffer */
744 if (!flipto) {
745 /* walk the flip chain looking for backbuffer */
746 for (i=0;i<chain->nrofsurfaces;i++) {
747 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
748 flipable++;
749 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
750 flipto = chain->surfaces[i];
752 /* sanity checks ... */
753 if (!flipto) {
754 if (flipable>1) {
755 for (i=0;i<chain->nrofsurfaces;i++)
756 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
757 break;
758 if (i==chain->nrofsurfaces) {
759 /* we do not have a frontbuffer either */
760 for (i=0;i<chain->nrofsurfaces;i++)
761 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
762 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
763 break;
765 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
766 int k = j % chain->nrofsurfaces;
767 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
768 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
769 flipto = chain->surfaces[k];
770 break;
775 if (!flipto)
776 flipto = This;
778 TRACE("flipping to %p\n",flipto);
780 return flipto;
783 #ifdef HAVE_LIBXXF86DGA
784 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
785 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
787 ICOM_THIS(IDirectDrawSurface4Impl,iface);
788 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
789 DWORD xheight;
790 LPBYTE surf;
792 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
793 iflipto = _common_find_flipto(This,iflipto);
795 /* and flip! */
796 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
797 if (iflipto->s.palette && iflipto->s.palette->cm)
798 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
799 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
802 /* We need to switch the lowlevel surfaces, for DGA this is: */
804 /* The height within the framebuffer */
805 xheight = This->t.dga.fb_height;
806 This->t.dga.fb_height = iflipto->t.dga.fb_height;
807 iflipto->t.dga.fb_height = xheight;
809 /* And the assciated surface pointer */
810 surf = This->s.surface_desc.y.lpSurface;
811 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
812 iflipto->s.surface_desc.y.lpSurface = surf;
814 return DD_OK;
816 #endif /* defined(HAVE_LIBXXF86DGA) */
818 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
819 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
821 ICOM_THIS(IDirectDrawSurface4Impl,iface);
822 XImage *image;
823 LPBYTE surf;
824 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
826 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
827 iflipto = _common_find_flipto(This,iflipto);
829 #if defined(HAVE_MESAGL) && 0 /* does not work */
830 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
831 TRACE(" - OpenGL flip\n");
832 ENTER_GL();
833 glXSwapBuffers(display, This->s.ddraw->d.drawable);
834 LEAVE_GL();
836 return DD_OK;
838 #endif /* defined(HAVE_MESAGL) */
840 if (!This->s.ddraw->d.paintable)
841 return DD_OK;
843 Xlib_copy_surface_on_screen(iflipto);
845 /* We need to switch the lowlevel surfaces, for xlib this is: */
846 /* The surface pointer */
847 surf = This->s.surface_desc.y.lpSurface;
848 This->s.surface_desc.y.lpSurface = iflipto->s.surface_desc.y.lpSurface;
849 iflipto->s.surface_desc.y.lpSurface = surf;
850 /* the associated ximage */
851 image = This->t.xlib.image;
852 This->t.xlib.image = iflipto->t.xlib.image;
853 iflipto->t.xlib.image = image;
855 if (iflipto->s.palette && iflipto->s.palette->cm)
856 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
857 return DD_OK;
860 /* The IDirectDrawSurface4::SetPalette method attaches the specified
861 * DirectDrawPalette object to a surface. The surface uses this palette for all
862 * subsequent operations. The palette change takes place immediately.
864 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
865 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
867 ICOM_THIS(IDirectDrawSurface4Impl,iface);
868 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
869 int i;
870 TRACE("(%p)->(%p)\n",This,ipal);
872 if (ipal == NULL) {
873 if( This->s.palette != NULL )
874 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
875 This->s.palette = ipal;
877 return DD_OK;
880 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.x.dwRGBBitCount<=8))
882 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
883 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
885 if (!Options.managed)
886 TSXInstallColormap(display,ipal->cm);
888 for (i=0;i<256;i++) {
889 XColor xc;
891 xc.red = ipal->palents[i].peRed<<8;
892 xc.blue = ipal->palents[i].peBlue<<8;
893 xc.green = ipal->palents[i].peGreen<<8;
894 xc.flags = DoRed|DoBlue|DoGreen;
895 xc.pixel = i;
896 TSXStoreColor(display,ipal->cm,&xc);
898 TSXInstallColormap(display,ipal->cm);
901 /* According to spec, we are only supposed to
902 * AddRef if this is not the same palette.
904 if( This->s.palette != ipal )
906 if( ipal != NULL )
907 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
908 if( This->s.palette != NULL )
909 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
910 This->s.palette = ipal;
911 /* Perform the refresh */
912 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
914 return DD_OK;
917 #ifdef HAVE_LIBXXF86DGA
918 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
919 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
921 ICOM_THIS(IDirectDrawSurface4Impl,iface);
922 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
923 TRACE("(%p)->(%p)\n",This,ipal);
925 /* According to spec, we are only supposed to
926 * AddRef if this is not the same palette.
928 if( This->s.palette != ipal )
930 if( ipal != NULL )
931 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
932 if( This->s.palette != NULL )
933 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
934 This->s.palette = ipal;
935 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
937 return DD_OK;
939 #endif /* defined(HAVE_LIBXXF86DGA) */
941 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
943 int x, y;
944 LPBYTE first;
946 /* Do first row */
948 #define COLORFILL_ROW(type) { \
949 type *d = (type *) buf; \
950 for (x = 0; x < width; x++) \
951 d[x] = (type) color; \
952 break; \
955 switch(bpp) {
956 case 1: COLORFILL_ROW(BYTE)
957 case 2: COLORFILL_ROW(WORD)
958 case 4: COLORFILL_ROW(DWORD)
959 default:
960 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
961 return DDERR_UNSUPPORTED;
964 #undef COLORFILL_ROW
966 /* Now copy first row */
967 first = buf;
968 for (y = 1; y < height; y++) {
969 buf += lPitch;
970 memcpy(buf, first, width * bpp);
973 return DD_OK;
976 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
977 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
979 ICOM_THIS(IDirectDrawSurface4Impl,iface);
980 RECT xdst,xsrc;
981 DDSURFACEDESC ddesc,sdesc;
982 HRESULT ret = DD_OK;
983 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
984 int x, y;
985 LPBYTE dbuf, sbuf;
987 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
989 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
990 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
992 if (TRACE_ON(ddraw)) {
993 if (rdst) TRACE(" destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
994 if (rsrc) TRACE(" srcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
995 TRACE("\tflags: ");
996 _dump_DDBLT(dwFlags);
997 if (dwFlags & DDBLT_DDFX) {
998 TRACE(" blitfx: \n");
999 _dump_DDBLTFX(lpbltfx->dwDDFX);
1003 if (rdst) {
1004 memcpy(&xdst,rdst,sizeof(xdst));
1005 } else {
1006 xdst.top = 0;
1007 xdst.bottom = ddesc.dwHeight;
1008 xdst.left = 0;
1009 xdst.right = ddesc.dwWidth;
1012 if (rsrc) {
1013 memcpy(&xsrc,rsrc,sizeof(xsrc));
1014 } else {
1015 if (src) {
1016 xsrc.top = 0;
1017 xsrc.bottom = sdesc.dwHeight;
1018 xsrc.left = 0;
1019 xsrc.right = sdesc.dwWidth;
1020 } else {
1021 memset(&xsrc,0,sizeof(xsrc));
1025 bpp = GET_BPP(ddesc);
1026 srcheight = xsrc.bottom - xsrc.top;
1027 srcwidth = xsrc.right - xsrc.left;
1028 dstheight = xdst.bottom - xdst.top;
1029 dstwidth = xdst.right - xdst.left;
1030 width = (xdst.right - xdst.left) * bpp;
1031 dbuf = (BYTE *) ddesc.y.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1033 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1035 /* First, all the 'source-less' blits */
1036 if (dwFlags & DDBLT_COLORFILL) {
1037 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1038 ddesc.lPitch, lpbltfx->b.dwFillColor);
1039 dwFlags &= ~DDBLT_COLORFILL;
1042 if (dwFlags & DDBLT_DEPTHFILL) {
1043 #ifdef HAVE_MESAGL
1044 GLboolean ztest;
1046 /* Clears the screen */
1047 TRACE(" Filling depth buffer with %ld\n", lpbltfx->b.dwFillDepth);
1048 glClearDepth(lpbltfx->b.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1049 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1050 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1051 glClear(GL_DEPTH_BUFFER_BIT);
1052 glDepthMask(ztest);
1054 dwFlags &= ~(DDBLT_DEPTHFILL);
1055 #endif /* defined(HAVE_MESAGL) */
1058 if (dwFlags & DDBLT_ROP) {
1059 /* Catch some degenerate cases here */
1060 switch(lpbltfx->dwROP) {
1061 case BLACKNESS:
1062 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1063 break;
1064 case 0xAA0029: /* No-op */
1065 break;
1066 case WHITENESS:
1067 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1068 break;
1069 default:
1070 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->b.lpDDSPattern);
1071 goto error;
1073 dwFlags &= ~DDBLT_ROP;
1076 if (dwFlags & DDBLT_DDROPS) {
1077 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->b.lpDDSPattern);
1080 /* Now the 'with source' blits */
1081 if (src) {
1082 LPBYTE sbase;
1083 int sx, xinc, sy, yinc;
1085 sbase = (BYTE *) sdesc.y.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1086 xinc = (srcwidth << 16) / dstwidth;
1087 yinc = (srcheight << 16) / dstheight;
1089 if (!dwFlags) {
1091 /* No effects, we can cheat here */
1092 if (dstwidth == srcwidth) {
1093 if (dstheight == srcheight) {
1094 /* No stretching in either direction. This needs to be as fast as possible */
1095 sbuf = sbase;
1096 for (y = 0; y < dstheight; y++) {
1097 memcpy(dbuf, sbuf, width);
1098 sbuf += sdesc.lPitch;
1099 dbuf += ddesc.lPitch;
1101 } else {
1102 /* Stretching in Y direction only */
1103 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1104 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1105 memcpy(dbuf, sbuf, width);
1106 dbuf += ddesc.lPitch;
1109 } else {
1110 /* Stretching in X direction */
1111 int last_sy = -1;
1112 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1113 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1115 if ((sy >> 16) == (last_sy >> 16)) {
1116 /* Same as last row - copy already stretched row */
1117 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1118 } else {
1120 #define STRETCH_ROW(type) { \
1121 type *s = (type *) sbuf, *d = (type *) dbuf; \
1122 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1123 d[x] = s[sx >> 16]; \
1124 break; \
1127 switch(bpp) {
1128 case 1: STRETCH_ROW(BYTE)
1129 case 2: STRETCH_ROW(WORD)
1130 case 4: STRETCH_ROW(DWORD)
1131 default:
1132 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1133 ret = DDERR_UNSUPPORTED;
1134 goto error;
1137 #undef STRETCH_ROW
1140 last_sy = sy;
1141 dbuf += ddesc.lPitch;
1144 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1145 DWORD keylow, keyhigh;
1147 if (dwFlags & DDBLT_KEYSRC) {
1148 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1149 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1150 } else {
1151 /* I'm not sure if this is correct */
1152 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1153 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1154 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1157 #define COPYROW_COLORKEY(type) { \
1158 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1159 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1160 tmp = s[sx >> 16]; \
1161 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1163 break; \
1166 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1167 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1169 switch (bpp) {
1170 case 1: COPYROW_COLORKEY(BYTE)
1171 case 2: COPYROW_COLORKEY(WORD)
1172 case 4: COPYROW_COLORKEY(DWORD)
1173 default:
1174 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1175 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1176 ret = DDERR_UNSUPPORTED;
1177 goto error;
1179 dbuf += ddesc.lPitch;
1182 #undef COPYROW_COLORKEY
1184 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1189 error:
1191 if (dwFlags && FIXME_ON(ddraw)) {
1192 FIXME("\tUnsupported flags: ");
1193 _dump_DDBLT(dwFlags);
1196 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1197 if (src) IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1199 return DD_OK;
1202 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1203 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1205 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1206 int bpp, w, h, x, y;
1207 DDSURFACEDESC ddesc,sdesc;
1208 HRESULT ret = DD_OK;
1209 LPBYTE sbuf, dbuf;
1212 if (TRACE_ON(ddraw)) {
1213 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1214 This,dstx,dsty,src,rsrc,trans
1216 FIXME(" trans:");
1217 if (FIXME_ON(ddraw))
1218 _dump_DDBLTFAST(trans);
1219 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1221 /* We need to lock the surfaces, or we won't get refreshes when done. */
1222 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1223 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1225 bpp = GET_BPP(This->s.surface_desc);
1226 sbuf = (BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1227 dbuf = (BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1230 h=rsrc->bottom-rsrc->top;
1231 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1232 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1233 if (h<0) h=0;
1235 w=rsrc->right-rsrc->left;
1236 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1237 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1238 if (w<0) w=0;
1240 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1241 DWORD keylow, keyhigh;
1242 if (trans & DDBLTFAST_SRCCOLORKEY) {
1243 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1244 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1245 } else {
1246 /* I'm not sure if this is correct */
1247 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1248 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1249 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1252 #define COPYBOX_COLORKEY(type) { \
1253 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1254 s = (type *) ((BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1255 d = (type *) ((BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1256 for (y = 0; y < h; y++) { \
1257 for (x = 0; x < w; x++) { \
1258 tmp = s[x]; \
1259 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1261 (LPBYTE)s += sdesc.lPitch; \
1262 (LPBYTE)d += ddesc.lPitch; \
1264 break; \
1267 switch (bpp) {
1268 case 1: COPYBOX_COLORKEY(BYTE)
1269 case 2: COPYBOX_COLORKEY(WORD)
1270 case 4: COPYBOX_COLORKEY(DWORD)
1271 default:
1272 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1273 ret = DDERR_UNSUPPORTED;
1274 goto error;
1277 #undef COPYBOX_COLORKEY
1279 } else {
1280 int width = w * bpp;
1282 for (y = 0; y < h; y++) {
1283 memcpy(dbuf, sbuf, width);
1284 sbuf += sdesc.lPitch;
1285 dbuf += ddesc.lPitch;
1289 error:
1291 IDirectDrawSurface4_Unlock(iface,ddesc.y.lpSurface);
1292 IDirectDrawSurface4_Unlock(src,sdesc.y.lpSurface);
1293 return ret;
1296 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1297 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1299 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1300 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1301 This,ddbltbatch,x,y
1303 return DD_OK;
1306 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1307 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1309 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1310 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1311 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1312 return DD_OK;
1315 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1316 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1317 ) {
1318 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1319 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1321 /* Simply copy the surface description stored in the object */
1322 *ddsd = This->s.surface_desc;
1324 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1326 return DD_OK;
1329 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1330 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1331 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1332 return ++(This->ref);
1335 #ifdef HAVE_LIBXXF86DGA
1336 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1337 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1339 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1341 if (--(This->ref))
1342 return This->ref;
1344 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1345 /* clear out of surface list */
1346 if (This->t.dga.fb_height == -1)
1347 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1348 else
1349 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1351 /* Free the DIBSection (if any) */
1352 if (This->s.hdc != 0) {
1353 SelectObject(This->s.hdc, This->s.holdbitmap);
1354 DeleteDC(This->s.hdc);
1355 DeleteObject(This->s.DIBsection);
1358 HeapFree(GetProcessHeap(),0,This);
1359 return 0;
1361 #endif /* defined(HAVE_LIBXXF86DGA) */
1363 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1364 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1366 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1368 if (--(This->ref))
1369 return This->ref;
1371 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1373 if (This->t.xlib.image != NULL) {
1374 if (This->s.ddraw->d.pixel_convert != NULL) {
1375 /* In pixel conversion mode, there are 2 buffers to release. */
1376 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1378 #ifdef HAVE_LIBXXSHM
1379 if (This->s.ddraw->e.xlib.xshm_active) {
1380 TSXShmDetach(display, &(This->t.xlib.shminfo));
1381 TSXDestroyImage(This->t.xlib.image);
1382 shmdt(This->t.xlib.shminfo.shmaddr);
1383 } else {
1384 #endif
1385 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1386 This->t.xlib.image->data = NULL;
1387 TSXDestroyImage(This->t.xlib.image);
1388 #ifdef HAVE_LIBXXSHM
1390 #endif
1391 } else {
1392 This->t.xlib.image->data = NULL;
1394 #ifdef HAVE_LIBXXSHM
1395 if (This->s.ddraw->e.xlib.xshm_active) {
1396 TSXShmDetach(display, &(This->t.xlib.shminfo));
1397 TSXDestroyImage(This->t.xlib.image);
1398 shmdt(This->t.xlib.shminfo.shmaddr);
1399 } else {
1400 #endif
1401 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1402 TSXDestroyImage(This->t.xlib.image);
1403 #ifdef HAVE_LIBXXSHM
1405 #endif
1407 This->t.xlib.image = 0;
1408 } else {
1409 HeapFree(GetProcessHeap(),0,This->s.surface_desc.y.lpSurface);
1412 if (This->s.palette)
1413 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1415 /* Free the DIBSection (if any) */
1416 if (This->s.hdc != 0) {
1417 SelectObject(This->s.hdc, This->s.holdbitmap);
1418 DeleteDC(This->s.hdc);
1419 DeleteObject(This->s.DIBsection);
1422 HeapFree(GetProcessHeap(),0,This);
1423 return 0;
1426 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1427 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1429 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1430 int i,found = 0,xstart;
1431 struct _surface_chain *chain;
1433 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1434 if (TRACE_ON(ddraw)) {
1435 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1437 chain = This->s.chain;
1438 if (!chain)
1439 return DDERR_NOTFOUND;
1441 for (i=0;i<chain->nrofsurfaces;i++)
1442 if (chain->surfaces[i] == This)
1443 break;
1445 xstart = i;
1446 for (i=0;i<chain->nrofsurfaces;i++) {
1447 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1448 #if 0
1449 if (found) /* may not find the same caps twice, (doc) */
1450 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1451 #endif
1452 found = (i+1)+xstart;
1455 if (!found)
1456 return DDERR_NOTFOUND;
1457 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1458 /* FIXME: AddRef? */
1459 TRACE("found %p\n",*lpdsf);
1460 return DD_OK;
1463 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1464 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1466 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1467 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1469 return DDERR_ALREADYINITIALIZED;
1472 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1473 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1475 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1476 TRACE("(%p)->(%p)\n",This,pf);
1478 *pf = This->s.surface_desc.ddpfPixelFormat;
1479 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1480 return DD_OK;
1483 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1484 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1485 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1486 return DD_OK;
1489 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1490 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1492 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1493 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1494 return DD_OK;
1497 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1498 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1500 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1501 FIXME("(%p)->(%p),stub!\n",This,clipper);
1502 return DD_OK;
1505 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1506 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1508 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1509 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1510 int i;
1511 struct _surface_chain *chain;
1513 IDirectDrawSurface4_AddRef(iface);
1515 FIXME("(%p)->(%p)\n",This,surf);
1516 chain = This->s.chain;
1518 if (chain) {
1519 for (i=0;i<chain->nrofsurfaces;i++)
1520 if (chain->surfaces[i] == isurf)
1521 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1522 } else {
1523 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1524 chain->nrofsurfaces = 1;
1525 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1526 chain->surfaces[0] = This;
1527 This->s.chain = chain;
1530 if (chain->surfaces)
1531 chain->surfaces = HeapReAlloc(
1532 GetProcessHeap(),
1534 chain->surfaces,
1535 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1537 else
1538 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1539 isurf->s.chain = chain;
1540 chain->surfaces[chain->nrofsurfaces++] = isurf;
1541 return DD_OK;
1544 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1545 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1546 DDSURFACEDESC desc;
1547 BITMAPINFO *b_info;
1548 UINT usage;
1550 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1552 /* Creates a DIB Section of the same size / format as the surface */
1553 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1555 if (This->s.hdc == 0) {
1556 switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
1557 case 16:
1558 case 32:
1559 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1560 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1561 break;
1562 #endif
1564 case 24:
1565 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1566 break;
1568 default:
1569 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1570 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.x.dwRGBBitCount));
1571 break;
1574 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1575 b_info->bmiHeader.biWidth = desc.dwWidth;
1576 b_info->bmiHeader.biHeight = desc.dwHeight;
1577 b_info->bmiHeader.biPlanes = 1;
1578 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.x.dwRGBBitCount;
1579 #if 0
1580 if ((desc.ddpfPixelFormat.x.dwRGBBitCount != 16) &&
1581 (desc.ddpfPixelFormat.x.dwRGBBitCount != 32))
1582 #endif
1583 b_info->bmiHeader.biCompression = BI_RGB;
1584 #if 0
1585 else
1586 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1587 #endif
1588 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.x.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1589 b_info->bmiHeader.biXPelsPerMeter = 0;
1590 b_info->bmiHeader.biYPelsPerMeter = 0;
1591 b_info->bmiHeader.biClrUsed = 0;
1592 b_info->bmiHeader.biClrImportant = 0;
1594 switch (desc.ddpfPixelFormat.x.dwRGBBitCount) {
1595 case 16:
1596 case 32:
1597 #if 0
1599 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1601 usage = 0;
1602 masks[0] = desc.ddpfPixelFormat.y.dwRBitMask;
1603 masks[1] = desc.ddpfPixelFormat.z.dwGBitMask;
1604 masks[2] = desc.ddpfPixelFormat.xx.dwBBitMask;
1606 break;
1607 #endif
1608 case 24:
1609 /* Nothing to do */
1610 usage = DIB_RGB_COLORS;
1611 break;
1613 default: {
1614 int i;
1616 /* Fill the palette */
1617 usage = DIB_RGB_COLORS;
1619 if (This->s.palette == NULL) {
1620 ERR("Bad palette !!!\n");
1621 } else {
1622 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1623 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1625 for (i=0;i<(1<<desc.ddpfPixelFormat.x.dwRGBBitCount);i++) {
1626 rgb[i].rgbBlue = pent[i].peBlue;
1627 rgb[i].rgbRed = pent[i].peRed;
1628 rgb[i].rgbGreen = pent[i].peGreen;
1632 break;
1634 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1635 b_info,
1636 usage,
1637 &(This->s.bitmap_data),
1641 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1642 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1644 /* b_info is not useful anymore */
1645 HeapFree(GetProcessHeap(), 0, b_info);
1647 /* Create the DC */
1648 This->s.hdc = CreateCompatibleDC(0);
1649 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1652 /* Copy our surface in the DIB section */
1653 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1654 memcpy(This->s.bitmap_data,desc.y.lpSurface,desc.lPitch*desc.dwHeight);
1655 else
1656 /* TODO */
1657 FIXME("This case has to be done :/\n");
1659 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1660 *lphdc = This->s.hdc;
1662 return DD_OK;
1665 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1666 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1668 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1669 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1670 /* Copy the DIB section to our surface */
1671 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1672 memcpy(This->s.surface_desc.y.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1673 } else {
1674 /* TODO */
1675 FIXME("This case has to be done :/\n");
1677 /* Unlock the surface */
1678 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.y.lpSurface);
1679 return DD_OK;
1682 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1683 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1684 char xrefiid[50];
1686 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1687 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
1689 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1690 * the same interface. And IUnknown does that too of course.
1692 if ( !memcmp(&IID_IDirectDrawSurface4,refiid,sizeof(IID)) ||
1693 !memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID)) ||
1694 !memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID)) ||
1695 !memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID)) ||
1696 !memcmp(&IID_IUnknown,refiid,sizeof(IID))
1698 *obj = This;
1699 IDirectDrawSurface4_AddRef(iface);
1701 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1702 return S_OK;
1704 else if (!memcmp(&IID_IDirect3DTexture2,refiid,sizeof(IID)))
1706 /* Texture interface */
1707 *obj = d3dtexture2_create(This);
1708 IDirectDrawSurface4_AddRef(iface);
1709 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1710 return S_OK;
1712 else if (!memcmp(&IID_IDirect3DTexture,refiid,sizeof(IID)))
1714 /* Texture interface */
1715 *obj = d3dtexture_create(This);
1716 IDirectDrawSurface4_AddRef(iface);
1718 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1720 return S_OK;
1722 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1723 /* It is the OpenGL Direct3D Device */
1724 IDirectDrawSurface4_AddRef(iface);
1725 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1726 return S_OK;
1729 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
1730 return OLE_E_ENUM_NOMORE;
1733 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1734 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1735 TRACE("(%p)->(), stub!\n",This);
1736 return DD_OK; /* hmm */
1739 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1740 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1741 int i;
1742 struct _surface_chain *chain = This->s.chain;
1744 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1745 for (i=0;i<chain->nrofsurfaces;i++) {
1746 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1747 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1748 return DD_OK; /* FIXME: return value correct? */
1750 return DD_OK;
1753 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1754 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1755 FIXME("(%p)->(),stub!\n",This);
1756 return DD_OK;
1759 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1760 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1762 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1763 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1764 if (TRACE_ON(ddraw)) {
1765 _dump_colorkeyflag(dwFlags);
1766 DPRINTF(" : ");
1767 _dump_DDCOLORKEY((void *) ckey);
1768 DPRINTF("\n");
1771 /* If this surface was loaded as a texture, call also the texture
1772 SetColorKey callback */
1773 if (This->s.texture) {
1774 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1777 if( dwFlags & DDCKEY_SRCBLT )
1779 dwFlags &= ~DDCKEY_SRCBLT;
1780 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1781 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1784 if( dwFlags & DDCKEY_DESTBLT )
1786 dwFlags &= ~DDCKEY_DESTBLT;
1787 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1788 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1791 if( dwFlags & DDCKEY_SRCOVERLAY )
1793 dwFlags &= ~DDCKEY_SRCOVERLAY;
1794 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1795 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1798 if( dwFlags & DDCKEY_DESTOVERLAY )
1800 dwFlags &= ~DDCKEY_DESTOVERLAY;
1801 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1802 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1805 if( dwFlags )
1807 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1810 return DD_OK;
1814 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1815 LPDIRECTDRAWSURFACE4 iface,
1816 LPRECT lpRect )
1818 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1819 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1821 return DD_OK;
1824 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1825 LPDIRECTDRAWSURFACE4 iface,
1826 DWORD dwFlags,
1827 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1829 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1830 int i;
1831 struct _surface_chain *chain;
1833 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
1834 chain = This->s.chain;
1835 for (i=0;i<chain->nrofsurfaces;i++) {
1836 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
1837 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
1839 chain->surfaces[i]->s.chain = NULL;
1840 memcpy( chain->surfaces+i,
1841 chain->surfaces+(i+1),
1842 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
1844 chain->surfaces = HeapReAlloc(
1845 GetProcessHeap(),
1847 chain->surfaces,
1848 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
1850 chain->nrofsurfaces--;
1851 return DD_OK;
1854 return DD_OK;
1857 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1858 LPDIRECTDRAWSURFACE4 iface,
1859 DWORD dwFlags,
1860 LPVOID lpContext,
1861 LPDDENUMSURFACESCALLBACK lpfnCallback )
1863 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1864 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1865 lpContext, lpfnCallback );
1867 return DD_OK;
1870 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1871 LPDIRECTDRAWSURFACE4 iface,
1872 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1874 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1875 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
1877 return DD_OK;
1880 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1881 LPDIRECTDRAWSURFACE4 iface,
1882 DWORD dwFlags,
1883 LPDDCOLORKEY lpDDColorKey )
1885 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1886 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1888 if( dwFlags & DDCKEY_SRCBLT ) {
1889 dwFlags &= ~DDCKEY_SRCBLT;
1890 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1893 if( dwFlags & DDCKEY_DESTBLT )
1895 dwFlags &= ~DDCKEY_DESTBLT;
1896 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1899 if( dwFlags & DDCKEY_SRCOVERLAY )
1901 dwFlags &= ~DDCKEY_SRCOVERLAY;
1902 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1905 if( dwFlags & DDCKEY_DESTOVERLAY )
1907 dwFlags &= ~DDCKEY_DESTOVERLAY;
1908 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1911 if( dwFlags )
1913 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1916 return DD_OK;
1919 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1920 LPDIRECTDRAWSURFACE4 iface,
1921 DWORD dwFlags )
1923 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1924 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1926 return DD_OK;
1929 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1930 LPDIRECTDRAWSURFACE4 iface,
1931 LPDIRECTDRAWPALETTE* lplpDDPalette )
1933 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1934 FIXME("(%p)->(%p),stub!\n", This, lplpDDPalette);
1936 return DD_OK;
1939 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1940 LPDIRECTDRAWSURFACE4 iface,
1941 LONG lX,
1942 LONG lY)
1944 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1945 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1947 return DD_OK;
1950 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1951 LPDIRECTDRAWSURFACE4 iface,
1952 LPRECT lpSrcRect,
1953 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1954 LPRECT lpDestRect,
1955 DWORD dwFlags,
1956 LPDDOVERLAYFX lpDDOverlayFx )
1958 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1959 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
1960 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
1962 return DD_OK;
1965 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1966 LPDIRECTDRAWSURFACE4 iface,
1967 DWORD dwFlags )
1969 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1970 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1972 return DD_OK;
1975 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1976 LPDIRECTDRAWSURFACE4 iface,
1977 DWORD dwFlags,
1978 LPDIRECTDRAWSURFACE4 lpDDSReference )
1980 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1981 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
1983 return DD_OK;
1986 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
1987 LPDIRECTDRAWSURFACE4 iface,
1988 LPVOID* lplpDD )
1990 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1991 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
1993 /* Not sure about that... */
1994 *lplpDD = (void *) This->s.ddraw;
1996 return DD_OK;
1999 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2000 LPDIRECTDRAWSURFACE4 iface,
2001 DWORD dwFlags )
2003 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2004 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2006 return DD_OK;
2009 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2010 LPDIRECTDRAWSURFACE4 iface,
2011 DWORD dwFlags )
2013 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2014 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2016 return DD_OK;
2019 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2020 LPDIRECTDRAWSURFACE4 iface,
2021 LPDDSURFACEDESC lpDDSD,
2022 DWORD dwFlags )
2024 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2025 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2027 return DD_OK;
2030 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2031 REFGUID guidTag,
2032 LPVOID lpData,
2033 DWORD cbSize,
2034 DWORD dwFlags) {
2035 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2036 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2038 return DD_OK;
2041 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2042 REFGUID guidTag,
2043 LPVOID lpBuffer,
2044 LPDWORD lpcbBufferSize) {
2045 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2046 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2048 return DD_OK;
2051 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2052 REFGUID guidTag) {
2053 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2054 FIXME("(%p)->(%p)\n", This, guidTag);
2056 return DD_OK;
2059 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2060 LPDWORD lpValue) {
2061 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2062 FIXME("(%p)->(%p)\n", This, lpValue);
2064 return DD_OK;
2067 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2068 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2069 FIXME("(%p)\n", This);
2071 return DD_OK;
2074 #ifdef HAVE_LIBXXF86DGA
2075 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2077 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2078 IDirectDrawSurface4Impl_QueryInterface,
2079 IDirectDrawSurface4Impl_AddRef,
2080 DGA_IDirectDrawSurface4Impl_Release,
2081 IDirectDrawSurface4Impl_AddAttachedSurface,
2082 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2083 IDirectDrawSurface4Impl_Blt,
2084 IDirectDrawSurface4Impl_BltBatch,
2085 IDirectDrawSurface4Impl_BltFast,
2086 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2087 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2088 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2089 DGA_IDirectDrawSurface4Impl_Flip,
2090 IDirectDrawSurface4Impl_GetAttachedSurface,
2091 IDirectDrawSurface4Impl_GetBltStatus,
2092 IDirectDrawSurface4Impl_GetCaps,
2093 IDirectDrawSurface4Impl_GetClipper,
2094 IDirectDrawSurface4Impl_GetColorKey,
2095 IDirectDrawSurface4Impl_GetDC,
2096 IDirectDrawSurface4Impl_GetFlipStatus,
2097 IDirectDrawSurface4Impl_GetOverlayPosition,
2098 IDirectDrawSurface4Impl_GetPalette,
2099 IDirectDrawSurface4Impl_GetPixelFormat,
2100 IDirectDrawSurface4Impl_GetSurfaceDesc,
2101 IDirectDrawSurface4Impl_Initialize,
2102 IDirectDrawSurface4Impl_IsLost,
2103 IDirectDrawSurface4Impl_Lock,
2104 IDirectDrawSurface4Impl_ReleaseDC,
2105 IDirectDrawSurface4Impl_Restore,
2106 IDirectDrawSurface4Impl_SetClipper,
2107 IDirectDrawSurface4Impl_SetColorKey,
2108 IDirectDrawSurface4Impl_SetOverlayPosition,
2109 DGA_IDirectDrawSurface4Impl_SetPalette,
2110 DGA_IDirectDrawSurface4Impl_Unlock,
2111 IDirectDrawSurface4Impl_UpdateOverlay,
2112 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2113 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2114 IDirectDrawSurface4Impl_GetDDInterface,
2115 IDirectDrawSurface4Impl_PageLock,
2116 IDirectDrawSurface4Impl_PageUnlock,
2117 IDirectDrawSurface4Impl_SetSurfaceDesc,
2118 IDirectDrawSurface4Impl_SetPrivateData,
2119 IDirectDrawSurface4Impl_GetPrivateData,
2120 IDirectDrawSurface4Impl_FreePrivateData,
2121 IDirectDrawSurface4Impl_GetUniquenessValue,
2122 IDirectDrawSurface4Impl_ChangeUniquenessValue
2124 #endif /* defined(HAVE_LIBXXF86DGA) */
2126 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2128 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2129 IDirectDrawSurface4Impl_QueryInterface,
2130 IDirectDrawSurface4Impl_AddRef,
2131 Xlib_IDirectDrawSurface4Impl_Release,
2132 IDirectDrawSurface4Impl_AddAttachedSurface,
2133 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2134 IDirectDrawSurface4Impl_Blt,
2135 IDirectDrawSurface4Impl_BltBatch,
2136 IDirectDrawSurface4Impl_BltFast,
2137 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2138 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2139 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2140 Xlib_IDirectDrawSurface4Impl_Flip,
2141 IDirectDrawSurface4Impl_GetAttachedSurface,
2142 IDirectDrawSurface4Impl_GetBltStatus,
2143 IDirectDrawSurface4Impl_GetCaps,
2144 IDirectDrawSurface4Impl_GetClipper,
2145 IDirectDrawSurface4Impl_GetColorKey,
2146 IDirectDrawSurface4Impl_GetDC,
2147 IDirectDrawSurface4Impl_GetFlipStatus,
2148 IDirectDrawSurface4Impl_GetOverlayPosition,
2149 IDirectDrawSurface4Impl_GetPalette,
2150 IDirectDrawSurface4Impl_GetPixelFormat,
2151 IDirectDrawSurface4Impl_GetSurfaceDesc,
2152 IDirectDrawSurface4Impl_Initialize,
2153 IDirectDrawSurface4Impl_IsLost,
2154 IDirectDrawSurface4Impl_Lock,
2155 IDirectDrawSurface4Impl_ReleaseDC,
2156 IDirectDrawSurface4Impl_Restore,
2157 IDirectDrawSurface4Impl_SetClipper,
2158 IDirectDrawSurface4Impl_SetColorKey,
2159 IDirectDrawSurface4Impl_SetOverlayPosition,
2160 Xlib_IDirectDrawSurface4Impl_SetPalette,
2161 Xlib_IDirectDrawSurface4Impl_Unlock,
2162 IDirectDrawSurface4Impl_UpdateOverlay,
2163 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2164 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2165 IDirectDrawSurface4Impl_GetDDInterface,
2166 IDirectDrawSurface4Impl_PageLock,
2167 IDirectDrawSurface4Impl_PageUnlock,
2168 IDirectDrawSurface4Impl_SetSurfaceDesc,
2169 IDirectDrawSurface4Impl_SetPrivateData,
2170 IDirectDrawSurface4Impl_GetPrivateData,
2171 IDirectDrawSurface4Impl_FreePrivateData,
2172 IDirectDrawSurface4Impl_GetUniquenessValue,
2173 IDirectDrawSurface4Impl_ChangeUniquenessValue
2176 /******************************************************************************
2177 * DirectDrawCreateClipper (DDRAW.7)
2179 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2180 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2181 LPUNKNOWN pUnkOuter)
2183 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2184 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2186 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2187 (*ilplpDDClipper)->lpvtbl = &ddclipvt;
2188 (*ilplpDDClipper)->ref = 1;
2190 return DD_OK;
2193 /******************************************************************************
2194 * IDirectDrawClipper
2196 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2197 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
2199 ICOM_THIS(IDirectDrawClipperImpl,iface);
2200 FIXME("(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
2201 return DD_OK;
2204 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2205 ICOM_THIS(IDirectDrawClipperImpl,iface);
2206 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2208 This->ref--;
2209 if (This->ref)
2210 return This->ref;
2211 HeapFree(GetProcessHeap(),0,This);
2212 return 0;
2215 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2216 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2218 ICOM_THIS(IDirectDrawClipperImpl,iface);
2219 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2220 if (hmm) *hmm=0;
2221 return DD_OK;
2224 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2225 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2227 ICOM_THIS(IDirectDrawClipperImpl,iface);
2228 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2229 return DD_OK;
2232 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2233 LPDIRECTDRAWCLIPPER iface,
2234 REFIID riid,
2235 LPVOID* ppvObj )
2237 ICOM_THIS(IDirectDrawClipperImpl,iface);
2238 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2239 return OLE_E_ENUM_NOMORE;
2242 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2244 ICOM_THIS(IDirectDrawClipperImpl,iface);
2245 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2246 return ++(This->ref);
2249 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2250 LPDIRECTDRAWCLIPPER iface,
2251 HWND* HWndPtr )
2253 ICOM_THIS(IDirectDrawClipperImpl,iface);
2254 FIXME("(%p)->(%p),stub!\n",This,HWndPtr);
2255 return DD_OK;
2258 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2259 LPDIRECTDRAWCLIPPER iface,
2260 LPDIRECTDRAW lpDD,
2261 DWORD dwFlags )
2263 ICOM_THIS(IDirectDrawClipperImpl,iface);
2264 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2265 return DD_OK;
2268 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2269 LPDIRECTDRAWCLIPPER iface,
2270 BOOL* lpbChanged )
2272 ICOM_THIS(IDirectDrawClipperImpl,iface);
2273 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2274 return DD_OK;
2277 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2279 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2280 IDirectDrawClipperImpl_QueryInterface,
2281 IDirectDrawClipperImpl_AddRef,
2282 IDirectDrawClipperImpl_Release,
2283 IDirectDrawClipperImpl_GetClipList,
2284 IDirectDrawClipperImpl_GetHWnd,
2285 IDirectDrawClipperImpl_Initialize,
2286 IDirectDrawClipperImpl_IsClipListChanged,
2287 IDirectDrawClipperImpl_SetClipList,
2288 IDirectDrawClipperImpl_SetHwnd
2292 /******************************************************************************
2293 * IDirectDrawPalette
2295 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2296 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2298 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2299 int i;
2301 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2302 This,x,start,count,palent);
2304 /* No palette created and not in depth-convertion mode -> BUG ! */
2305 if ((This->cm == None) &&
2306 (This->ddraw->d.palette_convert == NULL))
2308 FIXME("app tried to read colormap for non-palettized mode\n");
2309 return DDERR_GENERIC;
2311 for (i=0;i<count;i++) {
2312 palent[i].peRed = This->palents[start+i].peRed;
2313 palent[i].peBlue = This->palents[start+i].peBlue;
2314 palent[i].peGreen = This->palents[start+i].peGreen;
2315 palent[i].peFlags = This->palents[start+i].peFlags;
2318 return DD_OK;
2321 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2322 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2324 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2325 XColor xc;
2326 int i;
2328 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2329 This,x,start,count,palent
2331 for (i=0;i<count;i++) {
2332 xc.red = palent[i].peRed<<8;
2333 xc.blue = palent[i].peBlue<<8;
2334 xc.green = palent[i].peGreen<<8;
2335 xc.flags = DoRed|DoBlue|DoGreen;
2336 xc.pixel = start+i;
2338 if (This->cm)
2339 TSXStoreColor(display,This->cm,&xc);
2341 This->palents[start+i].peRed = palent[i].peRed;
2342 This->palents[start+i].peBlue = palent[i].peBlue;
2343 This->palents[start+i].peGreen = palent[i].peGreen;
2344 This->palents[start+i].peFlags = palent[i].peFlags;
2347 /* Now, if we are in 'depth conversion mode', update the screen palette */
2348 /* FIXME: we need to update the image or we won't get palette fading. */
2349 if (This->ddraw->d.palette_convert != NULL)
2350 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2352 return DD_OK;
2355 #ifdef HAVE_LIBXXF86DGA
2356 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2357 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2359 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2360 XColor xc;
2361 Colormap cm;
2362 int i;
2364 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2365 This,x,start,count,palent
2367 if (!This->cm) /* should not happen */ {
2368 FIXME("app tried to set colormap in non-palettized mode\n");
2369 return DDERR_GENERIC;
2371 /* FIXME: free colorcells instead of freeing whole map */
2372 cm = This->cm;
2373 This->cm = TSXCopyColormapAndFree(display,This->cm);
2374 TSXFreeColormap(display,cm);
2376 for (i=0;i<count;i++) {
2377 xc.red = palent[i].peRed<<8;
2378 xc.blue = palent[i].peBlue<<8;
2379 xc.green = palent[i].peGreen<<8;
2380 xc.flags = DoRed|DoBlue|DoGreen;
2381 xc.pixel = i+start;
2383 TSXStoreColor(display,This->cm,&xc);
2385 This->palents[start+i].peRed = palent[i].peRed;
2386 This->palents[start+i].peBlue = palent[i].peBlue;
2387 This->palents[start+i].peGreen = palent[i].peGreen;
2388 This->palents[start+i].peFlags = palent[i].peFlags;
2390 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2391 return DD_OK;
2393 #endif /* defined(HAVE_LIBXXF86DGA) */
2395 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2396 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2397 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2398 if (!--(This->ref)) {
2399 if (This->cm) {
2400 TSXFreeColormap(display,This->cm);
2401 This->cm = 0;
2403 HeapFree(GetProcessHeap(),0,This);
2404 return 0;
2406 return This->ref;
2409 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2410 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2412 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2413 return ++(This->ref);
2416 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2417 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2419 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2420 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2422 return DDERR_ALREADYINITIALIZED;
2425 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2426 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2428 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2429 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2430 return DD_OK;
2433 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2434 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2436 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2437 char xrefiid[50];
2439 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2440 FIXME("(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2442 return S_OK;
2445 #ifdef HAVE_LIBXXF86DGA
2446 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2448 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2449 IDirectDrawPaletteImpl_QueryInterface,
2450 IDirectDrawPaletteImpl_AddRef,
2451 IDirectDrawPaletteImpl_Release,
2452 IDirectDrawPaletteImpl_GetCaps,
2453 IDirectDrawPaletteImpl_GetEntries,
2454 IDirectDrawPaletteImpl_Initialize,
2455 DGA_IDirectDrawPaletteImpl_SetEntries
2457 #endif /* defined(HAVE_LIBXXF86DGA) */
2459 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2461 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2462 IDirectDrawPaletteImpl_QueryInterface,
2463 IDirectDrawPaletteImpl_AddRef,
2464 IDirectDrawPaletteImpl_Release,
2465 IDirectDrawPaletteImpl_GetCaps,
2466 IDirectDrawPaletteImpl_GetEntries,
2467 IDirectDrawPaletteImpl_Initialize,
2468 Xlib_IDirectDrawPaletteImpl_SetEntries
2471 /*******************************************************************************
2472 * IDirect3D
2474 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2475 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2477 ICOM_THIS(IDirect3DImpl,iface);
2478 /* FIXME: Not sure if this is correct */
2479 char xrefiid[50];
2481 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2482 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2483 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2484 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2485 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2486 *obj = This->ddraw;
2487 IDirect3D_AddRef(iface);
2489 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2491 return S_OK;
2493 if ((!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) ||
2494 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2495 *obj = This;
2496 IDirect3D_AddRef(iface);
2498 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2500 return S_OK;
2502 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
2503 IDirect3D2Impl* d3d;
2505 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2506 d3d->ref = 1;
2507 d3d->ddraw = This->ddraw;
2508 IDirect3D_AddRef(iface);
2509 d3d->lpvtbl = &d3d2vt;
2510 *obj = d3d;
2512 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2514 return S_OK;
2516 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2517 return OLE_E_ENUM_NOMORE;
2520 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2521 ICOM_THIS(IDirect3DImpl,iface);
2522 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2524 return ++(This->ref);
2527 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2529 ICOM_THIS(IDirect3DImpl,iface);
2530 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2532 if (!--(This->ref)) {
2533 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2534 HeapFree(GetProcessHeap(),0,This);
2535 return 0;
2537 return This->ref;
2540 static HRESULT WINAPI IDirect3DImpl_Initialize(
2541 LPDIRECT3D iface, REFIID refiid )
2543 ICOM_THIS(IDirect3DImpl,iface);
2544 /* FIXME: Not sure if this is correct */
2545 char xrefiid[50];
2547 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2548 FIXME("(%p)->(%s):stub.\n",This,xrefiid);
2550 return DDERR_ALREADYINITIALIZED;
2553 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2554 LPD3DENUMDEVICESCALLBACK cb,
2555 LPVOID context) {
2556 ICOM_THIS(IDirect3DImpl,iface);
2557 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2559 /* Call functions defined in d3ddevices.c */
2560 if (!d3d_OpenGL_dx3(cb, context))
2561 return DD_OK;
2563 return DD_OK;
2566 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2567 LPDIRECT3DLIGHT *lplight,
2568 IUnknown *lpunk)
2570 ICOM_THIS(IDirect3DImpl,iface);
2571 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2573 /* Call the creation function that is located in d3dlight.c */
2574 *lplight = d3dlight_create_dx3(This);
2576 return DD_OK;
2579 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2580 LPDIRECT3DMATERIAL *lpmaterial,
2581 IUnknown *lpunk)
2583 ICOM_THIS(IDirect3DImpl,iface);
2584 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2586 /* Call the creation function that is located in d3dviewport.c */
2587 *lpmaterial = d3dmaterial_create(This);
2589 return DD_OK;
2592 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2593 LPDIRECT3DVIEWPORT *lpviewport,
2594 IUnknown *lpunk)
2596 ICOM_THIS(IDirect3DImpl,iface);
2597 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2599 /* Call the creation function that is located in d3dviewport.c */
2600 *lpviewport = d3dviewport_create(This);
2602 return DD_OK;
2605 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2606 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2607 LPD3DFINDDEVICERESULT lpfinddevrst)
2609 ICOM_THIS(IDirect3DImpl,iface);
2610 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2612 return DD_OK;
2615 static ICOM_VTABLE(IDirect3D) d3dvt =
2617 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2618 IDirect3DImpl_QueryInterface,
2619 IDirect3DImpl_AddRef,
2620 IDirect3DImpl_Release,
2621 IDirect3DImpl_Initialize,
2622 IDirect3DImpl_EnumDevices,
2623 IDirect3DImpl_CreateLight,
2624 IDirect3DImpl_CreateMaterial,
2625 IDirect3DImpl_CreateViewport,
2626 IDirect3DImpl_FindDevice
2629 /*******************************************************************************
2630 * IDirect3D2
2632 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2633 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2634 ICOM_THIS(IDirect3D2Impl,iface);
2636 /* FIXME: Not sure if this is correct */
2637 char xrefiid[50];
2639 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2640 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2641 if ((!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) ||
2642 (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) ||
2643 (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4)))) {
2644 *obj = This->ddraw;
2645 IDirect3D2_AddRef(iface);
2647 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2649 return S_OK;
2651 if ((!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) ||
2652 (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)))) {
2653 *obj = This;
2654 IDirect3D2_AddRef(iface);
2656 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2658 return S_OK;
2660 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
2661 IDirect3DImpl* d3d;
2663 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2664 d3d->ref = 1;
2665 d3d->ddraw = This->ddraw;
2666 IDirect3D2_AddRef(iface);
2667 d3d->lpvtbl = &d3dvt;
2668 *obj = d3d;
2670 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2672 return S_OK;
2674 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2675 return OLE_E_ENUM_NOMORE;
2678 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2679 ICOM_THIS(IDirect3D2Impl,iface);
2680 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2682 return ++(This->ref);
2685 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2686 ICOM_THIS(IDirect3D2Impl,iface);
2687 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2689 if (!--(This->ref)) {
2690 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2691 HeapFree(GetProcessHeap(),0,This);
2692 return 0;
2694 return This->ref;
2697 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2698 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2700 ICOM_THIS(IDirect3D2Impl,iface);
2701 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2703 /* Call functions defined in d3ddevices.c */
2704 if (!d3d_OpenGL(cb, context))
2705 return DD_OK;
2707 return DD_OK;
2710 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2711 LPDIRECT3DLIGHT *lplight,
2712 IUnknown *lpunk)
2714 ICOM_THIS(IDirect3D2Impl,iface);
2715 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2717 /* Call the creation function that is located in d3dlight.c */
2718 *lplight = d3dlight_create(This);
2720 return DD_OK;
2723 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2724 LPDIRECT3DMATERIAL2 *lpmaterial,
2725 IUnknown *lpunk)
2727 ICOM_THIS(IDirect3D2Impl,iface);
2728 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2730 /* Call the creation function that is located in d3dviewport.c */
2731 *lpmaterial = d3dmaterial2_create(This);
2733 return DD_OK;
2736 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2737 LPDIRECT3DVIEWPORT2 *lpviewport,
2738 IUnknown *lpunk)
2740 ICOM_THIS(IDirect3D2Impl,iface);
2741 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2743 /* Call the creation function that is located in d3dviewport.c */
2744 *lpviewport = d3dviewport2_create(This);
2746 return DD_OK;
2749 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2750 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2751 LPD3DFINDDEVICERESULT lpfinddevrst)
2753 ICOM_THIS(IDirect3D2Impl,iface);
2754 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2756 return DD_OK;
2759 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2760 REFCLSID rguid,
2761 LPDIRECTDRAWSURFACE surface,
2762 LPDIRECT3DDEVICE2 *device)
2764 ICOM_THIS(IDirect3D2Impl,iface);
2765 char xbuf[50];
2767 WINE_StringFromCLSID(rguid,xbuf);
2768 FIXME("(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2770 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2771 IDirect3D2_AddRef(iface);
2772 return DD_OK;
2775 return DDERR_INVALIDPARAMS;
2778 static ICOM_VTABLE(IDirect3D2) d3d2vt =
2780 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2781 IDirect3D2Impl_QueryInterface,
2782 IDirect3D2Impl_AddRef,
2783 IDirect3D2Impl_Release,
2784 IDirect3D2Impl_EnumDevices,
2785 IDirect3D2Impl_CreateLight,
2786 IDirect3D2Impl_CreateMaterial,
2787 IDirect3D2Impl_CreateViewport,
2788 IDirect3D2Impl_FindDevice,
2789 IDirect3D2Impl_CreateDevice
2792 /*******************************************************************************
2793 * IDirectDraw
2796 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2797 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2799 static INT ddrawXlibThisOffset = 0;
2801 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2802 IDirectDrawSurfaceImpl* lpdsf)
2804 int bpp;
2806 /* The surface was already allocated when entering in this function */
2807 TRACE("using system memory for a surface (%p) \n", lpdsf);
2809 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
2810 /* This is a Z Buffer */
2811 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.x.dwZBufferBitDepth);
2812 bpp = lpdsf->s.surface_desc.x.dwZBufferBitDepth / 8;
2813 } else {
2814 /* This is a standard image */
2815 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
2816 /* No pixel format => use DirectDraw's format */
2817 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2818 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
2821 bpp = GET_BPP(lpdsf->s.surface_desc);
2824 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
2825 /* The surface was preallocated : seems that we have nothing to do :-) */
2826 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
2829 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
2830 lpdsf->s.surface_desc.y.lpSurface =
2831 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
2832 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
2834 return DD_OK;
2837 #ifdef HAVE_LIBXXF86DGA
2838 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2839 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2841 ICOM_THIS(IDirectDraw2Impl,iface);
2842 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2843 int i, fbheight = This->e.dga.fb_height;
2845 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2846 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
2848 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
2849 GetProcessHeap(),
2850 HEAP_ZERO_MEMORY,
2851 sizeof(IDirectDrawSurfaceImpl)
2853 IDirectDraw2_AddRef(iface);
2855 (*ilpdsf)->ref = 1;
2856 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2857 (*ilpdsf)->s.ddraw = This;
2858 (*ilpdsf)->s.palette = NULL;
2859 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2861 /* Copy the surface description */
2862 (*ilpdsf)->s.surface_desc = *lpddsd;
2864 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2865 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2866 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2867 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2869 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
2871 /* Check if this a 'primary surface' or not */
2872 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2873 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2874 /* This is THE primary surface => there is DGA-specific code */
2876 /* First, store the surface description */
2877 (*ilpdsf)->s.surface_desc = *lpddsd;
2879 /* Find a viewport */
2880 for (i=0;i<32;i++)
2881 if (!(This->e.dga.vpmask & (1<<i)))
2882 break;
2883 TRACE("using viewport %d for a primary surface\n",i);
2884 /* if i == 32 or maximum ... return error */
2885 This->e.dga.vpmask|=(1<<i);
2886 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
2887 This->e.dga.fb_width*
2888 (This->d.directdraw_pixelformat.x.dwRGBBitCount/8);
2890 (*ilpdsf)->s.surface_desc.y.lpSurface =
2891 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2893 (*ilpdsf)->t.dga.fb_height = i*fbheight;
2895 /* Add flags if there were not present */
2896 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2897 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2898 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2899 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2900 /* We put our surface always in video memory */
2901 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2902 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2903 (*ilpdsf)->s.chain = NULL;
2905 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2906 IDirectDrawSurface4Impl* back;
2907 int i;
2909 for (i=lpddsd->dwBackBufferCount;i--;) {
2910 back = (IDirectDrawSurface4Impl*)HeapAlloc(
2911 GetProcessHeap(),
2912 HEAP_ZERO_MEMORY,
2913 sizeof(IDirectDrawSurface4Impl)
2915 IDirectDraw2_AddRef(iface);
2916 back->ref = 1;
2917 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2918 for (i=0;i<32;i++)
2919 if (!(This->e.dga.vpmask & (1<<i)))
2920 break;
2921 TRACE("using viewport %d for backbuffer\n",i);
2922 /* if i == 32 or maximum ... return error */
2923 This->e.dga.vpmask|=(1<<i);
2924 back->t.dga.fb_height = i*fbheight;
2925 /* Copy the surface description from the front buffer */
2926 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2927 /* Change the parameters that are not the same */
2928 back->s.surface_desc.y.lpSurface =
2929 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2931 back->s.ddraw = This;
2932 /* Add relevant info to front and back buffers */
2933 /* FIXME: backbuffer/frontbuffer handling broken here, but
2934 * will be fixed up in _Flip().
2936 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
2937 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
2938 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2939 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
2940 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
2943 } else {
2944 /* There is no DGA-specific code here...
2945 Go to the common surface creation function */
2946 return common_off_screen_CreateSurface(This, *ilpdsf);
2948 return DD_OK;
2950 #endif /* defined(HAVE_LIBXXF86DGA) */
2952 #ifdef HAVE_LIBXXSHM
2953 /* Error handlers for Image creation */
2954 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
2955 XShmErrorFlag = 1;
2956 return 0;
2959 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
2960 XImage *img;
2961 int (*WineXHandler)(Display *, XErrorEvent *);
2963 img = TSXShmCreateImage(display,
2964 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2965 This->d.pixmap_depth,
2966 ZPixmap,
2967 NULL,
2968 &(lpdsf->t.xlib.shminfo),
2969 lpdsf->s.surface_desc.dwWidth,
2970 lpdsf->s.surface_desc.dwHeight
2973 if (img == NULL) {
2974 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2975 This->e.xlib.xshm_active = 0;
2976 return NULL;
2979 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
2980 if (lpdsf->t.xlib.shminfo.shmid < 0) {
2981 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2982 This->e.xlib.xshm_active = 0;
2983 TSXDestroyImage(img);
2984 return NULL;
2987 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
2989 if (img->data == (char *) -1) {
2990 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2991 This->e.xlib.xshm_active = 0;
2992 TSXDestroyImage(img);
2993 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
2994 return NULL;
2996 lpdsf->t.xlib.shminfo.readOnly = False;
2998 /* This is where things start to get trickier....
2999 * First, we flush the current X connections to be sure to catch all
3000 * non-XShm related errors
3002 TSXSync(display, False);
3003 /* Then we enter in the non-thread safe part of the tests */
3004 EnterCriticalSection( &X11DRV_CritSection );
3006 /* Reset the error flag, sets our new error handler and try to attach
3007 * the surface
3009 XShmErrorFlag = 0;
3010 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3011 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3012 XSync(display, False);
3014 /* Check the error flag */
3015 if (XShmErrorFlag) {
3016 /* An error occured */
3017 XFlush(display);
3018 XShmErrorFlag = 0;
3019 XDestroyImage(img);
3020 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3021 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3022 XSetErrorHandler(WineXHandler);
3024 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3025 This->e.xlib.xshm_active = 0;
3027 /* Leave the critical section */
3028 LeaveCriticalSection( &X11DRV_CritSection );
3029 return NULL;
3031 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3032 * this works, but it may be a bit overkill....
3034 XSetErrorHandler(WineXHandler);
3035 LeaveCriticalSection( &X11DRV_CritSection );
3037 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3039 if (This->d.pixel_convert != NULL) {
3040 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(
3041 GetProcessHeap(),
3042 HEAP_ZERO_MEMORY,
3043 lpdsf->s.surface_desc.dwWidth *
3044 lpdsf->s.surface_desc.dwHeight *
3045 (This->d.directdraw_pixelformat.x.dwRGBBitCount)
3047 } else {
3048 lpdsf->s.surface_desc.y.lpSurface = img->data;
3050 return img;
3052 #endif /* HAVE_LIBXXSHM */
3054 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3055 XImage *img = NULL;
3056 void *img_data;
3058 #ifdef HAVE_LIBXXSHM
3059 if (This->e.xlib.xshm_active)
3060 img = create_xshmimage(This, lpdsf);
3062 if (img == NULL) {
3063 #endif
3064 /* Allocate surface memory */
3065 lpdsf->s.surface_desc.y.lpSurface = HeapAlloc(
3066 GetProcessHeap(),HEAP_ZERO_MEMORY,
3067 lpdsf->s.surface_desc.dwWidth *
3068 lpdsf->s.surface_desc.dwHeight *
3069 (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8)
3072 if (This->d.pixel_convert != NULL) {
3073 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3074 lpdsf->s.surface_desc.dwWidth *
3075 lpdsf->s.surface_desc.dwHeight *
3076 (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
3078 } else {
3079 img_data = lpdsf->s.surface_desc.y.lpSurface;
3082 /* In this case, create an XImage */
3083 img = TSXCreateImage(display,
3084 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3085 This->d.pixmap_depth,
3086 ZPixmap,
3088 img_data,
3089 lpdsf->s.surface_desc.dwWidth,
3090 lpdsf->s.surface_desc.dwHeight,
3092 lpdsf->s.surface_desc.dwWidth * (This->d.screen_pixelformat.x.dwRGBBitCount / 8)
3094 #ifdef HAVE_LIBXXSHM
3096 #endif
3097 if (This->d.pixel_convert != NULL) {
3098 lpdsf->s.surface_desc.lPitch = (This->d.directdraw_pixelformat.x.dwRGBBitCount / 8) * lpdsf->s.surface_desc.dwWidth;
3099 } else {
3100 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3102 return img;
3105 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3106 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3108 ICOM_THIS(IDirectDraw2Impl,iface);
3109 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3111 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3113 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3115 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3116 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3119 IDirectDraw2_AddRef(iface);
3121 (*ilpdsf)->s.ddraw = This;
3122 (*ilpdsf)->ref = 1;
3123 (*ilpdsf)->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3124 (*ilpdsf)->s.palette = NULL;
3125 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3127 /* Copy the surface description */
3128 (*ilpdsf)->s.surface_desc = *lpddsd;
3130 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3131 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3132 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3133 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3134 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3136 /* Check if this a 'primary surface' or not */
3137 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3138 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3139 XImage *img;
3141 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3142 /* Create the XImage */
3143 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3144 if (img == NULL)
3145 return DDERR_OUTOFMEMORY;
3146 (*ilpdsf)->t.xlib.image = img;
3148 /* Add flags if there were not present */
3149 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3150 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3151 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3152 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3153 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3155 /* Check for backbuffers */
3156 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3157 IDirectDrawSurface4Impl* back;
3158 XImage *img;
3159 int i;
3161 for (i=lpddsd->dwBackBufferCount;i--;) {
3162 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3163 GetProcessHeap(),HEAP_ZERO_MEMORY,
3164 sizeof(IDirectDrawSurface4Impl)
3167 TRACE("allocated back-buffer (%p)\n", back);
3169 IDirectDraw2_AddRef(iface);
3170 back->s.ddraw = This;
3172 back->ref = 1;
3173 back->lpvtbl = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3174 /* Copy the surface description from the front buffer */
3175 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3177 /* Create the XImage */
3178 img = create_ximage(This, back);
3179 if (img == NULL)
3180 return DDERR_OUTOFMEMORY;
3181 back->t.xlib.image = img;
3183 /* Add relevant info to front and back buffers */
3184 /* FIXME: backbuffer/frontbuffer handling broken here, but
3185 * will be fixed up in _Flip().
3187 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3188 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3189 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3190 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3191 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3194 } else {
3195 /* There is no Xlib-specific code here...
3196 Go to the common surface creation function */
3197 return common_off_screen_CreateSurface(This, *ilpdsf);
3199 return DD_OK;
3202 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3203 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3205 ICOM_THIS(IDirectDraw2Impl,iface);
3206 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3207 *dst = src; /* FIXME */
3208 return DD_OK;
3212 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3213 * even when the approbiate bitmasks are not specified.
3215 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3216 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3218 ICOM_THIS(IDirectDraw2Impl,iface);
3220 int i;
3221 const struct {
3222 int mask;
3223 char *name;
3224 } flagmap[] = {
3225 #define FE(x) { x, #x},
3226 FE(DDSCL_FULLSCREEN)
3227 FE(DDSCL_ALLOWREBOOT)
3228 FE(DDSCL_NOWINDOWCHANGES)
3229 FE(DDSCL_NORMAL)
3230 FE(DDSCL_ALLOWMODEX)
3231 FE(DDSCL_EXCLUSIVE)
3232 FE(DDSCL_SETFOCUSWINDOW)
3233 FE(DDSCL_SETDEVICEWINDOW)
3234 FE(DDSCL_CREATEDEVICEWINDOW)
3235 #undef FE
3239 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3240 This->d.mainWindow = hwnd;
3242 /* This will be overwritten in the case of Full Screen mode.
3243 Windowed games could work with that :-) */
3244 if (hwnd)
3246 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3247 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3248 WIN_ReleaseWndPtr(tmpWnd);
3250 if( !This->d.drawable ) {
3251 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3252 WIN_ReleaseDesktop();
3254 TRACE("Setting drawable to %ld\n", This->d.drawable);
3257 return DD_OK;
3260 /* Small helper to either use the cooperative window or create a new
3261 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3263 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3264 RECT rect;
3266 /* Do not destroy the application supplied cooperative window */
3267 if (This->d.window && This->d.window != This->d.mainWindow) {
3268 DestroyWindow(This->d.window);
3269 This->d.window = 0;
3271 /* Sanity check cooperative window before assigning it to drawing. */
3272 if ( IsWindow(This->d.mainWindow) &&
3273 IsWindowVisible(This->d.mainWindow)
3275 /* if it does not fit, resize the cooperative window.
3276 * and hope the app likes it
3278 GetWindowRect(This->d.mainWindow,&rect);
3279 if ((((rect.right-rect.left) >= This->d.width) &&
3280 ((rect.bottom-rect.top) >= This->d.height))
3282 This->d.window = This->d.mainWindow;
3283 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3287 /* ... failed, create new one. */
3288 if (!This->d.window) {
3289 This->d.window = CreateWindowExA(
3291 "WINE_DirectDraw",
3292 "WINE_DirectDraw",
3293 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3294 0,0,
3295 This->d.width,
3296 This->d.height,
3300 NULL
3302 /*Store THIS with the window. We'll use it in the window procedure*/
3303 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3304 ShowWindow(This->d.window,TRUE);
3305 UpdateWindow(This->d.window);
3307 SetFocus(This->d.window);
3310 static int _common_depth_to_pixelformat(DWORD depth,
3311 DDPIXELFORMAT *pixelformat,
3312 DDPIXELFORMAT *screen_pixelformat,
3313 int *pix_depth) {
3314 XVisualInfo *vi;
3315 XPixmapFormatValues *pf;
3316 XVisualInfo vt;
3317 int nvisuals, npixmap, i;
3318 int match = 0;
3319 int index = -2;
3321 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3322 pf = XListPixmapFormats(display, &npixmap);
3324 for (i = 0; i < npixmap; i++) {
3325 if (pf[i].depth == depth) {
3326 int j;
3328 for (j = 0; j < nvisuals; j++) {
3329 if (vi[j].depth == pf[i].depth) {
3330 pixelformat->dwSize = sizeof(*pixelformat);
3331 if (depth == 8) {
3332 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3333 pixelformat->y.dwRBitMask = 0;
3334 pixelformat->z.dwGBitMask = 0;
3335 pixelformat->xx.dwBBitMask = 0;
3336 } else {
3337 pixelformat->dwFlags = DDPF_RGB;
3338 pixelformat->y.dwRBitMask = vi[j].red_mask;
3339 pixelformat->z.dwGBitMask = vi[j].green_mask;
3340 pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3342 pixelformat->dwFourCC = 0;
3343 pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3344 pixelformat->xy.dwRGBAlphaBitMask= 0;
3346 *screen_pixelformat = *pixelformat;
3348 if (pix_depth != NULL)
3349 *pix_depth = vi[j].depth;
3351 match = 1;
3352 index = -1;
3354 goto clean_up_and_exit;
3358 ERR("No visual corresponding to pixmap format !\n");
3362 if (match == 0) {
3363 /* We try now to find an emulated mode */
3364 int c;
3366 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3367 if (ModeEmulations[c].dest.depth == depth) {
3368 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3369 for (i = 0; i < npixmap; i++) {
3370 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3371 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3372 int j;
3374 for (j = 0; j < nvisuals; j++) {
3375 if (vi[j].depth == pf[i].depth) {
3376 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3377 screen_pixelformat->dwFlags = DDPF_RGB;
3378 screen_pixelformat->dwFourCC = 0;
3379 screen_pixelformat->x.dwRGBBitCount = pf[i].bits_per_pixel;
3380 screen_pixelformat->y.dwRBitMask = vi[j].red_mask;
3381 screen_pixelformat->z.dwGBitMask = vi[j].green_mask;
3382 screen_pixelformat->xx.dwBBitMask = vi[j].blue_mask;
3383 screen_pixelformat->xy.dwRGBAlphaBitMask= 0;
3385 pixelformat->dwSize = sizeof(*pixelformat);
3386 pixelformat->dwFourCC = 0;
3387 if (depth == 8) {
3388 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3389 pixelformat->x.dwRGBBitCount = 8;
3390 pixelformat->y.dwRBitMask = 0;
3391 pixelformat->z.dwGBitMask = 0;
3392 pixelformat->xx.dwBBitMask = 0;
3393 } else {
3394 pixelformat->dwFlags = DDPF_RGB;
3395 pixelformat->x.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3396 pixelformat->y.dwRBitMask = ModeEmulations[c].dest.rmask;
3397 pixelformat->z.dwGBitMask = ModeEmulations[c].dest.gmask;
3398 pixelformat->xx.dwBBitMask = ModeEmulations[c].dest.bmask;
3400 pixelformat->xy.dwRGBAlphaBitMask= 0;
3402 if (pix_depth != NULL)
3403 *pix_depth = vi[j].depth;
3405 match = 2;
3406 index = c;
3408 goto clean_up_and_exit;
3411 ERR("No visual corresponding to pixmap format !\n");
3419 clean_up_and_exit:
3420 TSXFree(vi);
3421 TSXFree(pf);
3423 return index;
3426 #ifdef HAVE_LIBXXF86DGA
3427 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3428 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3430 ICOM_THIS(IDirectDrawImpl,iface);
3431 int i,mode_count;
3433 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3435 /* We hope getting the asked for depth */
3436 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3437 /* I.e. no visual found or emulated */
3438 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3439 return DDERR_UNSUPPORTEDMODE;
3442 if (This->d.width < width) {
3443 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3444 return DDERR_UNSUPPORTEDMODE;
3446 This->d.width = width;
3447 This->d.height = height;
3449 /* adjust fb_height, so we don't overlap */
3450 if (This->e.dga.fb_height < height)
3451 This->e.dga.fb_height = height;
3452 _common_IDirectDrawImpl_SetDisplayMode(This);
3454 #ifdef HAVE_LIBXXF86VM
3456 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3457 XF86VidModeModeLine mod_tmp;
3458 /* int dotclock_tmp; */
3460 /* save original video mode and set fullscreen if available*/
3461 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3462 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3463 orig_mode->hdisplay = mod_tmp.hdisplay;
3464 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3465 orig_mode->hsyncend = mod_tmp.hsyncend;
3466 orig_mode->htotal = mod_tmp.htotal;
3467 orig_mode->vdisplay = mod_tmp.vdisplay;
3468 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3469 orig_mode->vsyncend = mod_tmp.vsyncend;
3470 orig_mode->vtotal = mod_tmp.vtotal;
3471 orig_mode->flags = mod_tmp.flags;
3472 orig_mode->private = mod_tmp.private;
3474 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3475 for (i=0;i<mode_count;i++)
3477 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3479 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3480 *vidmode = *(all_modes[i]);
3481 break;
3482 } else
3483 TSXFree(all_modes[i]->private);
3485 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3486 TSXFree(all_modes);
3488 if (!vidmode)
3489 WARN("Fullscreen mode not available!\n");
3491 if (vidmode)
3493 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3494 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3495 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3496 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3497 #endif
3500 #endif
3502 /* FIXME: this function OVERWRITES several signal handlers.
3503 * can we save them? and restore them later? In a way that
3504 * it works for the library too?
3506 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3507 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3509 #ifdef RESTORE_SIGNALS
3510 EXC_InitHandlers();
3511 #endif
3512 return DD_OK;
3514 #endif /* defined(HAVE_LIBXXF86DGA) */
3516 /* *************************************
3517 16 / 15 bpp to palettized 8 bpp
3518 ************************************* */
3519 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3520 unsigned char *c_src = (unsigned char *) src;
3521 unsigned short *c_dst = (unsigned short *) dst;
3522 int y;
3524 if (palette != NULL) {
3525 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3527 for (y = height; y--; ) {
3528 #ifdef __i386__
3529 /* gcc generates slightly inefficient code for the the copy / lookup,
3530 * it generates one excess memory access (to pal) per pixel. Since
3531 * we know that pal is not modified by the memory write we can
3532 * put it into a register and reduce the number of memory accesses
3533 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3534 * (This is not guaranteed to be the fastest method.)
3536 __asm__ __volatile__(
3537 "xor %%eax,%%eax\n"
3538 "1:\n"
3539 " lodsb\n"
3540 " movw (%%edx,%%eax,2),%%ax\n"
3541 " stosw\n"
3542 " xor %%eax,%%eax\n"
3543 " loop 1b\n"
3544 : "=S" (c_src), "=D" (c_dst)
3545 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3546 : "eax", "cc", "memory"
3548 c_src+=(pitch-width);
3549 #else
3550 unsigned char * srclineend = c_src+width;
3551 while (c_src < srclineend)
3552 *c_dst++ = pal[*c_src++];
3553 c_src+=(pitch-width);
3554 #endif
3556 } else {
3557 WARN("No palette set...\n");
3558 memset(dst, 0, width * height * 2);
3561 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3562 int i;
3563 unsigned short *pal = (unsigned short *) screen_palette;
3565 for (i = 0; i < count; i++)
3566 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3567 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3568 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3570 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3571 int i;
3572 unsigned short *pal = (unsigned short *) screen_palette;
3574 for (i = 0; i < count; i++)
3575 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3576 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3577 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3580 /* *************************************
3581 24 to palettized 8 bpp
3582 ************************************* */
3583 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3584 unsigned char *c_src = (unsigned char *) src;
3585 unsigned char *c_dst = (unsigned char *) dst;
3586 int y;
3588 if (palette != NULL) {
3589 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3591 for (y = height; y--; ) {
3592 unsigned char * srclineend = c_src+width;
3593 while (c_src < srclineend ) {
3594 register long pixel = pal[*c_src++];
3595 *c_dst++ = pixel;
3596 *c_dst++ = pixel>>8;
3597 *c_dst++ = pixel>>16;
3599 c_src+=(pitch-width);
3601 } else {
3602 WARN("No palette set...\n");
3603 memset(dst, 0, width * height * 4);
3606 /* *************************************
3607 32 bpp to palettized 8 bpp
3608 ************************************* */
3609 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3610 unsigned char *c_src = (unsigned char *) src;
3611 unsigned int *c_dst = (unsigned int *) dst;
3612 int y;
3614 if (palette != NULL) {
3615 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3617 for (y = height; y--; ) {
3618 #ifdef __i386__
3619 /* See comment in pixel_convert_16_to_8 */
3620 __asm__ __volatile__(
3621 "xor %%eax,%%eax\n"
3622 "1:\n"
3623 " lodsb\n"
3624 " movl (%%edx,%%eax,4),%%eax\n"
3625 " stosl\n"
3626 " xor %%eax,%%eax\n"
3627 " loop 1b\n"
3628 : "=S" (c_src), "=D" (c_dst)
3629 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3630 : "eax", "cc", "memory"
3632 c_src+=(pitch-width);
3633 #else
3634 unsigned char * srclineend = c_src+width;
3635 while (c_src < srclineend )
3636 *c_dst++ = pal[*c_src++];
3637 c_src+=(pitch-width);
3638 #endif
3640 } else {
3641 WARN("No palette set...\n");
3642 memset(dst, 0, width * height * 4);
3646 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3647 int i;
3648 unsigned int *pal = (unsigned int *) screen_palette;
3650 for (i = 0; i < count; i++)
3651 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3652 (((unsigned int) palent[i].peGreen) << 8) |
3653 ((unsigned int) palent[i].peBlue));
3656 /* *************************************
3657 32 bpp to 16 bpp
3658 ************************************* */
3659 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3660 unsigned short *c_src = (unsigned short *) src;
3661 unsigned int *c_dst = (unsigned int *) dst;
3662 int y;
3664 for (y = height; y--; ) {
3665 unsigned short * srclineend = c_src+width;
3666 while (c_src < srclineend ) {
3667 *c_dst++ = (((*c_src & 0xF800) << 8) |
3668 ((*c_src & 0x07E0) << 5) |
3669 ((*c_src & 0x001F) << 3));
3670 c_src++;
3672 c_src+=((pitch/2)-width);
3677 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3678 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3680 ICOM_THIS(IDirectDrawImpl,iface);
3681 char buf[200];
3682 WND *tmpWnd;
3683 int c;
3685 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3686 This, width, height, depth);
3688 switch ((c = _common_depth_to_pixelformat(depth,
3689 &(This->d.directdraw_pixelformat),
3690 &(This->d.screen_pixelformat),
3691 &(This->d.pixmap_depth)))) {
3692 case -2:
3693 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3694 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3695 return DDERR_UNSUPPORTEDMODE;
3697 case -1:
3698 /* No convertion */
3699 This->d.pixel_convert = NULL;
3700 This->d.palette_convert = NULL;
3701 break;
3703 default:
3704 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3706 /* Set the depth convertion routines */
3707 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
3708 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
3711 This->d.width = width;
3712 This->d.height = height;
3714 _common_IDirectDrawImpl_SetDisplayMode(This);
3716 tmpWnd = WIN_FindWndPtr(This->d.window);
3717 This->d.paintable = 1;
3718 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3719 WIN_ReleaseWndPtr(tmpWnd);
3721 /* We don't have a context for this window. Host off the desktop */
3722 if( !This->d.drawable )
3724 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3725 WIN_ReleaseDesktop();
3727 TRACE("Setting drawable to %ld\n", This->d.drawable);
3729 return DD_OK;
3732 #ifdef HAVE_LIBXXF86DGA
3733 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3734 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3736 ICOM_THIS(IDirectDraw2Impl,iface);
3737 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3738 if (!caps1 && !caps2)
3739 return DDERR_INVALIDPARAMS;
3740 if (caps1) {
3741 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3742 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3743 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3745 if (caps2) {
3746 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3747 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3748 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3750 return DD_OK;
3752 #endif /* defined(HAVE_LIBXXF86DGA) */
3754 static void fill_caps(LPDDCAPS caps) {
3755 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3756 Need to be fixed, though.. */
3757 if (caps == NULL)
3758 return;
3760 caps->dwSize = sizeof(*caps);
3761 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
3762 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3763 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3764 caps->dwFXCaps = 0;
3765 caps->dwFXAlphaCaps = 0;
3766 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3767 caps->dwSVCaps = 0;
3768 caps->dwZBufferBitDepths = DDBD_16;
3769 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3770 to put textures in video memory.
3771 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3772 for example) ? */
3773 caps->dwVidMemTotal = 8192 * 1024;
3774 caps->dwVidMemFree = 8192 * 1024;
3775 /* These are all the supported capabilities of the surfaces */
3776 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3777 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3778 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3779 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3780 #ifdef HAVE_MESAGL
3781 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3782 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3783 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3784 #endif
3787 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3788 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3790 ICOM_THIS(IDirectDraw2Impl,iface);
3791 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3793 /* Put the same caps for the two capabilities */
3794 fill_caps(caps1);
3795 fill_caps(caps2);
3797 return DD_OK;
3800 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3801 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3803 ICOM_THIS(IDirectDraw2Impl,iface);
3804 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3805 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
3806 This,x,ilpddclip,lpunk
3808 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3809 (*ilpddclip)->ref = 1;
3810 (*ilpddclip)->lpvtbl = &ddclipvt;
3811 return DD_OK;
3814 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3815 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3817 int size = 0;
3819 if (TRACE_ON(ddraw))
3820 _dump_paletteformat(dwFlags);
3822 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3823 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3824 (*lpddpal)->ref = 1;
3825 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3826 (*lpddpal)->installed = 0;
3828 if (dwFlags & DDPCAPS_1BIT)
3829 size = 2;
3830 else if (dwFlags & DDPCAPS_2BIT)
3831 size = 4;
3832 else if (dwFlags & DDPCAPS_4BIT)
3833 size = 16;
3834 else if (dwFlags & DDPCAPS_8BIT)
3835 size = 256;
3836 else
3837 ERR("unhandled palette format\n");
3838 *psize = size;
3840 if (palent)
3842 /* Now, if we are in 'depth conversion mode', create the screen palette */
3843 if (This->d.palette_convert != NULL)
3844 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3846 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3847 } else if (This->d.palette_convert != NULL) {
3848 /* In that case, put all 0xFF */
3849 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3852 return DD_OK;
3855 #ifdef HAVE_LIBXXF86DGA
3856 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3857 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3859 ICOM_THIS(IDirectDraw2Impl,iface);
3860 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3861 HRESULT res;
3862 int xsize = 0,i;
3864 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3865 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3866 if (res != 0) return res;
3867 (*ilpddpal)->lpvtbl = &dga_ddpalvt;
3868 if (This->d.directdraw_pixelformat.x.dwRGBBitCount<=8) {
3869 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3870 } else {
3871 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
3872 (*ilpddpal)->cm = 0;
3874 if (((*ilpddpal)->cm)&&xsize) {
3875 for (i=0;i<xsize;i++) {
3876 XColor xc;
3878 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3879 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3880 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3881 xc.flags = DoRed|DoBlue|DoGreen;
3882 xc.pixel = i;
3883 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3886 return DD_OK;
3888 #endif /* defined(HAVE_LIBXXF86DGA) */
3890 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3891 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3893 ICOM_THIS(IDirectDraw2Impl,iface);
3894 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3895 int xsize;
3896 HRESULT res;
3898 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3899 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3900 if (res != 0) return res;
3901 (*ilpddpal)->lpvtbl = &xlib_ddpalvt;
3902 return DD_OK;
3905 #ifdef HAVE_LIBXXF86DGA
3906 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3907 ICOM_THIS(IDirectDraw2Impl,iface);
3908 TRACE("(%p)->()\n",This);
3909 Sleep(1000);
3910 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3911 #ifdef RESTORE_SIGNALS
3912 EXC_InitHandlers();
3913 #endif
3914 return DD_OK;
3916 #endif /* defined(HAVE_LIBXXF86DGA) */
3918 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3919 ICOM_THIS(IDirectDraw2Impl,iface);
3920 TRACE("(%p)->RestoreDisplayMode()\n", This);
3921 Sleep(1000);
3922 return DD_OK;
3925 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3926 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3928 ICOM_THIS(IDirectDraw2Impl,iface);
3929 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3930 return DD_OK;
3933 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3934 ICOM_THIS(IDirectDraw2Impl,iface);
3935 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
3937 return ++(This->ref);
3940 #ifdef HAVE_LIBXXF86DGA
3941 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3942 ICOM_THIS(IDirectDraw2Impl,iface);
3943 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
3945 if (!--(This->ref)) {
3946 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3947 if (This->d.window && (This->d.mainWindow != This->d.window))
3948 DestroyWindow(This->d.window);
3949 #ifdef HAVE_LIBXXF86VM
3950 if (orig_mode) {
3951 TSXF86VidModeSwitchToMode(
3952 display,
3953 DefaultScreen(display),
3954 orig_mode);
3955 if (orig_mode->privsize)
3956 TSXFree(orig_mode->private);
3957 free(orig_mode);
3958 orig_mode = NULL;
3960 #endif
3962 #ifdef RESTORE_SIGNALS
3963 EXC_InitHandlers();
3964 #endif
3965 HeapFree(GetProcessHeap(),0,This);
3966 return 0;
3968 return This->ref;
3970 #endif /* defined(HAVE_LIBXXF86DGA) */
3972 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3973 ICOM_THIS(IDirectDraw2Impl,iface);
3974 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
3976 if (!--(This->ref)) {
3977 if (This->d.window && (This->d.mainWindow != This->d.window))
3978 DestroyWindow(This->d.window);
3979 HeapFree(GetProcessHeap(),0,This);
3980 return 0;
3982 /* FIXME: destroy window ... */
3983 return This->ref;
3986 #ifdef HAVE_LIBXXF86DGA
3987 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
3988 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
3990 ICOM_THIS(IDirectDraw2Impl,iface);
3991 char xrefiid[50];
3993 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
3994 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
3995 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
3996 *obj = This;
3997 IDirectDraw2_AddRef(iface);
3999 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4001 return S_OK;
4003 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
4004 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4005 IDirectDraw2_AddRef(iface);
4006 *obj = This;
4008 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4010 return S_OK;
4012 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
4013 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4014 IDirectDraw2_AddRef(iface);
4015 *obj = This;
4017 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4019 return S_OK;
4021 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
4022 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4023 IDirectDraw2_AddRef(iface);
4024 *obj = This;
4026 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4028 return S_OK;
4030 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
4031 IDirect3DImpl* d3d;
4033 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4034 d3d->ref = 1;
4035 d3d->ddraw = (IDirectDrawImpl*)This;
4036 IDirectDraw2_AddRef(iface);
4037 d3d->lpvtbl = &d3dvt;
4038 *obj = d3d;
4040 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4042 return S_OK;
4044 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D2))) {
4045 IDirect3D2Impl* d3d;
4047 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4048 d3d->ref = 1;
4049 d3d->ddraw = (IDirectDrawImpl*)This;
4050 IDirectDraw2_AddRef(iface);
4051 d3d->lpvtbl = &d3d2vt;
4052 *obj = d3d;
4054 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4056 return S_OK;
4058 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4059 return OLE_E_ENUM_NOMORE;
4061 #endif /* defined(HAVE_LIBXXF86DGA) */
4063 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4064 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4066 ICOM_THIS(IDirectDraw2Impl,iface);
4067 char xrefiid[50];
4069 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4070 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4071 if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
4072 *obj = This;
4073 IDirectDraw2_AddRef(iface);
4075 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4077 return S_OK;
4079 if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
4080 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4081 IDirectDraw2_AddRef(iface);
4082 *obj = This;
4084 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4086 return S_OK;
4088 if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
4089 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4090 IDirectDraw2_AddRef(iface);
4091 *obj = This;
4093 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4095 return S_OK;
4097 if (!memcmp(&IID_IDirectDraw4,refiid,sizeof(IID_IDirectDraw4))) {
4098 This->lpvtbl = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4099 IDirectDraw2_AddRef(iface);
4100 *obj = This;
4102 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4104 return S_OK;
4106 if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
4107 IDirect3DImpl* d3d;
4109 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4110 d3d->ref = 1;
4111 d3d->ddraw = (IDirectDrawImpl*)This;
4112 IDirectDraw2_AddRef(iface);
4113 d3d->lpvtbl = &d3dvt;
4114 *obj = d3d;
4116 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4118 return S_OK;
4120 if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
4121 IDirect3D2Impl* d3d;
4123 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4124 d3d->ref = 1;
4125 d3d->ddraw = (IDirectDrawImpl*)This;
4126 IDirectDraw2_AddRef(iface);
4127 d3d->lpvtbl = &d3d2vt;
4128 *obj = d3d;
4130 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4132 return S_OK;
4134 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4135 return OLE_E_ENUM_NOMORE;
4138 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4139 LPDIRECTDRAW2 iface,BOOL *status
4141 ICOM_THIS(IDirectDraw2Impl,iface);
4142 TRACE("(%p)->(%p)\n",This,status);
4143 *status = TRUE;
4144 return DD_OK;
4147 #ifdef HAVE_LIBXXF86DGA
4148 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4149 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4151 ICOM_THIS(IDirectDraw2Impl,iface);
4152 DDSURFACEDESC ddsfd;
4153 static struct {
4154 int w,h;
4155 } modes[5] = { /* some of the usual modes */
4156 {512,384},
4157 {640,400},
4158 {640,480},
4159 {800,600},
4160 {1024,768},
4162 static int depths[4] = {8,16,24,32};
4163 int i,j;
4165 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4166 ddsfd.dwSize = sizeof(ddsfd);
4167 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4168 if (dwFlags & DDEDM_REFRESHRATES) {
4169 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4170 ddsfd.x.dwRefreshRate = 60;
4173 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4174 ddsfd.dwBackBufferCount = 1;
4175 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4176 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4177 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = depths[i];
4178 /* FIXME: those masks would have to be set in depth > 8 */
4179 if (depths[i]==8) {
4180 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4181 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4182 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4183 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4184 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4185 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4186 } else {
4187 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4189 /* FIXME: We should query those from X itself */
4190 switch (depths[i]) {
4191 case 16:
4192 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0xF800;
4193 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x07E0;
4194 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x001F;
4195 break;
4196 case 24:
4197 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4198 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4199 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4200 break;
4201 case 32:
4202 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0x00FF0000;
4203 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0x0000FF00;
4204 ddsfd.ddpfPixelFormat.xx.dwBBitMask= 0x000000FF;
4205 break;
4209 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4210 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4211 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4212 if (!modescb(&ddsfd,context)) return DD_OK;
4214 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4215 ddsfd.dwWidth = modes[j].w;
4216 ddsfd.dwHeight = modes[j].h;
4217 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4218 if (!modescb(&ddsfd,context)) return DD_OK;
4221 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4222 /* modeX is not standard VGA */
4224 ddsfd.dwHeight = 200;
4225 ddsfd.dwWidth = 320;
4226 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4227 if (!modescb(&ddsfd,context)) return DD_OK;
4230 return DD_OK;
4232 #endif /* defined(HAVE_LIBXXF86DGA) */
4234 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4235 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4237 ICOM_THIS(IDirectDraw2Impl,iface);
4238 XVisualInfo *vi;
4239 XPixmapFormatValues *pf;
4240 XVisualInfo vt;
4241 int nvisuals, npixmap, i, emu;
4242 int has_mode[] = { 0, 0, 0, 0 };
4243 int has_depth[] = { 8, 15, 16, 24 };
4244 DDSURFACEDESC ddsfd;
4245 static struct {
4246 int w,h;
4247 } modes[] = { /* some of the usual modes */
4248 {512,384},
4249 {640,400},
4250 {640,480},
4251 {800,600},
4252 {1024,768},
4253 {1280,1024}
4255 DWORD maxWidth, maxHeight;
4257 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4258 ddsfd.dwSize = sizeof(ddsfd);
4259 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4260 if (dwFlags & DDEDM_REFRESHRATES) {
4261 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4262 ddsfd.x.dwRefreshRate = 60;
4264 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4265 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4267 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4268 pf = XListPixmapFormats(display, &npixmap);
4270 i = 0;
4271 emu = 0;
4272 while ((i < npixmap) ||
4273 (emu != 4)) {
4274 int mode_index;
4275 int send_mode = 0;
4276 int j;
4278 if (i < npixmap) {
4279 for (j = 0; j < 4; j++) {
4280 if (has_depth[j] == pf[i].depth) {
4281 mode_index = j;
4282 break;
4285 if (j == 4) {
4286 i++;
4287 continue;
4291 if (has_mode[mode_index] == 0) {
4292 if (mode_index == 0) {
4293 send_mode = 1;
4295 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4296 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4297 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4298 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4299 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
4300 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4301 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4302 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4303 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4305 has_mode[mode_index] = 1;
4306 } else {
4307 /* All the 'true color' depths (15, 16 and 24)
4308 First, find the corresponding visual to extract the bit masks */
4309 for (j = 0; j < nvisuals; j++) {
4310 if (vi[j].depth == pf[i].depth) {
4311 ddsfd.ddsCaps.dwCaps = 0;
4312 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4313 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4314 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4315 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = pf[i].bits_per_pixel;
4316 ddsfd.ddpfPixelFormat.y.dwRBitMask = vi[j].red_mask;
4317 ddsfd.ddpfPixelFormat.z.dwGBitMask = vi[j].green_mask;
4318 ddsfd.ddpfPixelFormat.xx.dwBBitMask = vi[j].blue_mask;
4319 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4321 send_mode = 1;
4322 has_mode[mode_index] = 1;
4323 break;
4327 if (j == nvisuals)
4328 ERR("Did not find visual corresponding the the pixmap format !\n");
4332 i++;
4333 } else {
4334 /* Now to emulated modes */
4335 if (has_mode[emu] == 0) {
4336 int c;
4337 int l;
4338 int depth = has_depth[emu];
4340 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4341 if (ModeEmulations[c].dest.depth == depth) {
4342 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4343 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4344 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4345 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4346 int j;
4347 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4348 if ((vi[j].depth == pf[l].depth) &&
4349 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4350 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4351 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4352 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4353 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4354 if (depth == 8) {
4355 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4356 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = 8;
4357 ddsfd.ddpfPixelFormat.y.dwRBitMask = 0;
4358 ddsfd.ddpfPixelFormat.z.dwGBitMask = 0;
4359 ddsfd.ddpfPixelFormat.xx.dwBBitMask = 0;
4360 } else {
4361 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4362 ddsfd.ddpfPixelFormat.x.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4363 ddsfd.ddpfPixelFormat.y.dwRBitMask = ModeEmulations[c].dest.rmask;
4364 ddsfd.ddpfPixelFormat.z.dwGBitMask = ModeEmulations[c].dest.gmask;
4365 ddsfd.ddpfPixelFormat.xx.dwBBitMask = ModeEmulations[c].dest.bmask;
4367 ddsfd.ddpfPixelFormat.xy.dwRGBAlphaBitMask= 0;
4368 send_mode = 1;
4371 if (send_mode == 0)
4372 ERR("No visual corresponding to pixmap format !\n");
4380 emu++;
4383 if (send_mode) {
4384 int mode;
4386 if (TRACE_ON(ddraw)) {
4387 TRACE("Enumerating with pixel format : \n");
4388 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4389 DPRINTF("\n");
4392 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4393 /* Do not enumerate modes we cannot handle anyway */
4394 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4395 break;
4397 ddsfd.dwWidth = modes[mode].w;
4398 ddsfd.dwHeight = modes[mode].h;
4400 /* Now, send the mode description to the application */
4401 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4402 if (!modescb(&ddsfd, context))
4403 goto exit_enum;
4406 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4407 /* modeX is not standard VGA */
4408 ddsfd.dwWidth = 320;
4409 ddsfd.dwHeight = 200;
4410 if (!modescb(&ddsfd, context))
4411 goto exit_enum;
4416 exit_enum:
4417 TSXFree(vi);
4418 TSXFree(pf);
4420 return DD_OK;
4423 #ifdef HAVE_LIBXXF86DGA
4424 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4425 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4427 ICOM_THIS(IDirectDraw2Impl,iface);
4428 TRACE("(%p)->(%p)\n",This,lpddsfd);
4429 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4430 lpddsfd->dwHeight = This->d.height;
4431 lpddsfd->dwWidth = This->d.width;
4432 lpddsfd->lPitch = This->e.dga.fb_width*This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4433 lpddsfd->dwBackBufferCount = 1;
4434 lpddsfd->x.dwRefreshRate = 60;
4435 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4436 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4437 return DD_OK;
4439 #endif /* defined(HAVE_LIBXXF86DGA) */
4441 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4442 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4444 ICOM_THIS(IDirectDraw2Impl,iface);
4445 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4446 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4447 lpddsfd->dwHeight = This->d.height;
4448 lpddsfd->dwWidth = This->d.width;
4449 lpddsfd->lPitch = lpddsfd->dwWidth * This->d.directdraw_pixelformat.x.dwRGBBitCount/8;
4450 lpddsfd->dwBackBufferCount = 1;
4451 lpddsfd->x.dwRefreshRate = 60;
4452 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4453 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4454 return DD_OK;
4457 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4458 ICOM_THIS(IDirectDraw2Impl,iface);
4459 TRACE("(%p)->()\n",This);
4460 return DD_OK;
4463 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4464 LPDIRECTDRAW2 iface,LPDWORD freq
4466 ICOM_THIS(IDirectDraw2Impl,iface);
4467 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4468 *freq = 60*100; /* 60 Hz */
4469 return DD_OK;
4472 /* what can we directly decompress? */
4473 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4474 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4476 ICOM_THIS(IDirectDraw2Impl,iface);
4477 FIXME("(%p,%p,%p), stub\n",This,x,y);
4478 return DD_OK;
4481 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4482 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4484 ICOM_THIS(IDirectDraw2Impl,iface);
4485 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4486 return DD_OK;
4489 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4490 LPDIRECTDRAW2 iface )
4492 ICOM_THIS(IDirectDraw2Impl,iface);
4493 FIXME("(%p)->()\n", This );
4495 return DD_OK;
4498 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4499 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4500 ICOM_THIS(IDirectDraw2Impl,iface);
4501 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4503 return DD_OK;
4506 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4507 LPDWORD lpdwScanLine) {
4508 ICOM_THIS(IDirectDraw2Impl,iface);
4509 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4511 return DD_OK;
4514 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4515 GUID *lpGUID) {
4516 ICOM_THIS(IDirectDraw2Impl,iface);
4517 FIXME("(%p)->(%p)\n", This, lpGUID);
4519 return DD_OK;
4522 #ifdef HAVE_LIBXXF86DGA
4524 /* Note: Hack so we can reuse the old functions without compiler warnings */
4525 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4526 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4527 #else
4528 # define XCAST(fun) (void *)
4529 #endif
4531 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4533 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4534 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4535 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4536 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4537 XCAST(Compact)IDirectDraw2Impl_Compact,
4538 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4539 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4540 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4541 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4542 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4543 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4544 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4545 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4546 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4547 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4548 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4549 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4550 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4551 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4552 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4553 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4554 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4555 DGA_IDirectDrawImpl_SetDisplayMode,
4556 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4559 #undef XCAST
4561 #endif /* defined(HAVE_LIBXXF86DGA) */
4563 /* Note: Hack so we can reuse the old functions without compiler warnings */
4564 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4565 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4566 #else
4567 # define XCAST(fun) (void *)
4568 #endif
4570 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4572 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4573 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4574 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4575 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4576 XCAST(Compact)IDirectDraw2Impl_Compact,
4577 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4578 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4579 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4580 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4581 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4582 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4583 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4584 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4585 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4586 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4587 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4588 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4589 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4590 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4591 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4592 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4593 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4594 Xlib_IDirectDrawImpl_SetDisplayMode,
4595 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4598 #undef XCAST
4600 /*****************************************************************************
4601 * IDirectDraw2
4606 #ifdef HAVE_LIBXXF86DGA
4607 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4608 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4610 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4612 #endif /* defined(HAVE_LIBXXF86DGA) */
4614 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4615 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4617 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4620 #ifdef HAVE_LIBXXF86DGA
4621 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4622 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4624 ICOM_THIS(IDirectDraw2Impl,iface);
4625 TRACE("(%p)->(%p,%p,%p)\n",
4626 This,ddscaps,total,free
4628 if (total) *total = This->e.dga.fb_memsize * 1024;
4629 if (free) *free = This->e.dga.fb_memsize * 1024;
4630 return DD_OK;
4632 #endif /* defined(HAVE_LIBXXF86DGA) */
4634 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4635 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4637 ICOM_THIS(IDirectDraw2Impl,iface);
4638 TRACE("(%p)->(%p,%p,%p)\n",
4639 This,ddscaps,total,free
4641 if (total) *total = 2048 * 1024;
4642 if (free) *free = 2048 * 1024;
4643 return DD_OK;
4646 #ifdef HAVE_LIBXXF86DGA
4647 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4649 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4650 DGA_IDirectDraw2Impl_QueryInterface,
4651 IDirectDraw2Impl_AddRef,
4652 DGA_IDirectDraw2Impl_Release,
4653 IDirectDraw2Impl_Compact,
4654 IDirectDraw2Impl_CreateClipper,
4655 DGA_IDirectDraw2Impl_CreatePalette,
4656 DGA_IDirectDraw2Impl_CreateSurface,
4657 IDirectDraw2Impl_DuplicateSurface,
4658 DGA_IDirectDraw2Impl_EnumDisplayModes,
4659 IDirectDraw2Impl_EnumSurfaces,
4660 IDirectDraw2Impl_FlipToGDISurface,
4661 DGA_IDirectDraw2Impl_GetCaps,
4662 DGA_IDirectDraw2Impl_GetDisplayMode,
4663 IDirectDraw2Impl_GetFourCCCodes,
4664 IDirectDraw2Impl_GetGDISurface,
4665 IDirectDraw2Impl_GetMonitorFrequency,
4666 IDirectDraw2Impl_GetScanLine,
4667 IDirectDraw2Impl_GetVerticalBlankStatus,
4668 IDirectDraw2Impl_Initialize,
4669 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4670 IDirectDraw2Impl_SetCooperativeLevel,
4671 DGA_IDirectDraw2Impl_SetDisplayMode,
4672 IDirectDraw2Impl_WaitForVerticalBlank,
4673 DGA_IDirectDraw2Impl_GetAvailableVidMem
4675 #endif /* defined(HAVE_LIBXXF86DGA) */
4677 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4679 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4680 Xlib_IDirectDraw2Impl_QueryInterface,
4681 IDirectDraw2Impl_AddRef,
4682 Xlib_IDirectDraw2Impl_Release,
4683 IDirectDraw2Impl_Compact,
4684 IDirectDraw2Impl_CreateClipper,
4685 Xlib_IDirectDraw2Impl_CreatePalette,
4686 Xlib_IDirectDraw2Impl_CreateSurface,
4687 IDirectDraw2Impl_DuplicateSurface,
4688 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4689 IDirectDraw2Impl_EnumSurfaces,
4690 IDirectDraw2Impl_FlipToGDISurface,
4691 Xlib_IDirectDraw2Impl_GetCaps,
4692 Xlib_IDirectDraw2Impl_GetDisplayMode,
4693 IDirectDraw2Impl_GetFourCCCodes,
4694 IDirectDraw2Impl_GetGDISurface,
4695 IDirectDraw2Impl_GetMonitorFrequency,
4696 IDirectDraw2Impl_GetScanLine,
4697 IDirectDraw2Impl_GetVerticalBlankStatus,
4698 IDirectDraw2Impl_Initialize,
4699 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4700 IDirectDraw2Impl_SetCooperativeLevel,
4701 Xlib_IDirectDraw2Impl_SetDisplayMode,
4702 IDirectDraw2Impl_WaitForVerticalBlank,
4703 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4706 /*****************************************************************************
4707 * IDirectDraw4
4711 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4712 HDC hdc,
4713 LPDIRECTDRAWSURFACE *lpDDS) {
4714 ICOM_THIS(IDirectDraw4Impl,iface);
4715 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4717 return DD_OK;
4720 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4721 ICOM_THIS(IDirectDraw4Impl,iface);
4722 FIXME("(%p)->()\n", This);
4724 return DD_OK;
4727 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4728 ICOM_THIS(IDirectDraw4Impl,iface);
4729 FIXME("(%p)->()\n", This);
4731 return DD_OK;
4734 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4735 LPDDDEVICEIDENTIFIER lpdddi,
4736 DWORD dwFlags) {
4737 ICOM_THIS(IDirectDraw4Impl,iface);
4738 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4740 return DD_OK;
4743 #ifdef HAVE_LIBXXF86DGA
4745 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4746 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4747 #else
4748 # define XCAST(fun) (void*)
4749 #endif
4751 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
4753 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4754 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4755 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4756 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4757 XCAST(Compact)IDirectDraw2Impl_Compact,
4758 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4759 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4760 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4761 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4762 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4763 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4764 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4765 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4766 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4767 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4768 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4769 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4770 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4771 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4772 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4773 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4774 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4775 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4776 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4777 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4778 IDirectDraw4Impl_GetSurfaceFromDC,
4779 IDirectDraw4Impl_RestoreAllSurfaces,
4780 IDirectDraw4Impl_TestCooperativeLevel,
4781 IDirectDraw4Impl_GetDeviceIdentifier
4784 #undef XCAST
4786 #endif /* defined(HAVE_LIBXXF86DGA) */
4788 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4789 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
4790 #else
4791 # define XCAST(fun) (void*)
4792 #endif
4794 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
4796 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4797 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4798 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4799 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4800 XCAST(Compact)IDirectDraw2Impl_Compact,
4801 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4802 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4803 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4804 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4805 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4806 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4807 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4808 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4809 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4810 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4811 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4812 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4813 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4814 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4815 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4816 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4817 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4818 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4819 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4820 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4821 IDirectDraw4Impl_GetSurfaceFromDC,
4822 IDirectDraw4Impl_RestoreAllSurfaces,
4823 IDirectDraw4Impl_TestCooperativeLevel,
4824 IDirectDraw4Impl_GetDeviceIdentifier
4827 #undef XCAST
4829 /******************************************************************************
4830 * DirectDrawCreate
4833 LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4835 LRESULT ret;
4836 IDirectDrawImpl* ddraw = NULL;
4837 DWORD lastError;
4839 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4841 SetLastError( ERROR_SUCCESS );
4842 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4843 if( (!ddraw) &&
4844 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4847 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4850 if( ddraw )
4852 /* Perform any special direct draw functions */
4853 if (msg==WM_PAINT)
4854 ddraw->d.paintable = 1;
4856 /* Now let the application deal with the rest of this */
4857 if( ddraw->d.mainWindow )
4860 /* Don't think that we actually need to call this but...
4861 might as well be on the safe side of things... */
4863 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4864 it should be the procedures of our fake window that gets called
4865 instead of those of the window provided by the application.
4866 And with this patch, mouse clicks work with Monkey Island III
4867 - Lionel */
4868 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4870 if( !ret )
4872 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4873 /* We didn't handle the message - give it to the application */
4874 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4876 ret = CallWindowProcA(tmpWnd->winproc,
4877 ddraw->d.mainWindow, msg, wParam, lParam );
4879 WIN_ReleaseWndPtr(tmpWnd);
4883 } else {
4884 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4888 else
4890 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4893 return ret;
4896 HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4897 #ifdef HAVE_LIBXXF86DGA
4898 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4899 int memsize,banksize,width,major,minor,flags,height;
4900 char *addr;
4901 int fd;
4902 int depth;
4904 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4905 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4906 close(fd);
4908 if (fd == -1) {
4909 MESSAGE("Must be able to access /dev/mem to use XF86DGA!\n");
4910 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4911 return E_UNEXPECTED;
4913 if (!DDRAW_DGA_Available()) {
4914 TRACE("No XF86DGA detected.\n");
4915 return DDERR_GENERIC;
4917 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4918 (*ilplpDD)->lpvtbl = &dga_ddvt;
4919 (*ilplpDD)->ref = 1;
4920 TSXF86DGAQueryVersion(display,&major,&minor);
4921 TRACE("XF86DGA is version %d.%d\n",major,minor);
4922 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4923 if (!(flags & XF86DGADirectPresent))
4924 MESSAGE("direct video is NOT PRESENT.\n");
4925 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4926 (*ilplpDD)->e.dga.fb_width = width;
4927 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4928 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4929 (*ilplpDD)->e.dga.fb_height = height;
4930 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4931 addr,width,banksize,memsize
4933 TRACE("viewport height: %d\n",height);
4935 /* Get the screen dimensions as seen by Wine.
4936 In that case, it may be better to ignore the -desktop mode and return the
4937 real screen size => print a warning */
4938 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4939 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4940 if (((*ilplpDD)->d.height != height) ||
4941 ((*ilplpDD)->d.width != width))
4942 WARN("You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4943 (*ilplpDD)->e.dga.fb_addr = addr;
4944 (*ilplpDD)->e.dga.fb_memsize = memsize;
4945 (*ilplpDD)->e.dga.fb_banksize = banksize;
4946 (*ilplpDD)->e.dga.vpmask = 0;
4948 /* just assume the default depth is the DGA depth too */
4949 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4950 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4951 #ifdef RESTORE_SIGNALS
4952 EXC_InitHandlers();
4953 #endif
4955 return DD_OK;
4956 #else /* defined(HAVE_LIBXXF86DGA) */
4957 return DDERR_INVALIDDIRECTDRAWGUID;
4958 #endif /* defined(HAVE_LIBXXF86DGA) */
4961 BOOL
4962 DDRAW_XSHM_Available(void)
4964 #ifdef HAVE_LIBXXSHM
4965 if (TSXShmQueryExtension(display))
4967 int major, minor;
4968 Bool shpix;
4970 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
4971 (Options.noXSHM != 1))
4972 return 1;
4973 else
4974 return 0;
4976 else
4977 return 0;
4978 #else
4979 return 0;
4980 #endif
4983 HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4984 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4985 int depth;
4987 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4988 (*ilplpDD)->lpvtbl = &xlib_ddvt;
4989 (*ilplpDD)->ref = 1;
4990 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
4992 /* At DirectDraw creation, the depth is the default depth */
4993 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4994 _common_depth_to_pixelformat(depth,
4995 &((*ilplpDD)->d.directdraw_pixelformat),
4996 &((*ilplpDD)->d.screen_pixelformat),
4997 &((*ilplpDD)->d.pixmap_depth));
4998 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4999 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5001 #ifdef HAVE_LIBXXSHM
5002 /* Test if XShm is available. */
5003 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available()))
5004 TRACE("Using XShm extension.\n");
5005 #endif
5007 return DD_OK;
5010 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5011 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5012 char xclsid[50];
5013 WNDCLASSA wc;
5014 /* WND* pParentWindow; */
5015 HRESULT ret;
5017 if (HIWORD(lpGUID))
5018 WINE_StringFromCLSID(lpGUID,xclsid);
5019 else {
5020 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5021 lpGUID = NULL;
5024 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5026 if ((!lpGUID) ||
5027 (!memcmp(lpGUID,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
5028 (!memcmp(lpGUID,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
5029 (!memcmp(lpGUID,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
5030 /* if they didn't request a particular interface, use the best
5031 * supported one */
5032 if (DDRAW_DGA_Available())
5033 lpGUID = &DGA_DirectDraw_GUID;
5034 else
5035 lpGUID = &XLIB_DirectDraw_GUID;
5038 wc.style = CS_GLOBALCLASS;
5039 wc.lpfnWndProc = Xlib_DDWndProc;
5040 wc.cbClsExtra = 0;
5041 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5042 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5044 /* We can be a child of the desktop since we're really important */
5046 This code is not useful since hInstance is forced to 0 afterward
5047 pParentWindow = WIN_GetDesktop();
5048 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5050 wc.hInstance = 0;
5053 wc.hIcon = 0;
5054 wc.hCursor = (HCURSOR)IDC_ARROWA;
5055 wc.hbrBackground= NULL_BRUSH;
5056 wc.lpszMenuName = 0;
5057 wc.lpszClassName= "WINE_DirectDraw";
5058 RegisterClassA(&wc);
5060 if (!memcmp(lpGUID, &DGA_DirectDraw_GUID, sizeof(GUID)))
5061 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5062 else if (!memcmp(lpGUID, &XLIB_DirectDraw_GUID, sizeof(GUID)))
5063 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5064 else
5065 goto err;
5068 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5069 return ret;
5071 err:
5072 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
5073 return DDERR_INVALIDDIRECTDRAWGUID;
5076 /*******************************************************************************
5077 * DirectDraw ClassFactory
5079 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5082 typedef struct
5084 /* IUnknown fields */
5085 ICOM_VTABLE(IClassFactory)* lpvtbl;
5086 DWORD ref;
5087 } IClassFactoryImpl;
5089 static HRESULT WINAPI
5090 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5091 ICOM_THIS(IClassFactoryImpl,iface);
5092 char buf[80];
5094 if (HIWORD(riid))
5095 WINE_StringFromCLSID(riid,buf);
5096 else
5097 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5098 FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
5099 return E_NOINTERFACE;
5102 static ULONG WINAPI
5103 DDCF_AddRef(LPCLASSFACTORY iface) {
5104 ICOM_THIS(IClassFactoryImpl,iface);
5105 return ++(This->ref);
5108 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5109 ICOM_THIS(IClassFactoryImpl,iface);
5110 /* static class, won't be freed */
5111 return --(This->ref);
5114 static HRESULT WINAPI DDCF_CreateInstance(
5115 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5117 ICOM_THIS(IClassFactoryImpl,iface);
5118 char buf[80];
5120 WINE_StringFromCLSID(riid,buf);
5121 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
5122 if ((!memcmp(riid,&IID_IDirectDraw ,sizeof(IID_IDirectDraw ))) ||
5123 (!memcmp(riid,&IID_IDirectDraw2,sizeof(IID_IDirectDraw2))) ||
5124 (!memcmp(riid,&IID_IDirectDraw4,sizeof(IID_IDirectDraw4)))) {
5125 /* FIXME: reuse already created DirectDraw if present? */
5126 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5128 return E_NOINTERFACE;
5131 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5132 ICOM_THIS(IClassFactoryImpl,iface);
5133 FIXME("(%p)->(%d),stub!\n",This,dolock);
5134 return S_OK;
5137 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5139 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5140 DDCF_QueryInterface,
5141 DDCF_AddRef,
5142 DDCF_Release,
5143 DDCF_CreateInstance,
5144 DDCF_LockServer
5146 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5148 /*******************************************************************************
5149 * DllGetClassObject [DDRAW.13]
5150 * Retrieves class object from a DLL object
5152 * NOTES
5153 * Docs say returns STDAPI
5155 * PARAMS
5156 * rclsid [I] CLSID for the class object
5157 * riid [I] Reference to identifier of interface for class object
5158 * ppv [O] Address of variable to receive interface pointer for riid
5160 * RETURNS
5161 * Success: S_OK
5162 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5163 * E_UNEXPECTED
5165 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5167 char buf[80],xbuf[80];
5169 if (HIWORD(rclsid))
5170 WINE_StringFromCLSID(rclsid,xbuf);
5171 else
5172 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5173 if (HIWORD(riid))
5174 WINE_StringFromCLSID(riid,buf);
5175 else
5176 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5177 WINE_StringFromCLSID(riid,xbuf);
5178 TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
5179 if (!memcmp(riid,&IID_IClassFactory,sizeof(IID_IClassFactory))) {
5180 *ppv = (LPVOID)&DDRAW_CF;
5181 IClassFactory_AddRef((IClassFactory*)*ppv);
5182 return S_OK;
5184 FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5185 return E_NOINTERFACE;
5189 /*******************************************************************************
5190 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5192 * RETURNS
5193 * Success: S_OK
5194 * Failure: S_FALSE
5196 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5198 FIXME("(void): stub\n");
5199 return S_FALSE;
5202 #else /* !defined(X_DISPLAY_MISSING) */
5204 #include "windef.h"
5205 #include "winerror.h"
5206 #include "wtypes.h"
5208 #define DD_OK 0
5210 typedef void *LPUNKNOWN;
5211 typedef void *LPDIRECTDRAW;
5212 typedef void *LPDIRECTDRAWCLIPPER;
5213 typedef void *LPDDENUMCALLBACKA;
5214 typedef void *LPDDENUMCALLBACKEXA;
5215 typedef void *LPDDENUMCALLBACKEXW;
5216 typedef void *LPDDENUMCALLBACKW;
5218 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5220 return DD_OK;
5223 HRESULT WINAPI DirectDrawCreate(
5224 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5226 return DD_OK;
5229 HRESULT WINAPI DirectDrawCreateClipper(
5230 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5232 return DD_OK;
5235 HRESULT WINAPI DirectDrawEnumerateA(
5236 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5238 return DD_OK;
5241 HRESULT WINAPI DirectDrawEnumerateExA(
5242 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5244 return DD_OK;
5247 HRESULT WINAPI DirectDrawEnumerateExW(
5248 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5250 return DD_OK;
5253 HRESULT WINAPI DirectDrawEnumerateW(
5254 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5256 return DD_OK;
5259 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5261 return E_NOINTERFACE;
5264 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5266 return DD_OK;
5269 #endif /* !defined(X_DISPLAY_MISSING) */