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.
20 #ifndef X_DISPLAY_MISSING
26 # include <sys/types.h>
27 # ifdef HAVE_SYS_IPC_H
30 # ifdef HAVE_SYS_SHM_H
34 #endif /* defined(HAVE_LIBXXSHM) */
36 #ifdef HAVE_LIBXXF86DGA
37 #include "ts_xf86dga.h"
38 #endif /* defined(HAVE_LIBXXF86DGA) */
40 #ifdef HAVE_LIBXXF86DGA2
41 #include "ts_xf86dga2.h"
42 #endif /* defined(HAVE_LIBXXF86DGA2) */
44 #ifdef HAVE_LIBXXF86VM
45 #include "ts_xf86vmode.h"
46 #endif /* defined(HAVE_LIBXXF86VM) */
52 #ifdef HAVE_SYS_SIGNAL_H
53 # include <sys/signal.h>
63 #include "wine/exception.h"
66 #include "debugtools.h"
72 /* This for all the enumeration and creation of D3D-related objects */
73 #include "ddraw_private.h"
74 #include "d3d_private.h"
76 DEFAULT_DEBUG_CHANNEL(ddraw)
78 /* Restore signal handlers overwritten by XF86DGA
80 #define RESTORE_SIGNALS
82 /* Get DDSCAPS of surface (shortcutmacro) */
83 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
85 /* Get the number of bytes per pixel for a given surface */
86 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
88 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
90 /* Where do these GUIDs come from? mkuuid.
91 * They exist solely to distinguish between the targets Wine support,
92 * and should be different than any other GUIDs in existence.
94 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
98 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
101 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
105 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
108 #ifdef HAVE_LIBXXF86DGA
109 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
110 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
111 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
112 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
113 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
114 #endif /* defined(HAVE_LIBXXF86DGA) */
116 #ifdef HAVE_LIBXXF86DGA2
117 static struct ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt;
118 #endif /* defined(HAVE_LIBXXF86DGA2) */
120 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
121 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
122 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
123 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
124 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
126 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
127 static struct ICOM_VTABLE(IDirect3D) d3dvt;
128 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
130 /* This is for mode-emulation */
132 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
133 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
134 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
135 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
136 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
137 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
138 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
142 unsigned short depth;
149 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
150 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
154 ConvertMode screen, dest;
158 static Convert ModeEmulations[] = {
159 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
160 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
161 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
162 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
163 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
166 #ifdef HAVE_LIBXXF86VM
167 static XF86VidModeModeInfo *orig_mode = NULL;
171 static int XShmErrorFlag = 0;
175 DDRAW_DGA_Available(void)
177 #ifdef HAVE_LIBXXF86DGA
178 int fd, evbase, evret, majver, minver;
179 static BYTE return_value = 0xFF;
181 /* This prevents from probing X times for DGA */
182 if (return_value != 0xFF)
190 /* First, query the extenstion and its version */
191 if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
196 if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
201 #ifdef HAVE_LIBXXF86DGA2
203 /* We have DGA 2.0 available ! */
204 if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
205 TSXDGACloseFramebuffer(display, DefaultScreen(display));
213 #endif /* defined(HAVE_LIBXXF86DGA2) */
215 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
216 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
217 /* others. --stephenc */
218 if ((fd = open("/dev/mem", O_RDWR)) != -1)
227 #ifdef HAVE_LIBXXF86DGA2
229 #endif /* defined(HAVE_LIBXXF86DGA2) */
230 #else /* defined(HAVE_LIBXXF86DGA) */
232 #endif /* defined(HAVE_LIBXXF86DGA) */
235 /**********************************************************************/
240 } DirectDrawEnumerateProcData;
242 /***********************************************************************
243 * DirectDrawEnumerateExA (DDRAW.*)
245 HRESULT WINAPI DirectDrawEnumerateExA(
246 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
248 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
250 if (TRACE_ON(ddraw)) {
251 DPRINTF(" Flags : ");
252 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
253 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
254 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
255 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
256 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
257 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
261 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
262 /* For the moment, Wine does not support any 3D only accelerators */
265 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
266 /* For the moment, Wine does not support any attached secondary devices */
270 if (DDRAW_DGA_Available()) {
271 TRACE("Enumerating DGA interface\n");
272 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
276 TRACE("Enumerating Xlib interface\n");
277 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
280 TRACE("Enumerating Default interface\n");
281 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
287 /***********************************************************************
288 * DirectDrawEnumerateExW (DDRAW.*)
291 static BOOL CALLBACK DirectDrawEnumerateExProcW(
292 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
293 LPVOID lpContext, HMONITOR hm)
295 DirectDrawEnumerateProcData *pEPD =
296 (DirectDrawEnumerateProcData *) lpContext;
297 LPWSTR lpDriverDescriptionW =
298 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
299 LPWSTR lpDriverNameW =
300 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
302 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
303 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
305 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
306 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
311 /**********************************************************************/
313 HRESULT WINAPI DirectDrawEnumerateExW(
314 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
316 DirectDrawEnumerateProcData epd;
317 epd.lpCallback = (LPVOID) lpCallback;
318 epd.lpContext = lpContext;
320 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
324 /***********************************************************************
325 * DirectDrawEnumerateA (DDRAW.*)
328 static BOOL CALLBACK DirectDrawEnumerateProcA(
329 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
330 LPVOID lpContext, HMONITOR hm)
332 DirectDrawEnumerateProcData *pEPD =
333 (DirectDrawEnumerateProcData *) lpContext;
335 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
336 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
339 /**********************************************************************/
341 HRESULT WINAPI DirectDrawEnumerateA(
342 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
344 DirectDrawEnumerateProcData epd;
345 epd.lpCallback = (LPVOID) lpCallback;
346 epd.lpContext = lpContext;
348 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
352 /***********************************************************************
353 * DirectDrawEnumerateW (DDRAW.*)
356 static BOOL WINAPI DirectDrawEnumerateProcW(
357 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
358 LPVOID lpContext, HMONITOR hm)
360 DirectDrawEnumerateProcData *pEPD =
361 (DirectDrawEnumerateProcData *) lpContext;
363 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
364 lpGUID, lpDriverDescription, lpDriverName,
368 /**********************************************************************/
370 HRESULT WINAPI DirectDrawEnumerateW(
371 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
373 DirectDrawEnumerateProcData epd;
374 epd.lpCallback = (LPVOID) lpCallback;
375 epd.lpContext = lpContext;
377 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
381 /***********************************************************************
382 * DSoundHelp (DDRAW.?)
385 /* What is this doing here? */
387 DSoundHelp(DWORD x,DWORD y,DWORD z) {
388 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
392 /******************************************************************************
393 * internal helper functions
395 static void _dump_DDBLTFX(DWORD flagmask) {
401 #define FE(x) { x, #x},
402 FE(DDBLTFX_ARITHSTRETCHY)
403 FE(DDBLTFX_MIRRORLEFTRIGHT)
404 FE(DDBLTFX_MIRRORUPDOWN)
405 FE(DDBLTFX_NOTEARING)
406 FE(DDBLTFX_ROTATE180)
407 FE(DDBLTFX_ROTATE270)
409 FE(DDBLTFX_ZBUFFERRANGE)
410 FE(DDBLTFX_ZBUFFERBASEDEST)
413 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
414 if (flags[i].mask & flagmask) {
415 DPRINTF("%s ",flags[i].name);
422 static void _dump_DDBLTFAST(DWORD flagmask) {
428 #define FE(x) { x, #x},
429 FE(DDBLTFAST_NOCOLORKEY)
430 FE(DDBLTFAST_SRCCOLORKEY)
431 FE(DDBLTFAST_DESTCOLORKEY)
435 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
436 if (flags[i].mask & flagmask)
437 DPRINTF("%s ",flags[i].name);
441 static void _dump_DDBLT(DWORD flagmask) {
447 #define FE(x) { x, #x},
449 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
450 FE(DDBLT_ALPHADESTNEG)
451 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
452 FE(DDBLT_ALPHAEDGEBLEND)
454 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
455 FE(DDBLT_ALPHASRCNEG)
456 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
462 FE(DDBLT_KEYDESTOVERRIDE)
464 FE(DDBLT_KEYSRCOVERRIDE)
466 FE(DDBLT_ROTATIONANGLE)
468 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
469 FE(DDBLT_ZBUFFERDESTOVERRIDE)
470 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
471 FE(DDBLT_ZBUFFERSRCOVERRIDE)
476 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
477 if (flags[i].mask & flagmask)
478 DPRINTF("%s ",flags[i].name);
482 static void _dump_DDSCAPS(void *in) {
488 #define FE(x) { x, #x},
489 FE(DDSCAPS_RESERVED1)
491 FE(DDSCAPS_BACKBUFFER)
494 FE(DDSCAPS_FRONTBUFFER)
495 FE(DDSCAPS_OFFSCREENPLAIN)
498 FE(DDSCAPS_PRIMARYSURFACE)
499 FE(DDSCAPS_PRIMARYSURFACELEFT)
500 FE(DDSCAPS_SYSTEMMEMORY)
503 FE(DDSCAPS_VIDEOMEMORY)
505 FE(DDSCAPS_WRITEONLY)
508 FE(DDSCAPS_LIVEVIDEO)
512 FE(DDSCAPS_RESERVED2)
513 FE(DDSCAPS_ALLOCONLOAD)
514 FE(DDSCAPS_VIDEOPORT)
515 FE(DDSCAPS_LOCALVIDMEM)
516 FE(DDSCAPS_NONLOCALVIDMEM)
517 FE(DDSCAPS_STANDARDVGAMODE)
518 FE(DDSCAPS_OPTIMIZED)
521 DWORD flagmask = *((DWORD *) in);
522 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
523 if (flags[i].mask & flagmask)
524 DPRINTF("%s ",flags[i].name);
527 static void _dump_pixelformat_flag(DWORD flagmask) {
533 #define FE(x) { x, #x},
537 FE(DDPF_PALETTEINDEXED4)
538 FE(DDPF_PALETTEINDEXEDTO8)
539 FE(DDPF_PALETTEINDEXED8)
545 FE(DDPF_PALETTEINDEXED1)
546 FE(DDPF_PALETTEINDEXED2)
550 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
551 if (flags[i].mask & flagmask)
552 DPRINTF("%s ",flags[i].name);
555 static void _dump_paletteformat(DWORD dwFlags) {
561 #define FE(x) { x, #x},
563 FE(DDPCAPS_8BITENTRIES)
565 FE(DDPCAPS_INITIALIZE)
566 FE(DDPCAPS_PRIMARYSURFACE)
567 FE(DDPCAPS_PRIMARYSURFACELEFT)
575 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
576 if (flags[i].mask & dwFlags)
577 DPRINTF("%s ",flags[i].name);
581 static void _dump_pixelformat(void *in) {
582 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
586 _dump_pixelformat_flag(pf->dwFlags);
587 if (pf->dwFlags & DDPF_FOURCC) {
588 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
590 if (pf->dwFlags & DDPF_RGB) {
591 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
592 switch (pf->u.dwRGBBitCount) {
609 ERR("Unexpected bit depth !\n");
612 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
613 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
614 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
615 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
616 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
618 if (pf->dwFlags & DDPF_ZPIXELS) {
619 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
622 if (pf->dwFlags & DDPF_ZBUFFER) {
623 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
625 if (pf->dwFlags & DDPF_ALPHA) {
626 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
631 static void _dump_colorkeyflag(DWORD ck) {
637 #define FE(x) { x, #x},
638 FE(DDCKEY_COLORSPACE)
640 FE(DDCKEY_DESTOVERLAY)
642 FE(DDCKEY_SRCOVERLAY)
645 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
646 if (flags[i].mask & ck)
647 DPRINTF("%s ",flags[i].name);
650 static void _dump_DWORD(void *in) {
651 DPRINTF("%ld", *((DWORD *) in));
653 static void _dump_PTR(void *in) {
654 DPRINTF("%p", *((void **) in));
656 static void _dump_DDCOLORKEY(void *in) {
657 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
659 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
662 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
667 void (*func)(void *);
669 } flags[16], *fe = flags;
670 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
671 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
672 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
673 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
674 FE(DDSD_PITCH, _dump_DWORD, lPitch);
675 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
676 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
677 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
678 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
679 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
680 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
681 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
682 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
683 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
684 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
685 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
686 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
689 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
690 if (flags[i].mask & lpddsd->dwFlags) {
691 DPRINTF(" - %s : ",flags[i].name);
692 flags[i].func(flags[i].elt);
698 /******************************************************************************
699 * IDirectDrawSurface methods
701 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
702 * DDS and DDS2 use those functions. (Function calls did not change (except
703 * using different DirectDrawSurfaceX version), just added flags and functions)
706 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
707 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
709 ICOM_THIS(IDirectDrawSurface4Impl,iface);
710 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
711 This,lprect,lpddsd,flags,(DWORD)hnd);
712 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
713 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
714 This,lprect,lpddsd,flags,(DWORD)hnd);
716 /* First, copy the Surface description */
717 *lpddsd = This->s.surface_desc;
718 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
719 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
721 /* If asked only for a part, change the surface pointer */
723 TRACE(" lprect: %dx%d-%dx%d\n",
724 lprect->top,lprect->left,lprect->bottom,lprect->right
726 if ((lprect->top < 0) ||
727 (lprect->left < 0) ||
728 (lprect->bottom < 0) ||
729 (lprect->right < 0)) {
730 ERR(" Negative values in LPRECT !!!\n");
731 return DDERR_INVALIDPARAMS;
734 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
735 (lprect->top*This->s.surface_desc.lPitch) +
736 lprect->left*GET_BPP(This->s.surface_desc));
738 assert(This->s.surface_desc.u1.lpSurface);
741 /* wait for any previous operations to complete */
743 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE) &&
744 This->s.ddraw->e.xlib.xshm_active) {
746 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
747 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
749 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
755 #ifdef HAVE_LIBXXF86DGA
756 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
757 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
759 ICOM_THIS(IDirectDrawSurface4Impl,iface);
760 TRACE("(%p)->Unlock(%p)\n",This,surface);
763 #endif /* defined(HAVE_LIBXXF86DGA) */
765 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
766 if (This->s.ddraw->d.pixel_convert != NULL)
767 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
768 This->t.xlib.image->data,
769 This->s.surface_desc.dwWidth,
770 This->s.surface_desc.dwHeight,
771 This->s.surface_desc.lPitch,
775 if (This->s.ddraw->e.xlib.xshm_active) {
777 X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
779 /* let WaitShmCompletions track 'em for now */
780 /* (you may want to track it again whenever you implement DX7's partial surface locking,
781 where threads have concurrent access) */
782 X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
783 TSXShmPutImage(display,
784 This->s.ddraw->d.drawable,
785 DefaultGCOfScreen(X11DRV_GetXScreen()),
788 This->t.xlib.image->width,
789 This->t.xlib.image->height,
791 /* make sure the image is transferred ASAP */
796 TSXPutImage( display,
797 This->s.ddraw->d.drawable,
798 DefaultGCOfScreen(X11DRV_GetXScreen()),
801 This->t.xlib.image->width,
802 This->t.xlib.image->height);
805 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
806 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
808 ICOM_THIS(IDirectDrawSurface4Impl,iface);
809 TRACE("(%p)->Unlock(%p)\n",This,surface);
811 if (!This->s.ddraw->d.paintable)
814 /* Only redraw the screen when unlocking the buffer that is on screen */
815 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
816 Xlib_copy_surface_on_screen(This);
818 if (This->s.palette && This->s.palette->cm)
819 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
824 static IDirectDrawSurface4Impl* _common_find_flipto(
825 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
828 struct _surface_chain *chain = This->s.chain;
830 /* if there was no override flipto, look for current backbuffer */
832 /* walk the flip chain looking for backbuffer */
833 for (i=0;i<chain->nrofsurfaces;i++) {
834 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
836 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
837 flipto = chain->surfaces[i];
839 /* sanity checks ... */
842 for (i=0;i<chain->nrofsurfaces;i++)
843 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
845 if (i==chain->nrofsurfaces) {
846 /* we do not have a frontbuffer either */
847 for (i=0;i<chain->nrofsurfaces;i++)
848 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
849 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
852 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
853 int k = j % chain->nrofsurfaces;
854 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
855 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
856 flipto = chain->surfaces[k];
865 TRACE("flipping to %p\n",flipto);
870 #ifdef HAVE_LIBXXF86DGA
871 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
872 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
874 ICOM_THIS(IDirectDrawSurface4Impl,iface);
875 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
879 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
880 iflipto = _common_find_flipto(This,iflipto);
883 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
884 if (iflipto->s.palette && iflipto->s.palette->cm)
885 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
886 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
889 /* We need to switch the lowlevel surfaces, for DGA this is: */
891 /* The height within the framebuffer */
892 xheight = This->t.dga.fb_height;
893 This->t.dga.fb_height = iflipto->t.dga.fb_height;
894 iflipto->t.dga.fb_height = xheight;
896 /* And the assciated surface pointer */
897 surf = This->s.surface_desc.u1.lpSurface;
898 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
899 iflipto->s.surface_desc.u1.lpSurface = surf;
903 #endif /* defined(HAVE_LIBXXF86DGA) */
905 #ifdef HAVE_LIBXXF86DGA2
906 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
907 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
909 ICOM_THIS(IDirectDrawSurface4Impl,iface);
910 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
914 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
915 iflipto = _common_find_flipto(This,iflipto);
918 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
919 TSXDGASync(display,DefaultScreen(display));
921 if (iflipto->s.palette && iflipto->s.palette->cm)
922 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
923 /* We need to switch the lowlevel surfaces, for DGA this is: */
925 /* The height within the framebuffer */
926 xheight = This->t.dga.fb_height;
927 This->t.dga.fb_height = iflipto->t.dga.fb_height;
928 iflipto->t.dga.fb_height = xheight;
930 /* And the assciated surface pointer */
931 surf = This->s.surface_desc.u1.lpSurface;
932 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
933 iflipto->s.surface_desc.u1.lpSurface = surf;
937 #endif /* defined(HAVE_LIBXXF86DGA2) */
939 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
940 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
942 ICOM_THIS(IDirectDrawSurface4Impl,iface);
945 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
947 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
948 iflipto = _common_find_flipto(This,iflipto);
950 #if defined(HAVE_MESAGL) && 0 /* does not work */
951 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
952 TRACE(" - OpenGL flip\n");
954 glXSwapBuffers(display, This->s.ddraw->d.drawable);
959 #endif /* defined(HAVE_MESAGL) */
961 if (!This->s.ddraw->d.paintable)
964 /* We need to switch the lowlevel surfaces, for xlib this is: */
965 /* The surface pointer */
966 surf = This->s.surface_desc.u1.lpSurface;
967 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
968 iflipto->s.surface_desc.u1.lpSurface = surf;
969 /* the associated ximage */
970 image = This->t.xlib.image;
971 This->t.xlib.image = iflipto->t.xlib.image;
972 iflipto->t.xlib.image = image;
975 if (This->s.ddraw->e.xlib.xshm_active) {
977 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
978 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
980 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
983 Xlib_copy_surface_on_screen(This);
985 if (iflipto->s.palette && iflipto->s.palette->cm)
986 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
990 /* The IDirectDrawSurface4::SetPalette method attaches the specified
991 * DirectDrawPalette object to a surface. The surface uses this palette for all
992 * subsequent operations. The palette change takes place immediately.
994 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
995 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
997 ICOM_THIS(IDirectDrawSurface4Impl,iface);
998 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1000 TRACE("(%p)->(%p)\n",This,ipal);
1003 if( This->s.palette != NULL )
1004 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1005 This->s.palette = ipal;
1010 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
1012 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
1013 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
1015 if (!Options.managed)
1016 TSXInstallColormap(display,ipal->cm);
1018 for (i=0;i<256;i++) {
1021 xc.red = ipal->palents[i].peRed<<8;
1022 xc.blue = ipal->palents[i].peBlue<<8;
1023 xc.green = ipal->palents[i].peGreen<<8;
1024 xc.flags = DoRed|DoBlue|DoGreen;
1026 TSXStoreColor(display,ipal->cm,&xc);
1028 TSXInstallColormap(display,ipal->cm);
1031 /* According to spec, we are only supposed to
1032 * AddRef if this is not the same palette.
1034 if( This->s.palette != ipal )
1037 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1038 if( This->s.palette != NULL )
1039 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1040 This->s.palette = ipal;
1041 /* Perform the refresh */
1042 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1047 #ifdef HAVE_LIBXXF86DGA
1048 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1049 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1051 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1052 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1053 TRACE("(%p)->(%p)\n",This,ipal);
1055 /* According to spec, we are only supposed to
1056 * AddRef if this is not the same palette.
1058 if( This->s.palette != ipal )
1061 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1062 if( This->s.palette != NULL )
1063 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1064 This->s.palette = ipal;
1065 #ifdef HAVE_LIBXXF86DGA2
1066 if (This->s.ddraw->e.dga.version == 2)
1067 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1069 #endif /* defined(HAVE_LIBXXF86DGA2) */
1070 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1074 #endif /* defined(HAVE_LIBXXF86DGA) */
1076 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1083 #define COLORFILL_ROW(type) { \
1084 type *d = (type *) buf; \
1085 for (x = 0; x < width; x++) \
1086 d[x] = (type) color; \
1091 case 1: COLORFILL_ROW(BYTE)
1092 case 2: COLORFILL_ROW(WORD)
1093 case 4: COLORFILL_ROW(DWORD)
1095 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1096 return DDERR_UNSUPPORTED;
1099 #undef COLORFILL_ROW
1101 /* Now copy first row */
1103 for (y = 1; y < height; y++) {
1105 memcpy(buf, first, width * bpp);
1111 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1112 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1114 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1116 DDSURFACEDESC ddesc,sdesc;
1117 HRESULT ret = DD_OK;
1118 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1122 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1124 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1125 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1127 if (TRACE_ON(ddraw)) {
1128 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1129 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1131 _dump_DDBLT(dwFlags);
1132 if (dwFlags & DDBLT_DDFX) {
1133 TRACE("\tblitfx: ");
1134 _dump_DDBLTFX(lpbltfx->dwDDFX);
1139 if ((rdst->top < 0) ||
1141 (rdst->bottom < 0) ||
1142 (rdst->right < 0)) {
1143 ERR(" Negative values in LPRECT !!!\n");
1146 memcpy(&xdst,rdst,sizeof(xdst));
1149 xdst.bottom = ddesc.dwHeight;
1151 xdst.right = ddesc.dwWidth;
1155 if ((rsrc->top < 0) ||
1157 (rsrc->bottom < 0) ||
1158 (rsrc->right < 0)) {
1159 ERR(" Negative values in LPRECT !!!\n");
1162 memcpy(&xsrc,rsrc,sizeof(xsrc));
1166 xsrc.bottom = sdesc.dwHeight;
1168 xsrc.right = sdesc.dwWidth;
1170 memset(&xsrc,0,sizeof(xsrc));
1174 bpp = GET_BPP(ddesc);
1175 srcheight = xsrc.bottom - xsrc.top;
1176 srcwidth = xsrc.right - xsrc.left;
1177 dstheight = xdst.bottom - xdst.top;
1178 dstwidth = xdst.right - xdst.left;
1179 width = (xdst.right - xdst.left) * bpp;
1180 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1182 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1184 /* First, all the 'source-less' blits */
1185 if (dwFlags & DDBLT_COLORFILL) {
1186 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1187 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1188 dwFlags &= ~DDBLT_COLORFILL;
1191 if (dwFlags & DDBLT_DEPTHFILL) {
1195 /* Clears the screen */
1196 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1197 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1198 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1199 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1200 glClear(GL_DEPTH_BUFFER_BIT);
1203 dwFlags &= ~(DDBLT_DEPTHFILL);
1204 #endif /* defined(HAVE_MESAGL) */
1207 if (dwFlags & DDBLT_ROP) {
1208 /* Catch some degenerate cases here */
1209 switch(lpbltfx->dwROP) {
1211 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1213 case 0xAA0029: /* No-op */
1216 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1219 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1222 dwFlags &= ~DDBLT_ROP;
1225 if (dwFlags & DDBLT_DDROPS) {
1226 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1229 /* Now the 'with source' blits */
1232 int sx, xinc, sy, yinc;
1234 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1235 xinc = (srcwidth << 16) / dstwidth;
1236 yinc = (srcheight << 16) / dstheight;
1240 /* No effects, we can cheat here */
1241 if (dstwidth == srcwidth) {
1242 if (dstheight == srcheight) {
1243 /* No stretching in either direction. This needs to be as fast as possible */
1245 for (y = 0; y < dstheight; y++) {
1246 memcpy(dbuf, sbuf, width);
1247 sbuf += sdesc.lPitch;
1248 dbuf += ddesc.lPitch;
1251 /* Stretching in Y direction only */
1252 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1253 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1254 memcpy(dbuf, sbuf, width);
1255 dbuf += ddesc.lPitch;
1259 /* Stretching in X direction */
1261 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1262 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1264 if ((sy >> 16) == (last_sy >> 16)) {
1265 /* Same as last row - copy already stretched row */
1266 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1269 #define STRETCH_ROW(type) { \
1270 type *s = (type *) sbuf, *d = (type *) dbuf; \
1271 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1272 d[x] = s[sx >> 16]; \
1276 case 1: STRETCH_ROW(BYTE)
1277 case 2: STRETCH_ROW(WORD)
1278 case 4: STRETCH_ROW(DWORD)
1280 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1281 ret = DDERR_UNSUPPORTED;
1289 dbuf += ddesc.lPitch;
1292 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1293 DWORD keylow, keyhigh;
1295 if (dwFlags & DDBLT_KEYSRC) {
1296 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1297 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1299 /* I'm not sure if this is correct */
1300 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1301 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1302 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1306 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1307 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1309 #define COPYROW_COLORKEY(type) { \
1310 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1311 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1312 tmp = s[sx >> 16]; \
1313 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1318 case 1: COPYROW_COLORKEY(BYTE)
1319 case 2: COPYROW_COLORKEY(WORD)
1320 case 4: COPYROW_COLORKEY(DWORD)
1322 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1323 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1324 ret = DDERR_UNSUPPORTED;
1327 dbuf += ddesc.lPitch;
1330 #undef COPYROW_COLORKEY
1332 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1339 if (dwFlags && FIXME_ON(ddraw)) {
1340 FIXME("\tUnsupported flags: ");
1341 _dump_DDBLT(dwFlags);
1345 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1346 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1351 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1352 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1354 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1355 int bpp, w, h, x, y;
1356 DDSURFACEDESC ddesc,sdesc;
1357 HRESULT ret = DD_OK;
1362 if (TRACE_ON(ddraw)) {
1363 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1364 This,dstx,dsty,src,rsrc,trans
1367 if (FIXME_ON(ddraw))
1368 _dump_DDBLTFAST(trans);
1370 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1372 FIXME(" srcrect: NULL\n");
1375 /* We need to lock the surfaces, or we won't get refreshes when done. */
1376 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1377 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1380 WARN("rsrc is NULL!\n");
1382 rsrc->left = rsrc->top = 0;
1383 rsrc->right = sdesc.dwWidth;
1384 rsrc->bottom = sdesc.dwHeight;
1387 bpp = GET_BPP(This->s.surface_desc);
1388 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1389 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1392 h=rsrc->bottom-rsrc->top;
1393 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1394 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1397 w=rsrc->right-rsrc->left;
1398 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1399 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1402 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1403 DWORD keylow, keyhigh;
1404 if (trans & DDBLTFAST_SRCCOLORKEY) {
1405 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1406 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1408 /* I'm not sure if this is correct */
1409 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1410 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1411 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1414 #define COPYBOX_COLORKEY(type) { \
1415 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1416 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1417 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1418 for (y = 0; y < h; y++) { \
1419 for (x = 0; x < w; x++) { \
1421 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1423 (LPBYTE)s += sdesc.lPitch; \
1424 (LPBYTE)d += ddesc.lPitch; \
1430 case 1: COPYBOX_COLORKEY(BYTE)
1431 case 2: COPYBOX_COLORKEY(WORD)
1432 case 4: COPYBOX_COLORKEY(DWORD)
1434 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1435 ret = DDERR_UNSUPPORTED;
1439 #undef COPYBOX_COLORKEY
1442 int width = w * bpp;
1444 for (y = 0; y < h; y++) {
1445 memcpy(dbuf, sbuf, width);
1446 sbuf += sdesc.lPitch;
1447 dbuf += ddesc.lPitch;
1453 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1454 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1458 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1459 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1461 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1462 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1468 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1469 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1471 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1472 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1473 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1477 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1478 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1480 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1481 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1483 /* Simply copy the surface description stored in the object */
1484 *ddsd = This->s.surface_desc;
1486 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1491 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1492 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1493 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1494 return ++(This->ref);
1497 #ifdef HAVE_LIBXXF86DGA
1498 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1499 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1501 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1506 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1507 /* clear out of surface list */
1508 if (This->t.dga.fb_height == -1)
1509 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1511 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1513 /* Free the DIBSection (if any) */
1514 if (This->s.hdc != 0) {
1515 SelectObject(This->s.hdc, This->s.holdbitmap);
1516 DeleteDC(This->s.hdc);
1517 DeleteObject(This->s.DIBsection);
1520 /* Free the clipper if attached to this surface */
1521 if( This->s.lpClipper )
1522 IDirectDrawClipper_Release(This->s.lpClipper);
1524 HeapFree(GetProcessHeap(),0,This);
1527 #endif /* defined(HAVE_LIBXXF86DGA) */
1529 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1530 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1532 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1537 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1539 if (This->t.xlib.image != NULL) {
1540 if (This->s.ddraw->d.pixel_convert != NULL) {
1541 /* In pixel conversion mode, there are 2 buffers to release. */
1542 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1544 #ifdef HAVE_LIBXXSHM
1545 if (This->s.ddraw->e.xlib.xshm_active) {
1546 TSXShmDetach(display, &(This->t.xlib.shminfo));
1547 TSXDestroyImage(This->t.xlib.image);
1548 shmdt(This->t.xlib.shminfo.shmaddr);
1551 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1552 This->t.xlib.image->data = NULL;
1553 TSXDestroyImage(This->t.xlib.image);
1554 #ifdef HAVE_LIBXXSHM
1558 This->t.xlib.image->data = NULL;
1560 #ifdef HAVE_LIBXXSHM
1561 if (This->s.ddraw->e.xlib.xshm_active) {
1562 TSXShmDetach(display, &(This->t.xlib.shminfo));
1563 TSXDestroyImage(This->t.xlib.image);
1564 shmdt(This->t.xlib.shminfo.shmaddr);
1567 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1568 TSXDestroyImage(This->t.xlib.image);
1569 #ifdef HAVE_LIBXXSHM
1573 This->t.xlib.image = 0;
1575 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1578 if (This->s.palette)
1579 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1581 /* Free the DIBSection (if any) */
1582 if (This->s.hdc != 0) {
1583 SelectObject(This->s.hdc, This->s.holdbitmap);
1584 DeleteDC(This->s.hdc);
1585 DeleteObject(This->s.DIBsection);
1588 /* Free the clipper if present */
1589 if( This->s.lpClipper )
1590 IDirectDrawClipper_Release(This->s.lpClipper);
1592 HeapFree(GetProcessHeap(),0,This);
1596 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1597 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1599 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1600 int i,found = 0,xstart;
1601 struct _surface_chain *chain;
1603 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1604 if (TRACE_ON(ddraw)) {
1605 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1608 chain = This->s.chain;
1610 return DDERR_NOTFOUND;
1612 for (i=0;i<chain->nrofsurfaces;i++)
1613 if (chain->surfaces[i] == This)
1617 for (i=0;i<chain->nrofsurfaces;i++) {
1618 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1620 if (found) /* may not find the same caps twice, (doc) */
1621 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1623 found = (i+1)+xstart;
1627 return DDERR_NOTFOUND;
1628 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1629 /* FIXME: AddRef? */
1630 TRACE("found %p\n",*lpdsf);
1634 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1635 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1637 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1638 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1640 return DDERR_ALREADYINITIALIZED;
1643 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1644 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1646 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1647 TRACE("(%p)->(%p)\n",This,pf);
1649 *pf = This->s.surface_desc.ddpfPixelFormat;
1650 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1654 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1655 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1656 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1660 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1661 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1663 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1664 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1668 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1669 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1671 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1672 TRACE("(%p)->(%p)!\n",This,lpClipper);
1674 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1675 This->s.lpClipper = lpClipper;
1676 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1680 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1681 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1683 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1684 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1686 struct _surface_chain *chain;
1688 FIXME("(%p)->(%p)\n",This,surf);
1689 chain = This->s.chain;
1691 /* IDirectDrawSurface4_AddRef(surf); */
1694 for (i=0;i<chain->nrofsurfaces;i++)
1695 if (chain->surfaces[i] == isurf)
1696 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1698 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1699 chain->nrofsurfaces = 1;
1700 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1701 chain->surfaces[0] = This;
1702 This->s.chain = chain;
1705 if (chain->surfaces)
1706 chain->surfaces = HeapReAlloc(
1710 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1713 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1714 isurf->s.chain = chain;
1715 chain->surfaces[chain->nrofsurfaces++] = isurf;
1719 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1720 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1725 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1727 /* Creates a DIB Section of the same size / format as the surface */
1728 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1730 if (This->s.hdc == 0) {
1731 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1734 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1735 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1740 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1744 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1745 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1749 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1750 b_info->bmiHeader.biWidth = desc.dwWidth;
1751 b_info->bmiHeader.biHeight = desc.dwHeight;
1752 b_info->bmiHeader.biPlanes = 1;
1753 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1755 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1756 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1758 b_info->bmiHeader.biCompression = BI_RGB;
1761 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1763 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1764 b_info->bmiHeader.biXPelsPerMeter = 0;
1765 b_info->bmiHeader.biYPelsPerMeter = 0;
1766 b_info->bmiHeader.biClrUsed = 0;
1767 b_info->bmiHeader.biClrImportant = 0;
1769 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1774 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1777 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1778 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1779 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1785 usage = DIB_RGB_COLORS;
1791 /* Fill the palette */
1792 usage = DIB_RGB_COLORS;
1794 if (This->s.palette == NULL) {
1795 ERR("Bad palette !!!\n");
1797 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1798 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1800 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1801 rgb[i].rgbBlue = pent[i].peBlue;
1802 rgb[i].rgbRed = pent[i].peRed;
1803 rgb[i].rgbGreen = pent[i].peGreen;
1809 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1812 &(This->s.bitmap_data),
1816 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1817 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1819 /* b_info is not useful anymore */
1820 HeapFree(GetProcessHeap(), 0, b_info);
1823 This->s.hdc = CreateCompatibleDC(0);
1824 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1827 /* Copy our surface in the DIB section */
1828 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1829 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1832 FIXME("This case has to be done :/\n");
1834 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1835 *lphdc = This->s.hdc;
1840 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1841 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1843 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1844 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1845 /* Copy the DIB section to our surface */
1846 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1847 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1850 FIXME("This case has to be done :/\n");
1852 /* Unlock the surface */
1853 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1857 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1858 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1860 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
1862 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1863 * the same interface. And IUnknown does that too of course.
1865 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1866 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1867 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1868 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1869 IsEqualGUID( &IID_IUnknown, refiid )
1872 IDirectDrawSurface4_AddRef(iface);
1874 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1877 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1879 /* Texture interface */
1880 *obj = d3dtexture2_create(This);
1881 IDirectDrawSurface4_AddRef(iface);
1882 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1885 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1887 /* Texture interface */
1888 *obj = d3dtexture_create(This);
1889 IDirectDrawSurface4_AddRef(iface);
1891 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1895 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1896 /* It is the OpenGL Direct3D Device */
1897 IDirectDrawSurface4_AddRef(iface);
1898 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1902 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
1903 return OLE_E_ENUM_NOMORE;
1906 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1907 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1908 TRACE("(%p)->(), stub!\n",This);
1909 return DD_OK; /* hmm */
1912 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1913 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1915 struct _surface_chain *chain = This->s.chain;
1917 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1918 for (i=0;i<chain->nrofsurfaces;i++) {
1919 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1920 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1921 return DD_OK; /* FIXME: return value correct? */
1926 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1927 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1928 FIXME("(%p)->(),stub!\n",This);
1932 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1933 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1935 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1936 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1937 if (TRACE_ON(ddraw)) {
1938 _dump_colorkeyflag(dwFlags);
1940 _dump_DDCOLORKEY((void *) ckey);
1944 /* If this surface was loaded as a texture, call also the texture
1945 SetColorKey callback */
1946 if (This->s.texture) {
1947 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1950 if( dwFlags & DDCKEY_SRCBLT )
1952 dwFlags &= ~DDCKEY_SRCBLT;
1953 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1954 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1957 if( dwFlags & DDCKEY_DESTBLT )
1959 dwFlags &= ~DDCKEY_DESTBLT;
1960 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1961 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1964 if( dwFlags & DDCKEY_SRCOVERLAY )
1966 dwFlags &= ~DDCKEY_SRCOVERLAY;
1967 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1968 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1971 if( dwFlags & DDCKEY_DESTOVERLAY )
1973 dwFlags &= ~DDCKEY_DESTOVERLAY;
1974 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1975 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1980 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1987 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1988 LPDIRECTDRAWSURFACE4 iface,
1991 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1992 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1997 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1998 LPDIRECTDRAWSURFACE4 iface,
2000 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
2002 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2004 struct _surface_chain *chain;
2006 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
2007 chain = This->s.chain;
2008 for (i=0;i<chain->nrofsurfaces;i++) {
2009 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
2010 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
2012 chain->surfaces[i]->s.chain = NULL;
2013 memcpy( chain->surfaces+i,
2014 chain->surfaces+(i+1),
2015 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
2017 chain->surfaces = HeapReAlloc(
2021 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
2023 chain->nrofsurfaces--;
2030 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2031 LPDIRECTDRAWSURFACE4 iface,
2034 LPDDENUMSURFACESCALLBACK lpfnCallback )
2036 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2037 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2038 lpContext, lpfnCallback );
2043 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2044 LPDIRECTDRAWSURFACE4 iface,
2045 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2047 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2048 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2053 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2054 LPDIRECTDRAWSURFACE4 iface,
2056 LPDDCOLORKEY lpDDColorKey )
2058 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2059 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2061 if( dwFlags & DDCKEY_SRCBLT ) {
2062 dwFlags &= ~DDCKEY_SRCBLT;
2063 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2066 if( dwFlags & DDCKEY_DESTBLT )
2068 dwFlags &= ~DDCKEY_DESTBLT;
2069 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2072 if( dwFlags & DDCKEY_SRCOVERLAY )
2074 dwFlags &= ~DDCKEY_SRCOVERLAY;
2075 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2078 if( dwFlags & DDCKEY_DESTOVERLAY )
2080 dwFlags &= ~DDCKEY_DESTOVERLAY;
2081 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2086 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2092 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2093 LPDIRECTDRAWSURFACE4 iface,
2096 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2097 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2102 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2103 LPDIRECTDRAWSURFACE4 iface,
2104 LPDIRECTDRAWPALETTE* lplpDDPalette )
2106 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2107 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2109 if (This->s.palette != NULL) {
2110 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2112 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2115 return DDERR_NOPALETTEATTACHED;
2119 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2120 LPDIRECTDRAWSURFACE4 iface,
2124 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2125 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2130 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2131 LPDIRECTDRAWSURFACE4 iface,
2133 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2136 LPDDOVERLAYFX lpDDOverlayFx )
2138 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2139 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2140 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2145 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2146 LPDIRECTDRAWSURFACE4 iface,
2149 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2150 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2155 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2156 LPDIRECTDRAWSURFACE4 iface,
2158 LPDIRECTDRAWSURFACE4 lpDDSReference )
2160 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2161 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2166 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2167 LPDIRECTDRAWSURFACE4 iface,
2170 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2171 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2173 /* Not sure about that... */
2174 *lplpDD = (void *) This->s.ddraw;
2179 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2180 LPDIRECTDRAWSURFACE4 iface,
2183 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2184 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2189 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2190 LPDIRECTDRAWSURFACE4 iface,
2193 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2194 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2199 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2200 LPDIRECTDRAWSURFACE4 iface,
2201 LPDDSURFACEDESC lpDDSD,
2204 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2205 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2210 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2215 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2216 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2221 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2224 LPDWORD lpcbBufferSize) {
2225 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2226 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2231 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2233 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2234 FIXME("(%p)->(%p)\n", This, guidTag);
2239 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2241 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2242 FIXME("(%p)->(%p)\n", This, lpValue);
2247 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2248 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2249 FIXME("(%p)\n", This);
2254 #ifdef HAVE_LIBXXF86DGA
2255 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2257 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2258 IDirectDrawSurface4Impl_QueryInterface,
2259 IDirectDrawSurface4Impl_AddRef,
2260 DGA_IDirectDrawSurface4Impl_Release,
2261 IDirectDrawSurface4Impl_AddAttachedSurface,
2262 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2263 IDirectDrawSurface4Impl_Blt,
2264 IDirectDrawSurface4Impl_BltBatch,
2265 IDirectDrawSurface4Impl_BltFast,
2266 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2267 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2268 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2269 DGA_IDirectDrawSurface4Impl_Flip,
2270 IDirectDrawSurface4Impl_GetAttachedSurface,
2271 IDirectDrawSurface4Impl_GetBltStatus,
2272 IDirectDrawSurface4Impl_GetCaps,
2273 IDirectDrawSurface4Impl_GetClipper,
2274 IDirectDrawSurface4Impl_GetColorKey,
2275 IDirectDrawSurface4Impl_GetDC,
2276 IDirectDrawSurface4Impl_GetFlipStatus,
2277 IDirectDrawSurface4Impl_GetOverlayPosition,
2278 IDirectDrawSurface4Impl_GetPalette,
2279 IDirectDrawSurface4Impl_GetPixelFormat,
2280 IDirectDrawSurface4Impl_GetSurfaceDesc,
2281 IDirectDrawSurface4Impl_Initialize,
2282 IDirectDrawSurface4Impl_IsLost,
2283 IDirectDrawSurface4Impl_Lock,
2284 IDirectDrawSurface4Impl_ReleaseDC,
2285 IDirectDrawSurface4Impl_Restore,
2286 IDirectDrawSurface4Impl_SetClipper,
2287 IDirectDrawSurface4Impl_SetColorKey,
2288 IDirectDrawSurface4Impl_SetOverlayPosition,
2289 DGA_IDirectDrawSurface4Impl_SetPalette,
2290 DGA_IDirectDrawSurface4Impl_Unlock,
2291 IDirectDrawSurface4Impl_UpdateOverlay,
2292 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2293 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2294 IDirectDrawSurface4Impl_GetDDInterface,
2295 IDirectDrawSurface4Impl_PageLock,
2296 IDirectDrawSurface4Impl_PageUnlock,
2297 IDirectDrawSurface4Impl_SetSurfaceDesc,
2298 IDirectDrawSurface4Impl_SetPrivateData,
2299 IDirectDrawSurface4Impl_GetPrivateData,
2300 IDirectDrawSurface4Impl_FreePrivateData,
2301 IDirectDrawSurface4Impl_GetUniquenessValue,
2302 IDirectDrawSurface4Impl_ChangeUniquenessValue
2304 #endif /* defined(HAVE_LIBXXF86DGA) */
2306 #ifdef HAVE_LIBXXF86DGA2
2307 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2309 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2310 IDirectDrawSurface4Impl_QueryInterface,
2311 IDirectDrawSurface4Impl_AddRef,
2312 DGA_IDirectDrawSurface4Impl_Release,
2313 IDirectDrawSurface4Impl_AddAttachedSurface,
2314 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2315 IDirectDrawSurface4Impl_Blt,
2316 IDirectDrawSurface4Impl_BltBatch,
2317 IDirectDrawSurface4Impl_BltFast,
2318 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2319 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2320 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2321 DGA2_IDirectDrawSurface4Impl_Flip,
2322 IDirectDrawSurface4Impl_GetAttachedSurface,
2323 IDirectDrawSurface4Impl_GetBltStatus,
2324 IDirectDrawSurface4Impl_GetCaps,
2325 IDirectDrawSurface4Impl_GetClipper,
2326 IDirectDrawSurface4Impl_GetColorKey,
2327 IDirectDrawSurface4Impl_GetDC,
2328 IDirectDrawSurface4Impl_GetFlipStatus,
2329 IDirectDrawSurface4Impl_GetOverlayPosition,
2330 IDirectDrawSurface4Impl_GetPalette,
2331 IDirectDrawSurface4Impl_GetPixelFormat,
2332 IDirectDrawSurface4Impl_GetSurfaceDesc,
2333 IDirectDrawSurface4Impl_Initialize,
2334 IDirectDrawSurface4Impl_IsLost,
2335 IDirectDrawSurface4Impl_Lock,
2336 IDirectDrawSurface4Impl_ReleaseDC,
2337 IDirectDrawSurface4Impl_Restore,
2338 IDirectDrawSurface4Impl_SetClipper,
2339 IDirectDrawSurface4Impl_SetColorKey,
2340 IDirectDrawSurface4Impl_SetOverlayPosition,
2341 DGA_IDirectDrawSurface4Impl_SetPalette,
2342 DGA_IDirectDrawSurface4Impl_Unlock,
2343 IDirectDrawSurface4Impl_UpdateOverlay,
2344 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2345 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2346 IDirectDrawSurface4Impl_GetDDInterface,
2347 IDirectDrawSurface4Impl_PageLock,
2348 IDirectDrawSurface4Impl_PageUnlock,
2349 IDirectDrawSurface4Impl_SetSurfaceDesc,
2350 IDirectDrawSurface4Impl_SetPrivateData,
2351 IDirectDrawSurface4Impl_GetPrivateData,
2352 IDirectDrawSurface4Impl_FreePrivateData,
2353 IDirectDrawSurface4Impl_GetUniquenessValue,
2354 IDirectDrawSurface4Impl_ChangeUniquenessValue
2356 #endif /* defined(HAVE_LIBXXF86DGA2) */
2358 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2360 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2361 IDirectDrawSurface4Impl_QueryInterface,
2362 IDirectDrawSurface4Impl_AddRef,
2363 Xlib_IDirectDrawSurface4Impl_Release,
2364 IDirectDrawSurface4Impl_AddAttachedSurface,
2365 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2366 IDirectDrawSurface4Impl_Blt,
2367 IDirectDrawSurface4Impl_BltBatch,
2368 IDirectDrawSurface4Impl_BltFast,
2369 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2370 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2371 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2372 Xlib_IDirectDrawSurface4Impl_Flip,
2373 IDirectDrawSurface4Impl_GetAttachedSurface,
2374 IDirectDrawSurface4Impl_GetBltStatus,
2375 IDirectDrawSurface4Impl_GetCaps,
2376 IDirectDrawSurface4Impl_GetClipper,
2377 IDirectDrawSurface4Impl_GetColorKey,
2378 IDirectDrawSurface4Impl_GetDC,
2379 IDirectDrawSurface4Impl_GetFlipStatus,
2380 IDirectDrawSurface4Impl_GetOverlayPosition,
2381 IDirectDrawSurface4Impl_GetPalette,
2382 IDirectDrawSurface4Impl_GetPixelFormat,
2383 IDirectDrawSurface4Impl_GetSurfaceDesc,
2384 IDirectDrawSurface4Impl_Initialize,
2385 IDirectDrawSurface4Impl_IsLost,
2386 IDirectDrawSurface4Impl_Lock,
2387 IDirectDrawSurface4Impl_ReleaseDC,
2388 IDirectDrawSurface4Impl_Restore,
2389 IDirectDrawSurface4Impl_SetClipper,
2390 IDirectDrawSurface4Impl_SetColorKey,
2391 IDirectDrawSurface4Impl_SetOverlayPosition,
2392 Xlib_IDirectDrawSurface4Impl_SetPalette,
2393 Xlib_IDirectDrawSurface4Impl_Unlock,
2394 IDirectDrawSurface4Impl_UpdateOverlay,
2395 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2396 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2397 IDirectDrawSurface4Impl_GetDDInterface,
2398 IDirectDrawSurface4Impl_PageLock,
2399 IDirectDrawSurface4Impl_PageUnlock,
2400 IDirectDrawSurface4Impl_SetSurfaceDesc,
2401 IDirectDrawSurface4Impl_SetPrivateData,
2402 IDirectDrawSurface4Impl_GetPrivateData,
2403 IDirectDrawSurface4Impl_FreePrivateData,
2404 IDirectDrawSurface4Impl_GetUniquenessValue,
2405 IDirectDrawSurface4Impl_ChangeUniquenessValue
2408 /******************************************************************************
2409 * DirectDrawCreateClipper (DDRAW.7)
2411 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2412 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2413 LPUNKNOWN pUnkOuter)
2415 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2416 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2418 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2419 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2420 (*ilplpDDClipper)->ref = 1;
2422 (*ilplpDDClipper)->hWnd = 0;
2427 /******************************************************************************
2428 * IDirectDrawClipper
2430 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2431 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2433 ICOM_THIS(IDirectDrawClipperImpl,iface);
2435 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2437 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2438 return DDERR_INVALIDPARAMS;
2445 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2446 ICOM_THIS(IDirectDrawClipperImpl,iface);
2447 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2452 HeapFree(GetProcessHeap(),0,This);
2456 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2457 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2459 ICOM_THIS(IDirectDrawClipperImpl,iface);
2460 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2465 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2466 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2468 ICOM_THIS(IDirectDrawClipperImpl,iface);
2469 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2473 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2474 LPDIRECTDRAWCLIPPER iface,
2478 ICOM_THIS(IDirectDrawClipperImpl,iface);
2479 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2480 return OLE_E_ENUM_NOMORE;
2483 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2485 ICOM_THIS(IDirectDrawClipperImpl,iface);
2486 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2487 return ++(This->ref);
2490 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2491 LPDIRECTDRAWCLIPPER iface,
2494 ICOM_THIS(IDirectDrawClipperImpl,iface);
2495 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2497 *hWndPtr = This->hWnd;
2502 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2503 LPDIRECTDRAWCLIPPER iface,
2507 ICOM_THIS(IDirectDrawClipperImpl,iface);
2508 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2512 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2513 LPDIRECTDRAWCLIPPER iface,
2516 ICOM_THIS(IDirectDrawClipperImpl,iface);
2517 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2521 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2523 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2524 IDirectDrawClipperImpl_QueryInterface,
2525 IDirectDrawClipperImpl_AddRef,
2526 IDirectDrawClipperImpl_Release,
2527 IDirectDrawClipperImpl_GetClipList,
2528 IDirectDrawClipperImpl_GetHWnd,
2529 IDirectDrawClipperImpl_Initialize,
2530 IDirectDrawClipperImpl_IsClipListChanged,
2531 IDirectDrawClipperImpl_SetClipList,
2532 IDirectDrawClipperImpl_SetHwnd
2536 /******************************************************************************
2537 * IDirectDrawPalette
2539 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2540 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2542 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2545 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2546 This,x,start,count,palent);
2548 /* No palette created and not in depth-convertion mode -> BUG ! */
2549 if ((This->cm == None) &&
2550 (This->ddraw->d.palette_convert == NULL))
2552 FIXME("app tried to read colormap for non-palettized mode\n");
2553 return DDERR_GENERIC;
2555 for (i=0;i<count;i++) {
2556 palent[i].peRed = This->palents[start+i].peRed;
2557 palent[i].peBlue = This->palents[start+i].peBlue;
2558 palent[i].peGreen = This->palents[start+i].peGreen;
2559 palent[i].peFlags = This->palents[start+i].peFlags;
2565 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2566 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2568 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2572 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2573 This,x,start,count,palent
2575 for (i=0;i<count;i++) {
2576 xc.red = palent[i].peRed<<8;
2577 xc.blue = palent[i].peBlue<<8;
2578 xc.green = palent[i].peGreen<<8;
2579 xc.flags = DoRed|DoBlue|DoGreen;
2583 TSXStoreColor(display,This->cm,&xc);
2585 This->palents[start+i].peRed = palent[i].peRed;
2586 This->palents[start+i].peBlue = palent[i].peBlue;
2587 This->palents[start+i].peGreen = palent[i].peGreen;
2588 This->palents[start+i].peFlags = palent[i].peFlags;
2591 /* Now, if we are in 'depth conversion mode', update the screen palette */
2592 /* FIXME: we need to update the image or we won't get palette fading. */
2593 if (This->ddraw->d.palette_convert != NULL)
2594 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2599 #ifdef HAVE_LIBXXF86DGA
2600 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2601 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2603 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2608 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2609 This,x,start,count,palent
2611 if (!This->cm) /* should not happen */ {
2612 FIXME("app tried to set colormap in non-palettized mode\n");
2613 return DDERR_GENERIC;
2615 /* FIXME: free colorcells instead of freeing whole map */
2617 This->cm = TSXCopyColormapAndFree(display,This->cm);
2618 TSXFreeColormap(display,cm);
2620 for (i=0;i<count;i++) {
2621 xc.red = palent[i].peRed<<8;
2622 xc.blue = palent[i].peBlue<<8;
2623 xc.green = palent[i].peGreen<<8;
2624 xc.flags = DoRed|DoBlue|DoGreen;
2627 TSXStoreColor(display,This->cm,&xc);
2629 This->palents[start+i].peRed = palent[i].peRed;
2630 This->palents[start+i].peBlue = palent[i].peBlue;
2631 This->palents[start+i].peGreen = palent[i].peGreen;
2632 This->palents[start+i].peFlags = palent[i].peFlags;
2634 #ifdef HAVE_LIBXXF86DGA2
2635 if (This->ddraw->e.dga.version == 2)
2636 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2638 #endif /* defined(HAVE_LIBXXF86DGA2) */
2639 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2642 #endif /* defined(HAVE_LIBXXF86DGA) */
2644 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2645 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2646 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2647 if (!--(This->ref)) {
2649 TSXFreeColormap(display,This->cm);
2652 HeapFree(GetProcessHeap(),0,This);
2658 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2659 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2661 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2662 return ++(This->ref);
2665 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2666 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2668 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2669 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2671 return DDERR_ALREADYINITIALIZED;
2674 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2675 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2677 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2678 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2682 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2683 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2685 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2687 FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
2692 #ifdef HAVE_LIBXXF86DGA
2693 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2695 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2696 IDirectDrawPaletteImpl_QueryInterface,
2697 IDirectDrawPaletteImpl_AddRef,
2698 IDirectDrawPaletteImpl_Release,
2699 IDirectDrawPaletteImpl_GetCaps,
2700 IDirectDrawPaletteImpl_GetEntries,
2701 IDirectDrawPaletteImpl_Initialize,
2702 DGA_IDirectDrawPaletteImpl_SetEntries
2704 #endif /* defined(HAVE_LIBXXF86DGA) */
2706 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2708 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2709 IDirectDrawPaletteImpl_QueryInterface,
2710 IDirectDrawPaletteImpl_AddRef,
2711 IDirectDrawPaletteImpl_Release,
2712 IDirectDrawPaletteImpl_GetCaps,
2713 IDirectDrawPaletteImpl_GetEntries,
2714 IDirectDrawPaletteImpl_Initialize,
2715 Xlib_IDirectDrawPaletteImpl_SetEntries
2718 /*******************************************************************************
2721 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2722 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2724 ICOM_THIS(IDirect3DImpl,iface);
2725 /* FIXME: Not sure if this is correct */
2727 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2728 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2729 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2730 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2732 IDirect3D_AddRef(iface);
2734 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2738 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2739 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2741 IDirect3D_AddRef(iface);
2743 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2747 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2748 IDirect3D2Impl* d3d;
2750 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2752 d3d->ddraw = This->ddraw;
2753 IDirect3D_AddRef(iface);
2754 ICOM_VTBL(d3d) = &d3d2vt;
2757 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2761 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2762 return OLE_E_ENUM_NOMORE;
2765 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2766 ICOM_THIS(IDirect3DImpl,iface);
2767 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2769 return ++(This->ref);
2772 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2774 ICOM_THIS(IDirect3DImpl,iface);
2775 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2777 if (!--(This->ref)) {
2778 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2779 HeapFree(GetProcessHeap(),0,This);
2785 static HRESULT WINAPI IDirect3DImpl_Initialize(
2786 LPDIRECT3D iface, REFIID refiid )
2788 ICOM_THIS(IDirect3DImpl,iface);
2789 /* FIXME: Not sure if this is correct */
2791 FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
2793 return DDERR_ALREADYINITIALIZED;
2796 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2797 LPD3DENUMDEVICESCALLBACK cb,
2799 ICOM_THIS(IDirect3DImpl,iface);
2800 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2802 /* Call functions defined in d3ddevices.c */
2803 if (!d3d_OpenGL_dx3(cb, context))
2809 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2810 LPDIRECT3DLIGHT *lplight,
2813 ICOM_THIS(IDirect3DImpl,iface);
2814 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2816 /* Call the creation function that is located in d3dlight.c */
2817 *lplight = d3dlight_create_dx3(This);
2822 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2823 LPDIRECT3DMATERIAL *lpmaterial,
2826 ICOM_THIS(IDirect3DImpl,iface);
2827 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2829 /* Call the creation function that is located in d3dviewport.c */
2830 *lpmaterial = d3dmaterial_create(This);
2835 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2836 LPDIRECT3DVIEWPORT *lpviewport,
2839 ICOM_THIS(IDirect3DImpl,iface);
2840 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2842 /* Call the creation function that is located in d3dviewport.c */
2843 *lpviewport = d3dviewport_create(This);
2848 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2849 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2850 LPD3DFINDDEVICERESULT lpfinddevrst)
2852 ICOM_THIS(IDirect3DImpl,iface);
2853 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2858 static ICOM_VTABLE(IDirect3D) d3dvt =
2860 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2861 IDirect3DImpl_QueryInterface,
2862 IDirect3DImpl_AddRef,
2863 IDirect3DImpl_Release,
2864 IDirect3DImpl_Initialize,
2865 IDirect3DImpl_EnumDevices,
2866 IDirect3DImpl_CreateLight,
2867 IDirect3DImpl_CreateMaterial,
2868 IDirect3DImpl_CreateViewport,
2869 IDirect3DImpl_FindDevice
2872 /*******************************************************************************
2875 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2876 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2877 ICOM_THIS(IDirect3D2Impl,iface);
2879 /* FIXME: Not sure if this is correct */
2881 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2882 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2883 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2884 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2886 IDirect3D2_AddRef(iface);
2888 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2892 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2893 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2895 IDirect3D2_AddRef(iface);
2897 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2901 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2904 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2906 d3d->ddraw = This->ddraw;
2907 IDirect3D2_AddRef(iface);
2908 ICOM_VTBL(d3d) = &d3dvt;
2911 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2915 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2916 return OLE_E_ENUM_NOMORE;
2919 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2920 ICOM_THIS(IDirect3D2Impl,iface);
2921 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2923 return ++(This->ref);
2926 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2927 ICOM_THIS(IDirect3D2Impl,iface);
2928 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2930 if (!--(This->ref)) {
2931 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2932 HeapFree(GetProcessHeap(),0,This);
2938 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2939 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2941 ICOM_THIS(IDirect3D2Impl,iface);
2942 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2944 /* Call functions defined in d3ddevices.c */
2945 if (!d3d_OpenGL(cb, context))
2951 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2952 LPDIRECT3DLIGHT *lplight,
2955 ICOM_THIS(IDirect3D2Impl,iface);
2956 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2958 /* Call the creation function that is located in d3dlight.c */
2959 *lplight = d3dlight_create(This);
2964 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2965 LPDIRECT3DMATERIAL2 *lpmaterial,
2968 ICOM_THIS(IDirect3D2Impl,iface);
2969 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2971 /* Call the creation function that is located in d3dviewport.c */
2972 *lpmaterial = d3dmaterial2_create(This);
2977 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2978 LPDIRECT3DVIEWPORT2 *lpviewport,
2981 ICOM_THIS(IDirect3D2Impl,iface);
2982 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2984 /* Call the creation function that is located in d3dviewport.c */
2985 *lpviewport = d3dviewport2_create(This);
2990 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2991 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2992 LPD3DFINDDEVICERESULT lpfinddevrst)
2994 ICOM_THIS(IDirect3D2Impl,iface);
2995 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
3000 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
3002 LPDIRECTDRAWSURFACE surface,
3003 LPDIRECT3DDEVICE2 *device)
3005 ICOM_THIS(IDirect3D2Impl,iface);
3007 FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
3009 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
3010 IDirect3D2_AddRef(iface);
3014 return DDERR_INVALIDPARAMS;
3017 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3019 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3020 IDirect3D2Impl_QueryInterface,
3021 IDirect3D2Impl_AddRef,
3022 IDirect3D2Impl_Release,
3023 IDirect3D2Impl_EnumDevices,
3024 IDirect3D2Impl_CreateLight,
3025 IDirect3D2Impl_CreateMaterial,
3026 IDirect3D2Impl_CreateViewport,
3027 IDirect3D2Impl_FindDevice,
3028 IDirect3D2Impl_CreateDevice
3031 /*******************************************************************************
3035 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3036 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3038 static INT ddrawXlibThisOffset = 0;
3040 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3041 IDirectDrawSurfaceImpl* lpdsf)
3045 /* The surface was already allocated when entering in this function */
3046 TRACE("using system memory for a surface (%p) \n", lpdsf);
3048 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3049 /* This is a Z Buffer */
3050 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3051 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3053 /* This is a standard image */
3054 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3055 /* No pixel format => use DirectDraw's format */
3056 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3057 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3059 bpp = GET_BPP(lpdsf->s.surface_desc);
3062 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3063 /* The surface was preallocated : seems that we have nothing to do :-) */
3064 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3068 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3070 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3071 lpdsf->s.surface_desc.u1.lpSurface =
3072 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3073 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3078 #ifdef HAVE_LIBXXF86DGA
3079 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3080 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3082 ICOM_THIS(IDirectDraw2Impl,iface);
3083 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3084 int i, fbheight = This->e.dga.fb_height;
3086 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3087 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3089 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3092 sizeof(IDirectDrawSurfaceImpl)
3094 IDirectDraw2_AddRef(iface);
3097 #ifdef HAVE_LIBXXF86DGA2
3098 if (This->e.dga.version == 2)
3099 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3101 #endif /* defined(HAVE_LIBXXF86DGA2) */
3102 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3103 (*ilpdsf)->s.ddraw = This;
3104 (*ilpdsf)->s.palette = NULL;
3105 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3106 (*ilpdsf)->s.lpClipper = NULL;
3108 /* Copy the surface description */
3109 (*ilpdsf)->s.surface_desc = *lpddsd;
3111 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3112 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3113 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3114 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3116 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3118 /* Check if this a 'primary surface' or not */
3119 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3120 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3121 /* This is THE primary surface => there is DGA-specific code */
3123 /* First, store the surface description */
3124 (*ilpdsf)->s.surface_desc = *lpddsd;
3126 /* Find a viewport */
3128 if (!(This->e.dga.vpmask & (1<<i)))
3130 TRACE("using viewport %d for a primary surface\n",i);
3131 /* if i == 32 or maximum ... return error */
3132 This->e.dga.vpmask|=(1<<i);
3133 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3134 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3136 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3137 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3139 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3141 /* Add flags if there were not present */
3142 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3143 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3144 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3145 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3146 /* We put our surface always in video memory */
3147 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3148 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3149 (*ilpdsf)->s.chain = NULL;
3151 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3152 IDirectDrawSurface4Impl* back;
3155 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3158 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3161 sizeof(IDirectDrawSurface4Impl)
3163 IDirectDraw2_AddRef(iface);
3165 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3167 if (!(This->e.dga.vpmask & (1<<i)))
3169 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3170 /* if i == 32 or maximum ... return error */
3171 This->e.dga.vpmask|=(1<<i);
3172 back->t.dga.fb_height = i*fbheight;
3173 /* Copy the surface description from the front buffer */
3174 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3175 /* Change the parameters that are not the same */
3176 back->s.surface_desc.u1.lpSurface =
3177 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3179 back->s.ddraw = This;
3180 /* Add relevant info to front and back buffers */
3181 /* FIXME: backbuffer/frontbuffer handling broken here, but
3182 * will be fixed up in _Flip().
3184 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3185 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3186 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3187 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3188 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3192 /* There is no DGA-specific code here...
3193 Go to the common surface creation function */
3194 return common_off_screen_CreateSurface(This, *ilpdsf);
3198 #endif /* defined(HAVE_LIBXXF86DGA) */
3200 #ifdef HAVE_LIBXXSHM
3201 /* Error handlers for Image creation */
3202 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3207 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3209 int (*WineXHandler)(Display *, XErrorEvent *);
3211 img = TSXShmCreateImage(display,
3212 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3213 This->d.pixmap_depth,
3216 &(lpdsf->t.xlib.shminfo),
3217 lpdsf->s.surface_desc.dwWidth,
3218 lpdsf->s.surface_desc.dwHeight
3222 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3223 This->e.xlib.xshm_active = 0;
3227 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3228 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3229 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3230 This->e.xlib.xshm_active = 0;
3231 TSXDestroyImage(img);
3235 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3237 if (img->data == (char *) -1) {
3238 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3239 This->e.xlib.xshm_active = 0;
3240 TSXDestroyImage(img);
3241 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3244 lpdsf->t.xlib.shminfo.readOnly = False;
3246 /* This is where things start to get trickier....
3247 * First, we flush the current X connections to be sure to catch all
3248 * non-XShm related errors
3250 TSXSync(display, False);
3251 /* Then we enter in the non-thread safe part of the tests */
3252 EnterCriticalSection( &X11DRV_CritSection );
3254 /* Reset the error flag, sets our new error handler and try to attach
3258 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3259 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3260 XSync(display, False);
3262 /* Check the error flag */
3263 if (XShmErrorFlag) {
3264 /* An error occured */
3268 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3269 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3270 XSetErrorHandler(WineXHandler);
3272 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3273 This->e.xlib.xshm_active = 0;
3275 /* Leave the critical section */
3276 LeaveCriticalSection( &X11DRV_CritSection );
3279 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3280 * this works, but it may be a bit overkill....
3282 XSetErrorHandler(WineXHandler);
3283 LeaveCriticalSection( &X11DRV_CritSection );
3285 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3287 if (This->d.pixel_convert != NULL) {
3288 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3291 lpdsf->s.surface_desc.dwWidth *
3292 lpdsf->s.surface_desc.dwHeight *
3293 PFGET_BPP(This->d.directdraw_pixelformat)
3296 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3300 #endif /* HAVE_LIBXXSHM */
3302 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3306 #ifdef HAVE_LIBXXSHM
3307 if (This->e.xlib.xshm_active)
3308 img = create_xshmimage(This, lpdsf);
3312 /* Allocate surface memory */
3313 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3314 GetProcessHeap(),HEAP_ZERO_MEMORY,
3315 lpdsf->s.surface_desc.dwWidth *
3316 lpdsf->s.surface_desc.dwHeight *
3317 PFGET_BPP(This->d.directdraw_pixelformat)
3320 if (This->d.pixel_convert != NULL) {
3321 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3322 lpdsf->s.surface_desc.dwWidth *
3323 lpdsf->s.surface_desc.dwHeight *
3324 PFGET_BPP(This->d.screen_pixelformat)
3327 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3330 /* In this case, create an XImage */
3331 img = TSXCreateImage(display,
3332 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3333 This->d.pixmap_depth,
3337 lpdsf->s.surface_desc.dwWidth,
3338 lpdsf->s.surface_desc.dwHeight,
3340 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3342 #ifdef HAVE_LIBXXSHM
3345 if (This->d.pixel_convert != NULL)
3346 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3348 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3352 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3353 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3355 ICOM_THIS(IDirectDraw2Impl,iface);
3356 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3358 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3360 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3362 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3363 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3366 IDirectDraw2_AddRef(iface);
3368 (*ilpdsf)->s.ddraw = This;
3370 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3371 (*ilpdsf)->s.palette = NULL;
3372 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3373 (*ilpdsf)->s.lpClipper = NULL;
3375 /* Copy the surface description */
3376 (*ilpdsf)->s.surface_desc = *lpddsd;
3378 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3379 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3380 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3381 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3382 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3384 /* Check if this a 'primary surface' or not */
3385 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3386 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3389 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3390 /* Create the XImage */
3391 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3393 return DDERR_OUTOFMEMORY;
3394 (*ilpdsf)->t.xlib.image = img;
3396 /* Add flags if there were not present */
3397 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3398 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3399 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3400 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3401 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3403 /* Check for backbuffers */
3404 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3405 IDirectDrawSurface4Impl* back;
3409 for (i=lpddsd->dwBackBufferCount;i--;) {
3410 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3411 GetProcessHeap(),HEAP_ZERO_MEMORY,
3412 sizeof(IDirectDrawSurface4Impl)
3415 TRACE("allocated back-buffer (%p)\n", back);
3417 IDirectDraw2_AddRef(iface);
3418 back->s.ddraw = This;
3421 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3422 /* Copy the surface description from the front buffer */
3423 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3425 /* Create the XImage */
3426 img = create_ximage(This, back);
3428 return DDERR_OUTOFMEMORY;
3429 back->t.xlib.image = img;
3431 /* Add relevant info to front and back buffers */
3432 /* FIXME: backbuffer/frontbuffer handling broken here, but
3433 * will be fixed up in _Flip().
3435 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3436 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3437 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3438 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3439 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3443 /* There is no Xlib-specific code here...
3444 Go to the common surface creation function */
3445 return common_off_screen_CreateSurface(This, *ilpdsf);
3450 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3451 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3453 ICOM_THIS(IDirectDraw2Impl,iface);
3454 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3455 *dst = src; /* FIXME */
3460 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3461 * even when the approbiate bitmasks are not specified.
3463 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3464 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3466 ICOM_THIS(IDirectDraw2Impl,iface);
3472 #define FE(x) { x, #x},
3473 FE(DDSCL_FULLSCREEN)
3474 FE(DDSCL_ALLOWREBOOT)
3475 FE(DDSCL_NOWINDOWCHANGES)
3477 FE(DDSCL_ALLOWMODEX)
3479 FE(DDSCL_SETFOCUSWINDOW)
3480 FE(DDSCL_SETDEVICEWINDOW)
3481 FE(DDSCL_CREATEDEVICEWINDOW)
3485 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3486 if (TRACE_ON(ddraw)) {
3488 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3489 if (flags[i].mask & cooplevel) {
3490 DPRINTF("%s ",flags[i].name);
3495 This->d.mainWindow = hwnd;
3497 /* This will be overwritten in the case of Full Screen mode.
3498 Windowed games could work with that :-) */
3501 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3502 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3503 WIN_ReleaseWndPtr(tmpWnd);
3505 if( !This->d.drawable ) {
3506 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3507 WIN_ReleaseDesktop();
3509 TRACE("Setting drawable to %ld\n", This->d.drawable);
3515 #ifdef HAVE_LIBXXF86DGA2
3516 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3517 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3519 ICOM_THIS(IDirectDraw2Impl,iface);
3523 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3525 if (This->e.dga.version != 2) {
3531 TSXDGAQueryExtension(display, &evbase, &erbase);
3533 /* Now, start handling of DGA events giving the handle to the DDraw window
3534 as the window for which the event will be reported */
3535 TSXDGASelectInput(display, DefaultScreen(display),
3536 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3537 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3544 /* Small helper to either use the cooperative window or create a new
3545 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3547 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3550 /* Do not destroy the application supplied cooperative window */
3551 if (This->d.window && This->d.window != This->d.mainWindow) {
3552 DestroyWindow(This->d.window);
3555 /* Sanity check cooperative window before assigning it to drawing. */
3556 if ( IsWindow(This->d.mainWindow) &&
3557 IsWindowVisible(This->d.mainWindow)
3559 /* if it does not fit, resize the cooperative window.
3560 * and hope the app likes it
3562 GetWindowRect(This->d.mainWindow,&rect);
3563 if ((((rect.right-rect.left) >= This->d.width) &&
3564 ((rect.bottom-rect.top) >= This->d.height))
3566 This->d.window = This->d.mainWindow;
3567 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3571 /* ... failed, create new one. */
3572 if (!This->d.window) {
3573 This->d.window = CreateWindowExA(
3577 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3586 /*Store THIS with the window. We'll use it in the window procedure*/
3587 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3588 ShowWindow(This->d.window,TRUE);
3589 UpdateWindow(This->d.window);
3591 SetFocus(This->d.window);
3594 static int _common_depth_to_pixelformat(DWORD depth,
3595 DDPIXELFORMAT *pixelformat,
3596 DDPIXELFORMAT *screen_pixelformat,
3599 XPixmapFormatValues *pf;
3601 int nvisuals, npixmap, i;
3605 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3606 pf = XListPixmapFormats(display, &npixmap);
3608 for (i = 0; i < npixmap; i++) {
3609 if (pf[i].depth == depth) {
3612 for (j = 0; j < nvisuals; j++) {
3613 if (vi[j].depth == pf[i].depth) {
3614 pixelformat->dwSize = sizeof(*pixelformat);
3616 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3617 pixelformat->u1.dwRBitMask = 0;
3618 pixelformat->u2.dwGBitMask = 0;
3619 pixelformat->u3.dwBBitMask = 0;
3621 pixelformat->dwFlags = DDPF_RGB;
3622 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3623 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3624 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3626 pixelformat->dwFourCC = 0;
3627 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3628 pixelformat->u4.dwRGBAlphaBitMask= 0;
3630 *screen_pixelformat = *pixelformat;
3632 if (pix_depth != NULL)
3633 *pix_depth = vi[j].depth;
3638 goto clean_up_and_exit;
3642 ERR("No visual corresponding to pixmap format !\n");
3647 /* We try now to find an emulated mode */
3650 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3651 if (ModeEmulations[c].dest.depth == depth) {
3652 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3653 for (i = 0; i < npixmap; i++) {
3654 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3655 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3658 for (j = 0; j < nvisuals; j++) {
3659 if (vi[j].depth == pf[i].depth) {
3660 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3661 screen_pixelformat->dwFlags = DDPF_RGB;
3662 screen_pixelformat->dwFourCC = 0;
3663 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3664 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3665 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3666 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3667 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3669 pixelformat->dwSize = sizeof(*pixelformat);
3670 pixelformat->dwFourCC = 0;
3672 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3673 pixelformat->u.dwRGBBitCount = 8;
3674 pixelformat->u1.dwRBitMask = 0;
3675 pixelformat->u2.dwGBitMask = 0;
3676 pixelformat->u3.dwBBitMask = 0;
3678 pixelformat->dwFlags = DDPF_RGB;
3679 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3680 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3681 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3682 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3684 pixelformat->u4.dwRGBAlphaBitMask= 0;
3686 if (pix_depth != NULL)
3687 *pix_depth = vi[j].depth;
3692 goto clean_up_and_exit;
3695 ERR("No visual corresponding to pixmap format !\n");
3710 #ifdef HAVE_LIBXXF86DGA2
3711 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3712 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3714 /* Now, get the device / mode description */
3715 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3717 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3718 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3719 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3720 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3721 This->e.dga.dev->data,
3722 This->e.dga.dev->mode.imageWidth,
3723 (This->e.dga.dev->mode.imageWidth *
3724 This->e.dga.dev->mode.imageHeight *
3725 (This->e.dga.dev->mode.bitsPerPixel / 8))
3727 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3728 /* Get the screen dimensions as seen by Wine.
3729 In that case, it may be better to ignore the -desktop mode and return the
3730 real screen size => print a warning */
3731 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3732 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3733 This->e.dga.fb_addr = This->e.dga.dev->data;
3734 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3735 This->e.dga.dev->mode.imageHeight *
3736 (This->e.dga.dev->mode.bitsPerPixel / 8));
3737 This->e.dga.vpmask = 0;
3739 /* Fill the screen pixelformat */
3740 pf->dwSize = sizeof(DDPIXELFORMAT);
3742 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3743 if (This->e.dga.dev->mode.depth == 8) {
3744 pf->dwFlags = DDPF_PALETTEINDEXED8;
3745 pf->u1.dwRBitMask = 0;
3746 pf->u2.dwGBitMask = 0;
3747 pf->u3.dwBBitMask = 0;
3749 pf->dwFlags = DDPF_RGB;
3750 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3751 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3752 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3754 pf->u4.dwRGBAlphaBitMask= 0;
3756 This->d.screen_pixelformat = *pf;
3758 #endif /* defined(HAVE_LIBXXF86DGA2) */
3760 #ifdef HAVE_LIBXXF86DGA
3761 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3762 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3764 ICOM_THIS(IDirectDrawImpl,iface);
3767 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3769 #ifdef HAVE_LIBXXF86DGA2
3770 if (This->e.dga.version == 2) {
3771 XDGAMode *modes = This->e.dga.modes;
3772 int mode_to_use = -1;
3774 /* Search in the list a display mode that corresponds to what is requested */
3775 for (i = 0; i < This->e.dga.num_modes; i++) {
3776 if ((height == modes[i].viewportHeight) &&
3777 (width == modes[i].viewportWidth) &&
3778 (depth == modes[i].depth)) {
3779 mode_to_use = modes[i].num;
3783 if (mode_to_use < 0) {
3784 ERR("Could not find matching mode !!!\n");
3785 return DDERR_UNSUPPORTEDMODE;
3787 TRACE("Using mode number %d\n", mode_to_use);
3789 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3791 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3792 ERR("Error opening the frame buffer !!!\n");
3794 return DDERR_GENERIC;
3797 /* Initialize the frame buffer */
3798 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3800 /* Re-get (if necessary) the DGA events */
3801 TSXDGASelectInput(display, DefaultScreen(display),
3802 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3807 #endif /* defined(HAVE_LIBXXF86DGA2) */
3809 /* We hope getting the asked for depth */
3810 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3811 /* I.e. no visual found or emulated */
3812 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3813 return DDERR_UNSUPPORTEDMODE;
3816 if (This->d.width < width) {
3817 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3818 return DDERR_UNSUPPORTEDMODE;
3820 This->d.width = width;
3821 This->d.height = height;
3823 /* adjust fb_height, so we don't overlap */
3824 if (This->e.dga.fb_height < height)
3825 This->e.dga.fb_height = height;
3826 _common_IDirectDrawImpl_SetDisplayMode(This);
3828 #ifdef HAVE_LIBXXF86VM
3829 #ifdef HAVE_LIBXXF86DGA2
3830 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3831 #endif /* defined(HAVE_LIBXXF86DGA2) */
3833 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3834 XF86VidModeModeLine mod_tmp;
3835 /* int dotclock_tmp; */
3837 /* save original video mode and set fullscreen if available*/
3838 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3839 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3840 orig_mode->hdisplay = mod_tmp.hdisplay;
3841 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3842 orig_mode->hsyncend = mod_tmp.hsyncend;
3843 orig_mode->htotal = mod_tmp.htotal;
3844 orig_mode->vdisplay = mod_tmp.vdisplay;
3845 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3846 orig_mode->vsyncend = mod_tmp.vsyncend;
3847 orig_mode->vtotal = mod_tmp.vtotal;
3848 orig_mode->flags = mod_tmp.flags;
3849 orig_mode->private = mod_tmp.private;
3851 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3852 for (i=0;i<mode_count;i++)
3854 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3856 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3857 *vidmode = *(all_modes[i]);
3860 TSXFree(all_modes[i]->private);
3862 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3866 WARN("Fullscreen mode not available!\n");
3870 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3871 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3872 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3873 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3879 /* FIXME: this function OVERWRITES several signal handlers.
3880 * can we save them? and restore them later? In a way that
3881 * it works for the library too?
3883 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3884 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3886 #ifdef RESTORE_SIGNALS
3891 #endif /* defined(HAVE_LIBXXF86DGA) */
3893 /* *************************************
3894 16 / 15 bpp to palettized 8 bpp
3895 ************************************* */
3896 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3897 unsigned char *c_src = (unsigned char *) src;
3898 unsigned short *c_dst = (unsigned short *) dst;
3901 if (palette != NULL) {
3902 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3904 for (y = height; y--; ) {
3905 #if defined(__i386__) && defined(__GNUC__)
3906 /* gcc generates slightly inefficient code for the the copy / lookup,
3907 * it generates one excess memory access (to pal) per pixel. Since
3908 * we know that pal is not modified by the memory write we can
3909 * put it into a register and reduce the number of memory accesses
3910 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3911 * (This is not guaranteed to be the fastest method.)
3913 __asm__ __volatile__(
3917 " movw (%%edx,%%eax,2),%%ax\n"
3919 " xor %%eax,%%eax\n"
3921 : "=S" (c_src), "=D" (c_dst)
3922 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3923 : "eax", "cc", "memory"
3925 c_src+=(pitch-width);
3927 unsigned char * srclineend = c_src+width;
3928 while (c_src < srclineend)
3929 *c_dst++ = pal[*c_src++];
3930 c_src+=(pitch-width);
3934 WARN("No palette set...\n");
3935 memset(dst, 0, width * height * 2);
3938 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3940 unsigned short *pal = (unsigned short *) screen_palette;
3942 for (i = 0; i < count; i++)
3943 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3944 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3945 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3947 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3949 unsigned short *pal = (unsigned short *) screen_palette;
3951 for (i = 0; i < count; i++)
3952 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3953 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3954 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3957 /* *************************************
3958 24 to palettized 8 bpp
3959 ************************************* */
3960 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3961 unsigned char *c_src = (unsigned char *) src;
3962 unsigned char *c_dst = (unsigned char *) dst;
3965 if (palette != NULL) {
3966 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3968 for (y = height; y--; ) {
3969 unsigned char * srclineend = c_src+width;
3970 while (c_src < srclineend ) {
3971 register long pixel = pal[*c_src++];
3973 *c_dst++ = pixel>>8;
3974 *c_dst++ = pixel>>16;
3976 c_src+=(pitch-width);
3979 WARN("No palette set...\n");
3980 memset(dst, 0, width * height * 4);
3983 /* *************************************
3984 32 bpp to palettized 8 bpp
3985 ************************************* */
3986 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3987 unsigned char *c_src = (unsigned char *) src;
3988 unsigned int *c_dst = (unsigned int *) dst;
3991 if (palette != NULL) {
3992 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3994 for (y = height; y--; ) {
3995 #if defined(__i386__) && defined(__GNUC__)
3996 /* See comment in pixel_convert_16_to_8 */
3997 __asm__ __volatile__(
4001 " movl (%%edx,%%eax,4),%%eax\n"
4003 " xor %%eax,%%eax\n"
4005 : "=S" (c_src), "=D" (c_dst)
4006 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
4007 : "eax", "cc", "memory"
4009 c_src+=(pitch-width);
4011 unsigned char * srclineend = c_src+width;
4012 while (c_src < srclineend )
4013 *c_dst++ = pal[*c_src++];
4014 c_src+=(pitch-width);
4018 WARN("No palette set...\n");
4019 memset(dst, 0, width * height * 4);
4023 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4025 unsigned int *pal = (unsigned int *) screen_palette;
4027 for (i = 0; i < count; i++)
4028 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4029 (((unsigned int) palent[i].peGreen) << 8) |
4030 ((unsigned int) palent[i].peBlue));
4033 /* *************************************
4035 ************************************* */
4036 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4037 unsigned short *c_src = (unsigned short *) src;
4038 unsigned int *c_dst = (unsigned int *) dst;
4041 for (y = height; y--; ) {
4042 unsigned short * srclineend = c_src+width;
4043 while (c_src < srclineend ) {
4044 *c_dst++ = (((*c_src & 0xF800) << 8) |
4045 ((*c_src & 0x07E0) << 5) |
4046 ((*c_src & 0x001F) << 3));
4049 c_src+=((pitch/2)-width);
4054 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4055 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4057 ICOM_THIS(IDirectDrawImpl,iface);
4062 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4063 This, width, height, depth);
4065 switch ((c = _common_depth_to_pixelformat(depth,
4066 &(This->d.directdraw_pixelformat),
4067 &(This->d.screen_pixelformat),
4068 &(This->d.pixmap_depth)))) {
4070 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4071 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4072 return DDERR_UNSUPPORTEDMODE;
4076 This->d.pixel_convert = NULL;
4077 This->d.palette_convert = NULL;
4081 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4083 /* Set the depth convertion routines */
4084 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4085 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4088 This->d.width = width;
4089 This->d.height = height;
4091 _common_IDirectDrawImpl_SetDisplayMode(This);
4093 tmpWnd = WIN_FindWndPtr(This->d.window);
4094 This->d.paintable = 1;
4095 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4096 WIN_ReleaseWndPtr(tmpWnd);
4098 /* We don't have a context for this window. Host off the desktop */
4099 if( !This->d.drawable )
4101 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4102 WIN_ReleaseDesktop();
4104 TRACE("Setting drawable to %ld\n", This->d.drawable);
4106 if (Options.DXGrab) {
4107 /* Confine cursor movement (risky, but the user asked for it) */
4108 TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
4114 #ifdef HAVE_LIBXXF86DGA
4115 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4116 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4118 ICOM_THIS(IDirectDraw2Impl,iface);
4119 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4120 if (!caps1 && !caps2)
4121 return DDERR_INVALIDPARAMS;
4123 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4124 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4125 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4128 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4129 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4130 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4134 #endif /* defined(HAVE_LIBXXF86DGA) */
4136 static void fill_caps(LPDDCAPS caps) {
4137 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4138 Need to be fixed, though.. */
4142 caps->dwSize = sizeof(*caps);
4143 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4144 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4145 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4147 caps->dwFXAlphaCaps = 0;
4148 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4150 caps->dwZBufferBitDepths = DDBD_16;
4151 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4152 to put textures in video memory.
4153 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4155 caps->dwVidMemTotal = 8192 * 1024;
4156 caps->dwVidMemFree = 8192 * 1024;
4157 /* These are all the supported capabilities of the surfaces */
4158 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4159 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4160 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4161 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4163 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4164 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4165 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4169 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4170 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4172 ICOM_THIS(IDirectDraw2Impl,iface);
4173 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4175 /* Put the same caps for the two capabilities */
4182 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4183 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4185 ICOM_THIS(IDirectDraw2Impl,iface);
4186 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4187 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4188 This,x,ilpddclip,lpunk
4190 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4191 (*ilpddclip)->ref = 1;
4192 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4196 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4197 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4201 if (TRACE_ON(ddraw))
4202 _dump_paletteformat(dwFlags);
4204 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4205 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4206 (*lpddpal)->ref = 1;
4207 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4208 (*lpddpal)->installed = 0;
4210 if (dwFlags & DDPCAPS_1BIT)
4212 else if (dwFlags & DDPCAPS_2BIT)
4214 else if (dwFlags & DDPCAPS_4BIT)
4216 else if (dwFlags & DDPCAPS_8BIT)
4219 ERR("unhandled palette format\n");
4224 /* Now, if we are in 'depth conversion mode', create the screen palette */
4225 if (This->d.palette_convert != NULL)
4226 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4228 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4229 } else if (This->d.palette_convert != NULL) {
4230 /* In that case, put all 0xFF */
4231 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4237 #ifdef HAVE_LIBXXF86DGA
4238 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4239 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4241 ICOM_THIS(IDirectDraw2Impl,iface);
4242 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4246 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4247 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4248 if (res != 0) return res;
4249 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4250 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4251 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4253 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4254 (*ilpddpal)->cm = 0;
4256 if (((*ilpddpal)->cm)&&xsize) {
4257 for (i=0;i<xsize;i++) {
4260 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4261 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4262 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4263 xc.flags = DoRed|DoBlue|DoGreen;
4265 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4270 #endif /* defined(HAVE_LIBXXF86DGA) */
4272 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4273 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4275 ICOM_THIS(IDirectDraw2Impl,iface);
4276 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4280 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4281 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4282 if (res != 0) return res;
4283 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4287 #ifdef HAVE_LIBXXF86DGA
4288 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4289 ICOM_THIS(IDirectDraw2Impl,iface);
4290 TRACE("(%p)->()\n",This);
4292 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4293 #ifdef RESTORE_SIGNALS
4298 #endif /* defined(HAVE_LIBXXF86DGA) */
4300 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4301 ICOM_THIS(IDirectDraw2Impl,iface);
4302 TRACE("(%p)->RestoreDisplayMode()\n", This);
4307 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4308 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4310 ICOM_THIS(IDirectDraw2Impl,iface);
4311 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4315 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4316 ICOM_THIS(IDirectDraw2Impl,iface);
4317 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4319 return ++(This->ref);
4322 #ifdef HAVE_LIBXXF86DGA
4323 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4324 ICOM_THIS(IDirectDraw2Impl,iface);
4325 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4327 if (!--(This->ref)) {
4328 #ifdef HAVE_LIBXXF86DGA2
4329 if (This->e.dga.version == 2) {
4330 TRACE("Closing access to the FrameBuffer\n");
4331 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4332 TRACE("Going back to normal X mode of operation\n");
4333 TSXDGASetMode(display, DefaultScreen(display), 0);
4335 /* Set the input handling back to absolute */
4336 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4338 /* Remove the handling of DGA2 events */
4339 X11DRV_EVENT_SetDGAStatus(0, -1);
4341 /* Free the modes list */
4342 TSXFree(This->e.dga.modes);
4344 #endif /* defined(HAVE_LIBXXF86DGA2) */
4345 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4346 if (This->d.window && (This->d.mainWindow != This->d.window))
4347 DestroyWindow(This->d.window);
4348 #ifdef HAVE_LIBXXF86VM
4350 TSXF86VidModeSwitchToMode(
4352 DefaultScreen(display),
4354 if (orig_mode->privsize)
4355 TSXFree(orig_mode->private);
4361 #ifdef RESTORE_SIGNALS
4364 HeapFree(GetProcessHeap(),0,This);
4369 #endif /* defined(HAVE_LIBXXF86DGA) */
4371 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4372 ICOM_THIS(IDirectDraw2Impl,iface);
4373 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4375 if (!--(This->ref)) {
4376 if (This->d.window && (This->d.mainWindow != This->d.window))
4377 DestroyWindow(This->d.window);
4378 HeapFree(GetProcessHeap(),0,This);
4381 /* FIXME: destroy window ... */
4385 #ifdef HAVE_LIBXXF86DGA
4386 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4387 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4389 ICOM_THIS(IDirectDraw2Impl,iface);
4391 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4392 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4394 IDirectDraw2_AddRef(iface);
4396 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4400 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4401 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4402 IDirectDraw2_AddRef(iface);
4405 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4409 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4410 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4411 IDirectDraw2_AddRef(iface);
4414 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4418 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4419 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4420 IDirectDraw2_AddRef(iface);
4423 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4427 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4430 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4432 d3d->ddraw = (IDirectDrawImpl*)This;
4433 IDirectDraw2_AddRef(iface);
4434 ICOM_VTBL(d3d) = &d3dvt;
4437 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4441 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4442 IDirect3D2Impl* d3d;
4444 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4446 d3d->ddraw = (IDirectDrawImpl*)This;
4447 IDirectDraw2_AddRef(iface);
4448 ICOM_VTBL(d3d) = &d3d2vt;
4451 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4455 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4456 return OLE_E_ENUM_NOMORE;
4458 #endif /* defined(HAVE_LIBXXF86DGA) */
4460 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4461 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4463 ICOM_THIS(IDirectDraw2Impl,iface);
4465 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4466 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4468 IDirectDraw2_AddRef(iface);
4470 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4474 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4475 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4476 IDirectDraw2_AddRef(iface);
4479 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4483 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4484 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4485 IDirectDraw2_AddRef(iface);
4488 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4492 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4493 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4494 IDirectDraw2_AddRef(iface);
4497 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4501 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4504 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4506 d3d->ddraw = (IDirectDrawImpl*)This;
4507 IDirectDraw2_AddRef(iface);
4508 ICOM_VTBL(d3d) = &d3dvt;
4511 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4515 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4516 IDirect3D2Impl* d3d;
4518 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4520 d3d->ddraw = (IDirectDrawImpl*)This;
4521 IDirectDraw2_AddRef(iface);
4522 ICOM_VTBL(d3d) = &d3d2vt;
4525 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4529 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4530 return OLE_E_ENUM_NOMORE;
4533 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4534 LPDIRECTDRAW2 iface,BOOL *status
4536 ICOM_THIS(IDirectDraw2Impl,iface);
4537 TRACE("(%p)->(%p)\n",This,status);
4542 #ifdef HAVE_LIBXXF86DGA
4543 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4544 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4546 ICOM_THIS(IDirectDraw2Impl,iface);
4547 DDSURFACEDESC ddsfd;
4550 } modes[5] = { /* some of the usual modes */
4557 static int depths[4] = {8,16,24,32};
4560 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4561 ddsfd.dwSize = sizeof(ddsfd);
4562 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4563 if (dwFlags & DDEDM_REFRESHRATES) {
4564 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4565 ddsfd.u.dwRefreshRate = 60;
4567 ddsfd.ddsCaps.dwCaps = 0;
4568 ddsfd.dwBackBufferCount = 1;
4570 #ifdef HAVE_LIBXXF86DGA2
4571 if (This->e.dga.version == 2) {
4572 XDGAMode *modes = This->e.dga.modes;
4574 ddsfd.dwFlags |= DDSD_PITCH;
4575 for (i = 0; i < This->e.dga.num_modes; i++) {
4576 if (TRACE_ON(ddraw)) {
4577 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4579 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4580 modes[i].viewportWidth, modes[i].viewportHeight,
4582 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4583 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4584 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4585 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4586 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4589 /* Fill the pixel format */
4590 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4591 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4592 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4593 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4594 if (modes[i].depth == 8) {
4595 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4596 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4597 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4598 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4599 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4601 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4602 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4603 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4604 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4607 ddsfd.dwWidth = modes[i].viewportWidth;
4608 ddsfd.dwHeight = modes[i].viewportHeight;
4609 ddsfd.lPitch = modes[i].imageWidth;
4611 /* Send mode to the application */
4612 if (!modescb(&ddsfd,context)) return DD_OK;
4616 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4617 ddsfd.dwBackBufferCount = 1;
4618 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4619 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4620 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4621 /* FIXME: those masks would have to be set in depth > 8 */
4623 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4624 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4625 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4626 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4627 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4628 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4630 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4632 /* FIXME: We should query those from X itself */
4633 switch (depths[i]) {
4635 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4636 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4637 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4640 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4641 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4642 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4645 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4646 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4647 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4652 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4653 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4654 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4655 if (!modescb(&ddsfd,context)) return DD_OK;
4657 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4658 ddsfd.dwWidth = modes[j].w;
4659 ddsfd.dwHeight = modes[j].h;
4660 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4661 if (!modescb(&ddsfd,context)) return DD_OK;
4664 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4665 /* modeX is not standard VGA */
4667 ddsfd.dwHeight = 200;
4668 ddsfd.dwWidth = 320;
4669 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4670 if (!modescb(&ddsfd,context)) return DD_OK;
4673 #ifdef HAVE_LIBXXF86DGA2
4678 #endif /* defined(HAVE_LIBXXF86DGA) */
4680 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4681 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4683 ICOM_THIS(IDirectDraw2Impl,iface);
4685 XPixmapFormatValues *pf;
4687 int xbpp, nvisuals, npixmap, i, emu;
4688 int has_mode[] = { 0, 0, 0, 0 };
4689 int has_depth[] = { 8, 15, 16, 24 };
4690 DDSURFACEDESC ddsfd;
4693 } modes[] = { /* some of the usual modes */
4701 DWORD maxWidth, maxHeight;
4703 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4704 ddsfd.dwSize = sizeof(ddsfd);
4705 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
4706 if (dwFlags & DDEDM_REFRESHRATES) {
4707 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4708 ddsfd.u.dwRefreshRate = 60;
4710 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4711 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4713 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4714 pf = XListPixmapFormats(display, &npixmap);
4718 while ((i < npixmap) || (emu != 4)) {
4724 for (j = 0; j < 4; j++) {
4725 if (has_depth[j] == pf[i].depth) {
4736 if (has_mode[mode_index] == 0) {
4737 if (mode_index == 0) {
4740 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4741 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4742 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4743 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4744 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4745 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4746 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4747 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4748 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4752 has_mode[mode_index] = 1;
4754 /* All the 'true color' depths (15, 16 and 24)
4755 First, find the corresponding visual to extract the bit masks */
4756 for (j = 0; j < nvisuals; j++) {
4757 if (vi[j].depth == pf[i].depth) {
4758 ddsfd.ddsCaps.dwCaps = 0;
4759 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4760 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4761 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4762 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4763 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4764 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4765 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4766 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4768 xbpp = pf[i].bits_per_pixel/8;
4771 has_mode[mode_index] = 1;
4776 ERR("Did not find visual corresponding the the pixmap format !\n");
4781 /* Now to emulated modes */
4782 if (has_mode[emu] == 0) {
4785 int depth = has_depth[emu];
4787 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4788 if (ModeEmulations[c].dest.depth == depth) {
4789 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4790 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4791 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4792 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4794 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4795 if ((vi[j].depth == pf[l].depth) &&
4796 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4797 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4798 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4799 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4800 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4802 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4803 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4804 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4805 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4806 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4808 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4809 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4810 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4811 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4812 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4814 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4819 ERR("No visual corresponding to pixmap format !\n");
4833 if (TRACE_ON(ddraw)) {
4834 TRACE("Enumerating with pixel format : \n");
4835 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4839 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4840 /* Do not enumerate modes we cannot handle anyway */
4841 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4844 ddsfd.dwWidth = modes[mode].w;
4845 ddsfd.dwHeight= modes[mode].h;
4846 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4848 /* Now, send the mode description to the application */
4849 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4850 if (!modescb(&ddsfd, context))
4854 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4855 /* modeX is not standard VGA */
4856 ddsfd.dwWidth = 320;
4857 ddsfd.dwHeight = 200;
4858 ddsfd.lPitch = 320 * xbpp;
4859 if (!modescb(&ddsfd, context))
4871 #ifdef HAVE_LIBXXF86DGA
4872 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4873 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4875 ICOM_THIS(IDirectDraw2Impl,iface);
4876 TRACE("(%p)->(%p)\n",This,lpddsfd);
4877 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4878 lpddsfd->dwHeight = This->d.height;
4879 lpddsfd->dwWidth = This->d.width;
4880 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4881 lpddsfd->dwBackBufferCount = 1;
4882 lpddsfd->u.dwRefreshRate = 60;
4883 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4884 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4885 if (TRACE_ON(ddraw)) {
4886 _dump_surface_desc(lpddsfd);
4890 #endif /* defined(HAVE_LIBXXF86DGA) */
4892 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4893 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4895 ICOM_THIS(IDirectDraw2Impl,iface);
4896 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4897 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4898 lpddsfd->dwHeight = This->d.height;
4899 lpddsfd->dwWidth = This->d.width;
4900 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4901 lpddsfd->dwBackBufferCount = 1;
4902 lpddsfd->u.dwRefreshRate = 60;
4903 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4904 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4905 if (TRACE_ON(ddraw)) {
4906 _dump_surface_desc(lpddsfd);
4911 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4912 ICOM_THIS(IDirectDraw2Impl,iface);
4913 TRACE("(%p)->()\n",This);
4917 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4918 LPDIRECTDRAW2 iface,LPDWORD freq
4920 ICOM_THIS(IDirectDraw2Impl,iface);
4921 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4922 *freq = 60*100; /* 60 Hz */
4926 /* what can we directly decompress? */
4927 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4928 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4930 ICOM_THIS(IDirectDraw2Impl,iface);
4931 FIXME("(%p,%p,%p), stub\n",This,x,y);
4935 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4936 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4938 ICOM_THIS(IDirectDraw2Impl,iface);
4939 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4943 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4944 LPDIRECTDRAW2 iface )
4946 ICOM_THIS(IDirectDraw2Impl,iface);
4947 FIXME("(%p)->()\n", This );
4952 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4953 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4954 ICOM_THIS(IDirectDraw2Impl,iface);
4955 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4960 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4961 LPDWORD lpdwScanLine) {
4962 ICOM_THIS(IDirectDraw2Impl,iface);
4963 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4970 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4972 ICOM_THIS(IDirectDraw2Impl,iface);
4973 FIXME("(%p)->(%p)\n", This, lpGUID);
4978 #ifdef HAVE_LIBXXF86DGA
4980 /* Note: Hack so we can reuse the old functions without compiler warnings */
4981 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4982 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4984 # define XCAST(fun) (void *)
4987 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4989 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4990 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4991 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4992 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4993 XCAST(Compact)IDirectDraw2Impl_Compact,
4994 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4995 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4996 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4997 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4998 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4999 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5000 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5001 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5002 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5003 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5004 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5005 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5006 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5007 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5008 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5009 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5010 #ifdef HAVE_LIBXXF86DGA2
5011 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
5013 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5015 DGA_IDirectDrawImpl_SetDisplayMode,
5016 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5021 #endif /* defined(HAVE_LIBXXF86DGA) */
5023 /* Note: Hack so we can reuse the old functions without compiler warnings */
5024 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5025 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5027 # define XCAST(fun) (void *)
5030 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5032 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5033 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5034 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5035 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5036 XCAST(Compact)IDirectDraw2Impl_Compact,
5037 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5038 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5039 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5040 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5041 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5042 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5043 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5044 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5045 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5046 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5047 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5048 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5049 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5050 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5051 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5052 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5053 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5054 Xlib_IDirectDrawImpl_SetDisplayMode,
5055 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5060 /*****************************************************************************
5065 #ifdef HAVE_LIBXXF86DGA
5066 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5067 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5069 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5070 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5072 #endif /* defined(HAVE_LIBXXF86DGA) */
5074 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5075 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5077 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5078 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5081 #ifdef HAVE_LIBXXF86DGA
5082 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5083 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5085 ICOM_THIS(IDirectDraw2Impl,iface);
5086 TRACE("(%p)->(%p,%p,%p)\n",
5087 This,ddscaps,total,free
5089 if (total) *total = This->e.dga.fb_memsize * 1024;
5090 if (free) *free = This->e.dga.fb_memsize * 1024;
5093 #endif /* defined(HAVE_LIBXXF86DGA) */
5095 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5096 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5098 ICOM_THIS(IDirectDraw2Impl,iface);
5099 TRACE("(%p)->(%p,%p,%p)\n",
5100 This,ddscaps,total,free
5102 if (total) *total = 2048 * 1024;
5103 if (free) *free = 2048 * 1024;
5107 #ifdef HAVE_LIBXXF86DGA
5108 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5110 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5111 DGA_IDirectDraw2Impl_QueryInterface,
5112 IDirectDraw2Impl_AddRef,
5113 DGA_IDirectDraw2Impl_Release,
5114 IDirectDraw2Impl_Compact,
5115 IDirectDraw2Impl_CreateClipper,
5116 DGA_IDirectDraw2Impl_CreatePalette,
5117 DGA_IDirectDraw2Impl_CreateSurface,
5118 IDirectDraw2Impl_DuplicateSurface,
5119 DGA_IDirectDraw2Impl_EnumDisplayModes,
5120 IDirectDraw2Impl_EnumSurfaces,
5121 IDirectDraw2Impl_FlipToGDISurface,
5122 DGA_IDirectDraw2Impl_GetCaps,
5123 DGA_IDirectDraw2Impl_GetDisplayMode,
5124 IDirectDraw2Impl_GetFourCCCodes,
5125 IDirectDraw2Impl_GetGDISurface,
5126 IDirectDraw2Impl_GetMonitorFrequency,
5127 IDirectDraw2Impl_GetScanLine,
5128 IDirectDraw2Impl_GetVerticalBlankStatus,
5129 IDirectDraw2Impl_Initialize,
5130 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5131 IDirectDraw2Impl_SetCooperativeLevel,
5132 DGA_IDirectDraw2Impl_SetDisplayMode,
5133 IDirectDraw2Impl_WaitForVerticalBlank,
5134 DGA_IDirectDraw2Impl_GetAvailableVidMem
5136 #endif /* defined(HAVE_LIBXXF86DGA) */
5138 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5140 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5141 Xlib_IDirectDraw2Impl_QueryInterface,
5142 IDirectDraw2Impl_AddRef,
5143 Xlib_IDirectDraw2Impl_Release,
5144 IDirectDraw2Impl_Compact,
5145 IDirectDraw2Impl_CreateClipper,
5146 Xlib_IDirectDraw2Impl_CreatePalette,
5147 Xlib_IDirectDraw2Impl_CreateSurface,
5148 IDirectDraw2Impl_DuplicateSurface,
5149 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5150 IDirectDraw2Impl_EnumSurfaces,
5151 IDirectDraw2Impl_FlipToGDISurface,
5152 Xlib_IDirectDraw2Impl_GetCaps,
5153 Xlib_IDirectDraw2Impl_GetDisplayMode,
5154 IDirectDraw2Impl_GetFourCCCodes,
5155 IDirectDraw2Impl_GetGDISurface,
5156 IDirectDraw2Impl_GetMonitorFrequency,
5157 IDirectDraw2Impl_GetScanLine,
5158 IDirectDraw2Impl_GetVerticalBlankStatus,
5159 IDirectDraw2Impl_Initialize,
5160 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5161 IDirectDraw2Impl_SetCooperativeLevel,
5162 Xlib_IDirectDraw2Impl_SetDisplayMode,
5163 IDirectDraw2Impl_WaitForVerticalBlank,
5164 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5167 /*****************************************************************************
5172 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5174 LPDIRECTDRAWSURFACE *lpDDS) {
5175 ICOM_THIS(IDirectDraw4Impl,iface);
5176 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5181 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5182 ICOM_THIS(IDirectDraw4Impl,iface);
5183 FIXME("(%p)->()\n", This);
5188 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5189 ICOM_THIS(IDirectDraw4Impl,iface);
5190 FIXME("(%p)->()\n", This);
5195 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5196 LPDDDEVICEIDENTIFIER lpdddi,
5198 ICOM_THIS(IDirectDraw4Impl,iface);
5199 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5204 #ifdef HAVE_LIBXXF86DGA
5206 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5207 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5209 # define XCAST(fun) (void*)
5212 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5214 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5215 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5216 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5217 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5218 XCAST(Compact)IDirectDraw2Impl_Compact,
5219 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5220 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5221 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5222 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5223 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5224 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5225 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5226 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5227 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5228 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5229 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5230 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5231 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5232 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5233 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5234 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5235 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5236 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5237 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5238 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5239 IDirectDraw4Impl_GetSurfaceFromDC,
5240 IDirectDraw4Impl_RestoreAllSurfaces,
5241 IDirectDraw4Impl_TestCooperativeLevel,
5242 IDirectDraw4Impl_GetDeviceIdentifier
5247 #endif /* defined(HAVE_LIBXXF86DGA) */
5249 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5250 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5252 # define XCAST(fun) (void*)
5255 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5257 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5258 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5259 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5260 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5261 XCAST(Compact)IDirectDraw2Impl_Compact,
5262 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5263 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5264 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5265 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5266 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5267 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5268 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5269 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5270 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5271 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5272 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5273 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5274 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5275 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5276 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5277 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5278 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5279 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5280 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5281 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5282 IDirectDraw4Impl_GetSurfaceFromDC,
5283 IDirectDraw4Impl_RestoreAllSurfaces,
5284 IDirectDraw4Impl_TestCooperativeLevel,
5285 IDirectDraw4Impl_GetDeviceIdentifier
5290 /******************************************************************************
5294 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5297 IDirectDrawImpl* ddraw = NULL;
5300 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5302 SetLastError( ERROR_SUCCESS );
5303 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
5305 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
5308 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5313 /* Perform any special direct draw functions */
5315 ddraw->d.paintable = 1;
5317 /* Now let the application deal with the rest of this */
5318 if( ddraw->d.mainWindow )
5321 /* Don't think that we actually need to call this but...
5322 might as well be on the safe side of things... */
5324 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5325 it should be the procedures of our fake window that gets called
5326 instead of those of the window provided by the application.
5327 And with this patch, mouse clicks work with Monkey Island III
5329 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5333 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5334 /* We didn't handle the message - give it to the application */
5335 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5337 ret = CallWindowProcA(tmpWnd->winproc,
5338 ddraw->d.mainWindow, msg, wParam, lParam );
5340 WIN_ReleaseWndPtr(tmpWnd);
5345 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5351 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5357 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5358 #ifdef HAVE_LIBXXF86DGA
5359 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5360 int memsize,banksize,major,minor,flags;
5366 /* Get DGA availability / version */
5367 dga_version = DDRAW_DGA_Available();
5369 if (dga_version == 0) {
5370 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5371 return DDERR_GENERIC;
5374 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5375 (*ilplpDD)->ref = 1;
5376 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5377 #ifdef HAVE_LIBXXF86DGA2
5378 if (dga_version == 1) {
5379 (*ilplpDD)->e.dga.version = 1;
5380 #endif /* defined(HAVE_LIBXXF86DGA2) */
5381 TSXF86DGAQueryVersion(display,&major,&minor);
5382 TRACE("XF86DGA is version %d.%d\n",major,minor);
5383 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5384 if (!(flags & XF86DGADirectPresent))
5385 MESSAGE("direct video is NOT PRESENT.\n");
5386 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5387 (*ilplpDD)->e.dga.fb_width = width;
5388 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5389 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5390 (*ilplpDD)->e.dga.fb_height = height;
5391 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5392 addr,width,banksize,memsize
5394 TRACE("viewport height: %d\n",height);
5395 /* Get the screen dimensions as seen by Wine.
5396 In that case, it may be better to ignore the -desktop mode and return the
5397 real screen size => print a warning */
5398 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5399 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5400 if (((*ilplpDD)->d.height != height) ||
5401 ((*ilplpDD)->d.width != width))
5402 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5403 (*ilplpDD)->e.dga.fb_addr = addr;
5404 (*ilplpDD)->e.dga.fb_memsize = memsize;
5405 (*ilplpDD)->e.dga.vpmask = 0;
5407 /* just assume the default depth is the DGA depth too */
5408 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5409 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5410 #ifdef RESTORE_SIGNALS
5413 #ifdef HAVE_LIBXXF86DGA2
5417 int mode_to_use = 0;
5419 (*ilplpDD)->e.dga.version = 2;
5421 TSXDGAQueryVersion(display,&major,&minor);
5422 TRACE("XDGA is version %d.%d\n",major,minor);
5424 TRACE("Opening the frame buffer.\n");
5425 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5426 ERR("Error opening the frame buffer !!!\n");
5428 return DDERR_GENERIC;
5431 /* List all available modes */
5432 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5433 (*ilplpDD)->e.dga.modes = modes;
5434 (*ilplpDD)->e.dga.num_modes = num_modes;
5435 if (TRACE_ON(ddraw)) {
5436 TRACE("Available modes :\n");
5437 for (i = 0; i < num_modes; i++) {
5438 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5440 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5441 modes[i].viewportWidth, modes[i].viewportHeight,
5443 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5444 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5445 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5446 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5447 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5450 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5451 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5452 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5453 mode_to_use = modes[i].num;
5457 if (mode_to_use == 0) {
5458 ERR("Could not find mode !\n");
5461 DPRINTF("Using mode number %d\n", mode_to_use);
5464 /* Initialize the frame buffer */
5465 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5466 /* Set the input handling for relative mouse movements */
5467 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5469 #endif /* defined(HAVE_LIBXXF86DGA2) */
5471 #else /* defined(HAVE_LIBXXF86DGA) */
5472 return DDERR_INVALIDDIRECTDRAWGUID;
5473 #endif /* defined(HAVE_LIBXXF86DGA) */
5477 DDRAW_XSHM_Available(void)
5479 #ifdef HAVE_LIBXXSHM
5480 if (TSXShmQueryExtension(display))
5485 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5486 (Options.noXSHM != 1))
5498 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5499 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5502 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5503 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5504 (*ilplpDD)->ref = 1;
5505 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5507 /* At DirectDraw creation, the depth is the default depth */
5508 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5509 _common_depth_to_pixelformat(depth,
5510 &((*ilplpDD)->d.directdraw_pixelformat),
5511 &((*ilplpDD)->d.screen_pixelformat),
5512 &((*ilplpDD)->d.pixmap_depth));
5513 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5514 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5516 #ifdef HAVE_LIBXXSHM
5517 /* Test if XShm is available. */
5518 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5519 (*ilplpDD)->e.xlib.xshm_compl = 0;
5520 TRACE("Using XShm extension.\n");
5527 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5528 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5530 /* WND* pParentWindow; */
5533 if (!HIWORD(lpGUID)) lpGUID = NULL;
5535 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
5538 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5539 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5540 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5541 /* if they didn't request a particular interface, use the best
5543 if (DDRAW_DGA_Available())
5544 lpGUID = &DGA_DirectDraw_GUID;
5546 lpGUID = &XLIB_DirectDraw_GUID;
5549 wc.style = CS_GLOBALCLASS;
5550 wc.lpfnWndProc = Xlib_DDWndProc;
5552 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5553 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5555 /* We can be a child of the desktop since we're really important */
5557 This code is not useful since hInstance is forced to 0 afterward
5558 pParentWindow = WIN_GetDesktop();
5559 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5565 wc.hCursor = (HCURSOR)IDC_ARROWA;
5566 wc.hbrBackground= NULL_BRUSH;
5567 wc.lpszMenuName = 0;
5568 wc.lpszClassName= "WINE_DirectDraw";
5569 RegisterClassA(&wc);
5571 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5572 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5574 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5575 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5582 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5586 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
5587 debugstr_guid(lpGUID),lplpDD,pUnkOuter);
5588 return DDERR_INVALIDDIRECTDRAWGUID;
5591 /*******************************************************************************
5592 * DirectDraw ClassFactory
5594 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5599 /* IUnknown fields */
5600 ICOM_VFIELD(IClassFactory);
5602 } IClassFactoryImpl;
5604 static HRESULT WINAPI
5605 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5606 ICOM_THIS(IClassFactoryImpl,iface);
5608 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
5609 return E_NOINTERFACE;
5613 DDCF_AddRef(LPCLASSFACTORY iface) {
5614 ICOM_THIS(IClassFactoryImpl,iface);
5615 return ++(This->ref);
5618 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5619 ICOM_THIS(IClassFactoryImpl,iface);
5620 /* static class, won't be freed */
5621 return --(This->ref);
5624 static HRESULT WINAPI DDCF_CreateInstance(
5625 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5627 ICOM_THIS(IClassFactoryImpl,iface);
5629 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
5630 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5631 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5632 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5633 /* FIXME: reuse already created DirectDraw if present? */
5634 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5636 return CLASS_E_CLASSNOTAVAILABLE;
5639 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5640 ICOM_THIS(IClassFactoryImpl,iface);
5641 FIXME("(%p)->(%d),stub!\n",This,dolock);
5645 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5647 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5648 DDCF_QueryInterface,
5651 DDCF_CreateInstance,
5654 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5656 /*******************************************************************************
5657 * DllGetClassObject [DDRAW.13]
5658 * Retrieves class object from a DLL object
5661 * Docs say returns STDAPI
5664 * rclsid [I] CLSID for the class object
5665 * riid [I] Reference to identifier of interface for class object
5666 * ppv [O] Address of variable to receive interface pointer for riid
5670 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5673 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5675 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5676 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5677 *ppv = (LPVOID)&DDRAW_CF;
5678 IClassFactory_AddRef((IClassFactory*)*ppv);
5681 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5682 return CLASS_E_CLASSNOTAVAILABLE;
5686 /*******************************************************************************
5687 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5693 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5695 FIXME("(void): stub\n");
5699 #else /* !defined(X_DISPLAY_MISSING) */
5706 typedef void *LPUNKNOWN;
5707 typedef void *LPDIRECTDRAW;
5708 typedef void *LPDIRECTDRAWCLIPPER;
5709 typedef void *LPDDENUMCALLBACKA;
5710 typedef void *LPDDENUMCALLBACKEXA;
5711 typedef void *LPDDENUMCALLBACKEXW;
5712 typedef void *LPDDENUMCALLBACKW;
5714 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5719 HRESULT WINAPI DirectDrawCreate(
5720 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5725 HRESULT WINAPI DirectDrawCreateClipper(
5726 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5731 HRESULT WINAPI DirectDrawEnumerateA(
5732 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5737 HRESULT WINAPI DirectDrawEnumerateExA(
5738 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5743 HRESULT WINAPI DirectDrawEnumerateExW(
5744 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5749 HRESULT WINAPI DirectDrawEnumerateW(
5750 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5755 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5757 return CLASS_E_CLASSNOTAVAILABLE;
5760 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5765 #endif /* !defined(X_DISPLAY_MISSING) */