Fixed a crash in IDirectDrawSurface:BltFast.
[wine.git] / graphics / ddraw.c
blob56a8a65034d9f3947dc119ceb899f7f98711dd02
1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997-1999 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
5 */
6 /* XF86DGA:
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
10 * is running.
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
17 #include "config.h"
19 #ifndef X_DISPLAY_MISSING
21 #include "ts_xlib.h"
22 #include "ts_xutil.h"
24 #ifdef HAVE_LIBXXSHM
25 # include <sys/types.h>
26 # ifdef HAVE_SYS_IPC_H
27 # include <sys/ipc.h>
28 # endif
29 # ifdef HAVE_SYS_SHM_H
30 # include <sys/shm.h>
31 # endif
32 # include "ts_xshm.h"
33 #endif /* defined(HAVE_LIBXXSHM) */
35 #ifdef HAVE_LIBXXF86DGA
36 #include "ts_xf86dga.h"
37 #endif /* defined(HAVE_LIBXXF86DGA) */
39 #ifdef HAVE_LIBXXF86VM
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
43 #include "x11drv.h"
45 #include <unistd.h>
46 #include <assert.h>
47 #ifdef HAVE_SYS_SIGNAL_H
48 # include <sys/signal.h>
49 #endif
50 #include <fcntl.h>
51 #include <string.h>
52 #include <stdlib.h>
54 #include "winerror.h"
55 #include "gdi.h"
56 #include "heap.h"
57 #include "dc.h"
58 #include "win.h"
59 #include "wine/exception.h"
60 #include "ddraw.h"
61 #include "d3d.h"
62 #include "debugtools.h"
63 #include "spy.h"
64 #include "message.h"
65 #include "options.h"
66 #include "monitor.h"
68 /* This for all the enumeration and creation of D3D-related objects */
69 #include "ddraw_private.h"
70 #include "d3d_private.h"
72 DEFAULT_DEBUG_CHANNEL(ddraw)
74 /* Restore signal handlers overwritten by XF86DGA
76 #define RESTORE_SIGNALS
78 /* Get DDSCAPS of surface (shortcutmacro) */
79 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
81 /* Get the number of bytes per pixel for a given surface */
82 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
84 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
86 /* Where do these GUIDs come from? mkuuid.
87 * They exist solely to distinguish between the targets Wine support,
88 * and should be different than any other GUIDs in existence.
90 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
91 0xe2dcb020,
92 0xdc60,
93 0x11d1,
94 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
97 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
98 0x1574a740,
99 0xdc61,
100 0x11d1,
101 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
104 #ifdef HAVE_LIBXXF86DGA
105 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
106 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
107 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
108 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
109 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
110 #endif /* defined(HAVE_LIBXXF86DGA) */
112 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
113 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
114 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
115 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
116 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
118 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
119 static struct ICOM_VTABLE(IDirect3D) d3dvt;
120 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
122 /* This is for mode-emulation */
124 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
125 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
126 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
127 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
128 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
129 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
130 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
132 typedef struct {
133 unsigned short bpp;
134 unsigned short depth;
135 unsigned int rmask;
136 unsigned int gmask;
137 unsigned int bmask;
138 } ConvertMode;
140 typedef struct {
141 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
142 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
143 } ConvertFuncs;
145 typedef struct {
146 ConvertMode screen, dest;
147 ConvertFuncs funcs;
148 } Convert;
150 static Convert ModeEmulations[] = {
151 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
152 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
153 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
154 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
155 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
158 #ifdef HAVE_LIBXXF86VM
159 static XF86VidModeModeInfo *orig_mode = NULL;
160 #endif
162 #ifdef HAVE_LIBXXSHM
163 static int XShmErrorFlag = 0;
164 #endif
166 static BOOL
167 DDRAW_DGA_Available(void)
169 #ifdef HAVE_LIBXXF86DGA
170 int evbase, evret, fd;
172 if (Options.noDGA)
173 return 0;
175 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
176 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
177 /* others. --stephenc */
178 if ((fd = open("/dev/mem", O_RDWR)) != -1)
179 close(fd);
181 return (fd != -1) && TSXF86DGAQueryExtension(display,&evbase,&evret);
182 #else /* defined(HAVE_LIBXXF86DGA) */
183 return 0;
184 #endif /* defined(HAVE_LIBXXF86DGA) */
187 /**********************************************************************/
189 typedef struct {
190 LPVOID lpCallback;
191 LPVOID lpContext;
192 } DirectDrawEnumerateProcData;
194 /***********************************************************************
195 * DirectDrawEnumerateExA (DDRAW.*)
197 HRESULT WINAPI DirectDrawEnumerateExA(
198 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
200 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
202 if (TRACE_ON(ddraw)) {
203 DPRINTF(" Flags : ");
204 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
205 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
206 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
207 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
208 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
209 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
210 DPRINTF("\n");
213 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
214 /* For the moment, Wine does not support any 3D only accelerators */
215 return DD_OK;
218 if (DDRAW_DGA_Available()) {
219 TRACE("Enumerating DGA interface\n");
220 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
221 return DD_OK;
224 TRACE("Enumerating Xlib interface\n");
225 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
226 return DD_OK;
228 TRACE("Enumerating Default interface\n");
229 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
230 return DD_OK;
232 return DD_OK;
235 /***********************************************************************
236 * DirectDrawEnumerateExW (DDRAW.*)
239 static BOOL CALLBACK DirectDrawEnumerateExProcW(
240 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
241 LPVOID lpContext, HMONITOR hm)
243 DirectDrawEnumerateProcData *pEPD =
244 (DirectDrawEnumerateProcData *) lpContext;
245 LPWSTR lpDriverDescriptionW =
246 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
247 LPWSTR lpDriverNameW =
248 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
250 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
251 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
253 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
254 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
256 return bResult;
259 /**********************************************************************/
261 HRESULT WINAPI DirectDrawEnumerateExW(
262 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
264 DirectDrawEnumerateProcData epd;
265 epd.lpCallback = (LPVOID) lpCallback;
266 epd.lpContext = lpContext;
268 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
269 (LPVOID) &epd, 0);
272 /***********************************************************************
273 * DirectDrawEnumerateA (DDRAW.*)
276 static BOOL CALLBACK DirectDrawEnumerateProcA(
277 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
278 LPVOID lpContext, HMONITOR hm)
280 DirectDrawEnumerateProcData *pEPD =
281 (DirectDrawEnumerateProcData *) lpContext;
283 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
284 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
287 /**********************************************************************/
289 HRESULT WINAPI DirectDrawEnumerateA(
290 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
292 DirectDrawEnumerateProcData epd;
293 epd.lpCallback = (LPVOID) lpCallback;
294 epd.lpContext = lpContext;
296 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
297 (LPVOID) &epd, 0);
300 /***********************************************************************
301 * DirectDrawEnumerateW (DDRAW.*)
304 static BOOL WINAPI DirectDrawEnumerateProcW(
305 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
306 LPVOID lpContext, HMONITOR hm)
308 DirectDrawEnumerateProcData *pEPD =
309 (DirectDrawEnumerateProcData *) lpContext;
311 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
312 lpGUID, lpDriverDescription, lpDriverName,
313 pEPD->lpContext);
316 /**********************************************************************/
318 HRESULT WINAPI DirectDrawEnumerateW(
319 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
321 DirectDrawEnumerateProcData epd;
322 epd.lpCallback = (LPVOID) lpCallback;
323 epd.lpContext = lpContext;
325 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
326 (LPVOID) &epd, 0);
329 /***********************************************************************
330 * DSoundHelp (DDRAW.?)
333 /* What is this doing here? */
334 HRESULT WINAPI
335 DSoundHelp(DWORD x,DWORD y,DWORD z) {
336 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
337 return 0;
340 /******************************************************************************
341 * internal helper functions
343 static void _dump_DDBLTFX(DWORD flagmask) {
344 int i;
345 const struct {
346 DWORD mask;
347 char *name;
348 } flags[] = {
349 #define FE(x) { x, #x},
350 FE(DDBLTFX_ARITHSTRETCHY)
351 FE(DDBLTFX_MIRRORLEFTRIGHT)
352 FE(DDBLTFX_MIRRORUPDOWN)
353 FE(DDBLTFX_NOTEARING)
354 FE(DDBLTFX_ROTATE180)
355 FE(DDBLTFX_ROTATE270)
356 FE(DDBLTFX_ROTATE90)
357 FE(DDBLTFX_ZBUFFERRANGE)
358 FE(DDBLTFX_ZBUFFERBASEDEST)
359 #undef FE
361 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
362 if (flags[i].mask & flagmask) {
363 DPRINTF("%s ",flags[i].name);
366 DPRINTF("\n");
370 static void _dump_DDBLTFAST(DWORD flagmask) {
371 int i;
372 const struct {
373 DWORD mask;
374 char *name;
375 } flags[] = {
376 #define FE(x) { x, #x},
377 FE(DDBLTFAST_NOCOLORKEY)
378 FE(DDBLTFAST_SRCCOLORKEY)
379 FE(DDBLTFAST_DESTCOLORKEY)
380 FE(DDBLTFAST_WAIT)
381 #undef FE
383 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
384 if (flags[i].mask & flagmask)
385 DPRINTF("%s ",flags[i].name);
386 DPRINTF("\n");
389 static void _dump_DDBLT(DWORD flagmask) {
390 int i;
391 const struct {
392 DWORD mask;
393 char *name;
394 } flags[] = {
395 #define FE(x) { x, #x},
396 FE(DDBLT_ALPHADEST)
397 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
398 FE(DDBLT_ALPHADESTNEG)
399 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
400 FE(DDBLT_ALPHAEDGEBLEND)
401 FE(DDBLT_ALPHASRC)
402 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
403 FE(DDBLT_ALPHASRCNEG)
404 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
405 FE(DDBLT_ASYNC)
406 FE(DDBLT_COLORFILL)
407 FE(DDBLT_DDFX)
408 FE(DDBLT_DDROPS)
409 FE(DDBLT_KEYDEST)
410 FE(DDBLT_KEYDESTOVERRIDE)
411 FE(DDBLT_KEYSRC)
412 FE(DDBLT_KEYSRCOVERRIDE)
413 FE(DDBLT_ROP)
414 FE(DDBLT_ROTATIONANGLE)
415 FE(DDBLT_ZBUFFER)
416 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
417 FE(DDBLT_ZBUFFERDESTOVERRIDE)
418 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
419 FE(DDBLT_ZBUFFERSRCOVERRIDE)
420 FE(DDBLT_WAIT)
421 FE(DDBLT_DEPTHFILL)
422 #undef FE
424 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
425 if (flags[i].mask & flagmask)
426 DPRINTF("%s ",flags[i].name);
427 DPRINTF("\n");
430 static void _dump_DDSCAPS(void *in) {
431 int i;
432 const struct {
433 DWORD mask;
434 char *name;
435 } flags[] = {
436 #define FE(x) { x, #x},
437 FE(DDSCAPS_RESERVED1)
438 FE(DDSCAPS_ALPHA)
439 FE(DDSCAPS_BACKBUFFER)
440 FE(DDSCAPS_COMPLEX)
441 FE(DDSCAPS_FLIP)
442 FE(DDSCAPS_FRONTBUFFER)
443 FE(DDSCAPS_OFFSCREENPLAIN)
444 FE(DDSCAPS_OVERLAY)
445 FE(DDSCAPS_PALETTE)
446 FE(DDSCAPS_PRIMARYSURFACE)
447 FE(DDSCAPS_PRIMARYSURFACELEFT)
448 FE(DDSCAPS_SYSTEMMEMORY)
449 FE(DDSCAPS_TEXTURE)
450 FE(DDSCAPS_3DDEVICE)
451 FE(DDSCAPS_VIDEOMEMORY)
452 FE(DDSCAPS_VISIBLE)
453 FE(DDSCAPS_WRITEONLY)
454 FE(DDSCAPS_ZBUFFER)
455 FE(DDSCAPS_OWNDC)
456 FE(DDSCAPS_LIVEVIDEO)
457 FE(DDSCAPS_HWCODEC)
458 FE(DDSCAPS_MODEX)
459 FE(DDSCAPS_MIPMAP)
460 FE(DDSCAPS_RESERVED2)
461 FE(DDSCAPS_ALLOCONLOAD)
462 FE(DDSCAPS_VIDEOPORT)
463 FE(DDSCAPS_LOCALVIDMEM)
464 FE(DDSCAPS_NONLOCALVIDMEM)
465 FE(DDSCAPS_STANDARDVGAMODE)
466 FE(DDSCAPS_OPTIMIZED)
467 #undef FE
469 DWORD flagmask = *((DWORD *) in);
470 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
471 if (flags[i].mask & flagmask)
472 DPRINTF("%s ",flags[i].name);
475 static void _dump_pixelformat_flag(DWORD flagmask) {
476 int i;
477 const struct {
478 DWORD mask;
479 char *name;
480 } flags[] = {
481 #define FE(x) { x, #x},
482 FE(DDPF_ALPHAPIXELS)
483 FE(DDPF_ALPHA)
484 FE(DDPF_FOURCC)
485 FE(DDPF_PALETTEINDEXED4)
486 FE(DDPF_PALETTEINDEXEDTO8)
487 FE(DDPF_PALETTEINDEXED8)
488 FE(DDPF_RGB)
489 FE(DDPF_COMPRESSED)
490 FE(DDPF_RGBTOYUV)
491 FE(DDPF_YUV)
492 FE(DDPF_ZBUFFER)
493 FE(DDPF_PALETTEINDEXED1)
494 FE(DDPF_PALETTEINDEXED2)
495 FE(DDPF_ZPIXELS)
496 #undef FE
498 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
499 if (flags[i].mask & flagmask)
500 DPRINTF("%s ",flags[i].name);
503 static void _dump_paletteformat(DWORD dwFlags) {
504 int i;
505 const struct {
506 DWORD mask;
507 char *name;
508 } flags[] = {
509 #define FE(x) { x, #x},
510 FE(DDPCAPS_4BIT)
511 FE(DDPCAPS_8BITENTRIES)
512 FE(DDPCAPS_8BIT)
513 FE(DDPCAPS_INITIALIZE)
514 FE(DDPCAPS_PRIMARYSURFACE)
515 FE(DDPCAPS_PRIMARYSURFACELEFT)
516 FE(DDPCAPS_ALLOW256)
517 FE(DDPCAPS_VSYNC)
518 FE(DDPCAPS_1BIT)
519 FE(DDPCAPS_2BIT)
520 FE(DDPCAPS_ALPHA)
521 #undef FE
523 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
524 if (flags[i].mask & dwFlags)
525 DPRINTF("%s ",flags[i].name);
526 DPRINTF("\n");
529 static void _dump_pixelformat(void *in) {
530 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
531 char *cmd;
533 DPRINTF("( ");
534 _dump_pixelformat_flag(pf->dwFlags);
535 if (pf->dwFlags & DDPF_FOURCC) {
536 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
538 if (pf->dwFlags & DDPF_RGB) {
539 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
540 switch (pf->u.dwRGBBitCount) {
541 case 4:
542 cmd = "%1lx";
543 break;
544 case 8:
545 cmd = "%02lx";
546 break;
547 case 16:
548 cmd = "%04lx";
549 break;
550 case 24:
551 cmd = "%06lx";
552 break;
553 case 32:
554 cmd = "%08lx";
555 break;
556 default:
557 ERR("Unexpected bit depth !\n");
558 cmd = "%d";
560 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
561 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
562 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
563 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
564 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
566 if (pf->dwFlags & DDPF_ZPIXELS) {
567 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
570 if (pf->dwFlags & DDPF_ZBUFFER) {
571 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
573 if (pf->dwFlags & DDPF_ALPHA) {
574 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
576 DPRINTF(")");
579 static void _dump_colorkeyflag(DWORD ck) {
580 int i;
581 const struct {
582 DWORD mask;
583 char *name;
584 } flags[] = {
585 #define FE(x) { x, #x},
586 FE(DDCKEY_COLORSPACE)
587 FE(DDCKEY_DESTBLT)
588 FE(DDCKEY_DESTOVERLAY)
589 FE(DDCKEY_SRCBLT)
590 FE(DDCKEY_SRCOVERLAY)
591 #undef FE
593 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
594 if (flags[i].mask & ck)
595 DPRINTF("%s ",flags[i].name);
598 static void _dump_DWORD(void *in) {
599 DPRINTF("%ld", *((DWORD *) in));
601 static void _dump_PTR(void *in) {
602 DPRINTF("%p", *((void **) in));
604 static void _dump_DDCOLORKEY(void *in) {
605 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
607 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
610 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
611 int i;
612 struct {
613 DWORD mask;
614 char *name;
615 void (*func)(void *);
616 void *elt;
617 } flags[16], *fe = flags;
618 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
619 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
620 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
621 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
622 FE(DDSD_PITCH, _dump_DWORD, lPitch);
623 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
624 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
625 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
626 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
627 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
628 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
629 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
630 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
631 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
632 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
633 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
634 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
635 #undef FE
637 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
638 if (flags[i].mask & lpddsd->dwFlags) {
639 DPRINTF(" - %s : ",flags[i].name);
640 flags[i].func(flags[i].elt);
641 DPRINTF("\n");
646 /******************************************************************************
647 * IDirectDrawSurface methods
649 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
650 * DDS and DDS2 use those functions. (Function calls did not change (except
651 * using different DirectDrawSurfaceX version), just added flags and functions)
654 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
655 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
657 ICOM_THIS(IDirectDrawSurface4Impl,iface);
658 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
659 This,lprect,lpddsd,flags,(DWORD)hnd);
660 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
661 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
662 This,lprect,lpddsd,flags,(DWORD)hnd);
664 /* First, copy the Surface description */
665 *lpddsd = This->s.surface_desc;
666 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
667 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
669 /* If asked only for a part, change the surface pointer */
670 if (lprect) {
671 TRACE(" lprect: %dx%d-%dx%d\n",
672 lprect->top,lprect->left,lprect->bottom,lprect->right
674 if ((lprect->top < 0) ||
675 (lprect->left < 0) ||
676 (lprect->bottom < 0) ||
677 (lprect->right < 0)) {
678 ERR(" Negative values in LPRECT !!!\n");
679 return DDERR_INVALIDPARAMS;
682 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
683 (lprect->top*This->s.surface_desc.lPitch) +
684 lprect->left*GET_BPP(This->s.surface_desc));
685 } else {
686 assert(This->s.surface_desc.u1.lpSurface);
688 return DD_OK;
691 #ifdef HAVE_LIBXXF86DGA
692 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
693 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
695 ICOM_THIS(IDirectDrawSurface4Impl,iface);
696 TRACE("(%p)->Unlock(%p)\n",This,surface);
697 return DD_OK;
699 #endif /* defined(HAVE_LIBXXF86DGA) */
701 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
702 if (This->s.ddraw->d.pixel_convert != NULL)
703 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
704 This->t.xlib.image->data,
705 This->s.surface_desc.dwWidth,
706 This->s.surface_desc.dwHeight,
707 This->s.surface_desc.lPitch,
708 This->s.palette);
710 #ifdef HAVE_LIBXXSHM
711 if (This->s.ddraw->e.xlib.xshm_active) {
712 int compl = This->s.ddraw->e.xlib.xshm_compl;
713 if (compl)
714 X11DRV_EVENT_WaitShmCompletion( compl );
715 This->s.ddraw->e.xlib.xshm_compl = X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
716 TSXShmPutImage(display,
717 This->s.ddraw->d.drawable,
718 DefaultGCOfScreen(X11DRV_GetXScreen()),
719 This->t.xlib.image,
720 0, 0, 0, 0,
721 This->t.xlib.image->width,
722 This->t.xlib.image->height,
723 True);
725 else
726 #endif
727 TSXPutImage( display,
728 This->s.ddraw->d.drawable,
729 DefaultGCOfScreen(X11DRV_GetXScreen()),
730 This->t.xlib.image,
731 0, 0, 0, 0,
732 This->t.xlib.image->width,
733 This->t.xlib.image->height);
736 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
737 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
739 ICOM_THIS(IDirectDrawSurface4Impl,iface);
740 TRACE("(%p)->Unlock(%p)\n",This,surface);
742 if (!This->s.ddraw->d.paintable)
743 return DD_OK;
745 /* Only redraw the screen when unlocking the buffer that is on screen */
746 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
747 Xlib_copy_surface_on_screen(This);
749 if (This->s.palette && This->s.palette->cm)
750 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
752 return DD_OK;
755 static IDirectDrawSurface4Impl* _common_find_flipto(
756 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
758 int i,j,flipable=0;
759 struct _surface_chain *chain = This->s.chain;
761 /* if there was no override flipto, look for current backbuffer */
762 if (!flipto) {
763 /* walk the flip chain looking for backbuffer */
764 for (i=0;i<chain->nrofsurfaces;i++) {
765 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
766 flipable++;
767 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
768 flipto = chain->surfaces[i];
770 /* sanity checks ... */
771 if (!flipto) {
772 if (flipable>1) {
773 for (i=0;i<chain->nrofsurfaces;i++)
774 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
775 break;
776 if (i==chain->nrofsurfaces) {
777 /* we do not have a frontbuffer either */
778 for (i=0;i<chain->nrofsurfaces;i++)
779 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
780 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
781 break;
783 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
784 int k = j % chain->nrofsurfaces;
785 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
786 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
787 flipto = chain->surfaces[k];
788 break;
793 if (!flipto)
794 flipto = This;
796 TRACE("flipping to %p\n",flipto);
798 return flipto;
801 #ifdef HAVE_LIBXXF86DGA
802 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
803 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
805 ICOM_THIS(IDirectDrawSurface4Impl,iface);
806 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
807 DWORD xheight;
808 LPBYTE surf;
810 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
811 iflipto = _common_find_flipto(This,iflipto);
813 /* and flip! */
814 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
815 if (iflipto->s.palette && iflipto->s.palette->cm)
816 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
817 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
820 /* We need to switch the lowlevel surfaces, for DGA this is: */
822 /* The height within the framebuffer */
823 xheight = This->t.dga.fb_height;
824 This->t.dga.fb_height = iflipto->t.dga.fb_height;
825 iflipto->t.dga.fb_height = xheight;
827 /* And the assciated surface pointer */
828 surf = This->s.surface_desc.u1.lpSurface;
829 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
830 iflipto->s.surface_desc.u1.lpSurface = surf;
832 return DD_OK;
834 #endif /* defined(HAVE_LIBXXF86DGA) */
836 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
837 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
839 ICOM_THIS(IDirectDrawSurface4Impl,iface);
840 XImage *image;
841 LPBYTE surf;
842 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
844 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
845 iflipto = _common_find_flipto(This,iflipto);
847 #if defined(HAVE_MESAGL) && 0 /* does not work */
848 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
849 TRACE(" - OpenGL flip\n");
850 ENTER_GL();
851 glXSwapBuffers(display, This->s.ddraw->d.drawable);
852 LEAVE_GL();
854 return DD_OK;
856 #endif /* defined(HAVE_MESAGL) */
858 if (!This->s.ddraw->d.paintable)
859 return DD_OK;
861 /* We need to switch the lowlevel surfaces, for xlib this is: */
862 /* The surface pointer */
863 surf = This->s.surface_desc.u1.lpSurface;
864 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
865 iflipto->s.surface_desc.u1.lpSurface = surf;
866 /* the associated ximage */
867 image = This->t.xlib.image;
868 This->t.xlib.image = iflipto->t.xlib.image;
869 iflipto->t.xlib.image = image;
871 Xlib_copy_surface_on_screen(This);
873 if (iflipto->s.palette && iflipto->s.palette->cm)
874 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
875 return DD_OK;
878 /* The IDirectDrawSurface4::SetPalette method attaches the specified
879 * DirectDrawPalette object to a surface. The surface uses this palette for all
880 * subsequent operations. The palette change takes place immediately.
882 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
883 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
885 ICOM_THIS(IDirectDrawSurface4Impl,iface);
886 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
887 int i;
888 TRACE("(%p)->(%p)\n",This,ipal);
890 if (ipal == NULL) {
891 if( This->s.palette != NULL )
892 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
893 This->s.palette = ipal;
895 return DD_OK;
898 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
900 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
901 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
903 if (!Options.managed)
904 TSXInstallColormap(display,ipal->cm);
906 for (i=0;i<256;i++) {
907 XColor xc;
909 xc.red = ipal->palents[i].peRed<<8;
910 xc.blue = ipal->palents[i].peBlue<<8;
911 xc.green = ipal->palents[i].peGreen<<8;
912 xc.flags = DoRed|DoBlue|DoGreen;
913 xc.pixel = i;
914 TSXStoreColor(display,ipal->cm,&xc);
916 TSXInstallColormap(display,ipal->cm);
919 /* According to spec, we are only supposed to
920 * AddRef if this is not the same palette.
922 if( This->s.palette != ipal )
924 if( ipal != NULL )
925 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
926 if( This->s.palette != NULL )
927 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
928 This->s.palette = ipal;
929 /* Perform the refresh */
930 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
932 return DD_OK;
935 #ifdef HAVE_LIBXXF86DGA
936 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
937 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
939 ICOM_THIS(IDirectDrawSurface4Impl,iface);
940 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
941 TRACE("(%p)->(%p)\n",This,ipal);
943 /* According to spec, we are only supposed to
944 * AddRef if this is not the same palette.
946 if( This->s.palette != ipal )
948 if( ipal != NULL )
949 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
950 if( This->s.palette != NULL )
951 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
952 This->s.palette = ipal;
953 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
955 return DD_OK;
957 #endif /* defined(HAVE_LIBXXF86DGA) */
959 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
961 int x, y;
962 LPBYTE first;
964 /* Do first row */
966 #define COLORFILL_ROW(type) { \
967 type *d = (type *) buf; \
968 for (x = 0; x < width; x++) \
969 d[x] = (type) color; \
970 break; \
973 switch(bpp) {
974 case 1: COLORFILL_ROW(BYTE)
975 case 2: COLORFILL_ROW(WORD)
976 case 4: COLORFILL_ROW(DWORD)
977 default:
978 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
979 return DDERR_UNSUPPORTED;
982 #undef COLORFILL_ROW
984 /* Now copy first row */
985 first = buf;
986 for (y = 1; y < height; y++) {
987 buf += lPitch;
988 memcpy(buf, first, width * bpp);
991 return DD_OK;
994 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
995 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
997 ICOM_THIS(IDirectDrawSurface4Impl,iface);
998 RECT xdst,xsrc;
999 DDSURFACEDESC ddesc,sdesc;
1000 HRESULT ret = DD_OK;
1001 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1002 int x, y;
1003 LPBYTE dbuf, sbuf;
1005 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1007 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1008 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1010 if (TRACE_ON(ddraw)) {
1011 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1012 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1013 TRACE("\tflags: ");
1014 _dump_DDBLT(dwFlags);
1015 if (dwFlags & DDBLT_DDFX) {
1016 TRACE("\tblitfx: ");
1017 _dump_DDBLTFX(lpbltfx->dwDDFX);
1021 if (rdst) {
1022 if ((rdst->top < 0) ||
1023 (rdst->left < 0) ||
1024 (rdst->bottom < 0) ||
1025 (rdst->right < 0)) {
1026 ERR(" Negative values in LPRECT !!!\n");
1027 goto release;
1029 memcpy(&xdst,rdst,sizeof(xdst));
1030 } else {
1031 xdst.top = 0;
1032 xdst.bottom = ddesc.dwHeight;
1033 xdst.left = 0;
1034 xdst.right = ddesc.dwWidth;
1037 if (rsrc) {
1038 if ((rsrc->top < 0) ||
1039 (rsrc->left < 0) ||
1040 (rsrc->bottom < 0) ||
1041 (rsrc->right < 0)) {
1042 ERR(" Negative values in LPRECT !!!\n");
1043 goto release;
1045 memcpy(&xsrc,rsrc,sizeof(xsrc));
1046 } else {
1047 if (src) {
1048 xsrc.top = 0;
1049 xsrc.bottom = sdesc.dwHeight;
1050 xsrc.left = 0;
1051 xsrc.right = sdesc.dwWidth;
1052 } else {
1053 memset(&xsrc,0,sizeof(xsrc));
1057 bpp = GET_BPP(ddesc);
1058 srcheight = xsrc.bottom - xsrc.top;
1059 srcwidth = xsrc.right - xsrc.left;
1060 dstheight = xdst.bottom - xdst.top;
1061 dstwidth = xdst.right - xdst.left;
1062 width = (xdst.right - xdst.left) * bpp;
1063 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1065 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1067 /* First, all the 'source-less' blits */
1068 if (dwFlags & DDBLT_COLORFILL) {
1069 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1070 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1071 dwFlags &= ~DDBLT_COLORFILL;
1074 if (dwFlags & DDBLT_DEPTHFILL) {
1075 #ifdef HAVE_MESAGL
1076 GLboolean ztest;
1078 /* Clears the screen */
1079 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1080 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1081 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1082 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1083 glClear(GL_DEPTH_BUFFER_BIT);
1084 glDepthMask(ztest);
1086 dwFlags &= ~(DDBLT_DEPTHFILL);
1087 #endif /* defined(HAVE_MESAGL) */
1090 if (dwFlags & DDBLT_ROP) {
1091 /* Catch some degenerate cases here */
1092 switch(lpbltfx->dwROP) {
1093 case BLACKNESS:
1094 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1095 break;
1096 case 0xAA0029: /* No-op */
1097 break;
1098 case WHITENESS:
1099 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1100 break;
1101 default:
1102 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1103 goto error;
1105 dwFlags &= ~DDBLT_ROP;
1108 if (dwFlags & DDBLT_DDROPS) {
1109 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1112 /* Now the 'with source' blits */
1113 if (src) {
1114 LPBYTE sbase;
1115 int sx, xinc, sy, yinc;
1117 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1118 xinc = (srcwidth << 16) / dstwidth;
1119 yinc = (srcheight << 16) / dstheight;
1121 if (!dwFlags) {
1123 /* No effects, we can cheat here */
1124 if (dstwidth == srcwidth) {
1125 if (dstheight == srcheight) {
1126 /* No stretching in either direction. This needs to be as fast as possible */
1127 sbuf = sbase;
1128 for (y = 0; y < dstheight; y++) {
1129 memcpy(dbuf, sbuf, width);
1130 sbuf += sdesc.lPitch;
1131 dbuf += ddesc.lPitch;
1133 } else {
1134 /* Stretching in Y direction only */
1135 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1136 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1137 memcpy(dbuf, sbuf, width);
1138 dbuf += ddesc.lPitch;
1141 } else {
1142 /* Stretching in X direction */
1143 int last_sy = -1;
1144 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1145 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1147 if ((sy >> 16) == (last_sy >> 16)) {
1148 /* Same as last row - copy already stretched row */
1149 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1150 } else {
1152 #define STRETCH_ROW(type) { \
1153 type *s = (type *) sbuf, *d = (type *) dbuf; \
1154 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1155 d[x] = s[sx >> 16]; \
1156 break; }
1158 switch(bpp) {
1159 case 1: STRETCH_ROW(BYTE)
1160 case 2: STRETCH_ROW(WORD)
1161 case 4: STRETCH_ROW(DWORD)
1162 default:
1163 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1164 ret = DDERR_UNSUPPORTED;
1165 goto error;
1168 #undef STRETCH_ROW
1171 last_sy = sy;
1172 dbuf += ddesc.lPitch;
1175 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1176 DWORD keylow, keyhigh;
1178 if (dwFlags & DDBLT_KEYSRC) {
1179 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1180 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1181 } else {
1182 /* I'm not sure if this is correct */
1183 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1184 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1185 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1189 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1190 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1192 #define COPYROW_COLORKEY(type) { \
1193 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1194 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1195 tmp = s[sx >> 16]; \
1196 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1198 break; }
1200 switch (bpp) {
1201 case 1: COPYROW_COLORKEY(BYTE)
1202 case 2: COPYROW_COLORKEY(WORD)
1203 case 4: COPYROW_COLORKEY(DWORD)
1204 default:
1205 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1206 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1207 ret = DDERR_UNSUPPORTED;
1208 goto error;
1210 dbuf += ddesc.lPitch;
1213 #undef COPYROW_COLORKEY
1215 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1220 error:
1222 if (dwFlags && FIXME_ON(ddraw)) {
1223 FIXME("\tUnsupported flags: ");
1224 _dump_DDBLT(dwFlags);
1226 release:
1228 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1229 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1231 return DD_OK;
1234 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1235 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1237 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1238 int bpp, w, h, x, y;
1239 DDSURFACEDESC ddesc,sdesc;
1240 HRESULT ret = DD_OK;
1241 LPBYTE sbuf, dbuf;
1242 RECT rsrc2;
1244 if (TRACE_ON(ddraw)) {
1245 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1246 This,dstx,dsty,src,rsrc,trans
1248 FIXME(" trans:");
1249 if (FIXME_ON(ddraw))
1250 _dump_DDBLTFAST(trans);
1251 if (rsrc)
1252 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1253 else
1254 FIXME(" srcrect: NULL\n");
1257 /* We need to lock the surfaces, or we won't get refreshes when done. */
1258 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1259 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1261 if (!rsrc) {
1262 WARN("rsrc is NULL!\n");
1263 rsrc = &rsrc2;
1264 rsrc->left = rsrc->top = 0;
1265 rsrc->right = sdesc.dwWidth;
1266 rsrc->bottom = sdesc.dwHeight;
1269 bpp = GET_BPP(This->s.surface_desc);
1270 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1271 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1274 h=rsrc->bottom-rsrc->top;
1275 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1276 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1277 if (h<0) h=0;
1279 w=rsrc->right-rsrc->left;
1280 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1281 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1282 if (w<0) w=0;
1284 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1285 DWORD keylow, keyhigh;
1286 if (trans & DDBLTFAST_SRCCOLORKEY) {
1287 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1288 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1289 } else {
1290 /* I'm not sure if this is correct */
1291 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1292 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1293 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1296 #define COPYBOX_COLORKEY(type) { \
1297 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1298 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1299 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1300 for (y = 0; y < h; y++) { \
1301 for (x = 0; x < w; x++) { \
1302 tmp = s[x]; \
1303 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1305 (LPBYTE)s += sdesc.lPitch; \
1306 (LPBYTE)d += ddesc.lPitch; \
1308 break; \
1311 switch (bpp) {
1312 case 1: COPYBOX_COLORKEY(BYTE)
1313 case 2: COPYBOX_COLORKEY(WORD)
1314 case 4: COPYBOX_COLORKEY(DWORD)
1315 default:
1316 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1317 ret = DDERR_UNSUPPORTED;
1318 goto error;
1321 #undef COPYBOX_COLORKEY
1323 } else {
1324 int width = w * bpp;
1326 for (y = 0; y < h; y++) {
1327 memcpy(dbuf, sbuf, width);
1328 sbuf += sdesc.lPitch;
1329 dbuf += ddesc.lPitch;
1333 error:
1335 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1336 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1337 return ret;
1340 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1341 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1343 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1344 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1345 This,ddbltbatch,x,y
1347 return DD_OK;
1350 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1351 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1353 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1354 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1355 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1356 return DD_OK;
1359 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1360 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1361 ) {
1362 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1363 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1365 /* Simply copy the surface description stored in the object */
1366 *ddsd = This->s.surface_desc;
1368 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1370 return DD_OK;
1373 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1374 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1375 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1376 return ++(This->ref);
1379 #ifdef HAVE_LIBXXF86DGA
1380 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1381 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1383 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1385 if (--(This->ref))
1386 return This->ref;
1388 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1389 /* clear out of surface list */
1390 if (This->t.dga.fb_height == -1)
1391 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1392 else
1393 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1395 /* Free the DIBSection (if any) */
1396 if (This->s.hdc != 0) {
1397 SelectObject(This->s.hdc, This->s.holdbitmap);
1398 DeleteDC(This->s.hdc);
1399 DeleteObject(This->s.DIBsection);
1402 HeapFree(GetProcessHeap(),0,This);
1403 return S_OK;
1405 #endif /* defined(HAVE_LIBXXF86DGA) */
1407 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1408 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1410 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1412 if (--(This->ref))
1413 return This->ref;
1415 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1417 if (This->t.xlib.image != NULL) {
1418 if (This->s.ddraw->d.pixel_convert != NULL) {
1419 /* In pixel conversion mode, there are 2 buffers to release. */
1420 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1422 #ifdef HAVE_LIBXXSHM
1423 if (This->s.ddraw->e.xlib.xshm_active) {
1424 TSXShmDetach(display, &(This->t.xlib.shminfo));
1425 TSXDestroyImage(This->t.xlib.image);
1426 shmdt(This->t.xlib.shminfo.shmaddr);
1427 } else {
1428 #endif
1429 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1430 This->t.xlib.image->data = NULL;
1431 TSXDestroyImage(This->t.xlib.image);
1432 #ifdef HAVE_LIBXXSHM
1434 #endif
1435 } else {
1436 This->t.xlib.image->data = NULL;
1438 #ifdef HAVE_LIBXXSHM
1439 if (This->s.ddraw->e.xlib.xshm_active) {
1440 TSXShmDetach(display, &(This->t.xlib.shminfo));
1441 TSXDestroyImage(This->t.xlib.image);
1442 shmdt(This->t.xlib.shminfo.shmaddr);
1443 } else {
1444 #endif
1445 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1446 TSXDestroyImage(This->t.xlib.image);
1447 #ifdef HAVE_LIBXXSHM
1449 #endif
1451 This->t.xlib.image = 0;
1452 } else {
1453 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1456 if (This->s.palette)
1457 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1459 /* Free the DIBSection (if any) */
1460 if (This->s.hdc != 0) {
1461 SelectObject(This->s.hdc, This->s.holdbitmap);
1462 DeleteDC(This->s.hdc);
1463 DeleteObject(This->s.DIBsection);
1466 HeapFree(GetProcessHeap(),0,This);
1467 return S_OK;
1470 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1471 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1473 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1474 int i,found = 0,xstart;
1475 struct _surface_chain *chain;
1477 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1478 if (TRACE_ON(ddraw)) {
1479 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1481 chain = This->s.chain;
1482 if (!chain)
1483 return DDERR_NOTFOUND;
1485 for (i=0;i<chain->nrofsurfaces;i++)
1486 if (chain->surfaces[i] == This)
1487 break;
1489 xstart = i;
1490 for (i=0;i<chain->nrofsurfaces;i++) {
1491 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1492 #if 0
1493 if (found) /* may not find the same caps twice, (doc) */
1494 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1495 #endif
1496 found = (i+1)+xstart;
1499 if (!found)
1500 return DDERR_NOTFOUND;
1501 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1502 /* FIXME: AddRef? */
1503 TRACE("found %p\n",*lpdsf);
1504 return DD_OK;
1507 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1508 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1510 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1511 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1513 return DDERR_ALREADYINITIALIZED;
1516 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1517 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1519 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1520 TRACE("(%p)->(%p)\n",This,pf);
1522 *pf = This->s.surface_desc.ddpfPixelFormat;
1523 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1524 return DD_OK;
1527 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1528 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1529 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1530 return DD_OK;
1533 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1534 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1536 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1537 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1538 return DD_OK;
1541 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1542 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER clipper
1544 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1545 FIXME("(%p)->(%p),stub!\n",This,clipper);
1546 return DD_OK;
1549 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1550 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1552 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1553 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1554 int i;
1555 struct _surface_chain *chain;
1557 IDirectDrawSurface4_AddRef(iface);
1559 FIXME("(%p)->(%p)\n",This,surf);
1560 chain = This->s.chain;
1562 if (chain) {
1563 for (i=0;i<chain->nrofsurfaces;i++)
1564 if (chain->surfaces[i] == isurf)
1565 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1566 } else {
1567 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1568 chain->nrofsurfaces = 1;
1569 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1570 chain->surfaces[0] = This;
1571 This->s.chain = chain;
1574 if (chain->surfaces)
1575 chain->surfaces = HeapReAlloc(
1576 GetProcessHeap(),
1578 chain->surfaces,
1579 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1581 else
1582 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1583 isurf->s.chain = chain;
1584 chain->surfaces[chain->nrofsurfaces++] = isurf;
1585 return DD_OK;
1588 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1589 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1590 DDSURFACEDESC desc;
1591 BITMAPINFO *b_info;
1592 UINT usage;
1594 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1596 /* Creates a DIB Section of the same size / format as the surface */
1597 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1599 if (This->s.hdc == 0) {
1600 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1601 case 16:
1602 case 32:
1603 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1604 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1605 break;
1606 #endif
1608 case 24:
1609 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1610 break;
1612 default:
1613 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1614 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1615 break;
1618 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1619 b_info->bmiHeader.biWidth = desc.dwWidth;
1620 b_info->bmiHeader.biHeight = desc.dwHeight;
1621 b_info->bmiHeader.biPlanes = 1;
1622 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1623 #if 0
1624 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1625 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1626 #endif
1627 b_info->bmiHeader.biCompression = BI_RGB;
1628 #if 0
1629 else
1630 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1631 #endif
1632 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1633 b_info->bmiHeader.biXPelsPerMeter = 0;
1634 b_info->bmiHeader.biYPelsPerMeter = 0;
1635 b_info->bmiHeader.biClrUsed = 0;
1636 b_info->bmiHeader.biClrImportant = 0;
1638 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1639 case 16:
1640 case 32:
1641 #if 0
1643 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1645 usage = 0;
1646 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1647 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1648 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1650 break;
1651 #endif
1652 case 24:
1653 /* Nothing to do */
1654 usage = DIB_RGB_COLORS;
1655 break;
1657 default: {
1658 int i;
1660 /* Fill the palette */
1661 usage = DIB_RGB_COLORS;
1663 if (This->s.palette == NULL) {
1664 ERR("Bad palette !!!\n");
1665 } else {
1666 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1667 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1669 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1670 rgb[i].rgbBlue = pent[i].peBlue;
1671 rgb[i].rgbRed = pent[i].peRed;
1672 rgb[i].rgbGreen = pent[i].peGreen;
1676 break;
1678 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1679 b_info,
1680 usage,
1681 &(This->s.bitmap_data),
1685 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1686 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1688 /* b_info is not useful anymore */
1689 HeapFree(GetProcessHeap(), 0, b_info);
1691 /* Create the DC */
1692 This->s.hdc = CreateCompatibleDC(0);
1693 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1696 /* Copy our surface in the DIB section */
1697 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1698 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1699 else
1700 /* TODO */
1701 FIXME("This case has to be done :/\n");
1703 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1704 *lphdc = This->s.hdc;
1706 return DD_OK;
1709 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1710 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1712 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1713 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1714 /* Copy the DIB section to our surface */
1715 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1716 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1717 } else {
1718 /* TODO */
1719 FIXME("This case has to be done :/\n");
1721 /* Unlock the surface */
1722 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1723 return DD_OK;
1726 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1727 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1728 char xrefiid[50];
1730 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1731 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
1733 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1734 * the same interface. And IUnknown does that too of course.
1736 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1737 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1738 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1739 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1740 IsEqualGUID( &IID_IUnknown, refiid )
1742 *obj = This;
1743 IDirectDrawSurface4_AddRef(iface);
1745 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1746 return S_OK;
1748 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1750 /* Texture interface */
1751 *obj = d3dtexture2_create(This);
1752 IDirectDrawSurface4_AddRef(iface);
1753 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1754 return S_OK;
1756 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1758 /* Texture interface */
1759 *obj = d3dtexture_create(This);
1760 IDirectDrawSurface4_AddRef(iface);
1762 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1764 return S_OK;
1766 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1767 /* It is the OpenGL Direct3D Device */
1768 IDirectDrawSurface4_AddRef(iface);
1769 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1770 return S_OK;
1773 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
1774 return OLE_E_ENUM_NOMORE;
1777 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1778 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1779 TRACE("(%p)->(), stub!\n",This);
1780 return DD_OK; /* hmm */
1783 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1784 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1785 int i;
1786 struct _surface_chain *chain = This->s.chain;
1788 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1789 for (i=0;i<chain->nrofsurfaces;i++) {
1790 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1791 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1792 return DD_OK; /* FIXME: return value correct? */
1794 return DD_OK;
1797 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1798 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1799 FIXME("(%p)->(),stub!\n",This);
1800 return DD_OK;
1803 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1804 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1806 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1807 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1808 if (TRACE_ON(ddraw)) {
1809 _dump_colorkeyflag(dwFlags);
1810 DPRINTF(" : ");
1811 _dump_DDCOLORKEY((void *) ckey);
1812 DPRINTF("\n");
1815 /* If this surface was loaded as a texture, call also the texture
1816 SetColorKey callback */
1817 if (This->s.texture) {
1818 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1821 if( dwFlags & DDCKEY_SRCBLT )
1823 dwFlags &= ~DDCKEY_SRCBLT;
1824 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1825 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1828 if( dwFlags & DDCKEY_DESTBLT )
1830 dwFlags &= ~DDCKEY_DESTBLT;
1831 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1832 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1835 if( dwFlags & DDCKEY_SRCOVERLAY )
1837 dwFlags &= ~DDCKEY_SRCOVERLAY;
1838 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1839 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1842 if( dwFlags & DDCKEY_DESTOVERLAY )
1844 dwFlags &= ~DDCKEY_DESTOVERLAY;
1845 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1846 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1849 if( dwFlags )
1851 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1854 return DD_OK;
1858 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1859 LPDIRECTDRAWSURFACE4 iface,
1860 LPRECT lpRect )
1862 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1863 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1865 return DD_OK;
1868 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1869 LPDIRECTDRAWSURFACE4 iface,
1870 DWORD dwFlags,
1871 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1873 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1874 int i;
1875 struct _surface_chain *chain;
1877 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
1878 chain = This->s.chain;
1879 for (i=0;i<chain->nrofsurfaces;i++) {
1880 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
1881 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
1883 chain->surfaces[i]->s.chain = NULL;
1884 memcpy( chain->surfaces+i,
1885 chain->surfaces+(i+1),
1886 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
1888 chain->surfaces = HeapReAlloc(
1889 GetProcessHeap(),
1891 chain->surfaces,
1892 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
1894 chain->nrofsurfaces--;
1895 return DD_OK;
1898 return DD_OK;
1901 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
1902 LPDIRECTDRAWSURFACE4 iface,
1903 DWORD dwFlags,
1904 LPVOID lpContext,
1905 LPDDENUMSURFACESCALLBACK lpfnCallback )
1907 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1908 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
1909 lpContext, lpfnCallback );
1911 return DD_OK;
1914 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
1915 LPDIRECTDRAWSURFACE4 iface,
1916 LPDIRECTDRAWCLIPPER* lplpDDClipper )
1918 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1919 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
1921 return DD_OK;
1924 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
1925 LPDIRECTDRAWSURFACE4 iface,
1926 DWORD dwFlags,
1927 LPDDCOLORKEY lpDDColorKey )
1929 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1930 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
1932 if( dwFlags & DDCKEY_SRCBLT ) {
1933 dwFlags &= ~DDCKEY_SRCBLT;
1934 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
1937 if( dwFlags & DDCKEY_DESTBLT )
1939 dwFlags &= ~DDCKEY_DESTBLT;
1940 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
1943 if( dwFlags & DDCKEY_SRCOVERLAY )
1945 dwFlags &= ~DDCKEY_SRCOVERLAY;
1946 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
1949 if( dwFlags & DDCKEY_DESTOVERLAY )
1951 dwFlags &= ~DDCKEY_DESTOVERLAY;
1952 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
1955 if( dwFlags )
1957 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1960 return DD_OK;
1963 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
1964 LPDIRECTDRAWSURFACE4 iface,
1965 DWORD dwFlags )
1967 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1968 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
1970 return DD_OK;
1973 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
1974 LPDIRECTDRAWSURFACE4 iface,
1975 LPDIRECTDRAWPALETTE* lplpDDPalette )
1977 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1978 FIXME("(%p)->(%p),stub!\n", This, lplpDDPalette);
1980 return DD_OK;
1983 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
1984 LPDIRECTDRAWSURFACE4 iface,
1985 LONG lX,
1986 LONG lY)
1988 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1989 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
1991 return DD_OK;
1994 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
1995 LPDIRECTDRAWSURFACE4 iface,
1996 LPRECT lpSrcRect,
1997 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
1998 LPRECT lpDestRect,
1999 DWORD dwFlags,
2000 LPDDOVERLAYFX lpDDOverlayFx )
2002 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2003 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2004 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2006 return DD_OK;
2009 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
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_UpdateOverlayZOrder(
2020 LPDIRECTDRAWSURFACE4 iface,
2021 DWORD dwFlags,
2022 LPDIRECTDRAWSURFACE4 lpDDSReference )
2024 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2025 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2027 return DD_OK;
2030 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2031 LPDIRECTDRAWSURFACE4 iface,
2032 LPVOID* lplpDD )
2034 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2035 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2037 /* Not sure about that... */
2038 *lplpDD = (void *) This->s.ddraw;
2040 return DD_OK;
2043 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2044 LPDIRECTDRAWSURFACE4 iface,
2045 DWORD dwFlags )
2047 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2048 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2050 return DD_OK;
2053 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2054 LPDIRECTDRAWSURFACE4 iface,
2055 DWORD dwFlags )
2057 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2058 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2060 return DD_OK;
2063 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2064 LPDIRECTDRAWSURFACE4 iface,
2065 LPDDSURFACEDESC lpDDSD,
2066 DWORD dwFlags )
2068 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2069 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2071 return DD_OK;
2074 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2075 REFGUID guidTag,
2076 LPVOID lpData,
2077 DWORD cbSize,
2078 DWORD dwFlags) {
2079 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2080 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2082 return DD_OK;
2085 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2086 REFGUID guidTag,
2087 LPVOID lpBuffer,
2088 LPDWORD lpcbBufferSize) {
2089 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2090 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2092 return DD_OK;
2095 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2096 REFGUID guidTag) {
2097 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2098 FIXME("(%p)->(%p)\n", This, guidTag);
2100 return DD_OK;
2103 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2104 LPDWORD lpValue) {
2105 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2106 FIXME("(%p)->(%p)\n", This, lpValue);
2108 return DD_OK;
2111 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2112 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2113 FIXME("(%p)\n", This);
2115 return DD_OK;
2118 #ifdef HAVE_LIBXXF86DGA
2119 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2121 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2122 IDirectDrawSurface4Impl_QueryInterface,
2123 IDirectDrawSurface4Impl_AddRef,
2124 DGA_IDirectDrawSurface4Impl_Release,
2125 IDirectDrawSurface4Impl_AddAttachedSurface,
2126 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2127 IDirectDrawSurface4Impl_Blt,
2128 IDirectDrawSurface4Impl_BltBatch,
2129 IDirectDrawSurface4Impl_BltFast,
2130 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2131 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2132 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2133 DGA_IDirectDrawSurface4Impl_Flip,
2134 IDirectDrawSurface4Impl_GetAttachedSurface,
2135 IDirectDrawSurface4Impl_GetBltStatus,
2136 IDirectDrawSurface4Impl_GetCaps,
2137 IDirectDrawSurface4Impl_GetClipper,
2138 IDirectDrawSurface4Impl_GetColorKey,
2139 IDirectDrawSurface4Impl_GetDC,
2140 IDirectDrawSurface4Impl_GetFlipStatus,
2141 IDirectDrawSurface4Impl_GetOverlayPosition,
2142 IDirectDrawSurface4Impl_GetPalette,
2143 IDirectDrawSurface4Impl_GetPixelFormat,
2144 IDirectDrawSurface4Impl_GetSurfaceDesc,
2145 IDirectDrawSurface4Impl_Initialize,
2146 IDirectDrawSurface4Impl_IsLost,
2147 IDirectDrawSurface4Impl_Lock,
2148 IDirectDrawSurface4Impl_ReleaseDC,
2149 IDirectDrawSurface4Impl_Restore,
2150 IDirectDrawSurface4Impl_SetClipper,
2151 IDirectDrawSurface4Impl_SetColorKey,
2152 IDirectDrawSurface4Impl_SetOverlayPosition,
2153 DGA_IDirectDrawSurface4Impl_SetPalette,
2154 DGA_IDirectDrawSurface4Impl_Unlock,
2155 IDirectDrawSurface4Impl_UpdateOverlay,
2156 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2157 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2158 IDirectDrawSurface4Impl_GetDDInterface,
2159 IDirectDrawSurface4Impl_PageLock,
2160 IDirectDrawSurface4Impl_PageUnlock,
2161 IDirectDrawSurface4Impl_SetSurfaceDesc,
2162 IDirectDrawSurface4Impl_SetPrivateData,
2163 IDirectDrawSurface4Impl_GetPrivateData,
2164 IDirectDrawSurface4Impl_FreePrivateData,
2165 IDirectDrawSurface4Impl_GetUniquenessValue,
2166 IDirectDrawSurface4Impl_ChangeUniquenessValue
2168 #endif /* defined(HAVE_LIBXXF86DGA) */
2170 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2172 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2173 IDirectDrawSurface4Impl_QueryInterface,
2174 IDirectDrawSurface4Impl_AddRef,
2175 Xlib_IDirectDrawSurface4Impl_Release,
2176 IDirectDrawSurface4Impl_AddAttachedSurface,
2177 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2178 IDirectDrawSurface4Impl_Blt,
2179 IDirectDrawSurface4Impl_BltBatch,
2180 IDirectDrawSurface4Impl_BltFast,
2181 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2182 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2183 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2184 Xlib_IDirectDrawSurface4Impl_Flip,
2185 IDirectDrawSurface4Impl_GetAttachedSurface,
2186 IDirectDrawSurface4Impl_GetBltStatus,
2187 IDirectDrawSurface4Impl_GetCaps,
2188 IDirectDrawSurface4Impl_GetClipper,
2189 IDirectDrawSurface4Impl_GetColorKey,
2190 IDirectDrawSurface4Impl_GetDC,
2191 IDirectDrawSurface4Impl_GetFlipStatus,
2192 IDirectDrawSurface4Impl_GetOverlayPosition,
2193 IDirectDrawSurface4Impl_GetPalette,
2194 IDirectDrawSurface4Impl_GetPixelFormat,
2195 IDirectDrawSurface4Impl_GetSurfaceDesc,
2196 IDirectDrawSurface4Impl_Initialize,
2197 IDirectDrawSurface4Impl_IsLost,
2198 IDirectDrawSurface4Impl_Lock,
2199 IDirectDrawSurface4Impl_ReleaseDC,
2200 IDirectDrawSurface4Impl_Restore,
2201 IDirectDrawSurface4Impl_SetClipper,
2202 IDirectDrawSurface4Impl_SetColorKey,
2203 IDirectDrawSurface4Impl_SetOverlayPosition,
2204 Xlib_IDirectDrawSurface4Impl_SetPalette,
2205 Xlib_IDirectDrawSurface4Impl_Unlock,
2206 IDirectDrawSurface4Impl_UpdateOverlay,
2207 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2208 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2209 IDirectDrawSurface4Impl_GetDDInterface,
2210 IDirectDrawSurface4Impl_PageLock,
2211 IDirectDrawSurface4Impl_PageUnlock,
2212 IDirectDrawSurface4Impl_SetSurfaceDesc,
2213 IDirectDrawSurface4Impl_SetPrivateData,
2214 IDirectDrawSurface4Impl_GetPrivateData,
2215 IDirectDrawSurface4Impl_FreePrivateData,
2216 IDirectDrawSurface4Impl_GetUniquenessValue,
2217 IDirectDrawSurface4Impl_ChangeUniquenessValue
2220 /******************************************************************************
2221 * DirectDrawCreateClipper (DDRAW.7)
2223 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2224 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2225 LPUNKNOWN pUnkOuter)
2227 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2228 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2230 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2231 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2232 (*ilplpDDClipper)->ref = 1;
2234 return DD_OK;
2237 /******************************************************************************
2238 * IDirectDrawClipper
2240 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2241 LPDIRECTDRAWCLIPPER iface,DWORD x,HWND hwnd
2243 ICOM_THIS(IDirectDrawClipperImpl,iface);
2244 FIXME("(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This,x,(DWORD)hwnd);
2245 return DD_OK;
2248 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2249 ICOM_THIS(IDirectDrawClipperImpl,iface);
2250 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2252 This->ref--;
2253 if (This->ref)
2254 return This->ref;
2255 HeapFree(GetProcessHeap(),0,This);
2256 return S_OK;
2259 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2260 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2262 ICOM_THIS(IDirectDrawClipperImpl,iface);
2263 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2264 if (hmm) *hmm=0;
2265 return DD_OK;
2268 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2269 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2271 ICOM_THIS(IDirectDrawClipperImpl,iface);
2272 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2273 return DD_OK;
2276 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2277 LPDIRECTDRAWCLIPPER iface,
2278 REFIID riid,
2279 LPVOID* ppvObj )
2281 ICOM_THIS(IDirectDrawClipperImpl,iface);
2282 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2283 return OLE_E_ENUM_NOMORE;
2286 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2288 ICOM_THIS(IDirectDrawClipperImpl,iface);
2289 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2290 return ++(This->ref);
2293 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2294 LPDIRECTDRAWCLIPPER iface,
2295 HWND* HWndPtr )
2297 ICOM_THIS(IDirectDrawClipperImpl,iface);
2298 FIXME("(%p)->(%p),stub!\n",This,HWndPtr);
2299 return DD_OK;
2302 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2303 LPDIRECTDRAWCLIPPER iface,
2304 LPDIRECTDRAW lpDD,
2305 DWORD dwFlags )
2307 ICOM_THIS(IDirectDrawClipperImpl,iface);
2308 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2309 return DD_OK;
2312 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2313 LPDIRECTDRAWCLIPPER iface,
2314 BOOL* lpbChanged )
2316 ICOM_THIS(IDirectDrawClipperImpl,iface);
2317 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2318 return DD_OK;
2321 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2323 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2324 IDirectDrawClipperImpl_QueryInterface,
2325 IDirectDrawClipperImpl_AddRef,
2326 IDirectDrawClipperImpl_Release,
2327 IDirectDrawClipperImpl_GetClipList,
2328 IDirectDrawClipperImpl_GetHWnd,
2329 IDirectDrawClipperImpl_Initialize,
2330 IDirectDrawClipperImpl_IsClipListChanged,
2331 IDirectDrawClipperImpl_SetClipList,
2332 IDirectDrawClipperImpl_SetHwnd
2336 /******************************************************************************
2337 * IDirectDrawPalette
2339 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2340 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2342 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2343 int i;
2345 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2346 This,x,start,count,palent);
2348 /* No palette created and not in depth-convertion mode -> BUG ! */
2349 if ((This->cm == None) &&
2350 (This->ddraw->d.palette_convert == NULL))
2352 FIXME("app tried to read colormap for non-palettized mode\n");
2353 return DDERR_GENERIC;
2355 for (i=0;i<count;i++) {
2356 palent[i].peRed = This->palents[start+i].peRed;
2357 palent[i].peBlue = This->palents[start+i].peBlue;
2358 palent[i].peGreen = This->palents[start+i].peGreen;
2359 palent[i].peFlags = This->palents[start+i].peFlags;
2362 return DD_OK;
2365 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2366 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2368 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2369 XColor xc;
2370 int i;
2372 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2373 This,x,start,count,palent
2375 for (i=0;i<count;i++) {
2376 xc.red = palent[i].peRed<<8;
2377 xc.blue = palent[i].peBlue<<8;
2378 xc.green = palent[i].peGreen<<8;
2379 xc.flags = DoRed|DoBlue|DoGreen;
2380 xc.pixel = start+i;
2382 if (This->cm)
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;
2391 /* Now, if we are in 'depth conversion mode', update the screen palette */
2392 /* FIXME: we need to update the image or we won't get palette fading. */
2393 if (This->ddraw->d.palette_convert != NULL)
2394 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2396 return DD_OK;
2399 #ifdef HAVE_LIBXXF86DGA
2400 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2401 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2403 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2404 XColor xc;
2405 Colormap cm;
2406 int i;
2408 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2409 This,x,start,count,palent
2411 if (!This->cm) /* should not happen */ {
2412 FIXME("app tried to set colormap in non-palettized mode\n");
2413 return DDERR_GENERIC;
2415 /* FIXME: free colorcells instead of freeing whole map */
2416 cm = This->cm;
2417 This->cm = TSXCopyColormapAndFree(display,This->cm);
2418 TSXFreeColormap(display,cm);
2420 for (i=0;i<count;i++) {
2421 xc.red = palent[i].peRed<<8;
2422 xc.blue = palent[i].peBlue<<8;
2423 xc.green = palent[i].peGreen<<8;
2424 xc.flags = DoRed|DoBlue|DoGreen;
2425 xc.pixel = i+start;
2427 TSXStoreColor(display,This->cm,&xc);
2429 This->palents[start+i].peRed = palent[i].peRed;
2430 This->palents[start+i].peBlue = palent[i].peBlue;
2431 This->palents[start+i].peGreen = palent[i].peGreen;
2432 This->palents[start+i].peFlags = palent[i].peFlags;
2434 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2435 return DD_OK;
2437 #endif /* defined(HAVE_LIBXXF86DGA) */
2439 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2440 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2441 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2442 if (!--(This->ref)) {
2443 if (This->cm) {
2444 TSXFreeColormap(display,This->cm);
2445 This->cm = 0;
2447 HeapFree(GetProcessHeap(),0,This);
2448 return S_OK;
2450 return This->ref;
2453 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2454 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2456 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2457 return ++(This->ref);
2460 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2461 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2463 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2464 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2466 return DDERR_ALREADYINITIALIZED;
2469 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2470 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2472 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2473 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2474 return DD_OK;
2477 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2478 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2480 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2481 char xrefiid[50];
2483 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2484 FIXME("(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2486 return S_OK;
2489 #ifdef HAVE_LIBXXF86DGA
2490 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2492 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2493 IDirectDrawPaletteImpl_QueryInterface,
2494 IDirectDrawPaletteImpl_AddRef,
2495 IDirectDrawPaletteImpl_Release,
2496 IDirectDrawPaletteImpl_GetCaps,
2497 IDirectDrawPaletteImpl_GetEntries,
2498 IDirectDrawPaletteImpl_Initialize,
2499 DGA_IDirectDrawPaletteImpl_SetEntries
2501 #endif /* defined(HAVE_LIBXXF86DGA) */
2503 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2505 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2506 IDirectDrawPaletteImpl_QueryInterface,
2507 IDirectDrawPaletteImpl_AddRef,
2508 IDirectDrawPaletteImpl_Release,
2509 IDirectDrawPaletteImpl_GetCaps,
2510 IDirectDrawPaletteImpl_GetEntries,
2511 IDirectDrawPaletteImpl_Initialize,
2512 Xlib_IDirectDrawPaletteImpl_SetEntries
2515 /*******************************************************************************
2516 * IDirect3D
2518 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2519 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2521 ICOM_THIS(IDirect3DImpl,iface);
2522 /* FIXME: Not sure if this is correct */
2523 char xrefiid[50];
2525 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2526 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2527 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2528 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2529 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2530 *obj = This->ddraw;
2531 IDirect3D_AddRef(iface);
2533 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2535 return S_OK;
2537 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2538 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2539 *obj = This;
2540 IDirect3D_AddRef(iface);
2542 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2544 return S_OK;
2546 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2547 IDirect3D2Impl* d3d;
2549 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2550 d3d->ref = 1;
2551 d3d->ddraw = This->ddraw;
2552 IDirect3D_AddRef(iface);
2553 ICOM_VTBL(d3d) = &d3d2vt;
2554 *obj = d3d;
2556 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2558 return S_OK;
2560 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2561 return OLE_E_ENUM_NOMORE;
2564 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2565 ICOM_THIS(IDirect3DImpl,iface);
2566 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2568 return ++(This->ref);
2571 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2573 ICOM_THIS(IDirect3DImpl,iface);
2574 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2576 if (!--(This->ref)) {
2577 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2578 HeapFree(GetProcessHeap(),0,This);
2579 return S_OK;
2581 return This->ref;
2584 static HRESULT WINAPI IDirect3DImpl_Initialize(
2585 LPDIRECT3D iface, REFIID refiid )
2587 ICOM_THIS(IDirect3DImpl,iface);
2588 /* FIXME: Not sure if this is correct */
2589 char xrefiid[50];
2591 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2592 FIXME("(%p)->(%s):stub.\n",This,xrefiid);
2594 return DDERR_ALREADYINITIALIZED;
2597 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2598 LPD3DENUMDEVICESCALLBACK cb,
2599 LPVOID context) {
2600 ICOM_THIS(IDirect3DImpl,iface);
2601 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2603 /* Call functions defined in d3ddevices.c */
2604 if (!d3d_OpenGL_dx3(cb, context))
2605 return DD_OK;
2607 return DD_OK;
2610 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2611 LPDIRECT3DLIGHT *lplight,
2612 IUnknown *lpunk)
2614 ICOM_THIS(IDirect3DImpl,iface);
2615 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2617 /* Call the creation function that is located in d3dlight.c */
2618 *lplight = d3dlight_create_dx3(This);
2620 return DD_OK;
2623 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2624 LPDIRECT3DMATERIAL *lpmaterial,
2625 IUnknown *lpunk)
2627 ICOM_THIS(IDirect3DImpl,iface);
2628 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2630 /* Call the creation function that is located in d3dviewport.c */
2631 *lpmaterial = d3dmaterial_create(This);
2633 return DD_OK;
2636 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2637 LPDIRECT3DVIEWPORT *lpviewport,
2638 IUnknown *lpunk)
2640 ICOM_THIS(IDirect3DImpl,iface);
2641 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2643 /* Call the creation function that is located in d3dviewport.c */
2644 *lpviewport = d3dviewport_create(This);
2646 return DD_OK;
2649 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2650 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2651 LPD3DFINDDEVICERESULT lpfinddevrst)
2653 ICOM_THIS(IDirect3DImpl,iface);
2654 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2656 return DD_OK;
2659 static ICOM_VTABLE(IDirect3D) d3dvt =
2661 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2662 IDirect3DImpl_QueryInterface,
2663 IDirect3DImpl_AddRef,
2664 IDirect3DImpl_Release,
2665 IDirect3DImpl_Initialize,
2666 IDirect3DImpl_EnumDevices,
2667 IDirect3DImpl_CreateLight,
2668 IDirect3DImpl_CreateMaterial,
2669 IDirect3DImpl_CreateViewport,
2670 IDirect3DImpl_FindDevice
2673 /*******************************************************************************
2674 * IDirect3D2
2676 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2677 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2678 ICOM_THIS(IDirect3D2Impl,iface);
2680 /* FIXME: Not sure if this is correct */
2681 char xrefiid[50];
2683 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2684 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2685 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2686 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2687 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2688 *obj = This->ddraw;
2689 IDirect3D2_AddRef(iface);
2691 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2693 return S_OK;
2695 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2696 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2697 *obj = This;
2698 IDirect3D2_AddRef(iface);
2700 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2702 return S_OK;
2704 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2705 IDirect3DImpl* d3d;
2707 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2708 d3d->ref = 1;
2709 d3d->ddraw = This->ddraw;
2710 IDirect3D2_AddRef(iface);
2711 ICOM_VTBL(d3d) = &d3dvt;
2712 *obj = d3d;
2714 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2716 return S_OK;
2718 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2719 return OLE_E_ENUM_NOMORE;
2722 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2723 ICOM_THIS(IDirect3D2Impl,iface);
2724 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2726 return ++(This->ref);
2729 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2730 ICOM_THIS(IDirect3D2Impl,iface);
2731 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2733 if (!--(This->ref)) {
2734 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2735 HeapFree(GetProcessHeap(),0,This);
2736 return S_OK;
2738 return This->ref;
2741 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2742 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2744 ICOM_THIS(IDirect3D2Impl,iface);
2745 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2747 /* Call functions defined in d3ddevices.c */
2748 if (!d3d_OpenGL(cb, context))
2749 return DD_OK;
2751 return DD_OK;
2754 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2755 LPDIRECT3DLIGHT *lplight,
2756 IUnknown *lpunk)
2758 ICOM_THIS(IDirect3D2Impl,iface);
2759 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2761 /* Call the creation function that is located in d3dlight.c */
2762 *lplight = d3dlight_create(This);
2764 return DD_OK;
2767 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2768 LPDIRECT3DMATERIAL2 *lpmaterial,
2769 IUnknown *lpunk)
2771 ICOM_THIS(IDirect3D2Impl,iface);
2772 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2774 /* Call the creation function that is located in d3dviewport.c */
2775 *lpmaterial = d3dmaterial2_create(This);
2777 return DD_OK;
2780 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2781 LPDIRECT3DVIEWPORT2 *lpviewport,
2782 IUnknown *lpunk)
2784 ICOM_THIS(IDirect3D2Impl,iface);
2785 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2787 /* Call the creation function that is located in d3dviewport.c */
2788 *lpviewport = d3dviewport2_create(This);
2790 return DD_OK;
2793 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2794 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2795 LPD3DFINDDEVICERESULT lpfinddevrst)
2797 ICOM_THIS(IDirect3D2Impl,iface);
2798 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2800 return DD_OK;
2803 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2804 REFCLSID rguid,
2805 LPDIRECTDRAWSURFACE surface,
2806 LPDIRECT3DDEVICE2 *device)
2808 ICOM_THIS(IDirect3D2Impl,iface);
2809 char xbuf[50];
2811 WINE_StringFromCLSID(rguid,xbuf);
2812 FIXME("(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2814 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2815 IDirect3D2_AddRef(iface);
2816 return DD_OK;
2819 return DDERR_INVALIDPARAMS;
2822 static ICOM_VTABLE(IDirect3D2) d3d2vt =
2824 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2825 IDirect3D2Impl_QueryInterface,
2826 IDirect3D2Impl_AddRef,
2827 IDirect3D2Impl_Release,
2828 IDirect3D2Impl_EnumDevices,
2829 IDirect3D2Impl_CreateLight,
2830 IDirect3D2Impl_CreateMaterial,
2831 IDirect3D2Impl_CreateViewport,
2832 IDirect3D2Impl_FindDevice,
2833 IDirect3D2Impl_CreateDevice
2836 /*******************************************************************************
2837 * IDirectDraw
2840 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2841 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2843 static INT ddrawXlibThisOffset = 0;
2845 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
2846 IDirectDrawSurfaceImpl* lpdsf)
2848 int bpp;
2850 /* The surface was already allocated when entering in this function */
2851 TRACE("using system memory for a surface (%p) \n", lpdsf);
2853 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
2854 /* This is a Z Buffer */
2855 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
2856 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
2857 } else {
2858 /* This is a standard image */
2859 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
2860 /* No pixel format => use DirectDraw's format */
2861 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2862 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
2865 bpp = GET_BPP(lpdsf->s.surface_desc);
2868 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
2869 /* The surface was preallocated : seems that we have nothing to do :-) */
2870 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
2873 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
2874 lpdsf->s.surface_desc.u1.lpSurface =
2875 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
2876 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
2878 return DD_OK;
2881 #ifdef HAVE_LIBXXF86DGA
2882 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
2883 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
2885 ICOM_THIS(IDirectDraw2Impl,iface);
2886 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
2887 int i, fbheight = This->e.dga.fb_height;
2889 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
2890 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
2892 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
2893 GetProcessHeap(),
2894 HEAP_ZERO_MEMORY,
2895 sizeof(IDirectDrawSurfaceImpl)
2897 IDirectDraw2_AddRef(iface);
2899 (*ilpdsf)->ref = 1;
2900 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
2901 (*ilpdsf)->s.ddraw = This;
2902 (*ilpdsf)->s.palette = NULL;
2903 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
2905 /* Copy the surface description */
2906 (*ilpdsf)->s.surface_desc = *lpddsd;
2908 if (!(lpddsd->dwFlags & DDSD_WIDTH))
2909 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2910 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
2911 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2913 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
2915 /* Check if this a 'primary surface' or not */
2916 if ((lpddsd->dwFlags & DDSD_CAPS) &&
2917 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
2918 /* This is THE primary surface => there is DGA-specific code */
2920 /* First, store the surface description */
2921 (*ilpdsf)->s.surface_desc = *lpddsd;
2923 /* Find a viewport */
2924 for (i=0;i<32;i++)
2925 if (!(This->e.dga.vpmask & (1<<i)))
2926 break;
2927 TRACE("using viewport %d for a primary surface\n",i);
2928 /* if i == 32 or maximum ... return error */
2929 This->e.dga.vpmask|=(1<<i);
2930 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
2931 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
2933 (*ilpdsf)->s.surface_desc.u1.lpSurface =
2934 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2936 (*ilpdsf)->t.dga.fb_height = i*fbheight;
2938 /* Add flags if there were not present */
2939 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
2940 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
2941 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
2942 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
2943 /* We put our surface always in video memory */
2944 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
2945 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
2946 (*ilpdsf)->s.chain = NULL;
2948 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
2949 IDirectDrawSurface4Impl* back;
2950 int bbc;
2952 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
2953 int i;
2955 back = (IDirectDrawSurface4Impl*)HeapAlloc(
2956 GetProcessHeap(),
2957 HEAP_ZERO_MEMORY,
2958 sizeof(IDirectDrawSurface4Impl)
2960 IDirectDraw2_AddRef(iface);
2961 back->ref = 1;
2962 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
2963 for (i=0;i<32;i++)
2964 if (!(This->e.dga.vpmask & (1<<i)))
2965 break;
2966 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
2967 /* if i == 32 or maximum ... return error */
2968 This->e.dga.vpmask|=(1<<i);
2969 back->t.dga.fb_height = i*fbheight;
2970 /* Copy the surface description from the front buffer */
2971 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
2972 /* Change the parameters that are not the same */
2973 back->s.surface_desc.u1.lpSurface =
2974 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
2976 back->s.ddraw = This;
2977 /* Add relevant info to front and back buffers */
2978 /* FIXME: backbuffer/frontbuffer handling broken here, but
2979 * will be fixed up in _Flip().
2981 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
2982 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
2983 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
2984 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
2985 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
2988 } else {
2989 /* There is no DGA-specific code here...
2990 Go to the common surface creation function */
2991 return common_off_screen_CreateSurface(This, *ilpdsf);
2993 return DD_OK;
2995 #endif /* defined(HAVE_LIBXXF86DGA) */
2997 #ifdef HAVE_LIBXXSHM
2998 /* Error handlers for Image creation */
2999 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3000 XShmErrorFlag = 1;
3001 return 0;
3004 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3005 XImage *img;
3006 int (*WineXHandler)(Display *, XErrorEvent *);
3008 img = TSXShmCreateImage(display,
3009 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3010 This->d.pixmap_depth,
3011 ZPixmap,
3012 NULL,
3013 &(lpdsf->t.xlib.shminfo),
3014 lpdsf->s.surface_desc.dwWidth,
3015 lpdsf->s.surface_desc.dwHeight
3018 if (img == NULL) {
3019 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3020 This->e.xlib.xshm_active = 0;
3021 return NULL;
3024 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3025 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3026 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3027 This->e.xlib.xshm_active = 0;
3028 TSXDestroyImage(img);
3029 return NULL;
3032 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3034 if (img->data == (char *) -1) {
3035 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3036 This->e.xlib.xshm_active = 0;
3037 TSXDestroyImage(img);
3038 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3039 return NULL;
3041 lpdsf->t.xlib.shminfo.readOnly = False;
3043 /* This is where things start to get trickier....
3044 * First, we flush the current X connections to be sure to catch all
3045 * non-XShm related errors
3047 TSXSync(display, False);
3048 /* Then we enter in the non-thread safe part of the tests */
3049 EnterCriticalSection( &X11DRV_CritSection );
3051 /* Reset the error flag, sets our new error handler and try to attach
3052 * the surface
3054 XShmErrorFlag = 0;
3055 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3056 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3057 XSync(display, False);
3059 /* Check the error flag */
3060 if (XShmErrorFlag) {
3061 /* An error occured */
3062 XFlush(display);
3063 XShmErrorFlag = 0;
3064 XDestroyImage(img);
3065 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3066 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3067 XSetErrorHandler(WineXHandler);
3069 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3070 This->e.xlib.xshm_active = 0;
3072 /* Leave the critical section */
3073 LeaveCriticalSection( &X11DRV_CritSection );
3074 return NULL;
3076 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3077 * this works, but it may be a bit overkill....
3079 XSetErrorHandler(WineXHandler);
3080 LeaveCriticalSection( &X11DRV_CritSection );
3082 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3084 if (This->d.pixel_convert != NULL) {
3085 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3086 GetProcessHeap(),
3087 HEAP_ZERO_MEMORY,
3088 lpdsf->s.surface_desc.dwWidth *
3089 lpdsf->s.surface_desc.dwHeight *
3090 PFGET_BPP(This->d.directdraw_pixelformat)
3092 } else {
3093 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3095 return img;
3097 #endif /* HAVE_LIBXXSHM */
3099 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3100 XImage *img = NULL;
3101 void *img_data;
3103 #ifdef HAVE_LIBXXSHM
3104 if (This->e.xlib.xshm_active)
3105 img = create_xshmimage(This, lpdsf);
3107 if (img == NULL) {
3108 #endif
3109 /* Allocate surface memory */
3110 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3111 GetProcessHeap(),HEAP_ZERO_MEMORY,
3112 lpdsf->s.surface_desc.dwWidth *
3113 lpdsf->s.surface_desc.dwHeight *
3114 PFGET_BPP(This->d.directdraw_pixelformat)
3117 if (This->d.pixel_convert != NULL) {
3118 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3119 lpdsf->s.surface_desc.dwWidth *
3120 lpdsf->s.surface_desc.dwHeight *
3121 PFGET_BPP(This->d.screen_pixelformat)
3123 } else {
3124 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3127 /* In this case, create an XImage */
3128 img = TSXCreateImage(display,
3129 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3130 This->d.pixmap_depth,
3131 ZPixmap,
3133 img_data,
3134 lpdsf->s.surface_desc.dwWidth,
3135 lpdsf->s.surface_desc.dwHeight,
3137 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3139 #ifdef HAVE_LIBXXSHM
3141 #endif
3142 if (This->d.pixel_convert != NULL)
3143 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3144 else
3145 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3146 return img;
3149 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3150 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3152 ICOM_THIS(IDirectDraw2Impl,iface);
3153 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3155 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3157 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3159 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3160 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3163 IDirectDraw2_AddRef(iface);
3165 (*ilpdsf)->s.ddraw = This;
3166 (*ilpdsf)->ref = 1;
3167 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3168 (*ilpdsf)->s.palette = NULL;
3169 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3171 /* Copy the surface description */
3172 (*ilpdsf)->s.surface_desc = *lpddsd;
3174 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3175 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3176 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3177 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3178 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3180 /* Check if this a 'primary surface' or not */
3181 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3182 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3183 XImage *img;
3185 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3186 /* Create the XImage */
3187 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3188 if (img == NULL)
3189 return DDERR_OUTOFMEMORY;
3190 (*ilpdsf)->t.xlib.image = img;
3192 /* Add flags if there were not present */
3193 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3194 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3195 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3196 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3197 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3199 /* Check for backbuffers */
3200 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3201 IDirectDrawSurface4Impl* back;
3202 XImage *img;
3203 int i;
3205 for (i=lpddsd->dwBackBufferCount;i--;) {
3206 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3207 GetProcessHeap(),HEAP_ZERO_MEMORY,
3208 sizeof(IDirectDrawSurface4Impl)
3211 TRACE("allocated back-buffer (%p)\n", back);
3213 IDirectDraw2_AddRef(iface);
3214 back->s.ddraw = This;
3216 back->ref = 1;
3217 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3218 /* Copy the surface description from the front buffer */
3219 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3221 /* Create the XImage */
3222 img = create_ximage(This, back);
3223 if (img == NULL)
3224 return DDERR_OUTOFMEMORY;
3225 back->t.xlib.image = img;
3227 /* Add relevant info to front and back buffers */
3228 /* FIXME: backbuffer/frontbuffer handling broken here, but
3229 * will be fixed up in _Flip().
3231 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3232 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3233 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3234 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3235 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3238 } else {
3239 /* There is no Xlib-specific code here...
3240 Go to the common surface creation function */
3241 return common_off_screen_CreateSurface(This, *ilpdsf);
3243 return DD_OK;
3246 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3247 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3249 ICOM_THIS(IDirectDraw2Impl,iface);
3250 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3251 *dst = src; /* FIXME */
3252 return DD_OK;
3256 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3257 * even when the approbiate bitmasks are not specified.
3259 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3260 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3262 ICOM_THIS(IDirectDraw2Impl,iface);
3264 int i;
3265 const struct {
3266 int mask;
3267 char *name;
3268 } flagmap[] = {
3269 #define FE(x) { x, #x},
3270 FE(DDSCL_FULLSCREEN)
3271 FE(DDSCL_ALLOWREBOOT)
3272 FE(DDSCL_NOWINDOWCHANGES)
3273 FE(DDSCL_NORMAL)
3274 FE(DDSCL_ALLOWMODEX)
3275 FE(DDSCL_EXCLUSIVE)
3276 FE(DDSCL_SETFOCUSWINDOW)
3277 FE(DDSCL_SETDEVICEWINDOW)
3278 FE(DDSCL_CREATEDEVICEWINDOW)
3279 #undef FE
3283 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3284 This->d.mainWindow = hwnd;
3286 /* This will be overwritten in the case of Full Screen mode.
3287 Windowed games could work with that :-) */
3288 if (hwnd)
3290 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3291 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3292 WIN_ReleaseWndPtr(tmpWnd);
3294 if( !This->d.drawable ) {
3295 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3296 WIN_ReleaseDesktop();
3298 TRACE("Setting drawable to %ld\n", This->d.drawable);
3301 return DD_OK;
3304 /* Small helper to either use the cooperative window or create a new
3305 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3307 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3308 RECT rect;
3310 /* Do not destroy the application supplied cooperative window */
3311 if (This->d.window && This->d.window != This->d.mainWindow) {
3312 DestroyWindow(This->d.window);
3313 This->d.window = 0;
3315 /* Sanity check cooperative window before assigning it to drawing. */
3316 if ( IsWindow(This->d.mainWindow) &&
3317 IsWindowVisible(This->d.mainWindow)
3319 /* if it does not fit, resize the cooperative window.
3320 * and hope the app likes it
3322 GetWindowRect(This->d.mainWindow,&rect);
3323 if ((((rect.right-rect.left) >= This->d.width) &&
3324 ((rect.bottom-rect.top) >= This->d.height))
3326 This->d.window = This->d.mainWindow;
3327 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3331 /* ... failed, create new one. */
3332 if (!This->d.window) {
3333 This->d.window = CreateWindowExA(
3335 "WINE_DirectDraw",
3336 "WINE_DirectDraw",
3337 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3338 0,0,
3339 This->d.width,
3340 This->d.height,
3344 NULL
3346 /*Store THIS with the window. We'll use it in the window procedure*/
3347 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3348 ShowWindow(This->d.window,TRUE);
3349 UpdateWindow(This->d.window);
3351 SetFocus(This->d.window);
3354 static int _common_depth_to_pixelformat(DWORD depth,
3355 DDPIXELFORMAT *pixelformat,
3356 DDPIXELFORMAT *screen_pixelformat,
3357 int *pix_depth) {
3358 XVisualInfo *vi;
3359 XPixmapFormatValues *pf;
3360 XVisualInfo vt;
3361 int nvisuals, npixmap, i;
3362 int match = 0;
3363 int index = -2;
3365 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3366 pf = XListPixmapFormats(display, &npixmap);
3368 for (i = 0; i < npixmap; i++) {
3369 if (pf[i].depth == depth) {
3370 int j;
3372 for (j = 0; j < nvisuals; j++) {
3373 if (vi[j].depth == pf[i].depth) {
3374 pixelformat->dwSize = sizeof(*pixelformat);
3375 if (depth == 8) {
3376 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3377 pixelformat->u1.dwRBitMask = 0;
3378 pixelformat->u2.dwGBitMask = 0;
3379 pixelformat->u3.dwBBitMask = 0;
3380 } else {
3381 pixelformat->dwFlags = DDPF_RGB;
3382 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3383 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3384 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3386 pixelformat->dwFourCC = 0;
3387 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3388 pixelformat->u4.dwRGBAlphaBitMask= 0;
3390 *screen_pixelformat = *pixelformat;
3392 if (pix_depth != NULL)
3393 *pix_depth = vi[j].depth;
3395 match = 1;
3396 index = -1;
3398 goto clean_up_and_exit;
3402 ERR("No visual corresponding to pixmap format !\n");
3406 if (match == 0) {
3407 /* We try now to find an emulated mode */
3408 int c;
3410 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3411 if (ModeEmulations[c].dest.depth == depth) {
3412 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3413 for (i = 0; i < npixmap; i++) {
3414 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3415 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3416 int j;
3418 for (j = 0; j < nvisuals; j++) {
3419 if (vi[j].depth == pf[i].depth) {
3420 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3421 screen_pixelformat->dwFlags = DDPF_RGB;
3422 screen_pixelformat->dwFourCC = 0;
3423 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3424 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3425 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3426 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3427 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3429 pixelformat->dwSize = sizeof(*pixelformat);
3430 pixelformat->dwFourCC = 0;
3431 if (depth == 8) {
3432 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3433 pixelformat->u.dwRGBBitCount = 8;
3434 pixelformat->u1.dwRBitMask = 0;
3435 pixelformat->u2.dwGBitMask = 0;
3436 pixelformat->u3.dwBBitMask = 0;
3437 } else {
3438 pixelformat->dwFlags = DDPF_RGB;
3439 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3440 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3441 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3442 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3444 pixelformat->u4.dwRGBAlphaBitMask= 0;
3446 if (pix_depth != NULL)
3447 *pix_depth = vi[j].depth;
3449 match = 2;
3450 index = c;
3452 goto clean_up_and_exit;
3455 ERR("No visual corresponding to pixmap format !\n");
3463 clean_up_and_exit:
3464 TSXFree(vi);
3465 TSXFree(pf);
3467 return index;
3470 #ifdef HAVE_LIBXXF86DGA
3471 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3472 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3474 ICOM_THIS(IDirectDrawImpl,iface);
3475 int i,mode_count;
3477 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3479 /* We hope getting the asked for depth */
3480 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3481 /* I.e. no visual found or emulated */
3482 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3483 return DDERR_UNSUPPORTEDMODE;
3486 if (This->d.width < width) {
3487 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3488 return DDERR_UNSUPPORTEDMODE;
3490 This->d.width = width;
3491 This->d.height = height;
3493 /* adjust fb_height, so we don't overlap */
3494 if (This->e.dga.fb_height < height)
3495 This->e.dga.fb_height = height;
3496 _common_IDirectDrawImpl_SetDisplayMode(This);
3498 #ifdef HAVE_LIBXXF86VM
3500 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3501 XF86VidModeModeLine mod_tmp;
3502 /* int dotclock_tmp; */
3504 /* save original video mode and set fullscreen if available*/
3505 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3506 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3507 orig_mode->hdisplay = mod_tmp.hdisplay;
3508 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3509 orig_mode->hsyncend = mod_tmp.hsyncend;
3510 orig_mode->htotal = mod_tmp.htotal;
3511 orig_mode->vdisplay = mod_tmp.vdisplay;
3512 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3513 orig_mode->vsyncend = mod_tmp.vsyncend;
3514 orig_mode->vtotal = mod_tmp.vtotal;
3515 orig_mode->flags = mod_tmp.flags;
3516 orig_mode->private = mod_tmp.private;
3518 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3519 for (i=0;i<mode_count;i++)
3521 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3523 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3524 *vidmode = *(all_modes[i]);
3525 break;
3526 } else
3527 TSXFree(all_modes[i]->private);
3529 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3530 TSXFree(all_modes);
3532 if (!vidmode)
3533 WARN("Fullscreen mode not available!\n");
3535 if (vidmode)
3537 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3538 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3539 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3540 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3541 #endif
3544 #endif
3546 /* FIXME: this function OVERWRITES several signal handlers.
3547 * can we save them? and restore them later? In a way that
3548 * it works for the library too?
3550 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3551 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3553 #ifdef RESTORE_SIGNALS
3554 SIGNAL_Init();
3555 #endif
3556 return DD_OK;
3558 #endif /* defined(HAVE_LIBXXF86DGA) */
3560 /* *************************************
3561 16 / 15 bpp to palettized 8 bpp
3562 ************************************* */
3563 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3564 unsigned char *c_src = (unsigned char *) src;
3565 unsigned short *c_dst = (unsigned short *) dst;
3566 int y;
3568 if (palette != NULL) {
3569 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3571 for (y = height; y--; ) {
3572 #if defined(__i386__) && defined(__GNUC__)
3573 /* gcc generates slightly inefficient code for the the copy / lookup,
3574 * it generates one excess memory access (to pal) per pixel. Since
3575 * we know that pal is not modified by the memory write we can
3576 * put it into a register and reduce the number of memory accesses
3577 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3578 * (This is not guaranteed to be the fastest method.)
3580 __asm__ __volatile__(
3581 "xor %%eax,%%eax\n"
3582 "1:\n"
3583 " lodsb\n"
3584 " movw (%%edx,%%eax,2),%%ax\n"
3585 " stosw\n"
3586 " xor %%eax,%%eax\n"
3587 " loop 1b\n"
3588 : "=S" (c_src), "=D" (c_dst)
3589 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3590 : "eax", "cc", "memory"
3592 c_src+=(pitch-width);
3593 #else
3594 unsigned char * srclineend = c_src+width;
3595 while (c_src < srclineend)
3596 *c_dst++ = pal[*c_src++];
3597 c_src+=(pitch-width);
3598 #endif
3600 } else {
3601 WARN("No palette set...\n");
3602 memset(dst, 0, width * height * 2);
3605 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3606 int i;
3607 unsigned short *pal = (unsigned short *) screen_palette;
3609 for (i = 0; i < count; i++)
3610 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3611 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3612 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3614 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3615 int i;
3616 unsigned short *pal = (unsigned short *) screen_palette;
3618 for (i = 0; i < count; i++)
3619 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3620 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3621 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3624 /* *************************************
3625 24 to palettized 8 bpp
3626 ************************************* */
3627 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3628 unsigned char *c_src = (unsigned char *) src;
3629 unsigned char *c_dst = (unsigned char *) dst;
3630 int y;
3632 if (palette != NULL) {
3633 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3635 for (y = height; y--; ) {
3636 unsigned char * srclineend = c_src+width;
3637 while (c_src < srclineend ) {
3638 register long pixel = pal[*c_src++];
3639 *c_dst++ = pixel;
3640 *c_dst++ = pixel>>8;
3641 *c_dst++ = pixel>>16;
3643 c_src+=(pitch-width);
3645 } else {
3646 WARN("No palette set...\n");
3647 memset(dst, 0, width * height * 4);
3650 /* *************************************
3651 32 bpp to palettized 8 bpp
3652 ************************************* */
3653 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3654 unsigned char *c_src = (unsigned char *) src;
3655 unsigned int *c_dst = (unsigned int *) dst;
3656 int y;
3658 if (palette != NULL) {
3659 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3661 for (y = height; y--; ) {
3662 #if defined(__i386__) && defined(__GNUC__)
3663 /* See comment in pixel_convert_16_to_8 */
3664 __asm__ __volatile__(
3665 "xor %%eax,%%eax\n"
3666 "1:\n"
3667 " lodsb\n"
3668 " movl (%%edx,%%eax,4),%%eax\n"
3669 " stosl\n"
3670 " xor %%eax,%%eax\n"
3671 " loop 1b\n"
3672 : "=S" (c_src), "=D" (c_dst)
3673 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3674 : "eax", "cc", "memory"
3676 c_src+=(pitch-width);
3677 #else
3678 unsigned char * srclineend = c_src+width;
3679 while (c_src < srclineend )
3680 *c_dst++ = pal[*c_src++];
3681 c_src+=(pitch-width);
3682 #endif
3684 } else {
3685 WARN("No palette set...\n");
3686 memset(dst, 0, width * height * 4);
3690 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3691 int i;
3692 unsigned int *pal = (unsigned int *) screen_palette;
3694 for (i = 0; i < count; i++)
3695 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3696 (((unsigned int) palent[i].peGreen) << 8) |
3697 ((unsigned int) palent[i].peBlue));
3700 /* *************************************
3701 32 bpp to 16 bpp
3702 ************************************* */
3703 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3704 unsigned short *c_src = (unsigned short *) src;
3705 unsigned int *c_dst = (unsigned int *) dst;
3706 int y;
3708 for (y = height; y--; ) {
3709 unsigned short * srclineend = c_src+width;
3710 while (c_src < srclineend ) {
3711 *c_dst++ = (((*c_src & 0xF800) << 8) |
3712 ((*c_src & 0x07E0) << 5) |
3713 ((*c_src & 0x001F) << 3));
3714 c_src++;
3716 c_src+=((pitch/2)-width);
3721 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3722 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3724 ICOM_THIS(IDirectDrawImpl,iface);
3725 char buf[200];
3726 WND *tmpWnd;
3727 int c;
3729 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3730 This, width, height, depth);
3732 switch ((c = _common_depth_to_pixelformat(depth,
3733 &(This->d.directdraw_pixelformat),
3734 &(This->d.screen_pixelformat),
3735 &(This->d.pixmap_depth)))) {
3736 case -2:
3737 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3738 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3739 return DDERR_UNSUPPORTEDMODE;
3741 case -1:
3742 /* No convertion */
3743 This->d.pixel_convert = NULL;
3744 This->d.palette_convert = NULL;
3745 break;
3747 default:
3748 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3750 /* Set the depth convertion routines */
3751 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
3752 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
3755 This->d.width = width;
3756 This->d.height = height;
3758 _common_IDirectDrawImpl_SetDisplayMode(This);
3760 tmpWnd = WIN_FindWndPtr(This->d.window);
3761 This->d.paintable = 1;
3762 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3763 WIN_ReleaseWndPtr(tmpWnd);
3765 /* We don't have a context for this window. Host off the desktop */
3766 if( !This->d.drawable )
3768 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3769 WIN_ReleaseDesktop();
3771 TRACE("Setting drawable to %ld\n", This->d.drawable);
3773 return DD_OK;
3776 #ifdef HAVE_LIBXXF86DGA
3777 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3778 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3780 ICOM_THIS(IDirectDraw2Impl,iface);
3781 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3782 if (!caps1 && !caps2)
3783 return DDERR_INVALIDPARAMS;
3784 if (caps1) {
3785 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3786 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3787 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3789 if (caps2) {
3790 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3791 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3792 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3794 return DD_OK;
3796 #endif /* defined(HAVE_LIBXXF86DGA) */
3798 static void fill_caps(LPDDCAPS caps) {
3799 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3800 Need to be fixed, though.. */
3801 if (caps == NULL)
3802 return;
3804 caps->dwSize = sizeof(*caps);
3805 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
3806 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
3807 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
3808 caps->dwFXCaps = 0;
3809 caps->dwFXAlphaCaps = 0;
3810 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
3811 caps->dwSVCaps = 0;
3812 caps->dwZBufferBitDepths = DDBD_16;
3813 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3814 to put textures in video memory.
3815 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3816 for example) ? */
3817 caps->dwVidMemTotal = 8192 * 1024;
3818 caps->dwVidMemFree = 8192 * 1024;
3819 /* These are all the supported capabilities of the surfaces */
3820 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
3821 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
3822 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
3823 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
3824 #ifdef HAVE_MESAGL
3825 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
3826 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
3827 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
3828 #endif
3831 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
3832 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3834 ICOM_THIS(IDirectDraw2Impl,iface);
3835 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3837 /* Put the same caps for the two capabilities */
3838 fill_caps(caps1);
3839 fill_caps(caps2);
3841 return DD_OK;
3844 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
3845 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
3847 ICOM_THIS(IDirectDraw2Impl,iface);
3848 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
3849 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
3850 This,x,ilpddclip,lpunk
3852 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
3853 (*ilpddclip)->ref = 1;
3854 ICOM_VTBL(*ilpddclip) = &ddclipvt;
3855 return DD_OK;
3858 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
3859 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
3861 int size = 0;
3863 if (TRACE_ON(ddraw))
3864 _dump_paletteformat(dwFlags);
3866 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
3867 if (*lpddpal == NULL) return E_OUTOFMEMORY;
3868 (*lpddpal)->ref = 1;
3869 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
3870 (*lpddpal)->installed = 0;
3872 if (dwFlags & DDPCAPS_1BIT)
3873 size = 2;
3874 else if (dwFlags & DDPCAPS_2BIT)
3875 size = 4;
3876 else if (dwFlags & DDPCAPS_4BIT)
3877 size = 16;
3878 else if (dwFlags & DDPCAPS_8BIT)
3879 size = 256;
3880 else
3881 ERR("unhandled palette format\n");
3882 *psize = size;
3884 if (palent)
3886 /* Now, if we are in 'depth conversion mode', create the screen palette */
3887 if (This->d.palette_convert != NULL)
3888 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
3890 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
3891 } else if (This->d.palette_convert != NULL) {
3892 /* In that case, put all 0xFF */
3893 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
3896 return DD_OK;
3899 #ifdef HAVE_LIBXXF86DGA
3900 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
3901 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3903 ICOM_THIS(IDirectDraw2Impl,iface);
3904 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3905 HRESULT res;
3906 int xsize = 0,i;
3908 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3909 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3910 if (res != 0) return res;
3911 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
3912 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
3913 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
3914 } else {
3915 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
3916 (*ilpddpal)->cm = 0;
3918 if (((*ilpddpal)->cm)&&xsize) {
3919 for (i=0;i<xsize;i++) {
3920 XColor xc;
3922 xc.red = (*ilpddpal)->palents[i].peRed<<8;
3923 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
3924 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
3925 xc.flags = DoRed|DoBlue|DoGreen;
3926 xc.pixel = i;
3927 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
3930 return DD_OK;
3932 #endif /* defined(HAVE_LIBXXF86DGA) */
3934 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
3935 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
3937 ICOM_THIS(IDirectDraw2Impl,iface);
3938 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
3939 int xsize;
3940 HRESULT res;
3942 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
3943 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
3944 if (res != 0) return res;
3945 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
3946 return DD_OK;
3949 #ifdef HAVE_LIBXXF86DGA
3950 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3951 ICOM_THIS(IDirectDraw2Impl,iface);
3952 TRACE("(%p)->()\n",This);
3953 Sleep(1000);
3954 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3955 #ifdef RESTORE_SIGNALS
3956 SIGNAL_Init();
3957 #endif
3958 return DD_OK;
3960 #endif /* defined(HAVE_LIBXXF86DGA) */
3962 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
3963 ICOM_THIS(IDirectDraw2Impl,iface);
3964 TRACE("(%p)->RestoreDisplayMode()\n", This);
3965 Sleep(1000);
3966 return DD_OK;
3969 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
3970 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
3972 ICOM_THIS(IDirectDraw2Impl,iface);
3973 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
3974 return DD_OK;
3977 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
3978 ICOM_THIS(IDirectDraw2Impl,iface);
3979 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
3981 return ++(This->ref);
3984 #ifdef HAVE_LIBXXF86DGA
3985 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
3986 ICOM_THIS(IDirectDraw2Impl,iface);
3987 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
3989 if (!--(This->ref)) {
3990 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
3991 if (This->d.window && (This->d.mainWindow != This->d.window))
3992 DestroyWindow(This->d.window);
3993 #ifdef HAVE_LIBXXF86VM
3994 if (orig_mode) {
3995 TSXF86VidModeSwitchToMode(
3996 display,
3997 DefaultScreen(display),
3998 orig_mode);
3999 if (orig_mode->privsize)
4000 TSXFree(orig_mode->private);
4001 free(orig_mode);
4002 orig_mode = NULL;
4004 #endif
4006 #ifdef RESTORE_SIGNALS
4007 SIGNAL_Init();
4008 #endif
4009 HeapFree(GetProcessHeap(),0,This);
4010 return S_OK;
4012 return This->ref;
4014 #endif /* defined(HAVE_LIBXXF86DGA) */
4016 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4017 ICOM_THIS(IDirectDraw2Impl,iface);
4018 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4020 if (!--(This->ref)) {
4021 if (This->d.window && (This->d.mainWindow != This->d.window))
4022 DestroyWindow(This->d.window);
4023 HeapFree(GetProcessHeap(),0,This);
4024 return S_OK;
4026 /* FIXME: destroy window ... */
4027 return This->ref;
4030 #ifdef HAVE_LIBXXF86DGA
4031 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4032 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4034 ICOM_THIS(IDirectDraw2Impl,iface);
4035 char xrefiid[50];
4037 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4038 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4039 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4040 *obj = This;
4041 IDirectDraw2_AddRef(iface);
4043 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4045 return S_OK;
4047 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4048 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4049 IDirectDraw2_AddRef(iface);
4050 *obj = This;
4052 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4054 return S_OK;
4056 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4057 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4058 IDirectDraw2_AddRef(iface);
4059 *obj = This;
4061 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4063 return S_OK;
4065 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4066 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4067 IDirectDraw2_AddRef(iface);
4068 *obj = This;
4070 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4072 return S_OK;
4074 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4075 IDirect3DImpl* d3d;
4077 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4078 d3d->ref = 1;
4079 d3d->ddraw = (IDirectDrawImpl*)This;
4080 IDirectDraw2_AddRef(iface);
4081 ICOM_VTBL(d3d) = &d3dvt;
4082 *obj = d3d;
4084 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4086 return S_OK;
4088 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4089 IDirect3D2Impl* d3d;
4091 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4092 d3d->ref = 1;
4093 d3d->ddraw = (IDirectDrawImpl*)This;
4094 IDirectDraw2_AddRef(iface);
4095 ICOM_VTBL(d3d) = &d3d2vt;
4096 *obj = d3d;
4098 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4100 return S_OK;
4102 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4103 return OLE_E_ENUM_NOMORE;
4105 #endif /* defined(HAVE_LIBXXF86DGA) */
4107 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4108 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4110 ICOM_THIS(IDirectDraw2Impl,iface);
4111 char xrefiid[50];
4113 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4114 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4115 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4116 *obj = This;
4117 IDirectDraw2_AddRef(iface);
4119 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4121 return S_OK;
4123 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4124 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4125 IDirectDraw2_AddRef(iface);
4126 *obj = This;
4128 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4130 return S_OK;
4132 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4133 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4134 IDirectDraw2_AddRef(iface);
4135 *obj = This;
4137 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4139 return S_OK;
4141 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4142 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4143 IDirectDraw2_AddRef(iface);
4144 *obj = This;
4146 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4148 return S_OK;
4150 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4151 IDirect3DImpl* d3d;
4153 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4154 d3d->ref = 1;
4155 d3d->ddraw = (IDirectDrawImpl*)This;
4156 IDirectDraw2_AddRef(iface);
4157 ICOM_VTBL(d3d) = &d3dvt;
4158 *obj = d3d;
4160 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4162 return S_OK;
4164 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4165 IDirect3D2Impl* d3d;
4167 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4168 d3d->ref = 1;
4169 d3d->ddraw = (IDirectDrawImpl*)This;
4170 IDirectDraw2_AddRef(iface);
4171 ICOM_VTBL(d3d) = &d3d2vt;
4172 *obj = d3d;
4174 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4176 return S_OK;
4178 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4179 return OLE_E_ENUM_NOMORE;
4182 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4183 LPDIRECTDRAW2 iface,BOOL *status
4185 ICOM_THIS(IDirectDraw2Impl,iface);
4186 TRACE("(%p)->(%p)\n",This,status);
4187 *status = TRUE;
4188 return DD_OK;
4191 #ifdef HAVE_LIBXXF86DGA
4192 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4193 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4195 ICOM_THIS(IDirectDraw2Impl,iface);
4196 DDSURFACEDESC ddsfd;
4197 static struct {
4198 int w,h;
4199 } modes[5] = { /* some of the usual modes */
4200 {512,384},
4201 {640,400},
4202 {640,480},
4203 {800,600},
4204 {1024,768},
4206 static int depths[4] = {8,16,24,32};
4207 int i,j;
4209 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4210 ddsfd.dwSize = sizeof(ddsfd);
4211 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4212 if (dwFlags & DDEDM_REFRESHRATES) {
4213 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4214 ddsfd.u.dwRefreshRate = 60;
4217 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4218 ddsfd.dwBackBufferCount = 1;
4219 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4220 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4221 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4222 /* FIXME: those masks would have to be set in depth > 8 */
4223 if (depths[i]==8) {
4224 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4225 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4226 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4227 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4228 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4229 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4230 } else {
4231 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4233 /* FIXME: We should query those from X itself */
4234 switch (depths[i]) {
4235 case 16:
4236 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4237 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4238 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4239 break;
4240 case 24:
4241 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4242 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4243 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4244 break;
4245 case 32:
4246 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4247 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4248 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4249 break;
4253 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4254 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4255 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4256 if (!modescb(&ddsfd,context)) return DD_OK;
4258 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4259 ddsfd.dwWidth = modes[j].w;
4260 ddsfd.dwHeight = modes[j].h;
4261 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4262 if (!modescb(&ddsfd,context)) return DD_OK;
4265 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4266 /* modeX is not standard VGA */
4268 ddsfd.dwHeight = 200;
4269 ddsfd.dwWidth = 320;
4270 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4271 if (!modescb(&ddsfd,context)) return DD_OK;
4274 return DD_OK;
4276 #endif /* defined(HAVE_LIBXXF86DGA) */
4278 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4279 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4281 ICOM_THIS(IDirectDraw2Impl,iface);
4282 XVisualInfo *vi;
4283 XPixmapFormatValues *pf;
4284 XVisualInfo vt;
4285 int nvisuals, npixmap, i, emu;
4286 int has_mode[] = { 0, 0, 0, 0 };
4287 int has_depth[] = { 8, 15, 16, 24 };
4288 DDSURFACEDESC ddsfd;
4289 static struct {
4290 int w,h;
4291 } modes[] = { /* some of the usual modes */
4292 {512,384},
4293 {640,400},
4294 {640,480},
4295 {800,600},
4296 {1024,768},
4297 {1280,1024}
4299 DWORD maxWidth, maxHeight;
4301 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4302 ddsfd.dwSize = sizeof(ddsfd);
4303 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4304 if (dwFlags & DDEDM_REFRESHRATES) {
4305 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4306 ddsfd.u.dwRefreshRate = 60;
4308 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4309 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4311 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4312 pf = XListPixmapFormats(display, &npixmap);
4314 i = 0;
4315 emu = 0;
4316 while ((i < npixmap) ||
4317 (emu != 4)) {
4318 int mode_index;
4319 int send_mode = 0;
4320 int j;
4322 if (i < npixmap) {
4323 for (j = 0; j < 4; j++) {
4324 if (has_depth[j] == pf[i].depth) {
4325 mode_index = j;
4326 break;
4329 if (j == 4) {
4330 i++;
4331 continue;
4335 if (has_mode[mode_index] == 0) {
4336 if (mode_index == 0) {
4337 send_mode = 1;
4339 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4340 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4341 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4342 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4343 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4344 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4345 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4346 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4347 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4349 has_mode[mode_index] = 1;
4350 } else {
4351 /* All the 'true color' depths (15, 16 and 24)
4352 First, find the corresponding visual to extract the bit masks */
4353 for (j = 0; j < nvisuals; j++) {
4354 if (vi[j].depth == pf[i].depth) {
4355 ddsfd.ddsCaps.dwCaps = 0;
4356 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4357 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4358 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4359 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4360 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4361 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4362 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4363 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4365 send_mode = 1;
4366 has_mode[mode_index] = 1;
4367 break;
4371 if (j == nvisuals)
4372 ERR("Did not find visual corresponding the the pixmap format !\n");
4376 i++;
4377 } else {
4378 /* Now to emulated modes */
4379 if (has_mode[emu] == 0) {
4380 int c;
4381 int l;
4382 int depth = has_depth[emu];
4384 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4385 if (ModeEmulations[c].dest.depth == depth) {
4386 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4387 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4388 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4389 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4390 int j;
4391 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4392 if ((vi[j].depth == pf[l].depth) &&
4393 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4394 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4395 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4396 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4397 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4398 if (depth == 8) {
4399 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4400 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4401 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4402 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4403 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4404 } else {
4405 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4406 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4407 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4408 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4409 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4411 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4412 send_mode = 1;
4415 if (send_mode == 0)
4416 ERR("No visual corresponding to pixmap format !\n");
4424 emu++;
4427 if (send_mode) {
4428 int mode;
4430 if (TRACE_ON(ddraw)) {
4431 TRACE("Enumerating with pixel format : \n");
4432 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4433 DPRINTF("\n");
4436 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4437 /* Do not enumerate modes we cannot handle anyway */
4438 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4439 break;
4441 ddsfd.dwWidth = modes[mode].w;
4442 ddsfd.dwHeight = modes[mode].h;
4444 /* Now, send the mode description to the application */
4445 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4446 if (!modescb(&ddsfd, context))
4447 goto exit_enum;
4450 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4451 /* modeX is not standard VGA */
4452 ddsfd.dwWidth = 320;
4453 ddsfd.dwHeight = 200;
4454 if (!modescb(&ddsfd, context))
4455 goto exit_enum;
4460 exit_enum:
4461 TSXFree(vi);
4462 TSXFree(pf);
4464 return DD_OK;
4467 #ifdef HAVE_LIBXXF86DGA
4468 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4469 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4471 ICOM_THIS(IDirectDraw2Impl,iface);
4472 TRACE("(%p)->(%p)\n",This,lpddsfd);
4473 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4474 lpddsfd->dwHeight = This->d.height;
4475 lpddsfd->dwWidth = This->d.width;
4476 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4477 lpddsfd->dwBackBufferCount = 1;
4478 lpddsfd->u.dwRefreshRate = 60;
4479 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4480 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4481 return DD_OK;
4483 #endif /* defined(HAVE_LIBXXF86DGA) */
4485 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4486 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4488 ICOM_THIS(IDirectDraw2Impl,iface);
4489 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4490 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4491 lpddsfd->dwHeight = This->d.height;
4492 lpddsfd->dwWidth = This->d.width;
4493 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4494 lpddsfd->dwBackBufferCount = 1;
4495 lpddsfd->u.dwRefreshRate = 60;
4496 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4497 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4498 return DD_OK;
4501 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4502 ICOM_THIS(IDirectDraw2Impl,iface);
4503 TRACE("(%p)->()\n",This);
4504 return DD_OK;
4507 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4508 LPDIRECTDRAW2 iface,LPDWORD freq
4510 ICOM_THIS(IDirectDraw2Impl,iface);
4511 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4512 *freq = 60*100; /* 60 Hz */
4513 return DD_OK;
4516 /* what can we directly decompress? */
4517 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4518 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4520 ICOM_THIS(IDirectDraw2Impl,iface);
4521 FIXME("(%p,%p,%p), stub\n",This,x,y);
4522 return DD_OK;
4525 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4526 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4528 ICOM_THIS(IDirectDraw2Impl,iface);
4529 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4530 return DD_OK;
4533 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4534 LPDIRECTDRAW2 iface )
4536 ICOM_THIS(IDirectDraw2Impl,iface);
4537 FIXME("(%p)->()\n", This );
4539 return DD_OK;
4542 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4543 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4544 ICOM_THIS(IDirectDraw2Impl,iface);
4545 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4547 return DD_OK;
4550 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4551 LPDWORD lpdwScanLine) {
4552 ICOM_THIS(IDirectDraw2Impl,iface);
4553 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4555 return DD_OK;
4558 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4559 GUID *lpGUID) {
4560 ICOM_THIS(IDirectDraw2Impl,iface);
4561 FIXME("(%p)->(%p)\n", This, lpGUID);
4563 return DD_OK;
4566 #ifdef HAVE_LIBXXF86DGA
4568 /* Note: Hack so we can reuse the old functions without compiler warnings */
4569 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4570 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4571 #else
4572 # define XCAST(fun) (void *)
4573 #endif
4575 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4577 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4578 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4579 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4580 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4581 XCAST(Compact)IDirectDraw2Impl_Compact,
4582 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4583 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4584 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4585 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4586 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4587 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4588 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4589 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4590 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4591 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4592 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4593 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4594 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4595 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4596 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4597 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4598 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4599 DGA_IDirectDrawImpl_SetDisplayMode,
4600 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4603 #undef XCAST
4605 #endif /* defined(HAVE_LIBXXF86DGA) */
4607 /* Note: Hack so we can reuse the old functions without compiler warnings */
4608 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4609 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4610 #else
4611 # define XCAST(fun) (void *)
4612 #endif
4614 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4616 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4617 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4618 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4619 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4620 XCAST(Compact)IDirectDraw2Impl_Compact,
4621 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4622 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4623 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4624 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4625 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4626 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4627 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4628 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4629 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4630 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4631 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4632 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4633 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4634 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4635 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4636 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4637 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4638 Xlib_IDirectDrawImpl_SetDisplayMode,
4639 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4642 #undef XCAST
4644 /*****************************************************************************
4645 * IDirectDraw2
4650 #ifdef HAVE_LIBXXF86DGA
4651 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4652 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4654 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4656 #endif /* defined(HAVE_LIBXXF86DGA) */
4658 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4659 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
4661 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4664 #ifdef HAVE_LIBXXF86DGA
4665 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4666 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4668 ICOM_THIS(IDirectDraw2Impl,iface);
4669 TRACE("(%p)->(%p,%p,%p)\n",
4670 This,ddscaps,total,free
4672 if (total) *total = This->e.dga.fb_memsize * 1024;
4673 if (free) *free = This->e.dga.fb_memsize * 1024;
4674 return DD_OK;
4676 #endif /* defined(HAVE_LIBXXF86DGA) */
4678 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4679 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4681 ICOM_THIS(IDirectDraw2Impl,iface);
4682 TRACE("(%p)->(%p,%p,%p)\n",
4683 This,ddscaps,total,free
4685 if (total) *total = 2048 * 1024;
4686 if (free) *free = 2048 * 1024;
4687 return DD_OK;
4690 #ifdef HAVE_LIBXXF86DGA
4691 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4693 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4694 DGA_IDirectDraw2Impl_QueryInterface,
4695 IDirectDraw2Impl_AddRef,
4696 DGA_IDirectDraw2Impl_Release,
4697 IDirectDraw2Impl_Compact,
4698 IDirectDraw2Impl_CreateClipper,
4699 DGA_IDirectDraw2Impl_CreatePalette,
4700 DGA_IDirectDraw2Impl_CreateSurface,
4701 IDirectDraw2Impl_DuplicateSurface,
4702 DGA_IDirectDraw2Impl_EnumDisplayModes,
4703 IDirectDraw2Impl_EnumSurfaces,
4704 IDirectDraw2Impl_FlipToGDISurface,
4705 DGA_IDirectDraw2Impl_GetCaps,
4706 DGA_IDirectDraw2Impl_GetDisplayMode,
4707 IDirectDraw2Impl_GetFourCCCodes,
4708 IDirectDraw2Impl_GetGDISurface,
4709 IDirectDraw2Impl_GetMonitorFrequency,
4710 IDirectDraw2Impl_GetScanLine,
4711 IDirectDraw2Impl_GetVerticalBlankStatus,
4712 IDirectDraw2Impl_Initialize,
4713 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4714 IDirectDraw2Impl_SetCooperativeLevel,
4715 DGA_IDirectDraw2Impl_SetDisplayMode,
4716 IDirectDraw2Impl_WaitForVerticalBlank,
4717 DGA_IDirectDraw2Impl_GetAvailableVidMem
4719 #endif /* defined(HAVE_LIBXXF86DGA) */
4721 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4723 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4724 Xlib_IDirectDraw2Impl_QueryInterface,
4725 IDirectDraw2Impl_AddRef,
4726 Xlib_IDirectDraw2Impl_Release,
4727 IDirectDraw2Impl_Compact,
4728 IDirectDraw2Impl_CreateClipper,
4729 Xlib_IDirectDraw2Impl_CreatePalette,
4730 Xlib_IDirectDraw2Impl_CreateSurface,
4731 IDirectDraw2Impl_DuplicateSurface,
4732 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4733 IDirectDraw2Impl_EnumSurfaces,
4734 IDirectDraw2Impl_FlipToGDISurface,
4735 Xlib_IDirectDraw2Impl_GetCaps,
4736 Xlib_IDirectDraw2Impl_GetDisplayMode,
4737 IDirectDraw2Impl_GetFourCCCodes,
4738 IDirectDraw2Impl_GetGDISurface,
4739 IDirectDraw2Impl_GetMonitorFrequency,
4740 IDirectDraw2Impl_GetScanLine,
4741 IDirectDraw2Impl_GetVerticalBlankStatus,
4742 IDirectDraw2Impl_Initialize,
4743 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4744 IDirectDraw2Impl_SetCooperativeLevel,
4745 Xlib_IDirectDraw2Impl_SetDisplayMode,
4746 IDirectDraw2Impl_WaitForVerticalBlank,
4747 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4750 /*****************************************************************************
4751 * IDirectDraw4
4755 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4756 HDC hdc,
4757 LPDIRECTDRAWSURFACE *lpDDS) {
4758 ICOM_THIS(IDirectDraw4Impl,iface);
4759 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4761 return DD_OK;
4764 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4765 ICOM_THIS(IDirectDraw4Impl,iface);
4766 FIXME("(%p)->()\n", This);
4768 return DD_OK;
4771 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4772 ICOM_THIS(IDirectDraw4Impl,iface);
4773 FIXME("(%p)->()\n", This);
4775 return DD_OK;
4778 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
4779 LPDDDEVICEIDENTIFIER lpdddi,
4780 DWORD dwFlags) {
4781 ICOM_THIS(IDirectDraw4Impl,iface);
4782 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
4784 return DD_OK;
4787 #ifdef HAVE_LIBXXF86DGA
4789 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4790 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4791 #else
4792 # define XCAST(fun) (void*)
4793 #endif
4795 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
4797 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4798 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4799 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4800 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4801 XCAST(Compact)IDirectDraw2Impl_Compact,
4802 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4803 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4804 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4805 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4806 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4807 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4808 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4809 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4810 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4811 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4812 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4813 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4814 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4815 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4816 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4817 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4818 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4819 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
4820 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4821 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
4822 IDirectDraw4Impl_GetSurfaceFromDC,
4823 IDirectDraw4Impl_RestoreAllSurfaces,
4824 IDirectDraw4Impl_TestCooperativeLevel,
4825 IDirectDraw4Impl_GetDeviceIdentifier
4828 #undef XCAST
4830 #endif /* defined(HAVE_LIBXXF86DGA) */
4832 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4833 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
4834 #else
4835 # define XCAST(fun) (void*)
4836 #endif
4838 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
4840 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4841 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4842 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4843 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4844 XCAST(Compact)IDirectDraw2Impl_Compact,
4845 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4846 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4847 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4848 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4849 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4850 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4851 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4852 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4853 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4854 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4855 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4856 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4857 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4858 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4859 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4860 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4861 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4862 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
4863 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4864 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
4865 IDirectDraw4Impl_GetSurfaceFromDC,
4866 IDirectDraw4Impl_RestoreAllSurfaces,
4867 IDirectDraw4Impl_TestCooperativeLevel,
4868 IDirectDraw4Impl_GetDeviceIdentifier
4871 #undef XCAST
4873 /******************************************************************************
4874 * DirectDrawCreate
4877 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
4879 LRESULT ret;
4880 IDirectDrawImpl* ddraw = NULL;
4881 DWORD lastError;
4883 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4885 SetLastError( ERROR_SUCCESS );
4886 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
4887 if( (!ddraw) &&
4888 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
4891 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
4894 if( ddraw )
4896 /* Perform any special direct draw functions */
4897 if (msg==WM_PAINT)
4898 ddraw->d.paintable = 1;
4900 /* Now let the application deal with the rest of this */
4901 if( ddraw->d.mainWindow )
4904 /* Don't think that we actually need to call this but...
4905 might as well be on the safe side of things... */
4907 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4908 it should be the procedures of our fake window that gets called
4909 instead of those of the window provided by the application.
4910 And with this patch, mouse clicks work with Monkey Island III
4911 - Lionel */
4912 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
4914 if( !ret )
4916 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
4917 /* We didn't handle the message - give it to the application */
4918 if (ddraw && ddraw->d.mainWindow && tmpWnd)
4920 ret = CallWindowProcA(tmpWnd->winproc,
4921 ddraw->d.mainWindow, msg, wParam, lParam );
4923 WIN_ReleaseWndPtr(tmpWnd);
4927 } else {
4928 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
4932 else
4934 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
4937 return ret;
4940 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
4941 #ifdef HAVE_LIBXXF86DGA
4942 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
4943 int memsize,banksize,width,major,minor,flags,height;
4944 char *addr;
4945 int fd;
4946 int depth;
4948 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4949 if ((fd = open("/dev/mem", O_RDWR)) != -1)
4950 close(fd);
4952 if (fd == -1) {
4953 MESSAGE("Must be able to access /dev/mem to use XF86DGA!\n");
4954 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
4955 return E_UNEXPECTED;
4957 if (!DDRAW_DGA_Available()) {
4958 TRACE("No XF86DGA detected.\n");
4959 return DDERR_GENERIC;
4961 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
4962 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
4963 (*ilplpDD)->ref = 1;
4964 TSXF86DGAQueryVersion(display,&major,&minor);
4965 TRACE("XF86DGA is version %d.%d\n",major,minor);
4966 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
4967 if (!(flags & XF86DGADirectPresent))
4968 MESSAGE("direct video is NOT PRESENT.\n");
4969 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
4970 (*ilplpDD)->e.dga.fb_width = width;
4971 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
4972 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
4973 (*ilplpDD)->e.dga.fb_height = height;
4974 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4975 addr,width,banksize,memsize
4977 TRACE("viewport height: %d\n",height);
4979 /* Get the screen dimensions as seen by Wine.
4980 In that case, it may be better to ignore the -desktop mode and return the
4981 real screen size => print a warning */
4982 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4983 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4984 if (((*ilplpDD)->d.height != height) ||
4985 ((*ilplpDD)->d.width != width))
4986 WARN("You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4987 (*ilplpDD)->e.dga.fb_addr = addr;
4988 (*ilplpDD)->e.dga.fb_memsize = memsize;
4989 (*ilplpDD)->e.dga.fb_banksize = banksize;
4990 (*ilplpDD)->e.dga.vpmask = 0;
4992 /* just assume the default depth is the DGA depth too */
4993 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
4994 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
4995 #ifdef RESTORE_SIGNALS
4996 SIGNAL_Init();
4997 #endif
4999 return DD_OK;
5000 #else /* defined(HAVE_LIBXXF86DGA) */
5001 return DDERR_INVALIDDIRECTDRAWGUID;
5002 #endif /* defined(HAVE_LIBXXF86DGA) */
5005 static BOOL
5006 DDRAW_XSHM_Available(void)
5008 #ifdef HAVE_LIBXXSHM
5009 if (TSXShmQueryExtension(display))
5011 int major, minor;
5012 Bool shpix;
5014 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5015 (Options.noXSHM != 1))
5016 return 1;
5017 else
5018 return 0;
5020 else
5021 return 0;
5022 #else
5023 return 0;
5024 #endif
5027 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5028 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5029 int depth;
5031 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5032 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5033 (*ilplpDD)->ref = 1;
5034 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5036 /* At DirectDraw creation, the depth is the default depth */
5037 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5038 _common_depth_to_pixelformat(depth,
5039 &((*ilplpDD)->d.directdraw_pixelformat),
5040 &((*ilplpDD)->d.screen_pixelformat),
5041 &((*ilplpDD)->d.pixmap_depth));
5042 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5043 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5045 #ifdef HAVE_LIBXXSHM
5046 /* Test if XShm is available. */
5047 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5048 (*ilplpDD)->e.xlib.xshm_compl = 0;
5049 TRACE("Using XShm extension.\n");
5051 #endif
5053 return DD_OK;
5056 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5057 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5058 char xclsid[50];
5059 WNDCLASSA wc;
5060 /* WND* pParentWindow; */
5061 HRESULT ret;
5063 if (HIWORD(lpGUID))
5064 WINE_StringFromCLSID(lpGUID,xclsid);
5065 else {
5066 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5067 lpGUID = NULL;
5070 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5072 if ( ( !lpGUID ) ||
5073 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5074 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5075 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5076 /* if they didn't request a particular interface, use the best
5077 * supported one */
5078 if (DDRAW_DGA_Available())
5079 lpGUID = &DGA_DirectDraw_GUID;
5080 else
5081 lpGUID = &XLIB_DirectDraw_GUID;
5084 wc.style = CS_GLOBALCLASS;
5085 wc.lpfnWndProc = Xlib_DDWndProc;
5086 wc.cbClsExtra = 0;
5087 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5088 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5090 /* We can be a child of the desktop since we're really important */
5092 This code is not useful since hInstance is forced to 0 afterward
5093 pParentWindow = WIN_GetDesktop();
5094 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5096 wc.hInstance = 0;
5099 wc.hIcon = 0;
5100 wc.hCursor = (HCURSOR)IDC_ARROWA;
5101 wc.hbrBackground= NULL_BRUSH;
5102 wc.lpszMenuName = 0;
5103 wc.lpszClassName= "WINE_DirectDraw";
5104 RegisterClassA(&wc);
5106 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5107 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5109 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5110 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5112 else {
5113 goto err;
5117 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5118 return ret;
5120 err:
5121 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
5122 return DDERR_INVALIDDIRECTDRAWGUID;
5125 /*******************************************************************************
5126 * DirectDraw ClassFactory
5128 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5131 typedef struct
5133 /* IUnknown fields */
5134 ICOM_VFIELD(IClassFactory);
5135 DWORD ref;
5136 } IClassFactoryImpl;
5138 static HRESULT WINAPI
5139 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5140 ICOM_THIS(IClassFactoryImpl,iface);
5141 char buf[80];
5143 if (HIWORD(riid))
5144 WINE_StringFromCLSID(riid,buf);
5145 else
5146 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5147 FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
5148 return E_NOINTERFACE;
5151 static ULONG WINAPI
5152 DDCF_AddRef(LPCLASSFACTORY iface) {
5153 ICOM_THIS(IClassFactoryImpl,iface);
5154 return ++(This->ref);
5157 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5158 ICOM_THIS(IClassFactoryImpl,iface);
5159 /* static class, won't be freed */
5160 return --(This->ref);
5163 static HRESULT WINAPI DDCF_CreateInstance(
5164 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5166 ICOM_THIS(IClassFactoryImpl,iface);
5167 char buf[80];
5169 WINE_StringFromCLSID(riid,buf);
5170 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
5171 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5172 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5173 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5174 /* FIXME: reuse already created DirectDraw if present? */
5175 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5177 return CLASS_E_CLASSNOTAVAILABLE;
5180 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5181 ICOM_THIS(IClassFactoryImpl,iface);
5182 FIXME("(%p)->(%d),stub!\n",This,dolock);
5183 return S_OK;
5186 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5188 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5189 DDCF_QueryInterface,
5190 DDCF_AddRef,
5191 DDCF_Release,
5192 DDCF_CreateInstance,
5193 DDCF_LockServer
5195 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5197 /*******************************************************************************
5198 * DllGetClassObject [DDRAW.13]
5199 * Retrieves class object from a DLL object
5201 * NOTES
5202 * Docs say returns STDAPI
5204 * PARAMS
5205 * rclsid [I] CLSID for the class object
5206 * riid [I] Reference to identifier of interface for class object
5207 * ppv [O] Address of variable to receive interface pointer for riid
5209 * RETURNS
5210 * Success: S_OK
5211 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5212 * E_UNEXPECTED
5214 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5216 char buf[80],xbuf[80];
5218 if (HIWORD(rclsid))
5219 WINE_StringFromCLSID(rclsid,xbuf);
5220 else
5221 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5222 if (HIWORD(riid))
5223 WINE_StringFromCLSID(riid,buf);
5224 else
5225 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5226 WINE_StringFromCLSID(riid,xbuf);
5227 TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
5228 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5229 *ppv = (LPVOID)&DDRAW_CF;
5230 IClassFactory_AddRef((IClassFactory*)*ppv);
5231 return S_OK;
5233 FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5234 return CLASS_E_CLASSNOTAVAILABLE;
5238 /*******************************************************************************
5239 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5241 * RETURNS
5242 * Success: S_OK
5243 * Failure: S_FALSE
5245 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5247 FIXME("(void): stub\n");
5248 return S_FALSE;
5251 #else /* !defined(X_DISPLAY_MISSING) */
5253 #include "windef.h"
5254 #include "winerror.h"
5255 #include "wtypes.h"
5257 #define DD_OK 0
5259 typedef void *LPUNKNOWN;
5260 typedef void *LPDIRECTDRAW;
5261 typedef void *LPDIRECTDRAWCLIPPER;
5262 typedef void *LPDDENUMCALLBACKA;
5263 typedef void *LPDDENUMCALLBACKEXA;
5264 typedef void *LPDDENUMCALLBACKEXW;
5265 typedef void *LPDDENUMCALLBACKW;
5267 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5269 return DD_OK;
5272 HRESULT WINAPI DirectDrawCreate(
5273 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5275 return DD_OK;
5278 HRESULT WINAPI DirectDrawCreateClipper(
5279 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5281 return DD_OK;
5284 HRESULT WINAPI DirectDrawEnumerateA(
5285 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5287 return DD_OK;
5290 HRESULT WINAPI DirectDrawEnumerateExA(
5291 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5293 return DD_OK;
5296 HRESULT WINAPI DirectDrawEnumerateExW(
5297 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5299 return DD_OK;
5302 HRESULT WINAPI DirectDrawEnumerateW(
5303 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5305 return DD_OK;
5308 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5310 return CLASS_E_CLASSNOTAVAILABLE;
5313 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5315 return DD_OK;
5318 #endif /* !defined(X_DISPLAY_MISSING) */