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