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