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);
743 #ifdef HAVE_LIBXXF86DGA
744 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
745 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
747 ICOM_THIS(IDirectDrawSurface4Impl,iface);
748 TRACE("(%p)->Unlock(%p)\n",This,surface);
751 #endif /* defined(HAVE_LIBXXF86DGA) */
753 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
754 if (This->s.ddraw->d.pixel_convert != NULL)
755 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
756 This->t.xlib.image->data,
757 This->s.surface_desc.dwWidth,
758 This->s.surface_desc.dwHeight,
759 This->s.surface_desc.lPitch,
763 if (This->s.ddraw->e.xlib.xshm_active) {
764 int compl = This->s.ddraw->e.xlib.xshm_compl;
766 X11DRV_EVENT_WaitShmCompletion( compl );
767 This->s.ddraw->e.xlib.xshm_compl = X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
768 TSXShmPutImage(display,
769 This->s.ddraw->d.drawable,
770 DefaultGCOfScreen(X11DRV_GetXScreen()),
773 This->t.xlib.image->width,
774 This->t.xlib.image->height,
779 TSXPutImage( display,
780 This->s.ddraw->d.drawable,
781 DefaultGCOfScreen(X11DRV_GetXScreen()),
784 This->t.xlib.image->width,
785 This->t.xlib.image->height);
788 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
789 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
791 ICOM_THIS(IDirectDrawSurface4Impl,iface);
792 TRACE("(%p)->Unlock(%p)\n",This,surface);
794 if (!This->s.ddraw->d.paintable)
797 /* Only redraw the screen when unlocking the buffer that is on screen */
798 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
799 Xlib_copy_surface_on_screen(This);
801 if (This->s.palette && This->s.palette->cm)
802 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
807 static IDirectDrawSurface4Impl* _common_find_flipto(
808 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
811 struct _surface_chain *chain = This->s.chain;
813 /* if there was no override flipto, look for current backbuffer */
815 /* walk the flip chain looking for backbuffer */
816 for (i=0;i<chain->nrofsurfaces;i++) {
817 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
819 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
820 flipto = chain->surfaces[i];
822 /* sanity checks ... */
825 for (i=0;i<chain->nrofsurfaces;i++)
826 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
828 if (i==chain->nrofsurfaces) {
829 /* we do not have a frontbuffer either */
830 for (i=0;i<chain->nrofsurfaces;i++)
831 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
832 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
835 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
836 int k = j % chain->nrofsurfaces;
837 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
838 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
839 flipto = chain->surfaces[k];
848 TRACE("flipping to %p\n",flipto);
853 #ifdef HAVE_LIBXXF86DGA
854 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
855 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
857 ICOM_THIS(IDirectDrawSurface4Impl,iface);
858 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
862 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
863 iflipto = _common_find_flipto(This,iflipto);
866 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
867 if (iflipto->s.palette && iflipto->s.palette->cm)
868 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
869 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
872 /* We need to switch the lowlevel surfaces, for DGA this is: */
874 /* The height within the framebuffer */
875 xheight = This->t.dga.fb_height;
876 This->t.dga.fb_height = iflipto->t.dga.fb_height;
877 iflipto->t.dga.fb_height = xheight;
879 /* And the assciated surface pointer */
880 surf = This->s.surface_desc.u1.lpSurface;
881 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
882 iflipto->s.surface_desc.u1.lpSurface = surf;
886 #endif /* defined(HAVE_LIBXXF86DGA) */
888 #ifdef HAVE_LIBXXF86DGA2
889 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
890 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
892 ICOM_THIS(IDirectDrawSurface4Impl,iface);
893 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
897 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
898 iflipto = _common_find_flipto(This,iflipto);
901 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
902 TSXDGASync(display,DefaultScreen(display));
904 if (iflipto->s.palette && iflipto->s.palette->cm)
905 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
906 /* We need to switch the lowlevel surfaces, for DGA this is: */
908 /* The height within the framebuffer */
909 xheight = This->t.dga.fb_height;
910 This->t.dga.fb_height = iflipto->t.dga.fb_height;
911 iflipto->t.dga.fb_height = xheight;
913 /* And the assciated surface pointer */
914 surf = This->s.surface_desc.u1.lpSurface;
915 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
916 iflipto->s.surface_desc.u1.lpSurface = surf;
920 #endif /* defined(HAVE_LIBXXF86DGA2) */
922 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
923 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
925 ICOM_THIS(IDirectDrawSurface4Impl,iface);
928 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
930 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
931 iflipto = _common_find_flipto(This,iflipto);
933 #if defined(HAVE_MESAGL) && 0 /* does not work */
934 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
935 TRACE(" - OpenGL flip\n");
937 glXSwapBuffers(display, This->s.ddraw->d.drawable);
942 #endif /* defined(HAVE_MESAGL) */
944 if (!This->s.ddraw->d.paintable)
947 /* We need to switch the lowlevel surfaces, for xlib this is: */
948 /* The surface pointer */
949 surf = This->s.surface_desc.u1.lpSurface;
950 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
951 iflipto->s.surface_desc.u1.lpSurface = surf;
952 /* the associated ximage */
953 image = This->t.xlib.image;
954 This->t.xlib.image = iflipto->t.xlib.image;
955 iflipto->t.xlib.image = image;
957 Xlib_copy_surface_on_screen(This);
959 if (iflipto->s.palette && iflipto->s.palette->cm)
960 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
964 /* The IDirectDrawSurface4::SetPalette method attaches the specified
965 * DirectDrawPalette object to a surface. The surface uses this palette for all
966 * subsequent operations. The palette change takes place immediately.
968 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
969 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
971 ICOM_THIS(IDirectDrawSurface4Impl,iface);
972 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
974 TRACE("(%p)->(%p)\n",This,ipal);
977 if( This->s.palette != NULL )
978 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
979 This->s.palette = ipal;
984 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
986 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
987 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
989 if (!Options.managed)
990 TSXInstallColormap(display,ipal->cm);
992 for (i=0;i<256;i++) {
995 xc.red = ipal->palents[i].peRed<<8;
996 xc.blue = ipal->palents[i].peBlue<<8;
997 xc.green = ipal->palents[i].peGreen<<8;
998 xc.flags = DoRed|DoBlue|DoGreen;
1000 TSXStoreColor(display,ipal->cm,&xc);
1002 TSXInstallColormap(display,ipal->cm);
1005 /* According to spec, we are only supposed to
1006 * AddRef if this is not the same palette.
1008 if( This->s.palette != ipal )
1011 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1012 if( This->s.palette != NULL )
1013 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1014 This->s.palette = ipal;
1015 /* Perform the refresh */
1016 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1021 #ifdef HAVE_LIBXXF86DGA
1022 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1023 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1025 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1026 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1027 TRACE("(%p)->(%p)\n",This,ipal);
1029 /* According to spec, we are only supposed to
1030 * AddRef if this is not the same palette.
1032 if( This->s.palette != ipal )
1035 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1036 if( This->s.palette != NULL )
1037 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1038 This->s.palette = ipal;
1039 #ifdef HAVE_LIBXXF86DGA2
1040 if (This->s.ddraw->e.dga.version == 2)
1041 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1043 #endif /* defined(HAVE_LIBXXF86DGA2) */
1044 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1048 #endif /* defined(HAVE_LIBXXF86DGA) */
1050 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1057 #define COLORFILL_ROW(type) { \
1058 type *d = (type *) buf; \
1059 for (x = 0; x < width; x++) \
1060 d[x] = (type) color; \
1065 case 1: COLORFILL_ROW(BYTE)
1066 case 2: COLORFILL_ROW(WORD)
1067 case 4: COLORFILL_ROW(DWORD)
1069 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1070 return DDERR_UNSUPPORTED;
1073 #undef COLORFILL_ROW
1075 /* Now copy first row */
1077 for (y = 1; y < height; y++) {
1079 memcpy(buf, first, width * bpp);
1085 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1086 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1088 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1090 DDSURFACEDESC ddesc,sdesc;
1091 HRESULT ret = DD_OK;
1092 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1096 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1098 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1099 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1101 if (TRACE_ON(ddraw)) {
1102 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1103 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1105 _dump_DDBLT(dwFlags);
1106 if (dwFlags & DDBLT_DDFX) {
1107 TRACE("\tblitfx: ");
1108 _dump_DDBLTFX(lpbltfx->dwDDFX);
1113 if ((rdst->top < 0) ||
1115 (rdst->bottom < 0) ||
1116 (rdst->right < 0)) {
1117 ERR(" Negative values in LPRECT !!!\n");
1120 memcpy(&xdst,rdst,sizeof(xdst));
1123 xdst.bottom = ddesc.dwHeight;
1125 xdst.right = ddesc.dwWidth;
1129 if ((rsrc->top < 0) ||
1131 (rsrc->bottom < 0) ||
1132 (rsrc->right < 0)) {
1133 ERR(" Negative values in LPRECT !!!\n");
1136 memcpy(&xsrc,rsrc,sizeof(xsrc));
1140 xsrc.bottom = sdesc.dwHeight;
1142 xsrc.right = sdesc.dwWidth;
1144 memset(&xsrc,0,sizeof(xsrc));
1148 bpp = GET_BPP(ddesc);
1149 srcheight = xsrc.bottom - xsrc.top;
1150 srcwidth = xsrc.right - xsrc.left;
1151 dstheight = xdst.bottom - xdst.top;
1152 dstwidth = xdst.right - xdst.left;
1153 width = (xdst.right - xdst.left) * bpp;
1154 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1156 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1158 /* First, all the 'source-less' blits */
1159 if (dwFlags & DDBLT_COLORFILL) {
1160 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1161 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1162 dwFlags &= ~DDBLT_COLORFILL;
1165 if (dwFlags & DDBLT_DEPTHFILL) {
1169 /* Clears the screen */
1170 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1171 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1172 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1173 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1174 glClear(GL_DEPTH_BUFFER_BIT);
1177 dwFlags &= ~(DDBLT_DEPTHFILL);
1178 #endif /* defined(HAVE_MESAGL) */
1181 if (dwFlags & DDBLT_ROP) {
1182 /* Catch some degenerate cases here */
1183 switch(lpbltfx->dwROP) {
1185 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1187 case 0xAA0029: /* No-op */
1190 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1193 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1196 dwFlags &= ~DDBLT_ROP;
1199 if (dwFlags & DDBLT_DDROPS) {
1200 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1203 /* Now the 'with source' blits */
1206 int sx, xinc, sy, yinc;
1208 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1209 xinc = (srcwidth << 16) / dstwidth;
1210 yinc = (srcheight << 16) / dstheight;
1214 /* No effects, we can cheat here */
1215 if (dstwidth == srcwidth) {
1216 if (dstheight == srcheight) {
1217 /* No stretching in either direction. This needs to be as fast as possible */
1219 for (y = 0; y < dstheight; y++) {
1220 memcpy(dbuf, sbuf, width);
1221 sbuf += sdesc.lPitch;
1222 dbuf += ddesc.lPitch;
1225 /* Stretching in Y direction only */
1226 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1227 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1228 memcpy(dbuf, sbuf, width);
1229 dbuf += ddesc.lPitch;
1233 /* Stretching in X direction */
1235 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1236 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1238 if ((sy >> 16) == (last_sy >> 16)) {
1239 /* Same as last row - copy already stretched row */
1240 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1243 #define STRETCH_ROW(type) { \
1244 type *s = (type *) sbuf, *d = (type *) dbuf; \
1245 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1246 d[x] = s[sx >> 16]; \
1250 case 1: STRETCH_ROW(BYTE)
1251 case 2: STRETCH_ROW(WORD)
1252 case 4: STRETCH_ROW(DWORD)
1254 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1255 ret = DDERR_UNSUPPORTED;
1263 dbuf += ddesc.lPitch;
1266 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1267 DWORD keylow, keyhigh;
1269 if (dwFlags & DDBLT_KEYSRC) {
1270 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1271 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1273 /* I'm not sure if this is correct */
1274 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1275 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1276 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1280 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1281 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1283 #define COPYROW_COLORKEY(type) { \
1284 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1285 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1286 tmp = s[sx >> 16]; \
1287 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1292 case 1: COPYROW_COLORKEY(BYTE)
1293 case 2: COPYROW_COLORKEY(WORD)
1294 case 4: COPYROW_COLORKEY(DWORD)
1296 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1297 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1298 ret = DDERR_UNSUPPORTED;
1301 dbuf += ddesc.lPitch;
1304 #undef COPYROW_COLORKEY
1306 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1313 if (dwFlags && FIXME_ON(ddraw)) {
1314 FIXME("\tUnsupported flags: ");
1315 _dump_DDBLT(dwFlags);
1319 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1320 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1325 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1326 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1328 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1329 int bpp, w, h, x, y;
1330 DDSURFACEDESC ddesc,sdesc;
1331 HRESULT ret = DD_OK;
1336 if (TRACE_ON(ddraw)) {
1337 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1338 This,dstx,dsty,src,rsrc,trans
1341 if (FIXME_ON(ddraw))
1342 _dump_DDBLTFAST(trans);
1344 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1346 FIXME(" srcrect: NULL\n");
1349 /* We need to lock the surfaces, or we won't get refreshes when done. */
1350 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1351 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1354 WARN("rsrc is NULL!\n");
1356 rsrc->left = rsrc->top = 0;
1357 rsrc->right = sdesc.dwWidth;
1358 rsrc->bottom = sdesc.dwHeight;
1361 bpp = GET_BPP(This->s.surface_desc);
1362 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1363 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1366 h=rsrc->bottom-rsrc->top;
1367 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1368 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1371 w=rsrc->right-rsrc->left;
1372 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1373 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1376 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1377 DWORD keylow, keyhigh;
1378 if (trans & DDBLTFAST_SRCCOLORKEY) {
1379 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1380 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1382 /* I'm not sure if this is correct */
1383 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1384 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1385 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1388 #define COPYBOX_COLORKEY(type) { \
1389 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1390 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1391 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1392 for (y = 0; y < h; y++) { \
1393 for (x = 0; x < w; x++) { \
1395 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1397 (LPBYTE)s += sdesc.lPitch; \
1398 (LPBYTE)d += ddesc.lPitch; \
1404 case 1: COPYBOX_COLORKEY(BYTE)
1405 case 2: COPYBOX_COLORKEY(WORD)
1406 case 4: COPYBOX_COLORKEY(DWORD)
1408 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1409 ret = DDERR_UNSUPPORTED;
1413 #undef COPYBOX_COLORKEY
1416 int width = w * bpp;
1418 for (y = 0; y < h; y++) {
1419 memcpy(dbuf, sbuf, width);
1420 sbuf += sdesc.lPitch;
1421 dbuf += ddesc.lPitch;
1427 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1428 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1432 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1433 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1435 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1436 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1442 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1443 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1445 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1446 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1447 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1451 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1452 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1454 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1455 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1457 /* Simply copy the surface description stored in the object */
1458 *ddsd = This->s.surface_desc;
1460 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1465 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1466 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1467 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1468 return ++(This->ref);
1471 #ifdef HAVE_LIBXXF86DGA
1472 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1473 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1475 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1480 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1481 /* clear out of surface list */
1482 if (This->t.dga.fb_height == -1)
1483 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1485 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1487 /* Free the DIBSection (if any) */
1488 if (This->s.hdc != 0) {
1489 SelectObject(This->s.hdc, This->s.holdbitmap);
1490 DeleteDC(This->s.hdc);
1491 DeleteObject(This->s.DIBsection);
1494 /* Free the clipper if attached to this surface */
1495 if( This->s.lpClipper )
1496 IDirectDrawClipper_Release(This->s.lpClipper);
1498 HeapFree(GetProcessHeap(),0,This);
1501 #endif /* defined(HAVE_LIBXXF86DGA) */
1503 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1504 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1506 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1511 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1513 if (This->t.xlib.image != NULL) {
1514 if (This->s.ddraw->d.pixel_convert != NULL) {
1515 /* In pixel conversion mode, there are 2 buffers to release. */
1516 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1518 #ifdef HAVE_LIBXXSHM
1519 if (This->s.ddraw->e.xlib.xshm_active) {
1520 TSXShmDetach(display, &(This->t.xlib.shminfo));
1521 TSXDestroyImage(This->t.xlib.image);
1522 shmdt(This->t.xlib.shminfo.shmaddr);
1525 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1526 This->t.xlib.image->data = NULL;
1527 TSXDestroyImage(This->t.xlib.image);
1528 #ifdef HAVE_LIBXXSHM
1532 This->t.xlib.image->data = NULL;
1534 #ifdef HAVE_LIBXXSHM
1535 if (This->s.ddraw->e.xlib.xshm_active) {
1536 TSXShmDetach(display, &(This->t.xlib.shminfo));
1537 TSXDestroyImage(This->t.xlib.image);
1538 shmdt(This->t.xlib.shminfo.shmaddr);
1541 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1542 TSXDestroyImage(This->t.xlib.image);
1543 #ifdef HAVE_LIBXXSHM
1547 This->t.xlib.image = 0;
1549 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1552 if (This->s.palette)
1553 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1555 /* Free the DIBSection (if any) */
1556 if (This->s.hdc != 0) {
1557 SelectObject(This->s.hdc, This->s.holdbitmap);
1558 DeleteDC(This->s.hdc);
1559 DeleteObject(This->s.DIBsection);
1562 /* Free the clipper if present */
1563 if( This->s.lpClipper )
1564 IDirectDrawClipper_Release(This->lpClipper);
1566 HeapFree(GetProcessHeap(),0,This);
1570 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1571 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1573 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1574 int i,found = 0,xstart;
1575 struct _surface_chain *chain;
1577 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1578 if (TRACE_ON(ddraw)) {
1579 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1582 chain = This->s.chain;
1584 return DDERR_NOTFOUND;
1586 for (i=0;i<chain->nrofsurfaces;i++)
1587 if (chain->surfaces[i] == This)
1591 for (i=0;i<chain->nrofsurfaces;i++) {
1592 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1594 if (found) /* may not find the same caps twice, (doc) */
1595 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1597 found = (i+1)+xstart;
1601 return DDERR_NOTFOUND;
1602 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1603 /* FIXME: AddRef? */
1604 TRACE("found %p\n",*lpdsf);
1608 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1609 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1611 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1612 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1614 return DDERR_ALREADYINITIALIZED;
1617 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1618 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1620 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1621 TRACE("(%p)->(%p)\n",This,pf);
1623 *pf = This->s.surface_desc.ddpfPixelFormat;
1624 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1628 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1629 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1630 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1634 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1635 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1637 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1638 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1642 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1643 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1645 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1646 TRACE("(%p)->(%p)!\n",This,lpClipper);
1648 IDirectDrawClipper_Release( This->s.lpClipper );
1649 This->s.lpClipper = lpClipper;
1650 IDirectDrawClipper_AddRef( lpClipper ); /* Add the reference to it */
1654 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1655 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1657 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1658 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1660 struct _surface_chain *chain;
1662 FIXME("(%p)->(%p)\n",This,surf);
1663 chain = This->s.chain;
1665 /* IDirectDrawSurface4_AddRef(surf); */
1668 for (i=0;i<chain->nrofsurfaces;i++)
1669 if (chain->surfaces[i] == isurf)
1670 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1672 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1673 chain->nrofsurfaces = 1;
1674 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1675 chain->surfaces[0] = This;
1676 This->s.chain = chain;
1679 if (chain->surfaces)
1680 chain->surfaces = HeapReAlloc(
1684 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1687 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1688 isurf->s.chain = chain;
1689 chain->surfaces[chain->nrofsurfaces++] = isurf;
1693 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1694 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1699 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1701 /* Creates a DIB Section of the same size / format as the surface */
1702 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1704 if (This->s.hdc == 0) {
1705 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1708 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1709 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1714 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1718 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1719 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1723 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1724 b_info->bmiHeader.biWidth = desc.dwWidth;
1725 b_info->bmiHeader.biHeight = desc.dwHeight;
1726 b_info->bmiHeader.biPlanes = 1;
1727 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1729 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1730 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1732 b_info->bmiHeader.biCompression = BI_RGB;
1735 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1737 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1738 b_info->bmiHeader.biXPelsPerMeter = 0;
1739 b_info->bmiHeader.biYPelsPerMeter = 0;
1740 b_info->bmiHeader.biClrUsed = 0;
1741 b_info->bmiHeader.biClrImportant = 0;
1743 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1748 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1751 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1752 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1753 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1759 usage = DIB_RGB_COLORS;
1765 /* Fill the palette */
1766 usage = DIB_RGB_COLORS;
1768 if (This->s.palette == NULL) {
1769 ERR("Bad palette !!!\n");
1771 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1772 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1774 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1775 rgb[i].rgbBlue = pent[i].peBlue;
1776 rgb[i].rgbRed = pent[i].peRed;
1777 rgb[i].rgbGreen = pent[i].peGreen;
1783 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1786 &(This->s.bitmap_data),
1790 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1791 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1793 /* b_info is not useful anymore */
1794 HeapFree(GetProcessHeap(), 0, b_info);
1797 This->s.hdc = CreateCompatibleDC(0);
1798 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1801 /* Copy our surface in the DIB section */
1802 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1803 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1806 FIXME("This case has to be done :/\n");
1808 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1809 *lphdc = This->s.hdc;
1814 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1815 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1817 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1818 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1819 /* Copy the DIB section to our surface */
1820 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1821 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1824 FIXME("This case has to be done :/\n");
1826 /* Unlock the surface */
1827 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1831 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1832 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1835 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
1836 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
1838 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1839 * the same interface. And IUnknown does that too of course.
1841 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1842 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1843 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1844 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1845 IsEqualGUID( &IID_IUnknown, refiid )
1848 IDirectDrawSurface4_AddRef(iface);
1850 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1853 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1855 /* Texture interface */
1856 *obj = d3dtexture2_create(This);
1857 IDirectDrawSurface4_AddRef(iface);
1858 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1861 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1863 /* Texture interface */
1864 *obj = d3dtexture_create(This);
1865 IDirectDrawSurface4_AddRef(iface);
1867 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1871 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1872 /* It is the OpenGL Direct3D Device */
1873 IDirectDrawSurface4_AddRef(iface);
1874 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1878 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
1879 return OLE_E_ENUM_NOMORE;
1882 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1883 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1884 TRACE("(%p)->(), stub!\n",This);
1885 return DD_OK; /* hmm */
1888 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1889 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1891 struct _surface_chain *chain = This->s.chain;
1893 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1894 for (i=0;i<chain->nrofsurfaces;i++) {
1895 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1896 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1897 return DD_OK; /* FIXME: return value correct? */
1902 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1903 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1904 FIXME("(%p)->(),stub!\n",This);
1908 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1909 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1911 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1912 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1913 if (TRACE_ON(ddraw)) {
1914 _dump_colorkeyflag(dwFlags);
1916 _dump_DDCOLORKEY((void *) ckey);
1920 /* If this surface was loaded as a texture, call also the texture
1921 SetColorKey callback */
1922 if (This->s.texture) {
1923 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1926 if( dwFlags & DDCKEY_SRCBLT )
1928 dwFlags &= ~DDCKEY_SRCBLT;
1929 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1930 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1933 if( dwFlags & DDCKEY_DESTBLT )
1935 dwFlags &= ~DDCKEY_DESTBLT;
1936 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1937 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1940 if( dwFlags & DDCKEY_SRCOVERLAY )
1942 dwFlags &= ~DDCKEY_SRCOVERLAY;
1943 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1944 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1947 if( dwFlags & DDCKEY_DESTOVERLAY )
1949 dwFlags &= ~DDCKEY_DESTOVERLAY;
1950 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1951 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
1956 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
1963 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1964 LPDIRECTDRAWSURFACE4 iface,
1967 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1968 FIXME("(%p)->(%p),stub!\n",This,lpRect);
1973 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
1974 LPDIRECTDRAWSURFACE4 iface,
1976 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
1978 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1980 struct _surface_chain *chain;
1982 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
1983 chain = This->s.chain;
1984 for (i=0;i<chain->nrofsurfaces;i++) {
1985 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
1986 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
1988 chain->surfaces[i]->s.chain = NULL;
1989 memcpy( chain->surfaces+i,
1990 chain->surfaces+(i+1),
1991 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
1993 chain->surfaces = HeapReAlloc(
1997 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
1999 chain->nrofsurfaces--;
2006 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2007 LPDIRECTDRAWSURFACE4 iface,
2010 LPDDENUMSURFACESCALLBACK lpfnCallback )
2012 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2013 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2014 lpContext, lpfnCallback );
2019 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2020 LPDIRECTDRAWSURFACE4 iface,
2021 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2023 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2024 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2029 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2030 LPDIRECTDRAWSURFACE4 iface,
2032 LPDDCOLORKEY lpDDColorKey )
2034 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2035 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2037 if( dwFlags & DDCKEY_SRCBLT ) {
2038 dwFlags &= ~DDCKEY_SRCBLT;
2039 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2042 if( dwFlags & DDCKEY_DESTBLT )
2044 dwFlags &= ~DDCKEY_DESTBLT;
2045 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2048 if( dwFlags & DDCKEY_SRCOVERLAY )
2050 dwFlags &= ~DDCKEY_SRCOVERLAY;
2051 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2054 if( dwFlags & DDCKEY_DESTOVERLAY )
2056 dwFlags &= ~DDCKEY_DESTOVERLAY;
2057 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2062 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2068 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2069 LPDIRECTDRAWSURFACE4 iface,
2072 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2073 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2078 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2079 LPDIRECTDRAWSURFACE4 iface,
2080 LPDIRECTDRAWPALETTE* lplpDDPalette )
2082 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2083 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2085 if (This->s.palette != NULL) {
2086 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2088 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2091 return DDERR_NOPALETTEATTACHED;
2095 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2096 LPDIRECTDRAWSURFACE4 iface,
2100 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2101 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2106 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2107 LPDIRECTDRAWSURFACE4 iface,
2109 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2112 LPDDOVERLAYFX lpDDOverlayFx )
2114 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2115 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2116 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2121 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2122 LPDIRECTDRAWSURFACE4 iface,
2125 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2126 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2131 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2132 LPDIRECTDRAWSURFACE4 iface,
2134 LPDIRECTDRAWSURFACE4 lpDDSReference )
2136 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2137 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2142 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2143 LPDIRECTDRAWSURFACE4 iface,
2146 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2147 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2149 /* Not sure about that... */
2150 *lplpDD = (void *) This->s.ddraw;
2155 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2156 LPDIRECTDRAWSURFACE4 iface,
2159 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2160 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2165 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2166 LPDIRECTDRAWSURFACE4 iface,
2169 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2170 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2175 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2176 LPDIRECTDRAWSURFACE4 iface,
2177 LPDDSURFACEDESC lpDDSD,
2180 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2181 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2186 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2191 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2192 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2197 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2200 LPDWORD lpcbBufferSize) {
2201 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2202 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2207 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2209 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2210 FIXME("(%p)->(%p)\n", This, guidTag);
2215 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2217 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2218 FIXME("(%p)->(%p)\n", This, lpValue);
2223 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2224 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2225 FIXME("(%p)\n", This);
2230 #ifdef HAVE_LIBXXF86DGA
2231 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2233 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2234 IDirectDrawSurface4Impl_QueryInterface,
2235 IDirectDrawSurface4Impl_AddRef,
2236 DGA_IDirectDrawSurface4Impl_Release,
2237 IDirectDrawSurface4Impl_AddAttachedSurface,
2238 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2239 IDirectDrawSurface4Impl_Blt,
2240 IDirectDrawSurface4Impl_BltBatch,
2241 IDirectDrawSurface4Impl_BltFast,
2242 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2243 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2244 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2245 DGA_IDirectDrawSurface4Impl_Flip,
2246 IDirectDrawSurface4Impl_GetAttachedSurface,
2247 IDirectDrawSurface4Impl_GetBltStatus,
2248 IDirectDrawSurface4Impl_GetCaps,
2249 IDirectDrawSurface4Impl_GetClipper,
2250 IDirectDrawSurface4Impl_GetColorKey,
2251 IDirectDrawSurface4Impl_GetDC,
2252 IDirectDrawSurface4Impl_GetFlipStatus,
2253 IDirectDrawSurface4Impl_GetOverlayPosition,
2254 IDirectDrawSurface4Impl_GetPalette,
2255 IDirectDrawSurface4Impl_GetPixelFormat,
2256 IDirectDrawSurface4Impl_GetSurfaceDesc,
2257 IDirectDrawSurface4Impl_Initialize,
2258 IDirectDrawSurface4Impl_IsLost,
2259 IDirectDrawSurface4Impl_Lock,
2260 IDirectDrawSurface4Impl_ReleaseDC,
2261 IDirectDrawSurface4Impl_Restore,
2262 IDirectDrawSurface4Impl_SetClipper,
2263 IDirectDrawSurface4Impl_SetColorKey,
2264 IDirectDrawSurface4Impl_SetOverlayPosition,
2265 DGA_IDirectDrawSurface4Impl_SetPalette,
2266 DGA_IDirectDrawSurface4Impl_Unlock,
2267 IDirectDrawSurface4Impl_UpdateOverlay,
2268 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2269 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2270 IDirectDrawSurface4Impl_GetDDInterface,
2271 IDirectDrawSurface4Impl_PageLock,
2272 IDirectDrawSurface4Impl_PageUnlock,
2273 IDirectDrawSurface4Impl_SetSurfaceDesc,
2274 IDirectDrawSurface4Impl_SetPrivateData,
2275 IDirectDrawSurface4Impl_GetPrivateData,
2276 IDirectDrawSurface4Impl_FreePrivateData,
2277 IDirectDrawSurface4Impl_GetUniquenessValue,
2278 IDirectDrawSurface4Impl_ChangeUniquenessValue
2280 #endif /* defined(HAVE_LIBXXF86DGA) */
2282 #ifdef HAVE_LIBXXF86DGA2
2283 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2285 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2286 IDirectDrawSurface4Impl_QueryInterface,
2287 IDirectDrawSurface4Impl_AddRef,
2288 DGA_IDirectDrawSurface4Impl_Release,
2289 IDirectDrawSurface4Impl_AddAttachedSurface,
2290 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2291 IDirectDrawSurface4Impl_Blt,
2292 IDirectDrawSurface4Impl_BltBatch,
2293 IDirectDrawSurface4Impl_BltFast,
2294 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2295 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2296 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2297 DGA2_IDirectDrawSurface4Impl_Flip,
2298 IDirectDrawSurface4Impl_GetAttachedSurface,
2299 IDirectDrawSurface4Impl_GetBltStatus,
2300 IDirectDrawSurface4Impl_GetCaps,
2301 IDirectDrawSurface4Impl_GetClipper,
2302 IDirectDrawSurface4Impl_GetColorKey,
2303 IDirectDrawSurface4Impl_GetDC,
2304 IDirectDrawSurface4Impl_GetFlipStatus,
2305 IDirectDrawSurface4Impl_GetOverlayPosition,
2306 IDirectDrawSurface4Impl_GetPalette,
2307 IDirectDrawSurface4Impl_GetPixelFormat,
2308 IDirectDrawSurface4Impl_GetSurfaceDesc,
2309 IDirectDrawSurface4Impl_Initialize,
2310 IDirectDrawSurface4Impl_IsLost,
2311 IDirectDrawSurface4Impl_Lock,
2312 IDirectDrawSurface4Impl_ReleaseDC,
2313 IDirectDrawSurface4Impl_Restore,
2314 IDirectDrawSurface4Impl_SetClipper,
2315 IDirectDrawSurface4Impl_SetColorKey,
2316 IDirectDrawSurface4Impl_SetOverlayPosition,
2317 DGA_IDirectDrawSurface4Impl_SetPalette,
2318 DGA_IDirectDrawSurface4Impl_Unlock,
2319 IDirectDrawSurface4Impl_UpdateOverlay,
2320 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2321 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2322 IDirectDrawSurface4Impl_GetDDInterface,
2323 IDirectDrawSurface4Impl_PageLock,
2324 IDirectDrawSurface4Impl_PageUnlock,
2325 IDirectDrawSurface4Impl_SetSurfaceDesc,
2326 IDirectDrawSurface4Impl_SetPrivateData,
2327 IDirectDrawSurface4Impl_GetPrivateData,
2328 IDirectDrawSurface4Impl_FreePrivateData,
2329 IDirectDrawSurface4Impl_GetUniquenessValue,
2330 IDirectDrawSurface4Impl_ChangeUniquenessValue
2332 #endif /* defined(HAVE_LIBXXF86DGA2) */
2334 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2336 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2337 IDirectDrawSurface4Impl_QueryInterface,
2338 IDirectDrawSurface4Impl_AddRef,
2339 Xlib_IDirectDrawSurface4Impl_Release,
2340 IDirectDrawSurface4Impl_AddAttachedSurface,
2341 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2342 IDirectDrawSurface4Impl_Blt,
2343 IDirectDrawSurface4Impl_BltBatch,
2344 IDirectDrawSurface4Impl_BltFast,
2345 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2346 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2347 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2348 Xlib_IDirectDrawSurface4Impl_Flip,
2349 IDirectDrawSurface4Impl_GetAttachedSurface,
2350 IDirectDrawSurface4Impl_GetBltStatus,
2351 IDirectDrawSurface4Impl_GetCaps,
2352 IDirectDrawSurface4Impl_GetClipper,
2353 IDirectDrawSurface4Impl_GetColorKey,
2354 IDirectDrawSurface4Impl_GetDC,
2355 IDirectDrawSurface4Impl_GetFlipStatus,
2356 IDirectDrawSurface4Impl_GetOverlayPosition,
2357 IDirectDrawSurface4Impl_GetPalette,
2358 IDirectDrawSurface4Impl_GetPixelFormat,
2359 IDirectDrawSurface4Impl_GetSurfaceDesc,
2360 IDirectDrawSurface4Impl_Initialize,
2361 IDirectDrawSurface4Impl_IsLost,
2362 IDirectDrawSurface4Impl_Lock,
2363 IDirectDrawSurface4Impl_ReleaseDC,
2364 IDirectDrawSurface4Impl_Restore,
2365 IDirectDrawSurface4Impl_SetClipper,
2366 IDirectDrawSurface4Impl_SetColorKey,
2367 IDirectDrawSurface4Impl_SetOverlayPosition,
2368 Xlib_IDirectDrawSurface4Impl_SetPalette,
2369 Xlib_IDirectDrawSurface4Impl_Unlock,
2370 IDirectDrawSurface4Impl_UpdateOverlay,
2371 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2372 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2373 IDirectDrawSurface4Impl_GetDDInterface,
2374 IDirectDrawSurface4Impl_PageLock,
2375 IDirectDrawSurface4Impl_PageUnlock,
2376 IDirectDrawSurface4Impl_SetSurfaceDesc,
2377 IDirectDrawSurface4Impl_SetPrivateData,
2378 IDirectDrawSurface4Impl_GetPrivateData,
2379 IDirectDrawSurface4Impl_FreePrivateData,
2380 IDirectDrawSurface4Impl_GetUniquenessValue,
2381 IDirectDrawSurface4Impl_ChangeUniquenessValue
2384 /******************************************************************************
2385 * DirectDrawCreateClipper (DDRAW.7)
2387 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2388 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2389 LPUNKNOWN pUnkOuter)
2391 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2392 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2394 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2395 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2396 (*ilplpDDClipper)->ref = 1;
2398 (*ilplpDDClipper)->hWnd = 0;
2403 /******************************************************************************
2404 * IDirectDrawClipper
2406 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2407 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2409 ICOM_THIS(IDirectDrawClipperImpl,iface);
2411 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2413 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2414 return DDERR_INVALIDPARAMS;
2421 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2422 ICOM_THIS(IDirectDrawClipperImpl,iface);
2423 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2428 HeapFree(GetProcessHeap(),0,This);
2432 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2433 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2435 ICOM_THIS(IDirectDrawClipperImpl,iface);
2436 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2441 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2442 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2444 ICOM_THIS(IDirectDrawClipperImpl,iface);
2445 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2449 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2450 LPDIRECTDRAWCLIPPER iface,
2454 ICOM_THIS(IDirectDrawClipperImpl,iface);
2455 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2456 return OLE_E_ENUM_NOMORE;
2459 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2461 ICOM_THIS(IDirectDrawClipperImpl,iface);
2462 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2463 return ++(This->ref);
2466 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2467 LPDIRECTDRAWCLIPPER iface,
2470 ICOM_THIS(IDirectDrawClipperImpl,iface);
2471 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2473 *hWndPtr = This->hWnd;
2478 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2479 LPDIRECTDRAWCLIPPER iface,
2483 ICOM_THIS(IDirectDrawClipperImpl,iface);
2484 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2488 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2489 LPDIRECTDRAWCLIPPER iface,
2492 ICOM_THIS(IDirectDrawClipperImpl,iface);
2493 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2497 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2499 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2500 IDirectDrawClipperImpl_QueryInterface,
2501 IDirectDrawClipperImpl_AddRef,
2502 IDirectDrawClipperImpl_Release,
2503 IDirectDrawClipperImpl_GetClipList,
2504 IDirectDrawClipperImpl_GetHWnd,
2505 IDirectDrawClipperImpl_Initialize,
2506 IDirectDrawClipperImpl_IsClipListChanged,
2507 IDirectDrawClipperImpl_SetClipList,
2508 IDirectDrawClipperImpl_SetHwnd
2512 /******************************************************************************
2513 * IDirectDrawPalette
2515 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2516 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2518 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2521 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2522 This,x,start,count,palent);
2524 /* No palette created and not in depth-convertion mode -> BUG ! */
2525 if ((This->cm == None) &&
2526 (This->ddraw->d.palette_convert == NULL))
2528 FIXME("app tried to read colormap for non-palettized mode\n");
2529 return DDERR_GENERIC;
2531 for (i=0;i<count;i++) {
2532 palent[i].peRed = This->palents[start+i].peRed;
2533 palent[i].peBlue = This->palents[start+i].peBlue;
2534 palent[i].peGreen = This->palents[start+i].peGreen;
2535 palent[i].peFlags = This->palents[start+i].peFlags;
2541 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2542 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2544 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2548 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2549 This,x,start,count,palent
2551 for (i=0;i<count;i++) {
2552 xc.red = palent[i].peRed<<8;
2553 xc.blue = palent[i].peBlue<<8;
2554 xc.green = palent[i].peGreen<<8;
2555 xc.flags = DoRed|DoBlue|DoGreen;
2559 TSXStoreColor(display,This->cm,&xc);
2561 This->palents[start+i].peRed = palent[i].peRed;
2562 This->palents[start+i].peBlue = palent[i].peBlue;
2563 This->palents[start+i].peGreen = palent[i].peGreen;
2564 This->palents[start+i].peFlags = palent[i].peFlags;
2567 /* Now, if we are in 'depth conversion mode', update the screen palette */
2568 /* FIXME: we need to update the image or we won't get palette fading. */
2569 if (This->ddraw->d.palette_convert != NULL)
2570 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2575 #ifdef HAVE_LIBXXF86DGA
2576 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2577 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2579 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2584 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2585 This,x,start,count,palent
2587 if (!This->cm) /* should not happen */ {
2588 FIXME("app tried to set colormap in non-palettized mode\n");
2589 return DDERR_GENERIC;
2591 /* FIXME: free colorcells instead of freeing whole map */
2593 This->cm = TSXCopyColormapAndFree(display,This->cm);
2594 TSXFreeColormap(display,cm);
2596 for (i=0;i<count;i++) {
2597 xc.red = palent[i].peRed<<8;
2598 xc.blue = palent[i].peBlue<<8;
2599 xc.green = palent[i].peGreen<<8;
2600 xc.flags = DoRed|DoBlue|DoGreen;
2603 TSXStoreColor(display,This->cm,&xc);
2605 This->palents[start+i].peRed = palent[i].peRed;
2606 This->palents[start+i].peBlue = palent[i].peBlue;
2607 This->palents[start+i].peGreen = palent[i].peGreen;
2608 This->palents[start+i].peFlags = palent[i].peFlags;
2610 #ifdef HAVE_LIBXXF86DGA2
2611 if (This->ddraw->e.dga.version == 2)
2612 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2614 #endif /* defined(HAVE_LIBXXF86DGA2) */
2615 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2618 #endif /* defined(HAVE_LIBXXF86DGA) */
2620 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2621 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2622 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2623 if (!--(This->ref)) {
2625 TSXFreeColormap(display,This->cm);
2628 HeapFree(GetProcessHeap(),0,This);
2634 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2635 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2637 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2638 return ++(This->ref);
2641 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2642 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2644 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2645 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2647 return DDERR_ALREADYINITIALIZED;
2650 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2651 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2653 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2654 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2658 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2659 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2661 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2664 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2665 FIXME("(%p)->(%s,%p) stub.\n",This,xrefiid,obj);
2670 #ifdef HAVE_LIBXXF86DGA
2671 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2673 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2674 IDirectDrawPaletteImpl_QueryInterface,
2675 IDirectDrawPaletteImpl_AddRef,
2676 IDirectDrawPaletteImpl_Release,
2677 IDirectDrawPaletteImpl_GetCaps,
2678 IDirectDrawPaletteImpl_GetEntries,
2679 IDirectDrawPaletteImpl_Initialize,
2680 DGA_IDirectDrawPaletteImpl_SetEntries
2682 #endif /* defined(HAVE_LIBXXF86DGA) */
2684 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2686 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2687 IDirectDrawPaletteImpl_QueryInterface,
2688 IDirectDrawPaletteImpl_AddRef,
2689 IDirectDrawPaletteImpl_Release,
2690 IDirectDrawPaletteImpl_GetCaps,
2691 IDirectDrawPaletteImpl_GetEntries,
2692 IDirectDrawPaletteImpl_Initialize,
2693 Xlib_IDirectDrawPaletteImpl_SetEntries
2696 /*******************************************************************************
2699 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2700 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2702 ICOM_THIS(IDirect3DImpl,iface);
2703 /* FIXME: Not sure if this is correct */
2706 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2707 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2708 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2709 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2710 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2712 IDirect3D_AddRef(iface);
2714 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2718 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2719 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2721 IDirect3D_AddRef(iface);
2723 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2727 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2728 IDirect3D2Impl* d3d;
2730 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2732 d3d->ddraw = This->ddraw;
2733 IDirect3D_AddRef(iface);
2734 ICOM_VTBL(d3d) = &d3d2vt;
2737 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2741 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2742 return OLE_E_ENUM_NOMORE;
2745 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2746 ICOM_THIS(IDirect3DImpl,iface);
2747 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2749 return ++(This->ref);
2752 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2754 ICOM_THIS(IDirect3DImpl,iface);
2755 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2757 if (!--(This->ref)) {
2758 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2759 HeapFree(GetProcessHeap(),0,This);
2765 static HRESULT WINAPI IDirect3DImpl_Initialize(
2766 LPDIRECT3D iface, REFIID refiid )
2768 ICOM_THIS(IDirect3DImpl,iface);
2769 /* FIXME: Not sure if this is correct */
2772 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2773 FIXME("(%p)->(%s):stub.\n",This,xrefiid);
2775 return DDERR_ALREADYINITIALIZED;
2778 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2779 LPD3DENUMDEVICESCALLBACK cb,
2781 ICOM_THIS(IDirect3DImpl,iface);
2782 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2784 /* Call functions defined in d3ddevices.c */
2785 if (!d3d_OpenGL_dx3(cb, context))
2791 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2792 LPDIRECT3DLIGHT *lplight,
2795 ICOM_THIS(IDirect3DImpl,iface);
2796 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2798 /* Call the creation function that is located in d3dlight.c */
2799 *lplight = d3dlight_create_dx3(This);
2804 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2805 LPDIRECT3DMATERIAL *lpmaterial,
2808 ICOM_THIS(IDirect3DImpl,iface);
2809 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2811 /* Call the creation function that is located in d3dviewport.c */
2812 *lpmaterial = d3dmaterial_create(This);
2817 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2818 LPDIRECT3DVIEWPORT *lpviewport,
2821 ICOM_THIS(IDirect3DImpl,iface);
2822 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2824 /* Call the creation function that is located in d3dviewport.c */
2825 *lpviewport = d3dviewport_create(This);
2830 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2831 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2832 LPD3DFINDDEVICERESULT lpfinddevrst)
2834 ICOM_THIS(IDirect3DImpl,iface);
2835 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2840 static ICOM_VTABLE(IDirect3D) d3dvt =
2842 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2843 IDirect3DImpl_QueryInterface,
2844 IDirect3DImpl_AddRef,
2845 IDirect3DImpl_Release,
2846 IDirect3DImpl_Initialize,
2847 IDirect3DImpl_EnumDevices,
2848 IDirect3DImpl_CreateLight,
2849 IDirect3DImpl_CreateMaterial,
2850 IDirect3DImpl_CreateViewport,
2851 IDirect3DImpl_FindDevice
2854 /*******************************************************************************
2857 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2858 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2859 ICOM_THIS(IDirect3D2Impl,iface);
2861 /* FIXME: Not sure if this is correct */
2864 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
2865 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
2866 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2867 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2868 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2870 IDirect3D2_AddRef(iface);
2872 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2876 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2877 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2879 IDirect3D2_AddRef(iface);
2881 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2885 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2888 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2890 d3d->ddraw = This->ddraw;
2891 IDirect3D2_AddRef(iface);
2892 ICOM_VTBL(d3d) = &d3dvt;
2895 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2899 FIXME("(%p):interface for IID %s NOT found!\n",This,xrefiid);
2900 return OLE_E_ENUM_NOMORE;
2903 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2904 ICOM_THIS(IDirect3D2Impl,iface);
2905 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2907 return ++(This->ref);
2910 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2911 ICOM_THIS(IDirect3D2Impl,iface);
2912 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2914 if (!--(This->ref)) {
2915 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2916 HeapFree(GetProcessHeap(),0,This);
2922 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2923 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2925 ICOM_THIS(IDirect3D2Impl,iface);
2926 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2928 /* Call functions defined in d3ddevices.c */
2929 if (!d3d_OpenGL(cb, context))
2935 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2936 LPDIRECT3DLIGHT *lplight,
2939 ICOM_THIS(IDirect3D2Impl,iface);
2940 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2942 /* Call the creation function that is located in d3dlight.c */
2943 *lplight = d3dlight_create(This);
2948 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2949 LPDIRECT3DMATERIAL2 *lpmaterial,
2952 ICOM_THIS(IDirect3D2Impl,iface);
2953 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2955 /* Call the creation function that is located in d3dviewport.c */
2956 *lpmaterial = d3dmaterial2_create(This);
2961 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
2962 LPDIRECT3DVIEWPORT2 *lpviewport,
2965 ICOM_THIS(IDirect3D2Impl,iface);
2966 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2968 /* Call the creation function that is located in d3dviewport.c */
2969 *lpviewport = d3dviewport2_create(This);
2974 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
2975 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2976 LPD3DFINDDEVICERESULT lpfinddevrst)
2978 ICOM_THIS(IDirect3D2Impl,iface);
2979 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2984 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
2986 LPDIRECTDRAWSURFACE surface,
2987 LPDIRECT3DDEVICE2 *device)
2989 ICOM_THIS(IDirect3D2Impl,iface);
2992 WINE_StringFromCLSID(rguid,xbuf);
2993 FIXME("(%p)->(%s,%p,%p): stub\n",This,xbuf,surface,device);
2995 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
2996 IDirect3D2_AddRef(iface);
3000 return DDERR_INVALIDPARAMS;
3003 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3005 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3006 IDirect3D2Impl_QueryInterface,
3007 IDirect3D2Impl_AddRef,
3008 IDirect3D2Impl_Release,
3009 IDirect3D2Impl_EnumDevices,
3010 IDirect3D2Impl_CreateLight,
3011 IDirect3D2Impl_CreateMaterial,
3012 IDirect3D2Impl_CreateViewport,
3013 IDirect3D2Impl_FindDevice,
3014 IDirect3D2Impl_CreateDevice
3017 /*******************************************************************************
3021 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3022 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3024 static INT ddrawXlibThisOffset = 0;
3026 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3027 IDirectDrawSurfaceImpl* lpdsf)
3031 /* The surface was already allocated when entering in this function */
3032 TRACE("using system memory for a surface (%p) \n", lpdsf);
3034 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3035 /* This is a Z Buffer */
3036 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3037 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3039 /* This is a standard image */
3040 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3041 /* No pixel format => use DirectDraw's format */
3042 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3043 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3046 bpp = GET_BPP(lpdsf->s.surface_desc);
3049 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3050 /* The surface was preallocated : seems that we have nothing to do :-) */
3051 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
3054 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3055 lpdsf->s.surface_desc.u1.lpSurface =
3056 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3057 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3062 #ifdef HAVE_LIBXXF86DGA
3063 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3064 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3066 ICOM_THIS(IDirectDraw2Impl,iface);
3067 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3068 int i, fbheight = This->e.dga.fb_height;
3070 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3071 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3073 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3076 sizeof(IDirectDrawSurfaceImpl)
3078 IDirectDraw2_AddRef(iface);
3081 #ifdef HAVE_LIBXXF86DGA2
3082 if (This->e.dga.version == 2)
3083 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3085 #endif /* defined(HAVE_LIBXXF86DGA2) */
3086 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3087 (*ilpdsf)->s.ddraw = This;
3088 (*ilpdsf)->s.palette = NULL;
3089 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3090 (*ilpdsf)->s.lpClipper = NULL;
3092 /* Copy the surface description */
3093 (*ilpdsf)->s.surface_desc = *lpddsd;
3095 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3096 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3097 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3098 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3100 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3102 /* Check if this a 'primary surface' or not */
3103 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3104 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3105 /* This is THE primary surface => there is DGA-specific code */
3107 /* First, store the surface description */
3108 (*ilpdsf)->s.surface_desc = *lpddsd;
3110 /* Find a viewport */
3112 if (!(This->e.dga.vpmask & (1<<i)))
3114 TRACE("using viewport %d for a primary surface\n",i);
3115 /* if i == 32 or maximum ... return error */
3116 This->e.dga.vpmask|=(1<<i);
3117 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3118 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3120 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3121 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3123 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3125 /* Add flags if there were not present */
3126 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3127 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3128 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3129 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3130 /* We put our surface always in video memory */
3131 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3132 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3133 (*ilpdsf)->s.chain = NULL;
3135 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3136 IDirectDrawSurface4Impl* back;
3139 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3142 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3145 sizeof(IDirectDrawSurface4Impl)
3147 IDirectDraw2_AddRef(iface);
3149 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3151 if (!(This->e.dga.vpmask & (1<<i)))
3153 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3154 /* if i == 32 or maximum ... return error */
3155 This->e.dga.vpmask|=(1<<i);
3156 back->t.dga.fb_height = i*fbheight;
3157 /* Copy the surface description from the front buffer */
3158 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3159 /* Change the parameters that are not the same */
3160 back->s.surface_desc.u1.lpSurface =
3161 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3163 back->s.ddraw = This;
3164 /* Add relevant info to front and back buffers */
3165 /* FIXME: backbuffer/frontbuffer handling broken here, but
3166 * will be fixed up in _Flip().
3168 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3169 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3170 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3171 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3172 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3176 /* There is no DGA-specific code here...
3177 Go to the common surface creation function */
3178 return common_off_screen_CreateSurface(This, *ilpdsf);
3182 #endif /* defined(HAVE_LIBXXF86DGA) */
3184 #ifdef HAVE_LIBXXSHM
3185 /* Error handlers for Image creation */
3186 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3191 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3193 int (*WineXHandler)(Display *, XErrorEvent *);
3195 img = TSXShmCreateImage(display,
3196 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3197 This->d.pixmap_depth,
3200 &(lpdsf->t.xlib.shminfo),
3201 lpdsf->s.surface_desc.dwWidth,
3202 lpdsf->s.surface_desc.dwHeight
3206 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3207 This->e.xlib.xshm_active = 0;
3211 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3212 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3213 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3214 This->e.xlib.xshm_active = 0;
3215 TSXDestroyImage(img);
3219 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3221 if (img->data == (char *) -1) {
3222 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3223 This->e.xlib.xshm_active = 0;
3224 TSXDestroyImage(img);
3225 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3228 lpdsf->t.xlib.shminfo.readOnly = False;
3230 /* This is where things start to get trickier....
3231 * First, we flush the current X connections to be sure to catch all
3232 * non-XShm related errors
3234 TSXSync(display, False);
3235 /* Then we enter in the non-thread safe part of the tests */
3236 EnterCriticalSection( &X11DRV_CritSection );
3238 /* Reset the error flag, sets our new error handler and try to attach
3242 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3243 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3244 XSync(display, False);
3246 /* Check the error flag */
3247 if (XShmErrorFlag) {
3248 /* An error occured */
3252 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3253 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3254 XSetErrorHandler(WineXHandler);
3256 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3257 This->e.xlib.xshm_active = 0;
3259 /* Leave the critical section */
3260 LeaveCriticalSection( &X11DRV_CritSection );
3263 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3264 * this works, but it may be a bit overkill....
3266 XSetErrorHandler(WineXHandler);
3267 LeaveCriticalSection( &X11DRV_CritSection );
3269 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3271 if (This->d.pixel_convert != NULL) {
3272 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3275 lpdsf->s.surface_desc.dwWidth *
3276 lpdsf->s.surface_desc.dwHeight *
3277 PFGET_BPP(This->d.directdraw_pixelformat)
3280 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3284 #endif /* HAVE_LIBXXSHM */
3286 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3290 #ifdef HAVE_LIBXXSHM
3291 if (This->e.xlib.xshm_active)
3292 img = create_xshmimage(This, lpdsf);
3296 /* Allocate surface memory */
3297 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3298 GetProcessHeap(),HEAP_ZERO_MEMORY,
3299 lpdsf->s.surface_desc.dwWidth *
3300 lpdsf->s.surface_desc.dwHeight *
3301 PFGET_BPP(This->d.directdraw_pixelformat)
3304 if (This->d.pixel_convert != NULL) {
3305 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3306 lpdsf->s.surface_desc.dwWidth *
3307 lpdsf->s.surface_desc.dwHeight *
3308 PFGET_BPP(This->d.screen_pixelformat)
3311 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3314 /* In this case, create an XImage */
3315 img = TSXCreateImage(display,
3316 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3317 This->d.pixmap_depth,
3321 lpdsf->s.surface_desc.dwWidth,
3322 lpdsf->s.surface_desc.dwHeight,
3324 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3326 #ifdef HAVE_LIBXXSHM
3329 if (This->d.pixel_convert != NULL)
3330 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3332 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3336 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3337 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3339 ICOM_THIS(IDirectDraw2Impl,iface);
3340 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3342 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3344 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3346 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3347 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3350 IDirectDraw2_AddRef(iface);
3352 (*ilpdsf)->s.ddraw = This;
3354 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3355 (*ilpdsf)->s.palette = NULL;
3356 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3357 (*ilpdsf)->s.lpClipper = NULL;
3359 /* Copy the surface description */
3360 (*ilpdsf)->s.surface_desc = *lpddsd;
3362 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3363 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3364 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3365 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3366 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3368 /* Check if this a 'primary surface' or not */
3369 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3370 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3373 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3374 /* Create the XImage */
3375 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3377 return DDERR_OUTOFMEMORY;
3378 (*ilpdsf)->t.xlib.image = img;
3380 /* Add flags if there were not present */
3381 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3382 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3383 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3384 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3385 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3387 /* Check for backbuffers */
3388 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3389 IDirectDrawSurface4Impl* back;
3393 for (i=lpddsd->dwBackBufferCount;i--;) {
3394 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3395 GetProcessHeap(),HEAP_ZERO_MEMORY,
3396 sizeof(IDirectDrawSurface4Impl)
3399 TRACE("allocated back-buffer (%p)\n", back);
3401 IDirectDraw2_AddRef(iface);
3402 back->s.ddraw = This;
3405 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3406 /* Copy the surface description from the front buffer */
3407 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3409 /* Create the XImage */
3410 img = create_ximage(This, back);
3412 return DDERR_OUTOFMEMORY;
3413 back->t.xlib.image = img;
3415 /* Add relevant info to front and back buffers */
3416 /* FIXME: backbuffer/frontbuffer handling broken here, but
3417 * will be fixed up in _Flip().
3419 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3420 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3421 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3422 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3423 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3427 /* There is no Xlib-specific code here...
3428 Go to the common surface creation function */
3429 return common_off_screen_CreateSurface(This, *ilpdsf);
3434 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3435 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3437 ICOM_THIS(IDirectDraw2Impl,iface);
3438 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3439 *dst = src; /* FIXME */
3444 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3445 * even when the approbiate bitmasks are not specified.
3447 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3448 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3450 ICOM_THIS(IDirectDraw2Impl,iface);
3456 #define FE(x) { x, #x},
3457 FE(DDSCL_FULLSCREEN)
3458 FE(DDSCL_ALLOWREBOOT)
3459 FE(DDSCL_NOWINDOWCHANGES)
3461 FE(DDSCL_ALLOWMODEX)
3463 FE(DDSCL_SETFOCUSWINDOW)
3464 FE(DDSCL_SETDEVICEWINDOW)
3465 FE(DDSCL_CREATEDEVICEWINDOW)
3469 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3470 if (TRACE_ON(ddraw)) {
3472 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3473 if (flags[i].mask & cooplevel) {
3474 DPRINTF("%s ",flags[i].name);
3479 This->d.mainWindow = hwnd;
3481 /* This will be overwritten in the case of Full Screen mode.
3482 Windowed games could work with that :-) */
3485 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3486 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3487 WIN_ReleaseWndPtr(tmpWnd);
3489 if( !This->d.drawable ) {
3490 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3491 WIN_ReleaseDesktop();
3493 TRACE("Setting drawable to %ld\n", This->d.drawable);
3499 /* Small helper to either use the cooperative window or create a new
3500 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3502 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3505 /* Do not destroy the application supplied cooperative window */
3506 if (This->d.window && This->d.window != This->d.mainWindow) {
3507 DestroyWindow(This->d.window);
3510 /* Sanity check cooperative window before assigning it to drawing. */
3511 if ( IsWindow(This->d.mainWindow) &&
3512 IsWindowVisible(This->d.mainWindow)
3514 /* if it does not fit, resize the cooperative window.
3515 * and hope the app likes it
3517 GetWindowRect(This->d.mainWindow,&rect);
3518 if ((((rect.right-rect.left) >= This->d.width) &&
3519 ((rect.bottom-rect.top) >= This->d.height))
3521 This->d.window = This->d.mainWindow;
3522 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3526 /* ... failed, create new one. */
3527 if (!This->d.window) {
3528 This->d.window = CreateWindowExA(
3532 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3541 /*Store THIS with the window. We'll use it in the window procedure*/
3542 SetWindowLongA(This->d.window,ddrawXlibThisOffset,(LONG)This);
3543 ShowWindow(This->d.window,TRUE);
3544 UpdateWindow(This->d.window);
3546 SetFocus(This->d.window);
3549 static int _common_depth_to_pixelformat(DWORD depth,
3550 DDPIXELFORMAT *pixelformat,
3551 DDPIXELFORMAT *screen_pixelformat,
3554 XPixmapFormatValues *pf;
3556 int nvisuals, npixmap, i;
3560 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3561 pf = XListPixmapFormats(display, &npixmap);
3563 for (i = 0; i < npixmap; i++) {
3564 if (pf[i].depth == depth) {
3567 for (j = 0; j < nvisuals; j++) {
3568 if (vi[j].depth == pf[i].depth) {
3569 pixelformat->dwSize = sizeof(*pixelformat);
3571 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3572 pixelformat->u1.dwRBitMask = 0;
3573 pixelformat->u2.dwGBitMask = 0;
3574 pixelformat->u3.dwBBitMask = 0;
3576 pixelformat->dwFlags = DDPF_RGB;
3577 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3578 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3579 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3581 pixelformat->dwFourCC = 0;
3582 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3583 pixelformat->u4.dwRGBAlphaBitMask= 0;
3585 *screen_pixelformat = *pixelformat;
3587 if (pix_depth != NULL)
3588 *pix_depth = vi[j].depth;
3593 goto clean_up_and_exit;
3597 ERR("No visual corresponding to pixmap format !\n");
3602 /* We try now to find an emulated mode */
3605 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3606 if (ModeEmulations[c].dest.depth == depth) {
3607 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3608 for (i = 0; i < npixmap; i++) {
3609 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3610 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3613 for (j = 0; j < nvisuals; j++) {
3614 if (vi[j].depth == pf[i].depth) {
3615 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3616 screen_pixelformat->dwFlags = DDPF_RGB;
3617 screen_pixelformat->dwFourCC = 0;
3618 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3619 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3620 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3621 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3622 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3624 pixelformat->dwSize = sizeof(*pixelformat);
3625 pixelformat->dwFourCC = 0;
3627 pixelformat->dwFlags = DDPF_PALETTEINDEXED8;
3628 pixelformat->u.dwRGBBitCount = 8;
3629 pixelformat->u1.dwRBitMask = 0;
3630 pixelformat->u2.dwGBitMask = 0;
3631 pixelformat->u3.dwBBitMask = 0;
3633 pixelformat->dwFlags = DDPF_RGB;
3634 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3635 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3636 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3637 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3639 pixelformat->u4.dwRGBAlphaBitMask= 0;
3641 if (pix_depth != NULL)
3642 *pix_depth = vi[j].depth;
3647 goto clean_up_and_exit;
3650 ERR("No visual corresponding to pixmap format !\n");
3665 #ifdef HAVE_LIBXXF86DGA
3666 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3667 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3669 ICOM_THIS(IDirectDrawImpl,iface);
3672 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3674 #ifdef HAVE_LIBXXF86DGA2
3675 if (This->e.dga.version == 2)
3676 /* For the moment, we suppose we have the correct display settings when in DGA 2.0 mode */
3678 #endif /* defined(HAVE_LIBXXF86DGA2) */
3680 /* We hope getting the asked for depth */
3681 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3682 /* I.e. no visual found or emulated */
3683 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3684 return DDERR_UNSUPPORTEDMODE;
3687 if (This->d.width < width) {
3688 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3689 return DDERR_UNSUPPORTEDMODE;
3691 This->d.width = width;
3692 This->d.height = height;
3694 /* adjust fb_height, so we don't overlap */
3695 if (This->e.dga.fb_height < height)
3696 This->e.dga.fb_height = height;
3697 _common_IDirectDrawImpl_SetDisplayMode(This);
3699 #ifdef HAVE_LIBXXF86VM
3700 #ifdef HAVE_LIBXXF86DGA2
3701 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3702 #endif /* defined(HAVE_LIBXXF86DGA2) */
3704 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3705 XF86VidModeModeLine mod_tmp;
3706 /* int dotclock_tmp; */
3708 /* save original video mode and set fullscreen if available*/
3709 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3710 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3711 orig_mode->hdisplay = mod_tmp.hdisplay;
3712 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3713 orig_mode->hsyncend = mod_tmp.hsyncend;
3714 orig_mode->htotal = mod_tmp.htotal;
3715 orig_mode->vdisplay = mod_tmp.vdisplay;
3716 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3717 orig_mode->vsyncend = mod_tmp.vsyncend;
3718 orig_mode->vtotal = mod_tmp.vtotal;
3719 orig_mode->flags = mod_tmp.flags;
3720 orig_mode->private = mod_tmp.private;
3722 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3723 for (i=0;i<mode_count;i++)
3725 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3727 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3728 *vidmode = *(all_modes[i]);
3731 TSXFree(all_modes[i]->private);
3733 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3737 WARN("Fullscreen mode not available!\n");
3741 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3742 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3743 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3744 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3750 /* FIXME: this function OVERWRITES several signal handlers.
3751 * can we save them? and restore them later? In a way that
3752 * it works for the library too?
3754 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3755 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3757 #ifdef RESTORE_SIGNALS
3762 #endif /* defined(HAVE_LIBXXF86DGA) */
3764 /* *************************************
3765 16 / 15 bpp to palettized 8 bpp
3766 ************************************* */
3767 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3768 unsigned char *c_src = (unsigned char *) src;
3769 unsigned short *c_dst = (unsigned short *) dst;
3772 if (palette != NULL) {
3773 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3775 for (y = height; y--; ) {
3776 #if defined(__i386__) && defined(__GNUC__)
3777 /* gcc generates slightly inefficient code for the the copy / lookup,
3778 * it generates one excess memory access (to pal) per pixel. Since
3779 * we know that pal is not modified by the memory write we can
3780 * put it into a register and reduce the number of memory accesses
3781 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3782 * (This is not guaranteed to be the fastest method.)
3784 __asm__ __volatile__(
3788 " movw (%%edx,%%eax,2),%%ax\n"
3790 " xor %%eax,%%eax\n"
3792 : "=S" (c_src), "=D" (c_dst)
3793 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3794 : "eax", "cc", "memory"
3796 c_src+=(pitch-width);
3798 unsigned char * srclineend = c_src+width;
3799 while (c_src < srclineend)
3800 *c_dst++ = pal[*c_src++];
3801 c_src+=(pitch-width);
3805 WARN("No palette set...\n");
3806 memset(dst, 0, width * height * 2);
3809 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3811 unsigned short *pal = (unsigned short *) screen_palette;
3813 for (i = 0; i < count; i++)
3814 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3815 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3816 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3818 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3820 unsigned short *pal = (unsigned short *) screen_palette;
3822 for (i = 0; i < count; i++)
3823 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3824 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3825 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3828 /* *************************************
3829 24 to palettized 8 bpp
3830 ************************************* */
3831 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3832 unsigned char *c_src = (unsigned char *) src;
3833 unsigned char *c_dst = (unsigned char *) dst;
3836 if (palette != NULL) {
3837 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3839 for (y = height; y--; ) {
3840 unsigned char * srclineend = c_src+width;
3841 while (c_src < srclineend ) {
3842 register long pixel = pal[*c_src++];
3844 *c_dst++ = pixel>>8;
3845 *c_dst++ = pixel>>16;
3847 c_src+=(pitch-width);
3850 WARN("No palette set...\n");
3851 memset(dst, 0, width * height * 4);
3854 /* *************************************
3855 32 bpp to palettized 8 bpp
3856 ************************************* */
3857 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3858 unsigned char *c_src = (unsigned char *) src;
3859 unsigned int *c_dst = (unsigned int *) dst;
3862 if (palette != NULL) {
3863 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3865 for (y = height; y--; ) {
3866 #if defined(__i386__) && defined(__GNUC__)
3867 /* See comment in pixel_convert_16_to_8 */
3868 __asm__ __volatile__(
3872 " movl (%%edx,%%eax,4),%%eax\n"
3874 " xor %%eax,%%eax\n"
3876 : "=S" (c_src), "=D" (c_dst)
3877 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3878 : "eax", "cc", "memory"
3880 c_src+=(pitch-width);
3882 unsigned char * srclineend = c_src+width;
3883 while (c_src < srclineend )
3884 *c_dst++ = pal[*c_src++];
3885 c_src+=(pitch-width);
3889 WARN("No palette set...\n");
3890 memset(dst, 0, width * height * 4);
3894 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3896 unsigned int *pal = (unsigned int *) screen_palette;
3898 for (i = 0; i < count; i++)
3899 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
3900 (((unsigned int) palent[i].peGreen) << 8) |
3901 ((unsigned int) palent[i].peBlue));
3904 /* *************************************
3906 ************************************* */
3907 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3908 unsigned short *c_src = (unsigned short *) src;
3909 unsigned int *c_dst = (unsigned int *) dst;
3912 for (y = height; y--; ) {
3913 unsigned short * srclineend = c_src+width;
3914 while (c_src < srclineend ) {
3915 *c_dst++ = (((*c_src & 0xF800) << 8) |
3916 ((*c_src & 0x07E0) << 5) |
3917 ((*c_src & 0x001F) << 3));
3920 c_src+=((pitch/2)-width);
3925 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
3926 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3928 ICOM_THIS(IDirectDrawImpl,iface);
3933 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3934 This, width, height, depth);
3936 switch ((c = _common_depth_to_pixelformat(depth,
3937 &(This->d.directdraw_pixelformat),
3938 &(This->d.screen_pixelformat),
3939 &(This->d.pixmap_depth)))) {
3941 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
3942 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
3943 return DDERR_UNSUPPORTEDMODE;
3947 This->d.pixel_convert = NULL;
3948 This->d.palette_convert = NULL;
3952 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
3954 /* Set the depth convertion routines */
3955 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
3956 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
3959 This->d.width = width;
3960 This->d.height = height;
3962 _common_IDirectDrawImpl_SetDisplayMode(This);
3964 tmpWnd = WIN_FindWndPtr(This->d.window);
3965 This->d.paintable = 1;
3966 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
3967 WIN_ReleaseWndPtr(tmpWnd);
3969 /* We don't have a context for this window. Host off the desktop */
3970 if( !This->d.drawable )
3972 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3973 WIN_ReleaseDesktop();
3975 TRACE("Setting drawable to %ld\n", This->d.drawable);
3980 #ifdef HAVE_LIBXXF86DGA
3981 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
3982 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
3984 ICOM_THIS(IDirectDraw2Impl,iface);
3985 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
3986 if (!caps1 && !caps2)
3987 return DDERR_INVALIDPARAMS;
3989 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
3990 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3991 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
3994 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
3995 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
3996 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4000 #endif /* defined(HAVE_LIBXXF86DGA) */
4002 static void fill_caps(LPDDCAPS caps) {
4003 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4004 Need to be fixed, though.. */
4008 caps->dwSize = sizeof(*caps);
4009 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4010 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4011 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4013 caps->dwFXAlphaCaps = 0;
4014 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4016 caps->dwZBufferBitDepths = DDBD_16;
4017 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4018 to put textures in video memory.
4019 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4021 caps->dwVidMemTotal = 8192 * 1024;
4022 caps->dwVidMemFree = 8192 * 1024;
4023 /* These are all the supported capabilities of the surfaces */
4024 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4025 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4026 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4027 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4029 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4030 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4031 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4035 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4036 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4038 ICOM_THIS(IDirectDraw2Impl,iface);
4039 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4041 /* Put the same caps for the two capabilities */
4048 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4049 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4051 ICOM_THIS(IDirectDraw2Impl,iface);
4052 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4053 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4054 This,x,ilpddclip,lpunk
4056 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4057 (*ilpddclip)->ref = 1;
4058 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4062 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4063 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4067 if (TRACE_ON(ddraw))
4068 _dump_paletteformat(dwFlags);
4070 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4071 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4072 (*lpddpal)->ref = 1;
4073 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4074 (*lpddpal)->installed = 0;
4076 if (dwFlags & DDPCAPS_1BIT)
4078 else if (dwFlags & DDPCAPS_2BIT)
4080 else if (dwFlags & DDPCAPS_4BIT)
4082 else if (dwFlags & DDPCAPS_8BIT)
4085 ERR("unhandled palette format\n");
4090 /* Now, if we are in 'depth conversion mode', create the screen palette */
4091 if (This->d.palette_convert != NULL)
4092 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4094 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4095 } else if (This->d.palette_convert != NULL) {
4096 /* In that case, put all 0xFF */
4097 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4103 #ifdef HAVE_LIBXXF86DGA
4104 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4105 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4107 ICOM_THIS(IDirectDraw2Impl,iface);
4108 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4112 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4113 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4114 if (res != 0) return res;
4115 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4116 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4117 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll);
4119 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4120 (*ilpddpal)->cm = 0;
4122 if (((*ilpddpal)->cm)&&xsize) {
4123 for (i=0;i<xsize;i++) {
4126 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4127 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4128 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4129 xc.flags = DoRed|DoBlue|DoGreen;
4131 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4136 #endif /* defined(HAVE_LIBXXF86DGA) */
4138 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4139 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4141 ICOM_THIS(IDirectDraw2Impl,iface);
4142 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4146 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4147 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4148 if (res != 0) return res;
4149 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4153 #ifdef HAVE_LIBXXF86DGA
4154 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4155 ICOM_THIS(IDirectDraw2Impl,iface);
4156 TRACE("(%p)->()\n",This);
4158 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4159 #ifdef RESTORE_SIGNALS
4164 #endif /* defined(HAVE_LIBXXF86DGA) */
4166 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4167 ICOM_THIS(IDirectDraw2Impl,iface);
4168 TRACE("(%p)->RestoreDisplayMode()\n", This);
4173 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4174 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4176 ICOM_THIS(IDirectDraw2Impl,iface);
4177 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4181 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4182 ICOM_THIS(IDirectDraw2Impl,iface);
4183 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4185 return ++(This->ref);
4188 #ifdef HAVE_LIBXXF86DGA
4189 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4190 ICOM_THIS(IDirectDraw2Impl,iface);
4191 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4193 if (!--(This->ref)) {
4194 #ifdef HAVE_LIBXXF86DGA2
4195 if (This->e.dga.version == 2) {
4196 TRACE("Closing access to the FrameBuffer\n");
4197 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4199 /* Set the input handling back to absolute */
4200 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4202 /* Ungrab mouse and keyboard */
4203 TSXUngrabPointer(display, CurrentTime);
4204 TSXUngrabKeyboard(display, CurrentTime);
4206 #endif /* defined(HAVE_LIBXXF86DGA2) */
4207 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4208 if (This->d.window && (This->d.mainWindow != This->d.window))
4209 DestroyWindow(This->d.window);
4210 #ifdef HAVE_LIBXXF86VM
4212 TSXF86VidModeSwitchToMode(
4214 DefaultScreen(display),
4216 if (orig_mode->privsize)
4217 TSXFree(orig_mode->private);
4223 #ifdef RESTORE_SIGNALS
4226 HeapFree(GetProcessHeap(),0,This);
4231 #endif /* defined(HAVE_LIBXXF86DGA) */
4233 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4234 ICOM_THIS(IDirectDraw2Impl,iface);
4235 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4237 if (!--(This->ref)) {
4238 if (This->d.window && (This->d.mainWindow != This->d.window))
4239 DestroyWindow(This->d.window);
4240 HeapFree(GetProcessHeap(),0,This);
4243 /* FIXME: destroy window ... */
4247 #ifdef HAVE_LIBXXF86DGA
4248 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4249 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4251 ICOM_THIS(IDirectDraw2Impl,iface);
4254 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4255 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4256 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4258 IDirectDraw2_AddRef(iface);
4260 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4264 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4265 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4266 IDirectDraw2_AddRef(iface);
4269 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4273 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4274 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4275 IDirectDraw2_AddRef(iface);
4278 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4282 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4283 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4284 IDirectDraw2_AddRef(iface);
4287 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4291 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4294 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4296 d3d->ddraw = (IDirectDrawImpl*)This;
4297 IDirectDraw2_AddRef(iface);
4298 ICOM_VTBL(d3d) = &d3dvt;
4301 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4305 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4306 IDirect3D2Impl* d3d;
4308 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4310 d3d->ddraw = (IDirectDrawImpl*)This;
4311 IDirectDraw2_AddRef(iface);
4312 ICOM_VTBL(d3d) = &d3d2vt;
4315 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4319 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4320 return OLE_E_ENUM_NOMORE;
4322 #endif /* defined(HAVE_LIBXXF86DGA) */
4324 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4325 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4327 ICOM_THIS(IDirectDraw2Impl,iface);
4330 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
4331 TRACE("(%p)->(%s,%p)\n",This,xrefiid,obj);
4332 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4334 IDirectDraw2_AddRef(iface);
4336 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4340 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4341 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4342 IDirectDraw2_AddRef(iface);
4345 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4349 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4350 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4351 IDirectDraw2_AddRef(iface);
4354 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4358 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4359 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4360 IDirectDraw2_AddRef(iface);
4363 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4367 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4370 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4372 d3d->ddraw = (IDirectDrawImpl*)This;
4373 IDirectDraw2_AddRef(iface);
4374 ICOM_VTBL(d3d) = &d3dvt;
4377 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4381 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4382 IDirect3D2Impl* d3d;
4384 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4386 d3d->ddraw = (IDirectDrawImpl*)This;
4387 IDirectDraw2_AddRef(iface);
4388 ICOM_VTBL(d3d) = &d3d2vt;
4391 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4395 WARN("(%p):interface for IID %s _NOT_ found!\n",This,xrefiid);
4396 return OLE_E_ENUM_NOMORE;
4399 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4400 LPDIRECTDRAW2 iface,BOOL *status
4402 ICOM_THIS(IDirectDraw2Impl,iface);
4403 TRACE("(%p)->(%p)\n",This,status);
4408 #ifdef HAVE_LIBXXF86DGA
4409 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4410 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4412 ICOM_THIS(IDirectDraw2Impl,iface);
4413 DDSURFACEDESC ddsfd;
4416 } modes[5] = { /* some of the usual modes */
4423 static int depths[4] = {8,16,24,32};
4426 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4427 ddsfd.dwSize = sizeof(ddsfd);
4428 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4429 if (dwFlags & DDEDM_REFRESHRATES) {
4430 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4431 ddsfd.u.dwRefreshRate = 60;
4434 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4435 ddsfd.dwBackBufferCount = 1;
4436 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4437 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4438 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4439 /* FIXME: those masks would have to be set in depth > 8 */
4441 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4442 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4443 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4444 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4445 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4446 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4448 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4450 /* FIXME: We should query those from X itself */
4451 switch (depths[i]) {
4453 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4454 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4455 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4458 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4459 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4460 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4463 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4464 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4465 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4470 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4471 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4472 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4473 if (!modescb(&ddsfd,context)) return DD_OK;
4475 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4476 ddsfd.dwWidth = modes[j].w;
4477 ddsfd.dwHeight = modes[j].h;
4478 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4479 if (!modescb(&ddsfd,context)) return DD_OK;
4482 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4483 /* modeX is not standard VGA */
4485 ddsfd.dwHeight = 200;
4486 ddsfd.dwWidth = 320;
4487 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4488 if (!modescb(&ddsfd,context)) return DD_OK;
4493 #endif /* defined(HAVE_LIBXXF86DGA) */
4495 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4496 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4498 ICOM_THIS(IDirectDraw2Impl,iface);
4500 XPixmapFormatValues *pf;
4502 int nvisuals, npixmap, i, emu;
4503 int has_mode[] = { 0, 0, 0, 0 };
4504 int has_depth[] = { 8, 15, 16, 24 };
4505 DDSURFACEDESC ddsfd;
4508 } modes[] = { /* some of the usual modes */
4516 DWORD maxWidth, maxHeight;
4518 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4519 ddsfd.dwSize = sizeof(ddsfd);
4520 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS;
4521 if (dwFlags & DDEDM_REFRESHRATES) {
4522 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4523 ddsfd.u.dwRefreshRate = 60;
4525 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4526 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4528 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4529 pf = XListPixmapFormats(display, &npixmap);
4533 while ((i < npixmap) ||
4540 for (j = 0; j < 4; j++) {
4541 if (has_depth[j] == pf[i].depth) {
4552 if (has_mode[mode_index] == 0) {
4553 if (mode_index == 0) {
4556 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4557 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4558 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4559 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4560 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4561 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4562 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4563 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4564 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4566 has_mode[mode_index] = 1;
4568 /* All the 'true color' depths (15, 16 and 24)
4569 First, find the corresponding visual to extract the bit masks */
4570 for (j = 0; j < nvisuals; j++) {
4571 if (vi[j].depth == pf[i].depth) {
4572 ddsfd.ddsCaps.dwCaps = 0;
4573 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4574 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4575 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4576 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4577 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4578 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4579 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4580 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4583 has_mode[mode_index] = 1;
4589 ERR("Did not find visual corresponding the the pixmap format !\n");
4595 /* Now to emulated modes */
4596 if (has_mode[emu] == 0) {
4599 int depth = has_depth[emu];
4601 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4602 if (ModeEmulations[c].dest.depth == depth) {
4603 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4604 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4605 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4606 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4608 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4609 if ((vi[j].depth == pf[l].depth) &&
4610 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4611 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4612 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4613 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4614 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4616 ddsfd.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;
4617 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4618 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4619 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4620 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4622 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4623 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4624 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4625 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4626 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4628 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4633 ERR("No visual corresponding to pixmap format !\n");
4647 if (TRACE_ON(ddraw)) {
4648 TRACE("Enumerating with pixel format : \n");
4649 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4653 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4654 /* Do not enumerate modes we cannot handle anyway */
4655 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4658 ddsfd.dwWidth = modes[mode].w;
4659 ddsfd.dwHeight = modes[mode].h;
4661 /* Now, send the mode description to the application */
4662 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4663 if (!modescb(&ddsfd, context))
4667 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4668 /* modeX is not standard VGA */
4669 ddsfd.dwWidth = 320;
4670 ddsfd.dwHeight = 200;
4671 if (!modescb(&ddsfd, context))
4684 #ifdef HAVE_LIBXXF86DGA
4685 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4686 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4688 ICOM_THIS(IDirectDraw2Impl,iface);
4689 TRACE("(%p)->(%p)\n",This,lpddsfd);
4690 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4691 lpddsfd->dwHeight = This->d.height;
4692 lpddsfd->dwWidth = This->d.width;
4693 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4694 lpddsfd->dwBackBufferCount = 1;
4695 lpddsfd->u.dwRefreshRate = 60;
4696 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4697 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4698 if (TRACE_ON(ddraw)) {
4699 _dump_surface_desc(lpddsfd);
4703 #endif /* defined(HAVE_LIBXXF86DGA) */
4705 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4706 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4708 ICOM_THIS(IDirectDraw2Impl,iface);
4709 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4710 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4711 lpddsfd->dwHeight = This->d.height;
4712 lpddsfd->dwWidth = This->d.width;
4713 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4714 lpddsfd->dwBackBufferCount = 1;
4715 lpddsfd->u.dwRefreshRate = 60;
4716 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4717 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4718 if (TRACE_ON(ddraw)) {
4719 _dump_surface_desc(lpddsfd);
4724 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4725 ICOM_THIS(IDirectDraw2Impl,iface);
4726 TRACE("(%p)->()\n",This);
4730 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4731 LPDIRECTDRAW2 iface,LPDWORD freq
4733 ICOM_THIS(IDirectDraw2Impl,iface);
4734 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4735 *freq = 60*100; /* 60 Hz */
4739 /* what can we directly decompress? */
4740 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4741 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4743 ICOM_THIS(IDirectDraw2Impl,iface);
4744 FIXME("(%p,%p,%p), stub\n",This,x,y);
4748 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4749 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4751 ICOM_THIS(IDirectDraw2Impl,iface);
4752 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4756 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4757 LPDIRECTDRAW2 iface )
4759 ICOM_THIS(IDirectDraw2Impl,iface);
4760 FIXME("(%p)->()\n", This );
4765 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4766 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4767 ICOM_THIS(IDirectDraw2Impl,iface);
4768 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4773 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4774 LPDWORD lpdwScanLine) {
4775 ICOM_THIS(IDirectDraw2Impl,iface);
4776 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4781 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4783 ICOM_THIS(IDirectDraw2Impl,iface);
4784 FIXME("(%p)->(%p)\n", This, lpGUID);
4789 #ifdef HAVE_LIBXXF86DGA
4791 /* Note: Hack so we can reuse the old functions without compiler warnings */
4792 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4793 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4795 # define XCAST(fun) (void *)
4798 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
4800 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4801 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
4802 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4803 XCAST(Release)DGA_IDirectDraw2Impl_Release,
4804 XCAST(Compact)IDirectDraw2Impl_Compact,
4805 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4806 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
4807 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
4808 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4809 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
4810 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4811 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4812 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
4813 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
4814 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4815 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4816 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4817 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4818 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4819 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4820 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
4821 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4822 DGA_IDirectDrawImpl_SetDisplayMode,
4823 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4828 #endif /* defined(HAVE_LIBXXF86DGA) */
4830 /* Note: Hack so we can reuse the old functions without compiler warnings */
4831 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4832 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4834 # define XCAST(fun) (void *)
4837 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
4839 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4840 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
4841 XCAST(AddRef)IDirectDraw2Impl_AddRef,
4842 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
4843 XCAST(Compact)IDirectDraw2Impl_Compact,
4844 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
4845 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
4846 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
4847 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
4848 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
4849 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
4850 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
4851 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
4852 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
4853 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
4854 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
4855 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
4856 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
4857 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
4858 XCAST(Initialize)IDirectDraw2Impl_Initialize,
4859 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4860 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
4861 Xlib_IDirectDrawImpl_SetDisplayMode,
4862 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
4867 /*****************************************************************************
4872 #ifdef HAVE_LIBXXF86DGA
4873 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
4874 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
4876 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
4877 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4879 #endif /* defined(HAVE_LIBXXF86DGA) */
4881 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
4882 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
4884 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
4885 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
4888 #ifdef HAVE_LIBXXF86DGA
4889 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
4890 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4892 ICOM_THIS(IDirectDraw2Impl,iface);
4893 TRACE("(%p)->(%p,%p,%p)\n",
4894 This,ddscaps,total,free
4896 if (total) *total = This->e.dga.fb_memsize * 1024;
4897 if (free) *free = This->e.dga.fb_memsize * 1024;
4900 #endif /* defined(HAVE_LIBXXF86DGA) */
4902 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4903 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
4905 ICOM_THIS(IDirectDraw2Impl,iface);
4906 TRACE("(%p)->(%p,%p,%p)\n",
4907 This,ddscaps,total,free
4909 if (total) *total = 2048 * 1024;
4910 if (free) *free = 2048 * 1024;
4914 #ifdef HAVE_LIBXXF86DGA
4915 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
4917 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4918 DGA_IDirectDraw2Impl_QueryInterface,
4919 IDirectDraw2Impl_AddRef,
4920 DGA_IDirectDraw2Impl_Release,
4921 IDirectDraw2Impl_Compact,
4922 IDirectDraw2Impl_CreateClipper,
4923 DGA_IDirectDraw2Impl_CreatePalette,
4924 DGA_IDirectDraw2Impl_CreateSurface,
4925 IDirectDraw2Impl_DuplicateSurface,
4926 DGA_IDirectDraw2Impl_EnumDisplayModes,
4927 IDirectDraw2Impl_EnumSurfaces,
4928 IDirectDraw2Impl_FlipToGDISurface,
4929 DGA_IDirectDraw2Impl_GetCaps,
4930 DGA_IDirectDraw2Impl_GetDisplayMode,
4931 IDirectDraw2Impl_GetFourCCCodes,
4932 IDirectDraw2Impl_GetGDISurface,
4933 IDirectDraw2Impl_GetMonitorFrequency,
4934 IDirectDraw2Impl_GetScanLine,
4935 IDirectDraw2Impl_GetVerticalBlankStatus,
4936 IDirectDraw2Impl_Initialize,
4937 DGA_IDirectDraw2Impl_RestoreDisplayMode,
4938 IDirectDraw2Impl_SetCooperativeLevel,
4939 DGA_IDirectDraw2Impl_SetDisplayMode,
4940 IDirectDraw2Impl_WaitForVerticalBlank,
4941 DGA_IDirectDraw2Impl_GetAvailableVidMem
4943 #endif /* defined(HAVE_LIBXXF86DGA) */
4945 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
4947 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4948 Xlib_IDirectDraw2Impl_QueryInterface,
4949 IDirectDraw2Impl_AddRef,
4950 Xlib_IDirectDraw2Impl_Release,
4951 IDirectDraw2Impl_Compact,
4952 IDirectDraw2Impl_CreateClipper,
4953 Xlib_IDirectDraw2Impl_CreatePalette,
4954 Xlib_IDirectDraw2Impl_CreateSurface,
4955 IDirectDraw2Impl_DuplicateSurface,
4956 Xlib_IDirectDraw2Impl_EnumDisplayModes,
4957 IDirectDraw2Impl_EnumSurfaces,
4958 IDirectDraw2Impl_FlipToGDISurface,
4959 Xlib_IDirectDraw2Impl_GetCaps,
4960 Xlib_IDirectDraw2Impl_GetDisplayMode,
4961 IDirectDraw2Impl_GetFourCCCodes,
4962 IDirectDraw2Impl_GetGDISurface,
4963 IDirectDraw2Impl_GetMonitorFrequency,
4964 IDirectDraw2Impl_GetScanLine,
4965 IDirectDraw2Impl_GetVerticalBlankStatus,
4966 IDirectDraw2Impl_Initialize,
4967 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
4968 IDirectDraw2Impl_SetCooperativeLevel,
4969 Xlib_IDirectDraw2Impl_SetDisplayMode,
4970 IDirectDraw2Impl_WaitForVerticalBlank,
4971 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4974 /*****************************************************************************
4979 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
4981 LPDIRECTDRAWSURFACE *lpDDS) {
4982 ICOM_THIS(IDirectDraw4Impl,iface);
4983 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
4988 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
4989 ICOM_THIS(IDirectDraw4Impl,iface);
4990 FIXME("(%p)->()\n", This);
4995 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
4996 ICOM_THIS(IDirectDraw4Impl,iface);
4997 FIXME("(%p)->()\n", This);
5002 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5003 LPDDDEVICEIDENTIFIER lpdddi,
5005 ICOM_THIS(IDirectDraw4Impl,iface);
5006 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5011 #ifdef HAVE_LIBXXF86DGA
5013 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5014 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5016 # define XCAST(fun) (void*)
5019 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5021 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5022 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5023 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5024 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5025 XCAST(Compact)IDirectDraw2Impl_Compact,
5026 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5027 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5028 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5029 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5030 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5031 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5032 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5033 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5034 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5035 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5036 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5037 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5038 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5039 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5040 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5041 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5042 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5043 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5044 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5045 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5046 IDirectDraw4Impl_GetSurfaceFromDC,
5047 IDirectDraw4Impl_RestoreAllSurfaces,
5048 IDirectDraw4Impl_TestCooperativeLevel,
5049 IDirectDraw4Impl_GetDeviceIdentifier
5054 #endif /* defined(HAVE_LIBXXF86DGA) */
5056 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5057 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5059 # define XCAST(fun) (void*)
5062 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5064 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5065 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5066 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5067 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5068 XCAST(Compact)IDirectDraw2Impl_Compact,
5069 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5070 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5071 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5072 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5073 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5074 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5075 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5076 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5077 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5078 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5079 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5080 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5081 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5082 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5083 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5084 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5085 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5086 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5087 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5088 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5089 IDirectDraw4Impl_GetSurfaceFromDC,
5090 IDirectDraw4Impl_RestoreAllSurfaces,
5091 IDirectDraw4Impl_TestCooperativeLevel,
5092 IDirectDraw4Impl_GetDeviceIdentifier
5097 /******************************************************************************
5101 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5104 IDirectDrawImpl* ddraw = NULL;
5107 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5109 SetLastError( ERROR_SUCCESS );
5110 ddraw = (IDirectDrawImpl*)GetWindowLongA( hwnd, ddrawXlibThisOffset );
5112 ( ( lastError = GetLastError() ) != ERROR_SUCCESS )
5115 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5120 /* Perform any special direct draw functions */
5122 ddraw->d.paintable = 1;
5124 /* Now let the application deal with the rest of this */
5125 if( ddraw->d.mainWindow )
5128 /* Don't think that we actually need to call this but...
5129 might as well be on the safe side of things... */
5131 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5132 it should be the procedures of our fake window that gets called
5133 instead of those of the window provided by the application.
5134 And with this patch, mouse clicks work with Monkey Island III
5136 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5140 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5141 /* We didn't handle the message - give it to the application */
5142 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5144 ret = CallWindowProcA(tmpWnd->winproc,
5145 ddraw->d.mainWindow, msg, wParam, lParam );
5147 WIN_ReleaseWndPtr(tmpWnd);
5152 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5158 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5164 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5165 #ifdef HAVE_LIBXXF86DGA
5166 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5167 int memsize,banksize,major,minor,flags;
5173 /* Get DGA availability / version */
5174 dga_version = DDRAW_DGA_Available();
5176 if (dga_version == 0) {
5177 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5178 return DDERR_GENERIC;
5181 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5182 (*ilplpDD)->ref = 1;
5183 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5184 #ifdef HAVE_LIBXXF86DGA2
5185 if (dga_version == 1) {
5186 (*ilplpDD)->e.dga.version = 1;
5187 #endif /* defined(HAVE_LIBXXF86DGA2) */
5188 TSXF86DGAQueryVersion(display,&major,&minor);
5189 TRACE("XF86DGA is version %d.%d\n",major,minor);
5190 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5191 if (!(flags & XF86DGADirectPresent))
5192 MESSAGE("direct video is NOT PRESENT.\n");
5193 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5194 (*ilplpDD)->e.dga.fb_width = width;
5195 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5196 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5197 (*ilplpDD)->e.dga.fb_height = height;
5198 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5199 addr,width,banksize,memsize
5201 TRACE("viewport height: %d\n",height);
5202 /* Get the screen dimensions as seen by Wine.
5203 In that case, it may be better to ignore the -desktop mode and return the
5204 real screen size => print a warning */
5205 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5206 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5207 if (((*ilplpDD)->d.height != height) ||
5208 ((*ilplpDD)->d.width != width))
5209 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5210 (*ilplpDD)->e.dga.fb_addr = addr;
5211 (*ilplpDD)->e.dga.fb_memsize = memsize;
5212 (*ilplpDD)->e.dga.vpmask = 0;
5214 /* just assume the default depth is the DGA depth too */
5215 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5216 _common_depth_to_pixelformat(depth, &((*ilplpDD)->d.directdraw_pixelformat), &((*ilplpDD)->d.screen_pixelformat), NULL);
5217 #ifdef RESTORE_SIGNALS
5220 #ifdef HAVE_LIBXXF86DGA2
5222 DDPIXELFORMAT *pf = &((*ilplpDD)->d.directdraw_pixelformat);
5225 int mode_to_use = 0;
5227 (*ilplpDD)->e.dga.version = 2;
5230 TSXGrabPointer(display, DefaultRootWindow(display), True,
5231 PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
5232 GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
5234 TSXGrabKeyboard(display, DefaultRootWindow(display), True, GrabModeAsync,
5235 GrabModeAsync, CurrentTime);
5238 TSXDGAQueryVersion(display,&major,&minor);
5239 TRACE("XDGA is version %d.%d\n",major,minor);
5241 TRACE("Opening the frame buffer.\n");
5242 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5243 ERR("Error opening the frame buffer !!!\n");
5245 TSXUngrabPointer(display, CurrentTime);
5246 TSXUngrabKeyboard(display, CurrentTime);
5248 return DDERR_GENERIC;
5251 /* Set the input handling for relative mouse movements */
5252 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5254 /* List all available modes */
5255 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5256 if (TRACE_ON(ddraw)) {
5257 TRACE("Available modes :\n");
5258 for (i = 0; i < num_modes; i++) {
5259 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5261 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5262 modes[i].viewportWidth, modes[i].viewportHeight,
5264 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5265 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5266 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5267 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5268 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5271 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5272 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5273 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5274 mode_to_use = modes[i].num;
5278 if (mode_to_use == 0) {
5279 ERR("Could not find mode !\n");
5282 DPRINTF("Using mode number %d\n", mode_to_use);
5285 /* Now, get the device / mode description */
5286 (*ilplpDD)->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode_to_use);
5288 (*ilplpDD)->e.dga.fb_width = (*ilplpDD)->e.dga.dev->mode.imageWidth;
5289 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
5290 (*ilplpDD)->e.dga.fb_height = (*ilplpDD)->e.dga.dev->mode.viewportHeight;
5291 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
5292 (*ilplpDD)->e.dga.dev->data,
5293 (*ilplpDD)->e.dga.dev->mode.imageWidth,
5294 ((*ilplpDD)->e.dga.dev->mode.imageWidth *
5295 (*ilplpDD)->e.dga.dev->mode.imageHeight *
5296 ((*ilplpDD)->e.dga.dev->mode.bitsPerPixel / 8))
5298 TRACE("viewport height: %d\n", (*ilplpDD)->e.dga.dev->mode.viewportHeight);
5299 /* Get the screen dimensions as seen by Wine.
5300 In that case, it may be better to ignore the -desktop mode and return the
5301 real screen size => print a warning */
5302 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5303 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5304 (*ilplpDD)->e.dga.fb_addr = (*ilplpDD)->e.dga.dev->data;
5305 (*ilplpDD)->e.dga.fb_memsize = ((*ilplpDD)->e.dga.dev->mode.imageWidth *
5306 (*ilplpDD)->e.dga.dev->mode.imageHeight *
5307 ((*ilplpDD)->e.dga.dev->mode.bitsPerPixel / 8));
5308 (*ilplpDD)->e.dga.vpmask = 0;
5310 /* Fill the screen pixelformat */
5311 if ((*ilplpDD)->e.dga.dev->mode.depth == 8) {
5312 pf->dwFlags = DDPF_PALETTEINDEXED8;
5313 pf->u1.dwRBitMask = 0;
5314 pf->u2.dwGBitMask = 0;
5315 pf->u3.dwBBitMask = 0;
5317 pf->dwFlags = DDPF_RGB;
5318 pf->u1.dwRBitMask = (*ilplpDD)->e.dga.dev->mode.redMask;
5319 pf->u2.dwGBitMask = (*ilplpDD)->e.dga.dev->mode.greenMask;
5320 pf->u3.dwBBitMask = (*ilplpDD)->e.dga.dev->mode.blueMask;
5323 pf->u.dwRGBBitCount = (*ilplpDD)->e.dga.dev->mode.bitsPerPixel;
5324 pf->u4.dwRGBAlphaBitMask= 0;
5326 (*ilplpDD)->d.screen_pixelformat = *pf;
5328 #endif /* defined(HAVE_LIBXXF86DGA2) */
5330 #else /* defined(HAVE_LIBXXF86DGA) */
5331 return DDERR_INVALIDDIRECTDRAWGUID;
5332 #endif /* defined(HAVE_LIBXXF86DGA) */
5336 DDRAW_XSHM_Available(void)
5338 #ifdef HAVE_LIBXXSHM
5339 if (TSXShmQueryExtension(display))
5344 if ((TSXShmQueryVersion(display, &major, &minor, &shpix)) &&
5345 (Options.noXSHM != 1))
5357 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5358 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5361 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5362 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5363 (*ilplpDD)->ref = 1;
5364 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5366 /* At DirectDraw creation, the depth is the default depth */
5367 depth = DefaultDepthOfScreen(X11DRV_GetXScreen());
5368 _common_depth_to_pixelformat(depth,
5369 &((*ilplpDD)->d.directdraw_pixelformat),
5370 &((*ilplpDD)->d.screen_pixelformat),
5371 &((*ilplpDD)->d.pixmap_depth));
5372 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5373 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5375 #ifdef HAVE_LIBXXSHM
5376 /* Test if XShm is available. */
5377 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5378 (*ilplpDD)->e.xlib.xshm_compl = 0;
5379 TRACE("Using XShm extension.\n");
5386 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5387 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5390 /* WND* pParentWindow; */
5394 WINE_StringFromCLSID(lpGUID,xclsid);
5396 sprintf(xclsid,"<guid-0x%08x>",(int)lpGUID);
5400 TRACE("(%s,%p,%p)\n",xclsid,ilplpDD,pUnkOuter);
5403 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5404 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5405 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5406 /* if they didn't request a particular interface, use the best
5408 if (DDRAW_DGA_Available())
5409 lpGUID = &DGA_DirectDraw_GUID;
5411 lpGUID = &XLIB_DirectDraw_GUID;
5414 wc.style = CS_GLOBALCLASS;
5415 wc.lpfnWndProc = Xlib_DDWndProc;
5417 wc.cbWndExtra = /* Defines extra mem for window. This is used for storing this */
5418 sizeof( LPDIRECTDRAW ); /* ddrawXlibThisOffset */
5420 /* We can be a child of the desktop since we're really important */
5422 This code is not useful since hInstance is forced to 0 afterward
5423 pParentWindow = WIN_GetDesktop();
5424 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5430 wc.hCursor = (HCURSOR)IDC_ARROWA;
5431 wc.hbrBackground= NULL_BRUSH;
5432 wc.lpszMenuName = 0;
5433 wc.lpszClassName= "WINE_DirectDraw";
5434 RegisterClassA(&wc);
5436 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5437 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5439 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5440 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5447 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5451 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid,lplpDD,pUnkOuter);
5452 return DDERR_INVALIDDIRECTDRAWGUID;
5455 /*******************************************************************************
5456 * DirectDraw ClassFactory
5458 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5463 /* IUnknown fields */
5464 ICOM_VFIELD(IClassFactory);
5466 } IClassFactoryImpl;
5468 static HRESULT WINAPI
5469 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5470 ICOM_THIS(IClassFactoryImpl,iface);
5474 WINE_StringFromCLSID(riid,buf);
5476 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5477 FIXME("(%p)->(%s,%p),stub!\n",This,buf,ppobj);
5478 return E_NOINTERFACE;
5482 DDCF_AddRef(LPCLASSFACTORY iface) {
5483 ICOM_THIS(IClassFactoryImpl,iface);
5484 return ++(This->ref);
5487 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5488 ICOM_THIS(IClassFactoryImpl,iface);
5489 /* static class, won't be freed */
5490 return --(This->ref);
5493 static HRESULT WINAPI DDCF_CreateInstance(
5494 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5496 ICOM_THIS(IClassFactoryImpl,iface);
5499 WINE_StringFromCLSID(riid,buf);
5500 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,buf,ppobj);
5501 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5502 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5503 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5504 /* FIXME: reuse already created DirectDraw if present? */
5505 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5507 return CLASS_E_CLASSNOTAVAILABLE;
5510 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5511 ICOM_THIS(IClassFactoryImpl,iface);
5512 FIXME("(%p)->(%d),stub!\n",This,dolock);
5516 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5518 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5519 DDCF_QueryInterface,
5522 DDCF_CreateInstance,
5525 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5527 /*******************************************************************************
5528 * DllGetClassObject [DDRAW.13]
5529 * Retrieves class object from a DLL object
5532 * Docs say returns STDAPI
5535 * rclsid [I] CLSID for the class object
5536 * riid [I] Reference to identifier of interface for class object
5537 * ppv [O] Address of variable to receive interface pointer for riid
5541 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5544 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5546 char buf[80],xbuf[80];
5549 WINE_StringFromCLSID(rclsid,xbuf);
5551 sprintf(xbuf,"<guid-0x%04x>",LOWORD(rclsid));
5553 WINE_StringFromCLSID(riid,buf);
5555 sprintf(buf,"<guid-0x%04x>",LOWORD(riid));
5556 WINE_StringFromCLSID(riid,xbuf);
5557 TRACE("(%p,%p,%p)\n", xbuf, buf, ppv);
5558 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5559 *ppv = (LPVOID)&DDRAW_CF;
5560 IClassFactory_AddRef((IClassFactory*)*ppv);
5563 FIXME("(%p,%p,%p): no interface found.\n", xbuf, buf, ppv);
5564 return CLASS_E_CLASSNOTAVAILABLE;
5568 /*******************************************************************************
5569 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5575 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5577 FIXME("(void): stub\n");
5581 #else /* !defined(X_DISPLAY_MISSING) */
5588 typedef void *LPUNKNOWN;
5589 typedef void *LPDIRECTDRAW;
5590 typedef void *LPDIRECTDRAWCLIPPER;
5591 typedef void *LPDDENUMCALLBACKA;
5592 typedef void *LPDDENUMCALLBACKEXA;
5593 typedef void *LPDDENUMCALLBACKEXW;
5594 typedef void *LPDDENUMCALLBACKW;
5596 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5601 HRESULT WINAPI DirectDrawCreate(
5602 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5607 HRESULT WINAPI DirectDrawCreateClipper(
5608 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5613 HRESULT WINAPI DirectDrawEnumerateA(
5614 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5619 HRESULT WINAPI DirectDrawEnumerateExA(
5620 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5625 HRESULT WINAPI DirectDrawEnumerateExW(
5626 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5631 HRESULT WINAPI DirectDrawEnumerateW(
5632 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5637 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5639 return CLASS_E_CLASSNOTAVAILABLE;
5642 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5647 #endif /* !defined(X_DISPLAY_MISSING) */