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>
64 #include "wine/exception.h"
67 #include "debugtools.h"
73 static char *ddProp = "WINE_DDRAW_Property";
75 /* This for all the enumeration and creation of D3D-related objects */
76 #include "ddraw_private.h"
77 #include "d3d_private.h"
79 DEFAULT_DEBUG_CHANNEL(ddraw);
81 /* Restore signal handlers overwritten by XF86DGA
83 #define RESTORE_SIGNALS
85 /* Get DDSCAPS of surface (shortcutmacro) */
86 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
88 /* Get the number of bytes per pixel for a given surface */
89 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
91 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
93 /* Where do these GUIDs come from? mkuuid.
94 * They exist solely to distinguish between the targets Wine support,
95 * and should be different than any other GUIDs in existence.
97 static GUID DGA_DirectDraw_GUID = { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
101 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
104 static GUID XLIB_DirectDraw_GUID = { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
108 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
111 #ifdef HAVE_LIBXXF86DGA
112 static struct ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt;
113 static struct ICOM_VTABLE(IDirectDraw) dga_ddvt;
114 static struct ICOM_VTABLE(IDirectDraw2) dga_dd2vt;
115 static struct ICOM_VTABLE(IDirectDraw4) dga_dd4vt;
116 static struct ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt;
117 #endif /* defined(HAVE_LIBXXF86DGA) */
119 #ifdef HAVE_LIBXXF86DGA2
120 static struct ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt;
121 #endif /* defined(HAVE_LIBXXF86DGA2) */
123 static struct ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt;
124 static struct ICOM_VTABLE(IDirectDraw) xlib_ddvt;
125 static struct ICOM_VTABLE(IDirectDraw2) xlib_dd2vt;
126 static struct ICOM_VTABLE(IDirectDraw4) xlib_dd4vt;
127 static struct ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt;
129 static struct ICOM_VTABLE(IDirectDrawClipper) ddclipvt;
130 static struct ICOM_VTABLE(IDirect3D) d3dvt;
131 static struct ICOM_VTABLE(IDirect3D2) d3d2vt;
133 /* This is for mode-emulation */
135 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
136 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
137 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
138 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
139 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
140 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) ;
141 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) ;
145 unsigned short depth;
152 void (*pixel_convert)(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette);
153 void (*palette_convert)(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count);
157 ConvertMode screen, dest;
161 static Convert ModeEmulations[] = {
162 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8, palette_convert_24_to_8 } },
163 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16, NULL } },
164 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8, palette_convert_24_to_8 } },
165 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_16_to_8 } },
166 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8, palette_convert_15_to_8 } },
169 #ifdef HAVE_LIBXXF86VM
170 static XF86VidModeModeInfo *orig_mode = NULL;
174 static int XShmErrorFlag = 0;
177 static inline BOOL get_option( const char *name, BOOL def )
179 return PROFILE_GetWineIniBool( "x11drv", name, def );
183 DDRAW_DGA_Available(void)
185 #ifdef HAVE_LIBXXF86DGA
186 int fd, evbase, evret, majver, minver;
187 static BYTE return_value = 0xFF;
189 /* This prevents from probing X times for DGA */
190 if (return_value != 0xFF)
193 if (!get_option( "UseDGA", 1 )) {
198 /* First, query the extenstion and its version */
199 if (!TSXF86DGAQueryExtension(display,&evbase,&evret)) {
204 if (!TSXF86DGAQueryVersion(display,&majver,&minver)) {
209 #ifdef HAVE_LIBXXF86DGA2
211 /* We have DGA 2.0 available ! */
212 if (TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
213 TSXDGACloseFramebuffer(display, DefaultScreen(display));
221 #endif /* defined(HAVE_LIBXXF86DGA2) */
223 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
224 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
225 /* others. --stephenc */
226 if ((fd = open("/dev/mem", O_RDWR)) != -1)
235 #ifdef HAVE_LIBXXF86DGA2
237 #endif /* defined(HAVE_LIBXXF86DGA2) */
238 #else /* defined(HAVE_LIBXXF86DGA) */
240 #endif /* defined(HAVE_LIBXXF86DGA) */
243 /**********************************************************************/
248 } DirectDrawEnumerateProcData;
250 /***********************************************************************
251 * DirectDrawEnumerateExA (DDRAW.*)
253 HRESULT WINAPI DirectDrawEnumerateExA(
254 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
256 TRACE("(%p,%p, %08lx)\n", lpCallback, lpContext, dwFlags);
258 if (TRACE_ON(ddraw)) {
259 DPRINTF(" Flags : ");
260 if (dwFlags & DDENUM_ATTACHEDSECONDARYDEVICES)
261 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
262 if (dwFlags & DDENUM_DETACHEDSECONDARYDEVICES)
263 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
264 if (dwFlags & DDENUM_NONDISPLAYDEVICES)
265 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
269 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
270 /* For the moment, Wine does not support any 3D only accelerators */
273 if (dwFlags == DDENUM_NONDISPLAYDEVICES) {
274 /* For the moment, Wine does not support any attached secondary devices */
278 if (DDRAW_DGA_Available()) {
279 TRACE("Enumerating DGA interface\n");
280 if (!lpCallback(&DGA_DirectDraw_GUID, "WINE with XFree86 DGA", "display", lpContext, 0))
284 TRACE("Enumerating Xlib interface\n");
285 if (!lpCallback(&XLIB_DirectDraw_GUID, "WINE with Xlib", "display", lpContext, 0))
288 TRACE("Enumerating Default interface\n");
289 if (!lpCallback(NULL,"WINE (default)", "display", lpContext, 0))
295 /***********************************************************************
296 * DirectDrawEnumerateExW (DDRAW.*)
299 static BOOL CALLBACK DirectDrawEnumerateExProcW(
300 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
301 LPVOID lpContext, HMONITOR hm)
303 DirectDrawEnumerateProcData *pEPD =
304 (DirectDrawEnumerateProcData *) lpContext;
305 LPWSTR lpDriverDescriptionW =
306 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription);
307 LPWSTR lpDriverNameW =
308 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName);
310 BOOL bResult = (*(LPDDENUMCALLBACKEXW *) pEPD->lpCallback)(
311 lpGUID, lpDriverDescriptionW, lpDriverNameW, pEPD->lpContext, hm);
313 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW);
314 HeapFree(GetProcessHeap(), 0, lpDriverNameW);
319 /**********************************************************************/
321 HRESULT WINAPI DirectDrawEnumerateExW(
322 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
324 DirectDrawEnumerateProcData epd;
325 epd.lpCallback = (LPVOID) lpCallback;
326 epd.lpContext = lpContext;
328 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW,
332 /***********************************************************************
333 * DirectDrawEnumerateA (DDRAW.*)
336 static BOOL CALLBACK DirectDrawEnumerateProcA(
337 GUID *lpGUID, LPSTR lpDriverDescription, LPSTR lpDriverName,
338 LPVOID lpContext, HMONITOR hm)
340 DirectDrawEnumerateProcData *pEPD =
341 (DirectDrawEnumerateProcData *) lpContext;
343 return ((LPDDENUMCALLBACKA) pEPD->lpCallback)(
344 lpGUID, lpDriverDescription, lpDriverName, pEPD->lpContext);
347 /**********************************************************************/
349 HRESULT WINAPI DirectDrawEnumerateA(
350 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
352 DirectDrawEnumerateProcData epd;
353 epd.lpCallback = (LPVOID) lpCallback;
354 epd.lpContext = lpContext;
356 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA,
360 /***********************************************************************
361 * DirectDrawEnumerateW (DDRAW.*)
364 static BOOL WINAPI DirectDrawEnumerateProcW(
365 GUID *lpGUID, LPWSTR lpDriverDescription, LPWSTR lpDriverName,
366 LPVOID lpContext, HMONITOR hm)
368 DirectDrawEnumerateProcData *pEPD =
369 (DirectDrawEnumerateProcData *) lpContext;
371 return ((LPDDENUMCALLBACKW) pEPD->lpCallback)(
372 lpGUID, lpDriverDescription, lpDriverName,
376 /**********************************************************************/
378 HRESULT WINAPI DirectDrawEnumerateW(
379 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
381 DirectDrawEnumerateProcData epd;
382 epd.lpCallback = (LPVOID) lpCallback;
383 epd.lpContext = lpContext;
385 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW,
389 /***********************************************************************
390 * DSoundHelp (DDRAW.?)
393 /* What is this doing here? */
395 DSoundHelp(DWORD x,DWORD y,DWORD z) {
396 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x,y,z);
400 /******************************************************************************
401 * internal helper functions
403 static void _dump_DDBLTFX(DWORD flagmask) {
409 #define FE(x) { x, #x},
410 FE(DDBLTFX_ARITHSTRETCHY)
411 FE(DDBLTFX_MIRRORLEFTRIGHT)
412 FE(DDBLTFX_MIRRORUPDOWN)
413 FE(DDBLTFX_NOTEARING)
414 FE(DDBLTFX_ROTATE180)
415 FE(DDBLTFX_ROTATE270)
417 FE(DDBLTFX_ZBUFFERRANGE)
418 FE(DDBLTFX_ZBUFFERBASEDEST)
421 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
422 if (flags[i].mask & flagmask) {
423 DPRINTF("%s ",flags[i].name);
430 static void _dump_DDBLTFAST(DWORD flagmask) {
436 #define FE(x) { x, #x},
437 FE(DDBLTFAST_NOCOLORKEY)
438 FE(DDBLTFAST_SRCCOLORKEY)
439 FE(DDBLTFAST_DESTCOLORKEY)
443 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
444 if (flags[i].mask & flagmask)
445 DPRINTF("%s ",flags[i].name);
449 static void _dump_DDBLT(DWORD flagmask) {
455 #define FE(x) { x, #x},
457 FE(DDBLT_ALPHADESTCONSTOVERRIDE)
458 FE(DDBLT_ALPHADESTNEG)
459 FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
460 FE(DDBLT_ALPHAEDGEBLEND)
462 FE(DDBLT_ALPHASRCCONSTOVERRIDE)
463 FE(DDBLT_ALPHASRCNEG)
464 FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
470 FE(DDBLT_KEYDESTOVERRIDE)
472 FE(DDBLT_KEYSRCOVERRIDE)
474 FE(DDBLT_ROTATIONANGLE)
476 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
477 FE(DDBLT_ZBUFFERDESTOVERRIDE)
478 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
479 FE(DDBLT_ZBUFFERSRCOVERRIDE)
484 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
485 if (flags[i].mask & flagmask)
486 DPRINTF("%s ",flags[i].name);
490 static void _dump_DDSCAPS(void *in) {
496 #define FE(x) { x, #x},
497 FE(DDSCAPS_RESERVED1)
499 FE(DDSCAPS_BACKBUFFER)
502 FE(DDSCAPS_FRONTBUFFER)
503 FE(DDSCAPS_OFFSCREENPLAIN)
506 FE(DDSCAPS_PRIMARYSURFACE)
507 FE(DDSCAPS_PRIMARYSURFACELEFT)
508 FE(DDSCAPS_SYSTEMMEMORY)
511 FE(DDSCAPS_VIDEOMEMORY)
513 FE(DDSCAPS_WRITEONLY)
516 FE(DDSCAPS_LIVEVIDEO)
520 FE(DDSCAPS_RESERVED2)
521 FE(DDSCAPS_ALLOCONLOAD)
522 FE(DDSCAPS_VIDEOPORT)
523 FE(DDSCAPS_LOCALVIDMEM)
524 FE(DDSCAPS_NONLOCALVIDMEM)
525 FE(DDSCAPS_STANDARDVGAMODE)
526 FE(DDSCAPS_OPTIMIZED)
529 DWORD flagmask = *((DWORD *) in);
530 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
531 if (flags[i].mask & flagmask)
532 DPRINTF("%s ",flags[i].name);
535 static void _dump_pixelformat_flag(DWORD flagmask) {
541 #define FE(x) { x, #x},
545 FE(DDPF_PALETTEINDEXED4)
546 FE(DDPF_PALETTEINDEXEDTO8)
547 FE(DDPF_PALETTEINDEXED8)
553 FE(DDPF_PALETTEINDEXED1)
554 FE(DDPF_PALETTEINDEXED2)
558 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
559 if (flags[i].mask & flagmask)
560 DPRINTF("%s ",flags[i].name);
563 static void _dump_paletteformat(DWORD dwFlags) {
569 #define FE(x) { x, #x},
571 FE(DDPCAPS_8BITENTRIES)
573 FE(DDPCAPS_INITIALIZE)
574 FE(DDPCAPS_PRIMARYSURFACE)
575 FE(DDPCAPS_PRIMARYSURFACELEFT)
583 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
584 if (flags[i].mask & dwFlags)
585 DPRINTF("%s ",flags[i].name);
589 static void _dump_pixelformat(void *in) {
590 LPDDPIXELFORMAT pf = (LPDDPIXELFORMAT) in;
594 _dump_pixelformat_flag(pf->dwFlags);
595 if (pf->dwFlags & DDPF_FOURCC) {
596 DPRINTF(", dwFourCC : %ld", pf->dwFourCC);
598 if (pf->dwFlags & DDPF_RGB) {
599 DPRINTF(", RGB bits: %ld, ", pf->u.dwRGBBitCount);
600 switch (pf->u.dwRGBBitCount) {
617 ERR("Unexpected bit depth !\n");
620 DPRINTF(" R "); DPRINTF(cmd, pf->u1.dwRBitMask);
621 DPRINTF(" G "); DPRINTF(cmd, pf->u2.dwGBitMask);
622 DPRINTF(" B "); DPRINTF(cmd, pf->u3.dwBBitMask);
623 if (pf->dwFlags & DDPF_ALPHAPIXELS) {
624 DPRINTF(" A "); DPRINTF(cmd, pf->u4.dwRGBAlphaBitMask);
626 if (pf->dwFlags & DDPF_ZPIXELS) {
627 DPRINTF(" Z "); DPRINTF(cmd, pf->u4.dwRGBZBitMask);
630 if (pf->dwFlags & DDPF_ZBUFFER) {
631 DPRINTF(", Z bits : %ld", pf->u.dwZBufferBitDepth);
633 if (pf->dwFlags & DDPF_ALPHA) {
634 DPRINTF(", Alpha bits : %ld", pf->u.dwAlphaBitDepth);
639 static void _dump_colorkeyflag(DWORD ck) {
645 #define FE(x) { x, #x},
646 FE(DDCKEY_COLORSPACE)
648 FE(DDCKEY_DESTOVERLAY)
650 FE(DDCKEY_SRCOVERLAY)
653 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
654 if (flags[i].mask & ck)
655 DPRINTF("%s ",flags[i].name);
658 static void _dump_DWORD(void *in) {
659 DPRINTF("%ld", *((DWORD *) in));
661 static void _dump_PTR(void *in) {
662 DPRINTF("%p", *((void **) in));
664 static void _dump_DDCOLORKEY(void *in) {
665 DDCOLORKEY *ddck = (DDCOLORKEY *) in;
667 DPRINTF(" Low : %ld - High : %ld", ddck->dwColorSpaceLowValue, ddck->dwColorSpaceHighValue);
670 static void _dump_surface_desc(DDSURFACEDESC *lpddsd) {
675 void (*func)(void *);
677 } flags[16], *fe = flags;
678 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
679 FE(DDSD_CAPS, _dump_DDSCAPS, ddsCaps);
680 FE(DDSD_HEIGHT, _dump_DWORD, dwHeight);
681 FE(DDSD_WIDTH, _dump_DWORD, dwWidth);
682 FE(DDSD_PITCH, _dump_DWORD, lPitch);
683 FE(DDSD_BACKBUFFERCOUNT, _dump_DWORD, dwBackBufferCount);
684 FE(DDSD_ZBUFFERBITDEPTH, _dump_DWORD, u.dwZBufferBitDepth);
685 FE(DDSD_ALPHABITDEPTH, _dump_DWORD, dwAlphaBitDepth);
686 FE(DDSD_PIXELFORMAT, _dump_pixelformat, ddpfPixelFormat);
687 FE(DDSD_CKDESTOVERLAY, _dump_DDCOLORKEY, ddckCKDestOverlay);
688 FE(DDSD_CKDESTBLT, _dump_DDCOLORKEY, ddckCKDestBlt);
689 FE(DDSD_CKSRCOVERLAY, _dump_DDCOLORKEY, ddckCKSrcOverlay);
690 FE(DDSD_CKSRCBLT, _dump_DDCOLORKEY, ddckCKSrcBlt);
691 FE(DDSD_MIPMAPCOUNT, _dump_DWORD, u.dwMipMapCount);
692 FE(DDSD_REFRESHRATE, _dump_DWORD, u.dwRefreshRate);
693 FE(DDSD_LINEARSIZE, _dump_DWORD, u1.dwLinearSize);
694 FE(DDSD_LPSURFACE, _dump_PTR, u1.lpSurface);
697 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
698 if (flags[i].mask & lpddsd->dwFlags) {
699 DPRINTF(" - %s : ",flags[i].name);
700 flags[i].func(flags[i].elt);
706 /******************************************************************************
707 * IDirectDrawSurface methods
709 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
710 * DDS and DDS2 use those functions. (Function calls did not change (except
711 * using different DirectDrawSurfaceX version), just added flags and functions)
714 static HRESULT WINAPI IDirectDrawSurface4Impl_Lock(
715 LPDIRECTDRAWSURFACE4 iface,LPRECT lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE hnd
717 ICOM_THIS(IDirectDrawSurface4Impl,iface);
718 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
719 This,lprect,lpddsd,flags,(DWORD)hnd);
720 if (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY))
721 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
722 This,lprect,lpddsd,flags,(DWORD)hnd);
724 /* First, copy the Surface description */
725 *lpddsd = This->s.surface_desc;
726 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
727 lpddsd->dwHeight,lpddsd->dwWidth,lpddsd->lPitch);
729 /* If asked only for a part, change the surface pointer */
731 TRACE(" lprect: %dx%d-%dx%d\n",
732 lprect->top,lprect->left,lprect->bottom,lprect->right
734 if ((lprect->top < 0) ||
735 (lprect->left < 0) ||
736 (lprect->bottom < 0) ||
737 (lprect->right < 0)) {
738 ERR(" Negative values in LPRECT !!!\n");
739 return DDERR_INVALIDPARAMS;
742 lpddsd->u1.lpSurface = (LPVOID) ((char *) This->s.surface_desc.u1.lpSurface +
743 (lprect->top*This->s.surface_desc.lPitch) +
744 lprect->left*GET_BPP(This->s.surface_desc));
746 assert(This->s.surface_desc.u1.lpSurface);
749 /* wait for any previous operations to complete */
751 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE) &&
752 This->s.ddraw->e.xlib.xshm_active) {
754 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
755 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
757 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
763 #ifdef HAVE_LIBXXF86DGA
764 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Unlock(
765 LPDIRECTDRAWSURFACE4 iface,LPVOID surface
767 ICOM_THIS(IDirectDrawSurface4Impl,iface);
768 TRACE("(%p)->Unlock(%p)\n",This,surface);
771 #endif /* defined(HAVE_LIBXXF86DGA) */
773 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl* This) {
774 if (This->s.ddraw->d.pixel_convert != NULL)
775 This->s.ddraw->d.pixel_convert(This->s.surface_desc.u1.lpSurface,
776 This->t.xlib.image->data,
777 This->s.surface_desc.dwWidth,
778 This->s.surface_desc.dwHeight,
779 This->s.surface_desc.lPitch,
783 if (This->s.ddraw->e.xlib.xshm_active) {
785 X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
787 /* let WaitShmCompletions track 'em for now */
788 /* (you may want to track it again whenever you implement DX7's partial surface locking,
789 where threads have concurrent access) */
790 X11DRV_EVENT_PrepareShmCompletion( This->s.ddraw->d.drawable );
791 TSXShmPutImage(display,
792 This->s.ddraw->d.drawable,
793 DefaultGCOfScreen(X11DRV_GetXScreen()),
796 This->t.xlib.image->width,
797 This->t.xlib.image->height,
799 /* make sure the image is transferred ASAP */
804 TSXPutImage( display,
805 This->s.ddraw->d.drawable,
806 DefaultGCOfScreen(X11DRV_GetXScreen()),
809 This->t.xlib.image->width,
810 This->t.xlib.image->height);
813 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Unlock(
814 LPDIRECTDRAWSURFACE4 iface,LPVOID surface)
816 ICOM_THIS(IDirectDrawSurface4Impl,iface);
817 TRACE("(%p)->Unlock(%p)\n",This,surface);
819 if (!This->s.ddraw->d.paintable)
822 /* Only redraw the screen when unlocking the buffer that is on screen */
823 if (This->t.xlib.image && (SDDSCAPS(This) & DDSCAPS_VISIBLE)) {
824 Xlib_copy_surface_on_screen(This);
826 if (This->s.palette && This->s.palette->cm)
827 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
832 static IDirectDrawSurface4Impl* _common_find_flipto(
833 IDirectDrawSurface4Impl* This,IDirectDrawSurface4Impl* flipto
836 struct _surface_chain *chain = This->s.chain;
838 /* if there was no override flipto, look for current backbuffer */
840 /* walk the flip chain looking for backbuffer */
841 for (i=0;i<chain->nrofsurfaces;i++) {
842 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP)
844 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_BACKBUFFER)
845 flipto = chain->surfaces[i];
847 /* sanity checks ... */
850 for (i=0;i<chain->nrofsurfaces;i++)
851 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FRONTBUFFER)
853 if (i==chain->nrofsurfaces) {
854 /* we do not have a frontbuffer either */
855 for (i=0;i<chain->nrofsurfaces;i++)
856 if (SDDSCAPS(chain->surfaces[i]) & DDSCAPS_FLIP) {
857 SDDSCAPS(chain->surfaces[i])|=DDSCAPS_FRONTBUFFER;
860 for (j=i+1;j<i+chain->nrofsurfaces+1;j++) {
861 int k = j % chain->nrofsurfaces;
862 if (SDDSCAPS(chain->surfaces[k]) & DDSCAPS_FLIP) {
863 SDDSCAPS(chain->surfaces[k])|=DDSCAPS_BACKBUFFER;
864 flipto = chain->surfaces[k];
873 TRACE("flipping to %p\n",flipto);
878 #ifdef HAVE_LIBXXF86DGA
879 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_Flip(
880 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
882 ICOM_THIS(IDirectDrawSurface4Impl,iface);
883 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
887 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
888 iflipto = _common_find_flipto(This,iflipto);
891 TSXF86DGASetViewPort(display,DefaultScreen(display),0,iflipto->t.dga.fb_height);
892 if (iflipto->s.palette && iflipto->s.palette->cm)
893 TSXF86DGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
894 while (!TSXF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
897 /* We need to switch the lowlevel surfaces, for DGA this is: */
899 /* The height within the framebuffer */
900 xheight = This->t.dga.fb_height;
901 This->t.dga.fb_height = iflipto->t.dga.fb_height;
902 iflipto->t.dga.fb_height = xheight;
904 /* And the assciated surface pointer */
905 surf = This->s.surface_desc.u1.lpSurface;
906 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
907 iflipto->s.surface_desc.u1.lpSurface = surf;
911 #endif /* defined(HAVE_LIBXXF86DGA) */
913 #ifdef HAVE_LIBXXF86DGA2
914 static HRESULT WINAPI DGA2_IDirectDrawSurface4Impl_Flip(
915 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
917 ICOM_THIS(IDirectDrawSurface4Impl,iface);
918 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
922 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
923 iflipto = _common_find_flipto(This,iflipto);
926 TSXDGASetViewport(display,DefaultScreen(display),0,iflipto->t.dga.fb_height, XDGAFlipRetrace);
927 TSXDGASync(display,DefaultScreen(display));
929 if (iflipto->s.palette && iflipto->s.palette->cm)
930 TSXDGAInstallColormap(display,DefaultScreen(display),iflipto->s.palette->cm);
931 /* We need to switch the lowlevel surfaces, for DGA this is: */
933 /* The height within the framebuffer */
934 xheight = This->t.dga.fb_height;
935 This->t.dga.fb_height = iflipto->t.dga.fb_height;
936 iflipto->t.dga.fb_height = xheight;
938 /* And the assciated surface pointer */
939 surf = This->s.surface_desc.u1.lpSurface;
940 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
941 iflipto->s.surface_desc.u1.lpSurface = surf;
945 #endif /* defined(HAVE_LIBXXF86DGA2) */
947 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_Flip(
948 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 flipto,DWORD dwFlags
950 ICOM_THIS(IDirectDrawSurface4Impl,iface);
953 IDirectDrawSurface4Impl* iflipto=(IDirectDrawSurface4Impl*)flipto;
955 TRACE("(%p)->Flip(%p,%08lx)\n",This,iflipto,dwFlags);
956 iflipto = _common_find_flipto(This,iflipto);
958 #if defined(HAVE_MESAGL) && 0 /* does not work */
959 if (This->s.d3d_device || (iflipto && iflipto->s.d3d_device)) {
960 TRACE(" - OpenGL flip\n");
962 glXSwapBuffers(display, This->s.ddraw->d.drawable);
967 #endif /* defined(HAVE_MESAGL) */
969 if (!This->s.ddraw->d.paintable)
972 /* We need to switch the lowlevel surfaces, for xlib this is: */
973 /* The surface pointer */
974 surf = This->s.surface_desc.u1.lpSurface;
975 This->s.surface_desc.u1.lpSurface = iflipto->s.surface_desc.u1.lpSurface;
976 iflipto->s.surface_desc.u1.lpSurface = surf;
977 /* the associated ximage */
978 image = This->t.xlib.image;
979 This->t.xlib.image = iflipto->t.xlib.image;
980 iflipto->t.xlib.image = image;
983 if (This->s.ddraw->e.xlib.xshm_active) {
985 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
986 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
988 X11DRV_EVENT_WaitShmCompletions( This->s.ddraw->d.drawable );
991 Xlib_copy_surface_on_screen(This);
993 if (iflipto->s.palette && iflipto->s.palette->cm)
994 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,iflipto->s.palette->cm);
998 /* The IDirectDrawSurface4::SetPalette method attaches the specified
999 * DirectDrawPalette object to a surface. The surface uses this palette for all
1000 * subsequent operations. The palette change takes place immediately.
1002 static HRESULT WINAPI Xlib_IDirectDrawSurface4Impl_SetPalette(
1003 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1005 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1006 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1008 TRACE("(%p)->(%p)\n",This,ipal);
1011 if( This->s.palette != NULL )
1012 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1013 This->s.palette = ipal;
1018 if( !(ipal->cm) && (This->s.ddraw->d.screen_pixelformat.u.dwRGBBitCount<=8))
1020 ipal->cm = TSXCreateColormap(display,This->s.ddraw->d.drawable,
1021 X11DRV_GetVisual(),AllocAll);
1023 if (!Options.managed)
1024 TSXInstallColormap(display,ipal->cm);
1026 for (i=0;i<256;i++) {
1029 xc.red = ipal->palents[i].peRed<<8;
1030 xc.blue = ipal->palents[i].peBlue<<8;
1031 xc.green = ipal->palents[i].peGreen<<8;
1032 xc.flags = DoRed|DoBlue|DoGreen;
1034 TSXStoreColor(display,ipal->cm,&xc);
1036 TSXInstallColormap(display,ipal->cm);
1039 /* According to spec, we are only supposed to
1040 * AddRef if this is not the same palette.
1042 if( This->s.palette != ipal )
1045 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1046 if( This->s.palette != NULL )
1047 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1048 This->s.palette = ipal;
1049 /* Perform the refresh */
1050 TSXSetWindowColormap(display,This->s.ddraw->d.drawable,This->s.palette->cm);
1055 #ifdef HAVE_LIBXXF86DGA
1056 static HRESULT WINAPI DGA_IDirectDrawSurface4Impl_SetPalette(
1057 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWPALETTE pal
1059 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1060 IDirectDrawPaletteImpl* ipal=(IDirectDrawPaletteImpl*)pal;
1061 TRACE("(%p)->(%p)\n",This,ipal);
1063 /* According to spec, we are only supposed to
1064 * AddRef if this is not the same palette.
1066 if( This->s.palette != ipal )
1069 IDirectDrawPalette_AddRef( (IDirectDrawPalette*)ipal );
1070 if( This->s.palette != NULL )
1071 IDirectDrawPalette_Release( (IDirectDrawPalette*)This->s.palette );
1072 This->s.palette = ipal;
1073 #ifdef HAVE_LIBXXF86DGA2
1074 if (This->s.ddraw->e.dga.version == 2)
1075 TSXDGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1077 #endif /* defined(HAVE_LIBXXF86DGA2) */
1078 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->s.palette->cm);
1082 #endif /* defined(HAVE_LIBXXF86DGA) */
1084 static HRESULT _Blt_ColorFill(LPBYTE buf, int width, int height, int bpp, LONG lPitch, DWORD color)
1091 #define COLORFILL_ROW(type) { \
1092 type *d = (type *) buf; \
1093 for (x = 0; x < width; x++) \
1094 d[x] = (type) color; \
1099 case 1: COLORFILL_ROW(BYTE)
1100 case 2: COLORFILL_ROW(WORD)
1101 case 4: COLORFILL_ROW(DWORD)
1103 FIXME("Color fill not implemented for bpp %d!\n", bpp*8);
1104 return DDERR_UNSUPPORTED;
1107 #undef COLORFILL_ROW
1109 /* Now copy first row */
1111 for (y = 1; y < height; y++) {
1113 memcpy(buf, first, width * bpp);
1119 static HRESULT WINAPI IDirectDrawSurface4Impl_Blt(
1120 LPDIRECTDRAWSURFACE4 iface,LPRECT rdst,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
1122 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1124 DDSURFACEDESC ddesc,sdesc;
1125 HRESULT ret = DD_OK;
1126 int bpp, srcheight, srcwidth, dstheight, dstwidth, width;
1130 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This,rdst,src,rsrc,dwFlags,lpbltfx);
1132 if (src) IDirectDrawSurface4_Lock(src, NULL, &sdesc, 0, 0);
1133 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,0,0);
1135 if (TRACE_ON(ddraw)) {
1136 if (rdst) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
1137 if (rsrc) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1139 _dump_DDBLT(dwFlags);
1140 if (dwFlags & DDBLT_DDFX) {
1141 TRACE("\tblitfx: ");
1142 _dump_DDBLTFX(lpbltfx->dwDDFX);
1147 if ((rdst->top < 0) ||
1149 (rdst->bottom < 0) ||
1150 (rdst->right < 0)) {
1151 ERR(" Negative values in LPRECT !!!\n");
1154 memcpy(&xdst,rdst,sizeof(xdst));
1157 xdst.bottom = ddesc.dwHeight;
1159 xdst.right = ddesc.dwWidth;
1163 if ((rsrc->top < 0) ||
1165 (rsrc->bottom < 0) ||
1166 (rsrc->right < 0)) {
1167 ERR(" Negative values in LPRECT !!!\n");
1170 memcpy(&xsrc,rsrc,sizeof(xsrc));
1174 xsrc.bottom = sdesc.dwHeight;
1176 xsrc.right = sdesc.dwWidth;
1178 memset(&xsrc,0,sizeof(xsrc));
1182 bpp = GET_BPP(ddesc);
1183 srcheight = xsrc.bottom - xsrc.top;
1184 srcwidth = xsrc.right - xsrc.left;
1185 dstheight = xdst.bottom - xdst.top;
1186 dstwidth = xdst.right - xdst.left;
1187 width = (xdst.right - xdst.left) * bpp;
1188 dbuf = (BYTE *) ddesc.u1.lpSurface + (xdst.top * ddesc.lPitch) + (xdst.left * bpp);
1190 dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
1192 /* First, all the 'source-less' blits */
1193 if (dwFlags & DDBLT_COLORFILL) {
1194 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp,
1195 ddesc.lPitch, lpbltfx->u4.dwFillColor);
1196 dwFlags &= ~DDBLT_COLORFILL;
1199 if (dwFlags & DDBLT_DEPTHFILL) {
1203 /* Clears the screen */
1204 TRACE(" Filling depth buffer with %ld\n", lpbltfx->u4.dwFillDepth);
1205 glClearDepth(lpbltfx->u4.dwFillDepth / 65535.0); /* We suppose a 16 bit Z Buffer */
1206 glGetBooleanv(GL_DEPTH_TEST, &ztest);
1207 glDepthMask(GL_TRUE); /* Enables Z writing to be sure to delete also the Z buffer */
1208 glClear(GL_DEPTH_BUFFER_BIT);
1211 dwFlags &= ~(DDBLT_DEPTHFILL);
1212 #endif /* defined(HAVE_MESAGL) */
1215 if (dwFlags & DDBLT_ROP) {
1216 /* Catch some degenerate cases here */
1217 switch(lpbltfx->dwROP) {
1219 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, 0);
1221 case 0xAA0029: /* No-op */
1224 ret = _Blt_ColorFill(dbuf, dstwidth, dstheight, bpp, ddesc.lPitch, ~0);
1227 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx->dwROP, lpbltfx->u4.lpDDSPattern);
1230 dwFlags &= ~DDBLT_ROP;
1233 if (dwFlags & DDBLT_DDROPS) {
1234 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx->dwDDROP, lpbltfx->u4.lpDDSPattern);
1237 /* Now the 'with source' blits */
1240 int sx, xinc, sy, yinc;
1242 sbase = (BYTE *) sdesc.u1.lpSurface + (xsrc.top * sdesc.lPitch) + xsrc.left * bpp;
1243 xinc = (srcwidth << 16) / dstwidth;
1244 yinc = (srcheight << 16) / dstheight;
1248 /* No effects, we can cheat here */
1249 if (dstwidth == srcwidth) {
1250 if (dstheight == srcheight) {
1251 /* No stretching in either direction. This needs to be as fast as possible */
1253 for (y = 0; y < dstheight; y++) {
1254 memcpy(dbuf, sbuf, width);
1255 sbuf += sdesc.lPitch;
1256 dbuf += ddesc.lPitch;
1259 /* Stretching in Y direction only */
1260 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1261 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1262 memcpy(dbuf, sbuf, width);
1263 dbuf += ddesc.lPitch;
1267 /* Stretching in X direction */
1269 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1270 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1272 if ((sy >> 16) == (last_sy >> 16)) {
1273 /* Same as last row - copy already stretched row */
1274 memcpy(dbuf, dbuf - ddesc.lPitch, width);
1277 #define STRETCH_ROW(type) { \
1278 type *s = (type *) sbuf, *d = (type *) dbuf; \
1279 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1280 d[x] = s[sx >> 16]; \
1284 case 1: STRETCH_ROW(BYTE)
1285 case 2: STRETCH_ROW(WORD)
1286 case 4: STRETCH_ROW(DWORD)
1289 for (x = sx = 0; x < dstwidth; x++, sx+= xinc) {
1292 s = sbuf+3*(sx>>16);
1294 pixel = (s[0]<<16)|(s[1]<<8)|s[2];
1295 d[0] = (pixel>>16)&0xff;
1296 d[1] = (pixel>> 8)&0xff;
1297 d[2] = (pixel )&0xff;
1302 FIXME("Stretched blit not implemented for bpp %d!\n", bpp*8);
1303 ret = DDERR_UNSUPPORTED;
1311 dbuf += ddesc.lPitch;
1314 } else if (dwFlags & (DDBLT_KEYSRC | DDBLT_KEYDEST)) {
1315 DWORD keylow, keyhigh;
1317 if (dwFlags & DDBLT_KEYSRC) {
1318 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1319 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1321 /* I'm not sure if this is correct */
1322 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1323 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1324 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1328 for (y = sy = 0; y < dstheight; y++, sy += yinc) {
1329 sbuf = sbase + (sy >> 16) * sdesc.lPitch;
1331 #define COPYROW_COLORKEY(type) { \
1332 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1333 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1334 tmp = s[sx >> 16]; \
1335 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1340 case 1: COPYROW_COLORKEY(BYTE)
1341 case 2: COPYROW_COLORKEY(WORD)
1342 case 4: COPYROW_COLORKEY(DWORD)
1344 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1345 (dwFlags & DDBLT_KEYSRC) ? "Source" : "Destination", bpp*8);
1346 ret = DDERR_UNSUPPORTED;
1349 dbuf += ddesc.lPitch;
1352 #undef COPYROW_COLORKEY
1354 dwFlags &= ~(DDBLT_KEYSRC | DDBLT_KEYDEST);
1361 if (dwFlags && FIXME_ON(ddraw)) {
1362 FIXME("\tUnsupported flags: ");
1363 _dump_DDBLT(dwFlags);
1367 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1368 if (src) IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1373 static HRESULT WINAPI IDirectDrawSurface4Impl_BltFast(
1374 LPDIRECTDRAWSURFACE4 iface,DWORD dstx,DWORD dsty,LPDIRECTDRAWSURFACE4 src,LPRECT rsrc,DWORD trans
1376 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1377 int bpp, w, h, x, y;
1378 DDSURFACEDESC ddesc,sdesc;
1379 HRESULT ret = DD_OK;
1384 if (TRACE_ON(ddraw)) {
1385 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1386 This,dstx,dsty,src,rsrc,trans
1389 if (FIXME_ON(ddraw))
1390 _dump_DDBLTFAST(trans);
1392 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
1394 FIXME(" srcrect: NULL\n");
1397 /* We need to lock the surfaces, or we won't get refreshes when done. */
1398 IDirectDrawSurface4_Lock(src, NULL,&sdesc,DDLOCK_READONLY, 0);
1399 IDirectDrawSurface4_Lock(iface,NULL,&ddesc,DDLOCK_WRITEONLY,0);
1402 WARN("rsrc is NULL!\n");
1404 rsrc->left = rsrc->top = 0;
1405 rsrc->right = sdesc.dwWidth;
1406 rsrc->bottom = sdesc.dwHeight;
1409 bpp = GET_BPP(This->s.surface_desc);
1410 sbuf = (BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp;
1411 dbuf = (BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp;
1414 h=rsrc->bottom-rsrc->top;
1415 if (h>ddesc.dwHeight-dsty) h=ddesc.dwHeight-dsty;
1416 if (h>sdesc.dwHeight-rsrc->top) h=sdesc.dwHeight-rsrc->top;
1419 w=rsrc->right-rsrc->left;
1420 if (w>ddesc.dwWidth-dstx) w=ddesc.dwWidth-dstx;
1421 if (w>sdesc.dwWidth-rsrc->left) w=sdesc.dwWidth-rsrc->left;
1424 if (trans & (DDBLTFAST_SRCCOLORKEY | DDBLTFAST_DESTCOLORKEY)) {
1425 DWORD keylow, keyhigh;
1426 if (trans & DDBLTFAST_SRCCOLORKEY) {
1427 keylow = sdesc.ddckCKSrcBlt.dwColorSpaceLowValue;
1428 keyhigh = sdesc.ddckCKSrcBlt.dwColorSpaceHighValue;
1430 /* I'm not sure if this is correct */
1431 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1432 keylow = ddesc.ddckCKDestBlt.dwColorSpaceLowValue;
1433 keyhigh = ddesc.ddckCKDestBlt.dwColorSpaceHighValue;
1436 #define COPYBOX_COLORKEY(type) { \
1437 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1438 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1439 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1440 for (y = 0; y < h; y++) { \
1441 for (x = 0; x < w; x++) { \
1443 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1445 (LPBYTE)s += sdesc.lPitch; \
1446 (LPBYTE)d += ddesc.lPitch; \
1452 case 1: COPYBOX_COLORKEY(BYTE)
1453 case 2: COPYBOX_COLORKEY(WORD)
1454 case 4: COPYBOX_COLORKEY(DWORD)
1456 FIXME("Source color key blitting not supported for bpp %d\n", bpp*8);
1457 ret = DDERR_UNSUPPORTED;
1461 #undef COPYBOX_COLORKEY
1464 int width = w * bpp;
1466 for (y = 0; y < h; y++) {
1467 memcpy(dbuf, sbuf, width);
1468 sbuf += sdesc.lPitch;
1469 dbuf += ddesc.lPitch;
1475 IDirectDrawSurface4_Unlock(iface,ddesc.u1.lpSurface);
1476 IDirectDrawSurface4_Unlock(src,sdesc.u1.lpSurface);
1480 static HRESULT WINAPI IDirectDrawSurface4Impl_BltBatch(
1481 LPDIRECTDRAWSURFACE4 iface,LPDDBLTBATCH ddbltbatch,DWORD x,DWORD y
1483 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1484 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1490 static HRESULT WINAPI IDirectDrawSurface4Impl_GetCaps(
1491 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS caps
1493 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1494 TRACE("(%p)->GetCaps(%p)\n",This,caps);
1495 caps->dwCaps = DDSCAPS_PALETTE; /* probably more */
1499 static HRESULT WINAPI IDirectDrawSurface4Impl_GetSurfaceDesc(
1500 LPDIRECTDRAWSURFACE4 iface,LPDDSURFACEDESC ddsd
1502 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1503 TRACE("(%p)->GetSurfaceDesc(%p)\n", This,ddsd);
1505 /* Simply copy the surface description stored in the object */
1506 *ddsd = This->s.surface_desc;
1508 if (TRACE_ON(ddraw)) { _dump_surface_desc(ddsd); }
1513 static ULONG WINAPI IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface) {
1514 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1515 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
1516 return ++(This->ref);
1519 #ifdef HAVE_LIBXXF86DGA
1520 static ULONG WINAPI DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1521 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1523 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
1528 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1529 /* clear out of surface list */
1530 if (This->t.dga.fb_height == -1)
1531 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1533 This->s.ddraw->e.dga.vpmask &= ~(1<<(This->t.dga.fb_height/This->s.ddraw->e.dga.fb_height));
1535 /* Free the DIBSection (if any) */
1536 if (This->s.hdc != 0) {
1537 SelectObject(This->s.hdc, This->s.holdbitmap);
1538 DeleteDC(This->s.hdc);
1539 DeleteObject(This->s.DIBsection);
1542 /* Free the clipper if attached to this surface */
1543 if( This->s.lpClipper )
1544 IDirectDrawClipper_Release(This->s.lpClipper);
1546 HeapFree(GetProcessHeap(),0,This);
1549 #endif /* defined(HAVE_LIBXXF86DGA) */
1551 static ULONG WINAPI Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface) {
1552 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1554 TRACE( "(%p)->() decrementing from %lu.\n", This, This->ref );
1559 IDirectDraw2_Release((IDirectDraw2*)This->s.ddraw);
1561 if (This->t.xlib.image != NULL) {
1562 if (This->s.ddraw->d.pixel_convert != NULL) {
1563 /* In pixel conversion mode, there are 2 buffers to release. */
1564 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1566 #ifdef HAVE_LIBXXSHM
1567 if (This->s.ddraw->e.xlib.xshm_active) {
1568 TSXShmDetach(display, &(This->t.xlib.shminfo));
1569 TSXDestroyImage(This->t.xlib.image);
1570 shmdt(This->t.xlib.shminfo.shmaddr);
1573 HeapFree(GetProcessHeap(),0,This->t.xlib.image->data);
1574 This->t.xlib.image->data = NULL;
1575 TSXDestroyImage(This->t.xlib.image);
1576 #ifdef HAVE_LIBXXSHM
1580 This->t.xlib.image->data = NULL;
1582 #ifdef HAVE_LIBXXSHM
1583 if (This->s.ddraw->e.xlib.xshm_active) {
1584 TSXShmDetach(display, &(This->t.xlib.shminfo));
1585 TSXDestroyImage(This->t.xlib.image);
1586 shmdt(This->t.xlib.shminfo.shmaddr);
1589 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1590 TSXDestroyImage(This->t.xlib.image);
1591 #ifdef HAVE_LIBXXSHM
1595 This->t.xlib.image = 0;
1597 HeapFree(GetProcessHeap(),0,This->s.surface_desc.u1.lpSurface);
1600 if (This->s.palette)
1601 IDirectDrawPalette_Release((IDirectDrawPalette*)This->s.palette);
1603 /* Free the DIBSection (if any) */
1604 if (This->s.hdc != 0) {
1605 SelectObject(This->s.hdc, This->s.holdbitmap);
1606 DeleteDC(This->s.hdc);
1607 DeleteObject(This->s.DIBsection);
1610 /* Free the clipper if present */
1611 if( This->s.lpClipper )
1612 IDirectDrawClipper_Release(This->s.lpClipper);
1614 HeapFree(GetProcessHeap(),0,This);
1618 static HRESULT WINAPI IDirectDrawSurface4Impl_GetAttachedSurface(
1619 LPDIRECTDRAWSURFACE4 iface,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE4 *lpdsf
1621 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1622 int i,found = 0,xstart;
1623 struct _surface_chain *chain;
1625 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This, lpddsd, lpdsf);
1626 if (TRACE_ON(ddraw)) {
1627 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd->dwCaps));
1630 chain = This->s.chain;
1632 return DDERR_NOTFOUND;
1634 for (i=0;i<chain->nrofsurfaces;i++)
1635 if (chain->surfaces[i] == This)
1639 for (i=0;i<chain->nrofsurfaces;i++) {
1640 if ((SDDSCAPS(chain->surfaces[(xstart+i)%chain->nrofsurfaces])&lpddsd->dwCaps) == lpddsd->dwCaps) {
1642 if (found) /* may not find the same caps twice, (doc) */
1643 return DDERR_INVALIDPARAMS;/*FIXME: correct? */
1645 found = (i+1)+xstart;
1649 return DDERR_NOTFOUND;
1650 *lpdsf = (LPDIRECTDRAWSURFACE4)chain->surfaces[found-1-xstart];
1651 /* FIXME: AddRef? */
1652 TRACE("found %p\n",*lpdsf);
1656 static HRESULT WINAPI IDirectDrawSurface4Impl_Initialize(
1657 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
1659 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1660 TRACE("(%p)->(%p, %p)\n",This,ddraw,lpdsfd);
1662 return DDERR_ALREADYINITIALIZED;
1665 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPixelFormat(
1666 LPDIRECTDRAWSURFACE4 iface,LPDDPIXELFORMAT pf
1668 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1669 TRACE("(%p)->(%p)\n",This,pf);
1671 *pf = This->s.surface_desc.ddpfPixelFormat;
1672 if (TRACE_ON(ddraw)) { _dump_pixelformat(pf); DPRINTF("\n"); }
1676 static HRESULT WINAPI IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface,DWORD dwFlags) {
1677 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1678 FIXME("(%p)->(0x%08lx),stub!\n",This,dwFlags);
1682 static HRESULT WINAPI IDirectDrawSurface4Impl_GetOverlayPosition(
1683 LPDIRECTDRAWSURFACE4 iface,LPLONG x1,LPLONG x2
1685 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1686 FIXME("(%p)->(%p,%p),stub!\n",This,x1,x2);
1690 static HRESULT WINAPI IDirectDrawSurface4Impl_SetClipper(
1691 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWCLIPPER lpClipper
1693 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1694 TRACE("(%p)->(%p)!\n",This,lpClipper);
1696 if (This->s.lpClipper) IDirectDrawClipper_Release( This->s.lpClipper );
1697 This->s.lpClipper = lpClipper;
1698 if (lpClipper) IDirectDrawClipper_AddRef( lpClipper );
1702 static HRESULT WINAPI IDirectDrawSurface4Impl_AddAttachedSurface(
1703 LPDIRECTDRAWSURFACE4 iface,LPDIRECTDRAWSURFACE4 surf
1705 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1706 IDirectDrawSurface4Impl*isurf = (IDirectDrawSurface4Impl*)surf;
1708 struct _surface_chain *chain;
1710 FIXME("(%p)->(%p)\n",This,surf);
1711 chain = This->s.chain;
1713 /* IDirectDrawSurface4_AddRef(surf); */
1716 for (i=0;i<chain->nrofsurfaces;i++)
1717 if (chain->surfaces[i] == isurf)
1718 FIXME("attaching already attached surface %p to %p!\n",iface,isurf);
1720 chain = HeapAlloc(GetProcessHeap(),0,sizeof(*chain));
1721 chain->nrofsurfaces = 1;
1722 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1723 chain->surfaces[0] = This;
1724 This->s.chain = chain;
1727 if (chain->surfaces)
1728 chain->surfaces = HeapReAlloc(
1732 sizeof(chain->surfaces[0])*(chain->nrofsurfaces+1)
1735 chain->surfaces = HeapAlloc(GetProcessHeap(),0,sizeof(chain->surfaces[0]));
1736 isurf->s.chain = chain;
1737 chain->surfaces[chain->nrofsurfaces++] = isurf;
1741 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface,HDC* lphdc) {
1742 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1747 FIXME("(%p)->GetDC(%p)\n",This,lphdc);
1749 /* Creates a DIB Section of the same size / format as the surface */
1750 IDirectDrawSurface4_Lock(iface,NULL,&desc,0,0);
1752 if (This->s.hdc == 0) {
1753 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1756 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1757 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD));
1762 b_info = (BITMAPINFO *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER));
1766 b_info = (BITMAPINFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
1767 sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (2 << desc.ddpfPixelFormat.u.dwRGBBitCount));
1771 b_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1772 b_info->bmiHeader.biWidth = desc.dwWidth;
1773 b_info->bmiHeader.biHeight = desc.dwHeight;
1774 b_info->bmiHeader.biPlanes = 1;
1775 b_info->bmiHeader.biBitCount = desc.ddpfPixelFormat.u.dwRGBBitCount;
1777 if ((desc.ddpfPixelFormat.u.dwRGBBitCount != 16) &&
1778 (desc.ddpfPixelFormat.u.dwRGBBitCount != 32))
1780 b_info->bmiHeader.biCompression = BI_RGB;
1783 b_info->bmiHeader.biCompression = BI_BITFIELDS;
1785 b_info->bmiHeader.biSizeImage = (desc.ddpfPixelFormat.u.dwRGBBitCount / 8) * desc.dwWidth * desc.dwHeight;
1786 b_info->bmiHeader.biXPelsPerMeter = 0;
1787 b_info->bmiHeader.biYPelsPerMeter = 0;
1788 b_info->bmiHeader.biClrUsed = 0;
1789 b_info->bmiHeader.biClrImportant = 0;
1791 switch (desc.ddpfPixelFormat.u.dwRGBBitCount) {
1796 DWORD *masks = (DWORD *) &(b_info->bmiColors);
1799 masks[0] = desc.ddpfPixelFormat.u1.dwRBitMask;
1800 masks[1] = desc.ddpfPixelFormat.u2.dwGBitMask;
1801 masks[2] = desc.ddpfPixelFormat.u3.dwBBitMask;
1807 usage = DIB_RGB_COLORS;
1813 /* Fill the palette */
1814 usage = DIB_RGB_COLORS;
1816 if (This->s.palette == NULL) {
1817 ERR("Bad palette !!!\n");
1819 RGBQUAD *rgb = (RGBQUAD *) &(b_info->bmiColors);
1820 PALETTEENTRY *pent = (PALETTEENTRY *)&(This->s.palette->palents);
1822 for (i=0;i<(1<<desc.ddpfPixelFormat.u.dwRGBBitCount);i++) {
1823 rgb[i].rgbBlue = pent[i].peBlue;
1824 rgb[i].rgbRed = pent[i].peRed;
1825 rgb[i].rgbGreen = pent[i].peGreen;
1831 This->s.DIBsection = CreateDIBSection(BeginPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps),
1834 &(This->s.bitmap_data),
1838 EndPaint(This->s.ddraw->d.mainWindow,&This->s.ddraw->d.ps);
1839 TRACE("DIBSection at : %p\n", This->s.bitmap_data);
1841 /* b_info is not useful anymore */
1842 HeapFree(GetProcessHeap(), 0, b_info);
1845 This->s.hdc = CreateCompatibleDC(0);
1846 This->s.holdbitmap = SelectObject(This->s.hdc, This->s.DIBsection);
1849 /* Copy our surface in the DIB section */
1850 if ((GET_BPP(desc) * desc.dwWidth) == desc.lPitch)
1851 memcpy(This->s.bitmap_data,desc.u1.lpSurface,desc.lPitch*desc.dwHeight);
1854 FIXME("This case has to be done :/\n");
1856 TRACE("HDC : %08lx\n", (DWORD) This->s.hdc);
1857 *lphdc = This->s.hdc;
1862 static HRESULT WINAPI IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface,HDC hdc) {
1863 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1865 FIXME("(%p)->(0x%08lx),stub!\n",This,(long)hdc);
1866 TRACE( "Copying DIBSection at : %p\n", This->s.bitmap_data);
1867 /* Copy the DIB section to our surface */
1868 if ((GET_BPP(This->s.surface_desc) * This->s.surface_desc.dwWidth) == This->s.surface_desc.lPitch) {
1869 memcpy(This->s.surface_desc.u1.lpSurface, This->s.bitmap_data, This->s.surface_desc.lPitch * This->s.surface_desc.dwHeight);
1872 FIXME("This case has to be done :/\n");
1874 /* Unlock the surface */
1875 IDirectDrawSurface4_Unlock(iface,This->s.surface_desc.u1.lpSurface);
1879 static HRESULT WINAPI IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface,REFIID refiid,LPVOID *obj) {
1880 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1882 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
1884 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1885 * the same interface. And IUnknown does that too of course.
1887 if ( IsEqualGUID( &IID_IDirectDrawSurface4, refiid ) ||
1888 IsEqualGUID( &IID_IDirectDrawSurface3, refiid ) ||
1889 IsEqualGUID( &IID_IDirectDrawSurface2, refiid ) ||
1890 IsEqualGUID( &IID_IDirectDrawSurface, refiid ) ||
1891 IsEqualGUID( &IID_IUnknown, refiid )
1894 IDirectDrawSurface4_AddRef(iface);
1896 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj);
1899 else if ( IsEqualGUID( &IID_IDirect3DTexture2, refiid ) )
1901 /* Texture interface */
1902 *obj = d3dtexture2_create(This);
1903 IDirectDrawSurface4_AddRef(iface);
1904 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj);
1907 else if ( IsEqualGUID( &IID_IDirect3DTexture, refiid ) )
1909 /* Texture interface */
1910 *obj = d3dtexture_create(This);
1911 IDirectDrawSurface4_AddRef(iface);
1913 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj);
1917 else if (is_OpenGL_dx3(refiid, (IDirectDrawSurfaceImpl*)This, (IDirect3DDeviceImpl**) obj)) {
1918 /* It is the OpenGL Direct3D Device */
1919 IDirectDrawSurface4_AddRef(iface);
1920 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj);
1924 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
1925 return OLE_E_ENUM_NOMORE;
1928 static HRESULT WINAPI IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface) {
1929 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1930 TRACE("(%p)->(), stub!\n",This);
1931 return DD_OK; /* hmm */
1934 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
1935 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1937 struct _surface_chain *chain = This->s.chain;
1939 TRACE("(%p)->(%p,%p)\n",This,context,esfcb);
1940 for (i=0;i<chain->nrofsurfaces;i++) {
1941 TRACE( "Enumerating attached surface (%p)\n", chain->surfaces[i]);
1942 if (esfcb((LPDIRECTDRAWSURFACE) chain->surfaces[i], &(chain->surfaces[i]->s.surface_desc), context) == DDENUMRET_CANCEL)
1943 return DD_OK; /* FIXME: return value correct? */
1948 static HRESULT WINAPI IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface) {
1949 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1950 FIXME("(%p)->(),stub!\n",This);
1954 static HRESULT WINAPI IDirectDrawSurface4Impl_SetColorKey(
1955 LPDIRECTDRAWSURFACE4 iface, DWORD dwFlags, LPDDCOLORKEY ckey )
1957 ICOM_THIS(IDirectDrawSurface4Impl,iface);
1958 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,ckey);
1959 if (TRACE_ON(ddraw)) {
1960 _dump_colorkeyflag(dwFlags);
1962 _dump_DDCOLORKEY((void *) ckey);
1966 /* If this surface was loaded as a texture, call also the texture
1967 SetColorKey callback */
1968 if (This->s.texture) {
1969 This->s.SetColorKey_cb(This->s.texture, dwFlags, ckey);
1972 if( dwFlags & DDCKEY_SRCBLT )
1974 dwFlags &= ~DDCKEY_SRCBLT;
1975 This->s.surface_desc.dwFlags |= DDSD_CKSRCBLT;
1976 memcpy( &(This->s.surface_desc.ddckCKSrcBlt), ckey, sizeof( *ckey ) );
1979 if( dwFlags & DDCKEY_DESTBLT )
1981 dwFlags &= ~DDCKEY_DESTBLT;
1982 This->s.surface_desc.dwFlags |= DDSD_CKDESTBLT;
1983 memcpy( &(This->s.surface_desc.ddckCKDestBlt), ckey, sizeof( *ckey ) );
1986 if( dwFlags & DDCKEY_SRCOVERLAY )
1988 dwFlags &= ~DDCKEY_SRCOVERLAY;
1989 This->s.surface_desc.dwFlags |= DDSD_CKSRCOVERLAY;
1990 memcpy( &(This->s.surface_desc.ddckCKSrcOverlay), ckey, sizeof( *ckey ) );
1993 if( dwFlags & DDCKEY_DESTOVERLAY )
1995 dwFlags &= ~DDCKEY_DESTOVERLAY;
1996 This->s.surface_desc.dwFlags |= DDSD_CKDESTOVERLAY;
1997 memcpy( &(This->s.surface_desc.ddckCKDestOverlay), ckey, sizeof( *ckey ) );
2002 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2009 static HRESULT WINAPI IDirectDrawSurface4Impl_AddOverlayDirtyRect(
2010 LPDIRECTDRAWSURFACE4 iface,
2013 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2014 FIXME("(%p)->(%p),stub!\n",This,lpRect);
2019 static HRESULT WINAPI IDirectDrawSurface4Impl_DeleteAttachedSurface(
2020 LPDIRECTDRAWSURFACE4 iface,
2022 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface )
2024 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2026 struct _surface_chain *chain;
2028 TRACE("(%p)->(0x%08lx,%p)\n",This,dwFlags,lpDDSAttachedSurface);
2029 chain = This->s.chain;
2030 for (i=0;i<chain->nrofsurfaces;i++) {
2031 if ((IDirectDrawSurface4Impl*)lpDDSAttachedSurface==chain->surfaces[i]){
2032 IDirectDrawSurface4_Release(lpDDSAttachedSurface);
2034 chain->surfaces[i]->s.chain = NULL;
2035 memcpy( chain->surfaces+i,
2036 chain->surfaces+(i+1),
2037 (chain->nrofsurfaces-i-1)*sizeof(chain->surfaces[i])
2039 chain->surfaces = HeapReAlloc(
2043 sizeof(chain->surfaces[i])*(chain->nrofsurfaces-1)
2045 chain->nrofsurfaces--;
2052 static HRESULT WINAPI IDirectDrawSurface4Impl_EnumOverlayZOrders(
2053 LPDIRECTDRAWSURFACE4 iface,
2056 LPDDENUMSURFACESCALLBACK lpfnCallback )
2058 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2059 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This,dwFlags,
2060 lpContext, lpfnCallback );
2065 static HRESULT WINAPI IDirectDrawSurface4Impl_GetClipper(
2066 LPDIRECTDRAWSURFACE4 iface,
2067 LPDIRECTDRAWCLIPPER* lplpDDClipper )
2069 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2070 FIXME("(%p)->(%p),stub!\n", This, lplpDDClipper);
2075 static HRESULT WINAPI IDirectDrawSurface4Impl_GetColorKey(
2076 LPDIRECTDRAWSURFACE4 iface,
2078 LPDDCOLORKEY lpDDColorKey )
2080 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2081 TRACE("(%p)->(0x%08lx,%p)\n", This, dwFlags, lpDDColorKey);
2083 if( dwFlags & DDCKEY_SRCBLT ) {
2084 dwFlags &= ~DDCKEY_SRCBLT;
2085 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcBlt), sizeof( *lpDDColorKey ) );
2088 if( dwFlags & DDCKEY_DESTBLT )
2090 dwFlags &= ~DDCKEY_DESTBLT;
2091 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestBlt), sizeof( *lpDDColorKey ) );
2094 if( dwFlags & DDCKEY_SRCOVERLAY )
2096 dwFlags &= ~DDCKEY_SRCOVERLAY;
2097 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKSrcOverlay), sizeof( *lpDDColorKey ) );
2100 if( dwFlags & DDCKEY_DESTOVERLAY )
2102 dwFlags &= ~DDCKEY_DESTOVERLAY;
2103 memcpy( lpDDColorKey, &(This->s.surface_desc.ddckCKDestOverlay), sizeof( *lpDDColorKey ) );
2108 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags );
2114 static HRESULT WINAPI IDirectDrawSurface4Impl_GetFlipStatus(
2115 LPDIRECTDRAWSURFACE4 iface,
2118 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2119 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2124 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPalette(
2125 LPDIRECTDRAWSURFACE4 iface,
2126 LPDIRECTDRAWPALETTE* lplpDDPalette )
2128 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2129 TRACE("(%p)->(%p),stub!\n", This, lplpDDPalette);
2131 if (This->s.palette != NULL) {
2132 IDirectDrawPalette_AddRef( (IDirectDrawPalette*) This->s.palette );
2134 *lplpDDPalette = (IDirectDrawPalette*) This->s.palette;
2137 return DDERR_NOPALETTEATTACHED;
2141 static HRESULT WINAPI IDirectDrawSurface4Impl_SetOverlayPosition(
2142 LPDIRECTDRAWSURFACE4 iface,
2146 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2147 FIXME("(%p)->(%ld,%ld),stub!\n", This, lX, lY);
2152 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlay(
2153 LPDIRECTDRAWSURFACE4 iface,
2155 LPDIRECTDRAWSURFACE4 lpDDDestSurface,
2158 LPDDOVERLAYFX lpDDOverlayFx )
2160 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2161 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This,
2162 lpSrcRect, lpDDDestSurface, lpDestRect, dwFlags, lpDDOverlayFx );
2167 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2168 LPDIRECTDRAWSURFACE4 iface,
2171 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2172 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2177 static HRESULT WINAPI IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2178 LPDIRECTDRAWSURFACE4 iface,
2180 LPDIRECTDRAWSURFACE4 lpDDSReference )
2182 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2183 FIXME("(%p)->(0x%08lx,%p),stub!\n", This, dwFlags, lpDDSReference);
2188 static HRESULT WINAPI IDirectDrawSurface4Impl_GetDDInterface(
2189 LPDIRECTDRAWSURFACE4 iface,
2192 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2193 FIXME("(%p)->(%p),stub!\n", This, lplpDD);
2195 /* Not sure about that... */
2196 *lplpDD = (void *) This->s.ddraw;
2201 static HRESULT WINAPI IDirectDrawSurface4Impl_PageLock(
2202 LPDIRECTDRAWSURFACE4 iface,
2205 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2206 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2211 static HRESULT WINAPI IDirectDrawSurface4Impl_PageUnlock(
2212 LPDIRECTDRAWSURFACE4 iface,
2215 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2216 FIXME("(%p)->(0x%08lx),stub!\n", This, dwFlags);
2221 static HRESULT WINAPI IDirectDrawSurface4Impl_SetSurfaceDesc(
2222 LPDIRECTDRAWSURFACE4 iface,
2223 LPDDSURFACEDESC lpDDSD,
2226 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2227 FIXME("(%p)->(%p,0x%08lx),stub!\n", This, lpDDSD, dwFlags);
2232 static HRESULT WINAPI IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2237 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2238 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This, guidTag, lpData, cbSize, dwFlags);
2243 static HRESULT WINAPI IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface,
2246 LPDWORD lpcbBufferSize) {
2247 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2248 FIXME("(%p)->(%p,%p,%p)\n", This, guidTag, lpBuffer, lpcbBufferSize);
2253 static HRESULT WINAPI IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface,
2255 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2256 FIXME("(%p)->(%p)\n", This, guidTag);
2261 static HRESULT WINAPI IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface,
2263 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2264 FIXME("(%p)->(%p)\n", This, lpValue);
2269 static HRESULT WINAPI IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface) {
2270 ICOM_THIS(IDirectDrawSurface4Impl,iface);
2271 FIXME("(%p)\n", This);
2276 #ifdef HAVE_LIBXXF86DGA
2277 static ICOM_VTABLE(IDirectDrawSurface4) dga_dds4vt =
2279 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2280 IDirectDrawSurface4Impl_QueryInterface,
2281 IDirectDrawSurface4Impl_AddRef,
2282 DGA_IDirectDrawSurface4Impl_Release,
2283 IDirectDrawSurface4Impl_AddAttachedSurface,
2284 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2285 IDirectDrawSurface4Impl_Blt,
2286 IDirectDrawSurface4Impl_BltBatch,
2287 IDirectDrawSurface4Impl_BltFast,
2288 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2289 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2290 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2291 DGA_IDirectDrawSurface4Impl_Flip,
2292 IDirectDrawSurface4Impl_GetAttachedSurface,
2293 IDirectDrawSurface4Impl_GetBltStatus,
2294 IDirectDrawSurface4Impl_GetCaps,
2295 IDirectDrawSurface4Impl_GetClipper,
2296 IDirectDrawSurface4Impl_GetColorKey,
2297 IDirectDrawSurface4Impl_GetDC,
2298 IDirectDrawSurface4Impl_GetFlipStatus,
2299 IDirectDrawSurface4Impl_GetOverlayPosition,
2300 IDirectDrawSurface4Impl_GetPalette,
2301 IDirectDrawSurface4Impl_GetPixelFormat,
2302 IDirectDrawSurface4Impl_GetSurfaceDesc,
2303 IDirectDrawSurface4Impl_Initialize,
2304 IDirectDrawSurface4Impl_IsLost,
2305 IDirectDrawSurface4Impl_Lock,
2306 IDirectDrawSurface4Impl_ReleaseDC,
2307 IDirectDrawSurface4Impl_Restore,
2308 IDirectDrawSurface4Impl_SetClipper,
2309 IDirectDrawSurface4Impl_SetColorKey,
2310 IDirectDrawSurface4Impl_SetOverlayPosition,
2311 DGA_IDirectDrawSurface4Impl_SetPalette,
2312 DGA_IDirectDrawSurface4Impl_Unlock,
2313 IDirectDrawSurface4Impl_UpdateOverlay,
2314 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2315 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2316 IDirectDrawSurface4Impl_GetDDInterface,
2317 IDirectDrawSurface4Impl_PageLock,
2318 IDirectDrawSurface4Impl_PageUnlock,
2319 IDirectDrawSurface4Impl_SetSurfaceDesc,
2320 IDirectDrawSurface4Impl_SetPrivateData,
2321 IDirectDrawSurface4Impl_GetPrivateData,
2322 IDirectDrawSurface4Impl_FreePrivateData,
2323 IDirectDrawSurface4Impl_GetUniquenessValue,
2324 IDirectDrawSurface4Impl_ChangeUniquenessValue
2326 #endif /* defined(HAVE_LIBXXF86DGA) */
2328 #ifdef HAVE_LIBXXF86DGA2
2329 static ICOM_VTABLE(IDirectDrawSurface4) dga2_dds4vt =
2331 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2332 IDirectDrawSurface4Impl_QueryInterface,
2333 IDirectDrawSurface4Impl_AddRef,
2334 DGA_IDirectDrawSurface4Impl_Release,
2335 IDirectDrawSurface4Impl_AddAttachedSurface,
2336 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2337 IDirectDrawSurface4Impl_Blt,
2338 IDirectDrawSurface4Impl_BltBatch,
2339 IDirectDrawSurface4Impl_BltFast,
2340 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2341 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2342 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2343 DGA2_IDirectDrawSurface4Impl_Flip,
2344 IDirectDrawSurface4Impl_GetAttachedSurface,
2345 IDirectDrawSurface4Impl_GetBltStatus,
2346 IDirectDrawSurface4Impl_GetCaps,
2347 IDirectDrawSurface4Impl_GetClipper,
2348 IDirectDrawSurface4Impl_GetColorKey,
2349 IDirectDrawSurface4Impl_GetDC,
2350 IDirectDrawSurface4Impl_GetFlipStatus,
2351 IDirectDrawSurface4Impl_GetOverlayPosition,
2352 IDirectDrawSurface4Impl_GetPalette,
2353 IDirectDrawSurface4Impl_GetPixelFormat,
2354 IDirectDrawSurface4Impl_GetSurfaceDesc,
2355 IDirectDrawSurface4Impl_Initialize,
2356 IDirectDrawSurface4Impl_IsLost,
2357 IDirectDrawSurface4Impl_Lock,
2358 IDirectDrawSurface4Impl_ReleaseDC,
2359 IDirectDrawSurface4Impl_Restore,
2360 IDirectDrawSurface4Impl_SetClipper,
2361 IDirectDrawSurface4Impl_SetColorKey,
2362 IDirectDrawSurface4Impl_SetOverlayPosition,
2363 DGA_IDirectDrawSurface4Impl_SetPalette,
2364 DGA_IDirectDrawSurface4Impl_Unlock,
2365 IDirectDrawSurface4Impl_UpdateOverlay,
2366 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2367 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2368 IDirectDrawSurface4Impl_GetDDInterface,
2369 IDirectDrawSurface4Impl_PageLock,
2370 IDirectDrawSurface4Impl_PageUnlock,
2371 IDirectDrawSurface4Impl_SetSurfaceDesc,
2372 IDirectDrawSurface4Impl_SetPrivateData,
2373 IDirectDrawSurface4Impl_GetPrivateData,
2374 IDirectDrawSurface4Impl_FreePrivateData,
2375 IDirectDrawSurface4Impl_GetUniquenessValue,
2376 IDirectDrawSurface4Impl_ChangeUniquenessValue
2378 #endif /* defined(HAVE_LIBXXF86DGA2) */
2380 static ICOM_VTABLE(IDirectDrawSurface4) xlib_dds4vt =
2382 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2383 IDirectDrawSurface4Impl_QueryInterface,
2384 IDirectDrawSurface4Impl_AddRef,
2385 Xlib_IDirectDrawSurface4Impl_Release,
2386 IDirectDrawSurface4Impl_AddAttachedSurface,
2387 IDirectDrawSurface4Impl_AddOverlayDirtyRect,
2388 IDirectDrawSurface4Impl_Blt,
2389 IDirectDrawSurface4Impl_BltBatch,
2390 IDirectDrawSurface4Impl_BltFast,
2391 IDirectDrawSurface4Impl_DeleteAttachedSurface,
2392 IDirectDrawSurface4Impl_EnumAttachedSurfaces,
2393 IDirectDrawSurface4Impl_EnumOverlayZOrders,
2394 Xlib_IDirectDrawSurface4Impl_Flip,
2395 IDirectDrawSurface4Impl_GetAttachedSurface,
2396 IDirectDrawSurface4Impl_GetBltStatus,
2397 IDirectDrawSurface4Impl_GetCaps,
2398 IDirectDrawSurface4Impl_GetClipper,
2399 IDirectDrawSurface4Impl_GetColorKey,
2400 IDirectDrawSurface4Impl_GetDC,
2401 IDirectDrawSurface4Impl_GetFlipStatus,
2402 IDirectDrawSurface4Impl_GetOverlayPosition,
2403 IDirectDrawSurface4Impl_GetPalette,
2404 IDirectDrawSurface4Impl_GetPixelFormat,
2405 IDirectDrawSurface4Impl_GetSurfaceDesc,
2406 IDirectDrawSurface4Impl_Initialize,
2407 IDirectDrawSurface4Impl_IsLost,
2408 IDirectDrawSurface4Impl_Lock,
2409 IDirectDrawSurface4Impl_ReleaseDC,
2410 IDirectDrawSurface4Impl_Restore,
2411 IDirectDrawSurface4Impl_SetClipper,
2412 IDirectDrawSurface4Impl_SetColorKey,
2413 IDirectDrawSurface4Impl_SetOverlayPosition,
2414 Xlib_IDirectDrawSurface4Impl_SetPalette,
2415 Xlib_IDirectDrawSurface4Impl_Unlock,
2416 IDirectDrawSurface4Impl_UpdateOverlay,
2417 IDirectDrawSurface4Impl_UpdateOverlayDisplay,
2418 IDirectDrawSurface4Impl_UpdateOverlayZOrder,
2419 IDirectDrawSurface4Impl_GetDDInterface,
2420 IDirectDrawSurface4Impl_PageLock,
2421 IDirectDrawSurface4Impl_PageUnlock,
2422 IDirectDrawSurface4Impl_SetSurfaceDesc,
2423 IDirectDrawSurface4Impl_SetPrivateData,
2424 IDirectDrawSurface4Impl_GetPrivateData,
2425 IDirectDrawSurface4Impl_FreePrivateData,
2426 IDirectDrawSurface4Impl_GetUniquenessValue,
2427 IDirectDrawSurface4Impl_ChangeUniquenessValue
2430 /******************************************************************************
2431 * DirectDrawCreateClipper (DDRAW.7)
2433 HRESULT WINAPI DirectDrawCreateClipper( DWORD dwFlags,
2434 LPDIRECTDRAWCLIPPER *lplpDDClipper,
2435 LPUNKNOWN pUnkOuter)
2437 IDirectDrawClipperImpl** ilplpDDClipper=(IDirectDrawClipperImpl**)lplpDDClipper;
2438 TRACE("(%08lx,%p,%p)\n", dwFlags, ilplpDDClipper, pUnkOuter);
2440 *ilplpDDClipper = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
2441 ICOM_VTBL(*ilplpDDClipper) = &ddclipvt;
2442 (*ilplpDDClipper)->ref = 1;
2444 (*ilplpDDClipper)->hWnd = 0;
2449 /******************************************************************************
2450 * IDirectDrawClipper
2452 static HRESULT WINAPI IDirectDrawClipperImpl_SetHwnd(
2453 LPDIRECTDRAWCLIPPER iface, DWORD dwFlags, HWND hWnd
2455 ICOM_THIS(IDirectDrawClipperImpl,iface);
2457 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This,dwFlags,(DWORD)hWnd);
2459 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags);
2460 return DDERR_INVALIDPARAMS;
2467 static ULONG WINAPI IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface) {
2468 ICOM_THIS(IDirectDrawClipperImpl,iface);
2469 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2474 HeapFree(GetProcessHeap(),0,This);
2478 static HRESULT WINAPI IDirectDrawClipperImpl_GetClipList(
2479 LPDIRECTDRAWCLIPPER iface,LPRECT rects,LPRGNDATA lprgn,LPDWORD hmm
2481 ICOM_THIS(IDirectDrawClipperImpl,iface);
2482 FIXME("(%p,%p,%p,%p),stub!\n",This,rects,lprgn,hmm);
2487 static HRESULT WINAPI IDirectDrawClipperImpl_SetClipList(
2488 LPDIRECTDRAWCLIPPER iface,LPRGNDATA lprgn,DWORD hmm
2490 ICOM_THIS(IDirectDrawClipperImpl,iface);
2491 FIXME("(%p,%p,%ld),stub!\n",This,lprgn,hmm);
2495 static HRESULT WINAPI IDirectDrawClipperImpl_QueryInterface(
2496 LPDIRECTDRAWCLIPPER iface,
2500 ICOM_THIS(IDirectDrawClipperImpl,iface);
2501 FIXME("(%p)->(%p,%p),stub!\n",This,riid,ppvObj);
2502 return OLE_E_ENUM_NOMORE;
2505 static ULONG WINAPI IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface )
2507 ICOM_THIS(IDirectDrawClipperImpl,iface);
2508 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2509 return ++(This->ref);
2512 static HRESULT WINAPI IDirectDrawClipperImpl_GetHWnd(
2513 LPDIRECTDRAWCLIPPER iface,
2516 ICOM_THIS(IDirectDrawClipperImpl,iface);
2517 FIXME("(%p)->(%p),stub!\n",This,hWndPtr);
2519 *hWndPtr = This->hWnd;
2524 static HRESULT WINAPI IDirectDrawClipperImpl_Initialize(
2525 LPDIRECTDRAWCLIPPER iface,
2529 ICOM_THIS(IDirectDrawClipperImpl,iface);
2530 FIXME("(%p)->(%p,0x%08lx),stub!\n",This,lpDD,dwFlags);
2534 static HRESULT WINAPI IDirectDrawClipperImpl_IsClipListChanged(
2535 LPDIRECTDRAWCLIPPER iface,
2538 ICOM_THIS(IDirectDrawClipperImpl,iface);
2539 FIXME("(%p)->(%p),stub!\n",This,lpbChanged);
2543 static ICOM_VTABLE(IDirectDrawClipper) ddclipvt =
2545 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2546 IDirectDrawClipperImpl_QueryInterface,
2547 IDirectDrawClipperImpl_AddRef,
2548 IDirectDrawClipperImpl_Release,
2549 IDirectDrawClipperImpl_GetClipList,
2550 IDirectDrawClipperImpl_GetHWnd,
2551 IDirectDrawClipperImpl_Initialize,
2552 IDirectDrawClipperImpl_IsClipListChanged,
2553 IDirectDrawClipperImpl_SetClipList,
2554 IDirectDrawClipperImpl_SetHwnd
2558 /******************************************************************************
2559 * IDirectDrawPalette
2561 static HRESULT WINAPI IDirectDrawPaletteImpl_GetEntries(
2562 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2564 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2567 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2568 This,x,start,count,palent);
2570 /* No palette created and not in depth-convertion mode -> BUG ! */
2571 if ((This->cm == None) &&
2572 (This->ddraw->d.palette_convert == NULL))
2574 FIXME("app tried to read colormap for non-palettized mode\n");
2575 return DDERR_GENERIC;
2577 for (i=0;i<count;i++) {
2578 palent[i].peRed = This->palents[start+i].peRed;
2579 palent[i].peBlue = This->palents[start+i].peBlue;
2580 palent[i].peGreen = This->palents[start+i].peGreen;
2581 palent[i].peFlags = This->palents[start+i].peFlags;
2587 static HRESULT WINAPI Xlib_IDirectDrawPaletteImpl_SetEntries(
2588 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2590 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2594 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2595 This,x,start,count,palent
2597 for (i=0;i<count;i++) {
2598 xc.red = palent[i].peRed<<8;
2599 xc.blue = palent[i].peBlue<<8;
2600 xc.green = palent[i].peGreen<<8;
2601 xc.flags = DoRed|DoBlue|DoGreen;
2605 TSXStoreColor(display,This->cm,&xc);
2607 This->palents[start+i].peRed = palent[i].peRed;
2608 This->palents[start+i].peBlue = palent[i].peBlue;
2609 This->palents[start+i].peGreen = palent[i].peGreen;
2610 This->palents[start+i].peFlags = palent[i].peFlags;
2613 /* Now, if we are in 'depth conversion mode', update the screen palette */
2614 /* FIXME: we need to update the image or we won't get palette fading. */
2615 if (This->ddraw->d.palette_convert != NULL)
2616 This->ddraw->d.palette_convert(palent, This->screen_palents, start, count);
2621 #ifdef HAVE_LIBXXF86DGA
2622 static HRESULT WINAPI DGA_IDirectDrawPaletteImpl_SetEntries(
2623 LPDIRECTDRAWPALETTE iface,DWORD x,DWORD start,DWORD count,LPPALETTEENTRY palent
2625 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2630 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2631 This,x,start,count,palent
2633 if (!This->cm) /* should not happen */ {
2634 FIXME("app tried to set colormap in non-palettized mode\n");
2635 return DDERR_GENERIC;
2637 /* FIXME: free colorcells instead of freeing whole map */
2639 This->cm = TSXCopyColormapAndFree(display,This->cm);
2640 TSXFreeColormap(display,cm);
2642 for (i=0;i<count;i++) {
2643 xc.red = palent[i].peRed<<8;
2644 xc.blue = palent[i].peBlue<<8;
2645 xc.green = palent[i].peGreen<<8;
2646 xc.flags = DoRed|DoBlue|DoGreen;
2649 TSXStoreColor(display,This->cm,&xc);
2651 This->palents[start+i].peRed = palent[i].peRed;
2652 This->palents[start+i].peBlue = palent[i].peBlue;
2653 This->palents[start+i].peGreen = palent[i].peGreen;
2654 This->palents[start+i].peFlags = palent[i].peFlags;
2656 #ifdef HAVE_LIBXXF86DGA2
2657 if (This->ddraw->e.dga.version == 2)
2658 TSXDGAInstallColormap(display,DefaultScreen(display),This->cm);
2660 #endif /* defined(HAVE_LIBXXF86DGA2) */
2661 TSXF86DGAInstallColormap(display,DefaultScreen(display),This->cm);
2664 #endif /* defined(HAVE_LIBXXF86DGA) */
2666 static ULONG WINAPI IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface) {
2667 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2668 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2669 if (!--(This->ref)) {
2671 TSXFreeColormap(display,This->cm);
2674 HeapFree(GetProcessHeap(),0,This);
2680 static ULONG WINAPI IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface) {
2681 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2683 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2684 return ++(This->ref);
2687 static HRESULT WINAPI IDirectDrawPaletteImpl_Initialize(
2688 LPDIRECTDRAWPALETTE iface,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
2690 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2691 TRACE("(%p)->(%p,%ld,%p)\n", This, ddraw, x, palent);
2693 return DDERR_ALREADYINITIALIZED;
2696 static HRESULT WINAPI IDirectDrawPaletteImpl_GetCaps(
2697 LPDIRECTDRAWPALETTE iface, LPDWORD lpdwCaps )
2699 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2700 FIXME("(%p)->(%p) stub.\n", This, lpdwCaps );
2704 static HRESULT WINAPI IDirectDrawPaletteImpl_QueryInterface(
2705 LPDIRECTDRAWPALETTE iface,REFIID refiid,LPVOID *obj )
2707 ICOM_THIS(IDirectDrawPaletteImpl,iface);
2709 FIXME("(%p)->(%s,%p) stub.\n",This,debugstr_guid(refiid),obj);
2714 #ifdef HAVE_LIBXXF86DGA
2715 static ICOM_VTABLE(IDirectDrawPalette) dga_ddpalvt =
2717 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2718 IDirectDrawPaletteImpl_QueryInterface,
2719 IDirectDrawPaletteImpl_AddRef,
2720 IDirectDrawPaletteImpl_Release,
2721 IDirectDrawPaletteImpl_GetCaps,
2722 IDirectDrawPaletteImpl_GetEntries,
2723 IDirectDrawPaletteImpl_Initialize,
2724 DGA_IDirectDrawPaletteImpl_SetEntries
2726 #endif /* defined(HAVE_LIBXXF86DGA) */
2728 static ICOM_VTABLE(IDirectDrawPalette) xlib_ddpalvt =
2730 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2731 IDirectDrawPaletteImpl_QueryInterface,
2732 IDirectDrawPaletteImpl_AddRef,
2733 IDirectDrawPaletteImpl_Release,
2734 IDirectDrawPaletteImpl_GetCaps,
2735 IDirectDrawPaletteImpl_GetEntries,
2736 IDirectDrawPaletteImpl_Initialize,
2737 Xlib_IDirectDrawPaletteImpl_SetEntries
2740 /*******************************************************************************
2743 static HRESULT WINAPI IDirect3DImpl_QueryInterface(
2744 LPDIRECT3D iface,REFIID refiid,LPVOID *obj
2746 ICOM_THIS(IDirect3DImpl,iface);
2747 /* FIXME: Not sure if this is correct */
2749 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2750 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2751 ( IsEqualGUID (&IID_IDirectDraw2, refiid ) ) ||
2752 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2754 IDirect3D_AddRef(iface);
2756 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2760 if ( ( IsEqualGUID( &IID_IDirect3D, refiid ) ) ||
2761 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2763 IDirect3D_AddRef(iface);
2765 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2769 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
2770 IDirect3D2Impl* d3d;
2772 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2774 d3d->ddraw = This->ddraw;
2775 IDirect3D_AddRef(iface);
2776 ICOM_VTBL(d3d) = &d3d2vt;
2779 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2783 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2784 return OLE_E_ENUM_NOMORE;
2787 static ULONG WINAPI IDirect3DImpl_AddRef(LPDIRECT3D iface) {
2788 ICOM_THIS(IDirect3DImpl,iface);
2789 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2791 return ++(This->ref);
2794 static ULONG WINAPI IDirect3DImpl_Release(LPDIRECT3D iface)
2796 ICOM_THIS(IDirect3DImpl,iface);
2797 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2799 if (!--(This->ref)) {
2800 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2801 HeapFree(GetProcessHeap(),0,This);
2807 static HRESULT WINAPI IDirect3DImpl_Initialize(
2808 LPDIRECT3D iface, REFIID refiid )
2810 ICOM_THIS(IDirect3DImpl,iface);
2811 /* FIXME: Not sure if this is correct */
2813 FIXME("(%p)->(%s):stub.\n",This,debugstr_guid(refiid));
2815 return DDERR_ALREADYINITIALIZED;
2818 static HRESULT WINAPI IDirect3DImpl_EnumDevices(LPDIRECT3D iface,
2819 LPD3DENUMDEVICESCALLBACK cb,
2821 ICOM_THIS(IDirect3DImpl,iface);
2822 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2824 /* Call functions defined in d3ddevices.c */
2825 if (!d3d_OpenGL_dx3(cb, context))
2831 static HRESULT WINAPI IDirect3DImpl_CreateLight(LPDIRECT3D iface,
2832 LPDIRECT3DLIGHT *lplight,
2835 ICOM_THIS(IDirect3DImpl,iface);
2836 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2838 /* Call the creation function that is located in d3dlight.c */
2839 *lplight = d3dlight_create_dx3(This);
2844 static HRESULT WINAPI IDirect3DImpl_CreateMaterial(LPDIRECT3D iface,
2845 LPDIRECT3DMATERIAL *lpmaterial,
2848 ICOM_THIS(IDirect3DImpl,iface);
2849 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2851 /* Call the creation function that is located in d3dviewport.c */
2852 *lpmaterial = d3dmaterial_create(This);
2857 static HRESULT WINAPI IDirect3DImpl_CreateViewport(LPDIRECT3D iface,
2858 LPDIRECT3DVIEWPORT *lpviewport,
2861 ICOM_THIS(IDirect3DImpl,iface);
2862 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
2864 /* Call the creation function that is located in d3dviewport.c */
2865 *lpviewport = d3dviewport_create(This);
2870 static HRESULT WINAPI IDirect3DImpl_FindDevice(LPDIRECT3D iface,
2871 LPD3DFINDDEVICESEARCH lpfinddevsrc,
2872 LPD3DFINDDEVICERESULT lpfinddevrst)
2874 ICOM_THIS(IDirect3DImpl,iface);
2875 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
2880 static ICOM_VTABLE(IDirect3D) d3dvt =
2882 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2883 IDirect3DImpl_QueryInterface,
2884 IDirect3DImpl_AddRef,
2885 IDirect3DImpl_Release,
2886 IDirect3DImpl_Initialize,
2887 IDirect3DImpl_EnumDevices,
2888 IDirect3DImpl_CreateLight,
2889 IDirect3DImpl_CreateMaterial,
2890 IDirect3DImpl_CreateViewport,
2891 IDirect3DImpl_FindDevice
2894 /*******************************************************************************
2897 static HRESULT WINAPI IDirect3D2Impl_QueryInterface(
2898 LPDIRECT3D2 iface,REFIID refiid,LPVOID *obj) {
2899 ICOM_THIS(IDirect3D2Impl,iface);
2901 /* FIXME: Not sure if this is correct */
2903 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
2904 if ( ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) ||
2905 ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) ||
2906 ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) ) {
2908 IDirect3D2_AddRef(iface);
2910 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj);
2914 if ( ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) ||
2915 ( IsEqualGUID( &IID_IUnknown, refiid ) ) ) {
2917 IDirect3D2_AddRef(iface);
2919 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
2923 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
2926 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
2928 d3d->ddraw = This->ddraw;
2929 IDirect3D2_AddRef(iface);
2930 ICOM_VTBL(d3d) = &d3dvt;
2933 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
2937 FIXME("(%p):interface for IID %s NOT found!\n",This,debugstr_guid(refiid));
2938 return OLE_E_ENUM_NOMORE;
2941 static ULONG WINAPI IDirect3D2Impl_AddRef(LPDIRECT3D2 iface) {
2942 ICOM_THIS(IDirect3D2Impl,iface);
2943 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
2945 return ++(This->ref);
2948 static ULONG WINAPI IDirect3D2Impl_Release(LPDIRECT3D2 iface) {
2949 ICOM_THIS(IDirect3D2Impl,iface);
2950 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
2952 if (!--(This->ref)) {
2953 IDirectDraw2_Release((IDirectDraw2*)This->ddraw);
2954 HeapFree(GetProcessHeap(),0,This);
2960 static HRESULT WINAPI IDirect3D2Impl_EnumDevices(
2961 LPDIRECT3D2 iface,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
2963 ICOM_THIS(IDirect3D2Impl,iface);
2964 FIXME("(%p)->(%p,%p),stub!\n",This,cb,context);
2966 /* Call functions defined in d3ddevices.c */
2967 if (!d3d_OpenGL(cb, context))
2973 static HRESULT WINAPI IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface,
2974 LPDIRECT3DLIGHT *lplight,
2977 ICOM_THIS(IDirect3D2Impl,iface);
2978 TRACE("(%p)->(%p,%p): stub\n", This, lplight, lpunk);
2980 /* Call the creation function that is located in d3dlight.c */
2981 *lplight = d3dlight_create(This);
2986 static HRESULT WINAPI IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface,
2987 LPDIRECT3DMATERIAL2 *lpmaterial,
2990 ICOM_THIS(IDirect3D2Impl,iface);
2991 TRACE("(%p)->(%p,%p): stub\n", This, lpmaterial, lpunk);
2993 /* Call the creation function that is located in d3dviewport.c */
2994 *lpmaterial = d3dmaterial2_create(This);
2999 static HRESULT WINAPI IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface,
3000 LPDIRECT3DVIEWPORT2 *lpviewport,
3003 ICOM_THIS(IDirect3D2Impl,iface);
3004 TRACE("(%p)->(%p,%p): stub\n", This, lpviewport, lpunk);
3006 /* Call the creation function that is located in d3dviewport.c */
3007 *lpviewport = d3dviewport2_create(This);
3012 static HRESULT WINAPI IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface,
3013 LPD3DFINDDEVICESEARCH lpfinddevsrc,
3014 LPD3DFINDDEVICERESULT lpfinddevrst)
3016 ICOM_THIS(IDirect3D2Impl,iface);
3017 TRACE("(%p)->(%p,%p): stub\n", This, lpfinddevsrc, lpfinddevrst);
3022 static HRESULT WINAPI IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface,
3024 LPDIRECTDRAWSURFACE surface,
3025 LPDIRECT3DDEVICE2 *device)
3027 ICOM_THIS(IDirect3D2Impl,iface);
3029 FIXME("(%p)->(%s,%p,%p): stub\n",This,debugstr_guid(rguid),surface,device);
3031 if (is_OpenGL(rguid, (IDirectDrawSurfaceImpl*)surface, (IDirect3DDevice2Impl**)device, This)) {
3032 IDirect3D2_AddRef(iface);
3036 return DDERR_INVALIDPARAMS;
3039 static ICOM_VTABLE(IDirect3D2) d3d2vt =
3041 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3042 IDirect3D2Impl_QueryInterface,
3043 IDirect3D2Impl_AddRef,
3044 IDirect3D2Impl_Release,
3045 IDirect3D2Impl_EnumDevices,
3046 IDirect3D2Impl_CreateLight,
3047 IDirect3D2Impl_CreateMaterial,
3048 IDirect3D2Impl_CreateViewport,
3049 IDirect3D2Impl_FindDevice,
3050 IDirect3D2Impl_CreateDevice
3053 /*******************************************************************************
3057 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3058 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3060 static HRESULT common_off_screen_CreateSurface(IDirectDraw2Impl* This,
3061 IDirectDrawSurfaceImpl* lpdsf)
3065 /* The surface was already allocated when entering in this function */
3066 TRACE("using system memory for a surface (%p) \n", lpdsf);
3068 if (lpdsf->s.surface_desc.dwFlags & DDSD_ZBUFFERBITDEPTH) {
3069 /* This is a Z Buffer */
3070 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf->s.surface_desc.u.dwZBufferBitDepth);
3071 bpp = lpdsf->s.surface_desc.u.dwZBufferBitDepth / 8;
3073 /* This is a standard image */
3074 if (!(lpdsf->s.surface_desc.dwFlags & DDSD_PIXELFORMAT)) {
3075 /* No pixel format => use DirectDraw's format */
3076 lpdsf->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3077 lpdsf->s.surface_desc.dwFlags |= DDSD_PIXELFORMAT;
3079 bpp = GET_BPP(lpdsf->s.surface_desc);
3082 if (lpdsf->s.surface_desc.dwFlags & DDSD_LPSURFACE) {
3083 /* The surface was preallocated : seems that we have nothing to do :-) */
3084 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3088 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf->s.surface_desc.dwWidth,lpdsf->s.surface_desc.dwHeight,bpp);
3090 lpdsf->s.surface_desc.dwFlags |= DDSD_PITCH|DDSD_LPSURFACE;
3091 lpdsf->s.surface_desc.u1.lpSurface =
3092 (LPBYTE)HeapAlloc(GetProcessHeap(),0,lpdsf->s.surface_desc.dwWidth * lpdsf->s.surface_desc.dwHeight * bpp);
3093 lpdsf->s.surface_desc.lPitch = lpdsf->s.surface_desc.dwWidth * bpp;
3098 #ifdef HAVE_LIBXXF86DGA
3099 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreateSurface(
3100 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3102 ICOM_THIS(IDirectDraw2Impl,iface);
3103 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3104 int i, fbheight = This->e.dga.fb_height;
3106 TRACE("(%p)->(%p,%p,%p)\n",This,lpddsd,ilpdsf,lpunk);
3107 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3109 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3112 sizeof(IDirectDrawSurfaceImpl)
3114 IDirectDraw2_AddRef(iface);
3117 #ifdef HAVE_LIBXXF86DGA2
3118 if (This->e.dga.version == 2)
3119 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga2_dds4vt;
3121 #endif /* defined(HAVE_LIBXXF86DGA2) */
3122 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&dga_dds4vt;
3123 (*ilpdsf)->s.ddraw = This;
3124 (*ilpdsf)->s.palette = NULL;
3125 (*ilpdsf)->t.dga.fb_height = -1; /* This is to have non-on screen surfaces freed */
3126 (*ilpdsf)->s.lpClipper = NULL;
3128 /* Copy the surface description */
3129 (*ilpdsf)->s.surface_desc = *lpddsd;
3131 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3132 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3133 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3134 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3136 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3138 /* Check if this a 'primary surface' or not */
3139 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3140 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3141 /* This is THE primary surface => there is DGA-specific code */
3143 /* First, store the surface description */
3144 (*ilpdsf)->s.surface_desc = *lpddsd;
3146 /* Find a viewport */
3148 if (!(This->e.dga.vpmask & (1<<i)))
3150 TRACE("using viewport %d for a primary surface\n",i);
3151 /* if i == 32 or maximum ... return error */
3152 This->e.dga.vpmask|=(1<<i);
3153 lpddsd->lPitch = (*ilpdsf)->s.surface_desc.lPitch =
3154 This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
3156 (*ilpdsf)->s.surface_desc.u1.lpSurface =
3157 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3159 (*ilpdsf)->t.dga.fb_height = i*fbheight;
3161 /* Add flags if there were not present */
3162 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3163 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3164 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3165 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This->d.width,This->d.height,lpddsd->lPitch);
3166 /* We put our surface always in video memory */
3167 SDDSCAPS((*ilpdsf)) |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3168 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3169 (*ilpdsf)->s.chain = NULL;
3171 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3172 IDirectDrawSurface4Impl* back;
3175 for (bbc=lpddsd->dwBackBufferCount;bbc--;) {
3178 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3181 sizeof(IDirectDrawSurface4Impl)
3183 IDirectDraw2_AddRef(iface);
3185 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&dga_dds4vt;
3187 if (!(This->e.dga.vpmask & (1<<i)))
3189 TRACE("using viewport %d for backbuffer %d\n",i, bbc);
3190 /* if i == 32 or maximum ... return error */
3191 This->e.dga.vpmask|=(1<<i);
3192 back->t.dga.fb_height = i*fbheight;
3193 /* Copy the surface description from the front buffer */
3194 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3195 /* Change the parameters that are not the same */
3196 back->s.surface_desc.u1.lpSurface =
3197 This->e.dga.fb_addr + i*fbheight*lpddsd->lPitch;
3199 back->s.ddraw = This;
3200 /* Add relevant info to front and back buffers */
3201 /* FIXME: backbuffer/frontbuffer handling broken here, but
3202 * will be fixed up in _Flip().
3204 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3205 SDDSCAPS(back) |= DDSCAPS_FLIP|DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY;
3206 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3207 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3208 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3212 /* There is no DGA-specific code here...
3213 Go to the common surface creation function */
3214 return common_off_screen_CreateSurface(This, *ilpdsf);
3218 #endif /* defined(HAVE_LIBXXF86DGA) */
3220 #ifdef HAVE_LIBXXSHM
3221 /* Error handlers for Image creation */
3222 static int XShmErrorHandler(Display *dpy, XErrorEvent *event) {
3227 static XImage *create_xshmimage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3229 int (*WineXHandler)(Display *, XErrorEvent *);
3231 img = TSXShmCreateImage(display, X11DRV_GetVisual(),
3232 This->d.pixmap_depth,
3235 &(lpdsf->t.xlib.shminfo),
3236 lpdsf->s.surface_desc.dwWidth,
3237 lpdsf->s.surface_desc.dwHeight
3241 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3242 This->e.xlib.xshm_active = 0;
3246 lpdsf->t.xlib.shminfo.shmid = shmget( IPC_PRIVATE, img->bytes_per_line * img->height, IPC_CREAT|0777 );
3247 if (lpdsf->t.xlib.shminfo.shmid < 0) {
3248 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3249 This->e.xlib.xshm_active = 0;
3250 TSXDestroyImage(img);
3254 lpdsf->t.xlib.shminfo.shmaddr = img->data = (char*)shmat(lpdsf->t.xlib.shminfo.shmid, 0, 0);
3256 if (img->data == (char *) -1) {
3257 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3258 This->e.xlib.xshm_active = 0;
3259 TSXDestroyImage(img);
3260 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3263 lpdsf->t.xlib.shminfo.readOnly = False;
3265 /* This is where things start to get trickier....
3266 * First, we flush the current X connections to be sure to catch all
3267 * non-XShm related errors
3269 TSXSync(display, False);
3270 /* Then we enter in the non-thread safe part of the tests */
3271 EnterCriticalSection( &X11DRV_CritSection );
3273 /* Reset the error flag, sets our new error handler and try to attach
3277 WineXHandler = XSetErrorHandler(XShmErrorHandler);
3278 XShmAttach(display, &(lpdsf->t.xlib.shminfo));
3279 XSync(display, False);
3281 /* Check the error flag */
3282 if (XShmErrorFlag) {
3283 /* An error occured */
3287 shmdt(lpdsf->t.xlib.shminfo.shmaddr);
3288 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3289 XSetErrorHandler(WineXHandler);
3291 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3292 This->e.xlib.xshm_active = 0;
3294 /* Leave the critical section */
3295 LeaveCriticalSection( &X11DRV_CritSection );
3298 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3299 * this works, but it may be a bit overkill....
3301 XSetErrorHandler(WineXHandler);
3302 LeaveCriticalSection( &X11DRV_CritSection );
3304 shmctl(lpdsf->t.xlib.shminfo.shmid, IPC_RMID, 0);
3306 if (This->d.pixel_convert != NULL) {
3307 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3310 lpdsf->s.surface_desc.dwWidth *
3311 lpdsf->s.surface_desc.dwHeight *
3312 PFGET_BPP(This->d.directdraw_pixelformat)
3315 lpdsf->s.surface_desc.u1.lpSurface = img->data;
3319 #endif /* HAVE_LIBXXSHM */
3321 static XImage *create_ximage(IDirectDraw2Impl* This, IDirectDrawSurface4Impl* lpdsf) {
3325 #ifdef HAVE_LIBXXSHM
3326 if (This->e.xlib.xshm_active)
3327 img = create_xshmimage(This, lpdsf);
3331 /* Allocate surface memory */
3332 lpdsf->s.surface_desc.u1.lpSurface = HeapAlloc(
3333 GetProcessHeap(),HEAP_ZERO_MEMORY,
3334 lpdsf->s.surface_desc.dwWidth *
3335 lpdsf->s.surface_desc.dwHeight *
3336 PFGET_BPP(This->d.directdraw_pixelformat)
3339 if (This->d.pixel_convert != NULL) {
3340 img_data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
3341 lpdsf->s.surface_desc.dwWidth *
3342 lpdsf->s.surface_desc.dwHeight *
3343 PFGET_BPP(This->d.screen_pixelformat)
3346 img_data = lpdsf->s.surface_desc.u1.lpSurface;
3349 /* In this case, create an XImage */
3350 img = TSXCreateImage(display, X11DRV_GetVisual(),
3351 This->d.pixmap_depth,
3355 lpdsf->s.surface_desc.dwWidth,
3356 lpdsf->s.surface_desc.dwHeight,
3358 lpdsf->s.surface_desc.dwWidth* PFGET_BPP(This->d.screen_pixelformat)
3360 #ifdef HAVE_LIBXXSHM
3363 if (This->d.pixel_convert != NULL)
3364 lpdsf->s.surface_desc.lPitch = PFGET_BPP(This->d.directdraw_pixelformat) * lpdsf->s.surface_desc.dwWidth;
3366 lpdsf->s.surface_desc.lPitch = img->bytes_per_line;
3370 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreateSurface(
3371 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
3373 ICOM_THIS(IDirectDraw2Impl,iface);
3374 IDirectDrawSurfaceImpl** ilpdsf=(IDirectDrawSurfaceImpl**)lpdsf;
3376 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This,lpddsd,ilpdsf,lpunk);
3378 if (TRACE_ON(ddraw)) { _dump_surface_desc(lpddsd); }
3380 *ilpdsf = (IDirectDrawSurfaceImpl*)HeapAlloc(
3381 GetProcessHeap(),HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl)
3384 IDirectDraw2_AddRef(iface);
3386 (*ilpdsf)->s.ddraw = This;
3388 ICOM_VTBL(*ilpdsf) = (ICOM_VTABLE(IDirectDrawSurface)*)&xlib_dds4vt;
3389 (*ilpdsf)->s.palette = NULL;
3390 (*ilpdsf)->t.xlib.image = NULL; /* This is for off-screen buffers */
3391 (*ilpdsf)->s.lpClipper = NULL;
3393 /* Copy the surface description */
3394 (*ilpdsf)->s.surface_desc = *lpddsd;
3396 if (!(lpddsd->dwFlags & DDSD_WIDTH))
3397 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3398 if (!(lpddsd->dwFlags & DDSD_HEIGHT))
3399 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3400 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT;
3402 /* Check if this a 'primary surface' or not */
3403 if ((lpddsd->dwFlags & DDSD_CAPS) &&
3404 (lpddsd->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE)) {
3407 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf);
3408 /* Create the XImage */
3409 img = create_ximage(This, (IDirectDrawSurface4Impl*) *ilpdsf);
3411 return DDERR_OUTOFMEMORY;
3412 (*ilpdsf)->t.xlib.image = img;
3414 /* Add flags if there were not present */
3415 (*ilpdsf)->s.surface_desc.dwFlags |= DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT;
3416 (*ilpdsf)->s.surface_desc.dwWidth = This->d.width;
3417 (*ilpdsf)->s.surface_desc.dwHeight = This->d.height;
3418 (*ilpdsf)->s.surface_desc.ddsCaps.dwCaps |= DDSCAPS_VISIBLE|DDSCAPS_VIDEOMEMORY;
3419 (*ilpdsf)->s.surface_desc.ddpfPixelFormat = This->d.directdraw_pixelformat;
3421 /* Check for backbuffers */
3422 if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
3423 IDirectDrawSurface4Impl* back;
3427 for (i=lpddsd->dwBackBufferCount;i--;) {
3428 back = (IDirectDrawSurface4Impl*)HeapAlloc(
3429 GetProcessHeap(),HEAP_ZERO_MEMORY,
3430 sizeof(IDirectDrawSurface4Impl)
3433 TRACE("allocated back-buffer (%p)\n", back);
3435 IDirectDraw2_AddRef(iface);
3436 back->s.ddraw = This;
3439 ICOM_VTBL(back) = (ICOM_VTABLE(IDirectDrawSurface4)*)&xlib_dds4vt;
3440 /* Copy the surface description from the front buffer */
3441 back->s.surface_desc = (*ilpdsf)->s.surface_desc;
3443 /* Create the XImage */
3444 img = create_ximage(This, back);
3446 return DDERR_OUTOFMEMORY;
3447 back->t.xlib.image = img;
3449 /* Add relevant info to front and back buffers */
3450 /* FIXME: backbuffer/frontbuffer handling broken here, but
3451 * will be fixed up in _Flip().
3453 SDDSCAPS((*ilpdsf)) |= DDSCAPS_FRONTBUFFER;
3454 SDDSCAPS(back) |= DDSCAPS_BACKBUFFER|DDSCAPS_VIDEOMEMORY|DDSCAPS_FLIP;
3455 back->s.surface_desc.dwFlags &= ~DDSD_BACKBUFFERCOUNT;
3456 SDDSCAPS(back) &= ~DDSCAPS_VISIBLE;
3457 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4)(*ilpdsf),(LPDIRECTDRAWSURFACE4)back);
3461 /* There is no Xlib-specific code here...
3462 Go to the common surface creation function */
3463 return common_off_screen_CreateSurface(This, *ilpdsf);
3468 static HRESULT WINAPI IDirectDraw2Impl_DuplicateSurface(
3469 LPDIRECTDRAW2 iface,LPDIRECTDRAWSURFACE src,LPDIRECTDRAWSURFACE *dst
3471 ICOM_THIS(IDirectDraw2Impl,iface);
3472 FIXME("(%p)->(%p,%p) simply copies\n",This,src,dst);
3473 *dst = src; /* FIXME */
3478 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3479 * even when the approbiate bitmasks are not specified.
3481 static HRESULT WINAPI IDirectDraw2Impl_SetCooperativeLevel(
3482 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3484 ICOM_THIS(IDirectDraw2Impl,iface);
3490 #define FE(x) { x, #x},
3491 FE(DDSCL_FULLSCREEN)
3492 FE(DDSCL_ALLOWREBOOT)
3493 FE(DDSCL_NOWINDOWCHANGES)
3495 FE(DDSCL_ALLOWMODEX)
3497 FE(DDSCL_SETFOCUSWINDOW)
3498 FE(DDSCL_SETDEVICEWINDOW)
3499 FE(DDSCL_CREATEDEVICEWINDOW)
3503 FIXME("(%p)->(%08lx,%08lx)\n",This,(DWORD)hwnd,cooplevel);
3504 if (TRACE_ON(ddraw)) {
3506 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
3507 if (flags[i].mask & cooplevel) {
3508 DPRINTF("%s ",flags[i].name);
3513 This->d.mainWindow = hwnd;
3515 /* This will be overwritten in the case of Full Screen mode.
3516 Windowed games could work with that :-) */
3519 WND *tmpWnd = WIN_FindWndPtr(hwnd);
3520 This->d.drawable = X11DRV_WND_GetXWindow(tmpWnd);
3521 WIN_ReleaseWndPtr(tmpWnd);
3523 if( !This->d.drawable ) {
3524 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
3525 WIN_ReleaseDesktop();
3527 TRACE("Setting drawable to %ld\n", This->d.drawable);
3533 #ifdef HAVE_LIBXXF86DGA2
3534 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetCooperativeLevel(
3535 LPDIRECTDRAW2 iface,HWND hwnd,DWORD cooplevel
3537 ICOM_THIS(IDirectDraw2Impl,iface);
3541 ret = IDirectDraw2Impl_SetCooperativeLevel(iface, hwnd, cooplevel);
3543 if (This->e.dga.version != 2) {
3549 TSXDGAQueryExtension(display, &evbase, &erbase);
3551 /* Now, start handling of DGA events giving the handle to the DDraw window
3552 as the window for which the event will be reported */
3553 TSXDGASelectInput(display, DefaultScreen(display),
3554 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3555 X11DRV_EVENT_SetDGAStatus(hwnd, evbase);
3562 /* Small helper to either use the cooperative window or create a new
3563 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3565 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl* This) {
3568 /* Do destroy only our window */
3569 if (This->d.window && GetPropA(This->d.window,ddProp)) {
3570 DestroyWindow(This->d.window);
3573 /* Sanity check cooperative window before assigning it to drawing. */
3574 if ( IsWindow(This->d.mainWindow) &&
3575 IsWindowVisible(This->d.mainWindow)
3577 /* if it does not fit, resize the cooperative window.
3578 * and hope the app likes it
3580 GetWindowRect(This->d.mainWindow,&rect);
3581 if ((((rect.right-rect.left) >= This->d.width) &&
3582 ((rect.bottom-rect.top) >= This->d.height))
3584 This->d.window = This->d.mainWindow;
3585 /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
3586 This->d.paintable = 1;
3589 /* ... failed, create new one. */
3590 if (!This->d.window) {
3591 This->d.window = CreateWindowExA(
3595 WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME,
3604 /*Store THIS with the window. We'll use it in the window procedure*/
3605 SetPropA(This->d.window,ddProp,(LONG)This);
3606 ShowWindow(This->d.window,TRUE);
3607 UpdateWindow(This->d.window);
3609 SetFocus(This->d.window);
3612 static int _common_depth_to_pixelformat(DWORD depth,
3613 DDPIXELFORMAT *pixelformat,
3614 DDPIXELFORMAT *screen_pixelformat,
3617 XPixmapFormatValues *pf;
3619 int nvisuals, npixmap, i;
3623 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
3624 pf = XListPixmapFormats(display, &npixmap);
3626 for (i = 0; i < npixmap; i++) {
3627 if (pf[i].depth == depth) {
3630 for (j = 0; j < nvisuals; j++) {
3631 if (vi[j].depth == pf[i].depth) {
3632 pixelformat->dwSize = sizeof(*pixelformat);
3634 pixelformat->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3635 pixelformat->u1.dwRBitMask = 0;
3636 pixelformat->u2.dwGBitMask = 0;
3637 pixelformat->u3.dwBBitMask = 0;
3639 pixelformat->dwFlags = DDPF_RGB;
3640 pixelformat->u1.dwRBitMask = vi[j].red_mask;
3641 pixelformat->u2.dwGBitMask = vi[j].green_mask;
3642 pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3644 pixelformat->dwFourCC = 0;
3645 pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3646 pixelformat->u4.dwRGBAlphaBitMask= 0;
3648 *screen_pixelformat = *pixelformat;
3650 if (pix_depth != NULL)
3651 *pix_depth = vi[j].depth;
3656 goto clean_up_and_exit;
3660 ERR("No visual corresponding to pixmap format !\n");
3665 /* We try now to find an emulated mode */
3668 for (c = 0; c < sizeof(ModeEmulations) / sizeof(Convert); c++) {
3669 if (ModeEmulations[c].dest.depth == depth) {
3670 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3671 for (i = 0; i < npixmap; i++) {
3672 if ((pf[i].depth == ModeEmulations[c].screen.depth) &&
3673 (pf[i].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
3676 for (j = 0; j < nvisuals; j++) {
3677 if (vi[j].depth == pf[i].depth) {
3678 screen_pixelformat->dwSize = sizeof(*screen_pixelformat);
3679 screen_pixelformat->dwFlags = DDPF_RGB;
3680 screen_pixelformat->dwFourCC = 0;
3681 screen_pixelformat->u.dwRGBBitCount = pf[i].bits_per_pixel;
3682 screen_pixelformat->u1.dwRBitMask = vi[j].red_mask;
3683 screen_pixelformat->u2.dwGBitMask = vi[j].green_mask;
3684 screen_pixelformat->u3.dwBBitMask = vi[j].blue_mask;
3685 screen_pixelformat->u4.dwRGBAlphaBitMask= 0;
3687 pixelformat->dwSize = sizeof(*pixelformat);
3688 pixelformat->dwFourCC = 0;
3690 pixelformat->dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
3691 pixelformat->u.dwRGBBitCount = 8;
3692 pixelformat->u1.dwRBitMask = 0;
3693 pixelformat->u2.dwGBitMask = 0;
3694 pixelformat->u3.dwBBitMask = 0;
3696 pixelformat->dwFlags = DDPF_RGB;
3697 pixelformat->u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
3698 pixelformat->u1.dwRBitMask = ModeEmulations[c].dest.rmask;
3699 pixelformat->u2.dwGBitMask = ModeEmulations[c].dest.gmask;
3700 pixelformat->u3.dwBBitMask = ModeEmulations[c].dest.bmask;
3702 pixelformat->u4.dwRGBAlphaBitMask= 0;
3704 if (pix_depth != NULL)
3705 *pix_depth = vi[j].depth;
3710 goto clean_up_and_exit;
3713 ERR("No visual corresponding to pixmap format !\n");
3728 #ifdef HAVE_LIBXXF86DGA2
3729 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl *This, int mode) {
3730 DDPIXELFORMAT *pf = &(This->d.directdraw_pixelformat);
3732 /* Now, get the device / mode description */
3733 This->e.dga.dev = TSXDGASetMode(display, DefaultScreen(display), mode);
3735 This->e.dga.fb_width = This->e.dga.dev->mode.imageWidth;
3736 TSXDGASetViewport(display,DefaultScreen(display),0,0, XDGAFlipImmediate);
3737 This->e.dga.fb_height = This->e.dga.dev->mode.viewportHeight;
3738 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3739 This->e.dga.dev->data,
3740 This->e.dga.dev->mode.imageWidth,
3741 (This->e.dga.dev->mode.imageWidth *
3742 This->e.dga.dev->mode.imageHeight *
3743 (This->e.dga.dev->mode.bitsPerPixel / 8))
3745 TRACE("viewport height: %d\n", This->e.dga.dev->mode.viewportHeight);
3746 /* Get the screen dimensions as seen by Wine.
3747 In that case, it may be better to ignore the -desktop mode and return the
3748 real screen size => print a warning */
3749 This->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
3750 This->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
3751 This->e.dga.fb_addr = This->e.dga.dev->data;
3752 This->e.dga.fb_memsize = (This->e.dga.dev->mode.imageWidth *
3753 This->e.dga.dev->mode.imageHeight *
3754 (This->e.dga.dev->mode.bitsPerPixel / 8));
3755 This->e.dga.vpmask = 0;
3757 /* Fill the screen pixelformat */
3758 pf->dwSize = sizeof(DDPIXELFORMAT);
3760 pf->u.dwRGBBitCount = This->e.dga.dev->mode.bitsPerPixel;
3761 if (This->e.dga.dev->mode.depth == 8) {
3762 pf->dwFlags = DDPF_PALETTEINDEXED8|DDPF_RGB;
3763 pf->u1.dwRBitMask = 0;
3764 pf->u2.dwGBitMask = 0;
3765 pf->u3.dwBBitMask = 0;
3767 pf->dwFlags = DDPF_RGB;
3768 pf->u1.dwRBitMask = This->e.dga.dev->mode.redMask;
3769 pf->u2.dwGBitMask = This->e.dga.dev->mode.greenMask;
3770 pf->u3.dwBBitMask = This->e.dga.dev->mode.blueMask;
3772 pf->u4.dwRGBAlphaBitMask= 0;
3774 This->d.screen_pixelformat = *pf;
3776 #endif /* defined(HAVE_LIBXXF86DGA2) */
3778 #ifdef HAVE_LIBXXF86DGA
3779 static HRESULT WINAPI DGA_IDirectDrawImpl_SetDisplayMode(
3780 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
3782 ICOM_THIS(IDirectDrawImpl,iface);
3785 TRACE("(%p)->(%ld,%ld,%ld)\n", This, width, height, depth);
3787 #ifdef HAVE_LIBXXF86DGA2
3788 if (This->e.dga.version == 2) {
3789 XDGAMode *modes = This->e.dga.modes;
3790 int mode_to_use = -1;
3792 /* Search in the list a display mode that corresponds to what is requested */
3793 for (i = 0; i < This->e.dga.num_modes; i++) {
3794 if ((height == modes[i].viewportHeight) &&
3795 (width == modes[i].viewportWidth) &&
3796 (depth == modes[i].depth)) {
3797 mode_to_use = modes[i].num;
3801 if (mode_to_use < 0) {
3802 ERR("Could not find matching mode !!!\n");
3803 return DDERR_UNSUPPORTEDMODE;
3805 TRACE("Using mode number %d\n", mode_to_use);
3807 TSXDGACloseFramebuffer(display, DefaultScreen(display));
3809 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
3810 ERR("Error opening the frame buffer !!!\n");
3812 return DDERR_GENERIC;
3815 /* Initialize the frame buffer */
3816 _DGA_Initialize_FrameBuffer(This, mode_to_use);
3818 /* Re-get (if necessary) the DGA events */
3819 TSXDGASelectInput(display, DefaultScreen(display),
3820 KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask );
3825 #endif /* defined(HAVE_LIBXXF86DGA2) */
3827 /* We hope getting the asked for depth */
3828 if (_common_depth_to_pixelformat(depth, &(This->d.directdraw_pixelformat), &(This->d.screen_pixelformat), NULL) != -1) {
3829 /* I.e. no visual found or emulated */
3830 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width,height,depth);
3831 return DDERR_UNSUPPORTEDMODE;
3834 if (This->d.width < width) {
3835 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width,height,depth,width,This->d.width);
3836 return DDERR_UNSUPPORTEDMODE;
3838 This->d.width = width;
3839 This->d.height = height;
3841 /* adjust fb_height, so we don't overlap */
3842 if (This->e.dga.fb_height < height)
3843 This->e.dga.fb_height = height;
3844 _common_IDirectDrawImpl_SetDisplayMode(This);
3846 #ifdef HAVE_LIBXXF86VM
3847 #ifdef HAVE_LIBXXF86DGA2
3848 if (This->e.dga.version == 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3849 #endif /* defined(HAVE_LIBXXF86DGA2) */
3851 XF86VidModeModeInfo **all_modes, *vidmode = NULL;
3852 XF86VidModeModeLine mod_tmp;
3853 /* int dotclock_tmp; */
3855 /* save original video mode and set fullscreen if available*/
3856 orig_mode = (XF86VidModeModeInfo *) malloc (sizeof(XF86VidModeModeInfo));
3857 TSXF86VidModeGetModeLine(display, DefaultScreen(display), &orig_mode->dotclock, &mod_tmp);
3858 orig_mode->hdisplay = mod_tmp.hdisplay;
3859 orig_mode->hsyncstart = mod_tmp.hsyncstart;
3860 orig_mode->hsyncend = mod_tmp.hsyncend;
3861 orig_mode->htotal = mod_tmp.htotal;
3862 orig_mode->vdisplay = mod_tmp.vdisplay;
3863 orig_mode->vsyncstart = mod_tmp.vsyncstart;
3864 orig_mode->vsyncend = mod_tmp.vsyncend;
3865 orig_mode->vtotal = mod_tmp.vtotal;
3866 orig_mode->flags = mod_tmp.flags;
3867 orig_mode->private = mod_tmp.private;
3869 TSXF86VidModeGetAllModeLines(display,DefaultScreen(display),&mode_count,&all_modes);
3870 for (i=0;i<mode_count;i++)
3872 if (all_modes[i]->hdisplay == width && all_modes[i]->vdisplay == height)
3874 vidmode = (XF86VidModeModeInfo *)malloc(sizeof(XF86VidModeModeInfo));
3875 *vidmode = *(all_modes[i]);
3878 TSXFree(all_modes[i]->private);
3880 for (i++;i<mode_count;i++) TSXFree(all_modes[i]->private);
3884 WARN("Fullscreen mode not available!\n");
3888 TRACE("SwitchToMode(%dx%d)\n",vidmode->hdisplay,vidmode->vdisplay);
3889 TSXF86VidModeSwitchToMode(display, DefaultScreen(display), vidmode);
3890 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3891 TSXF86VidModeSetViewPort(display, DefaultScreen(display), 0, 0);
3897 /* FIXME: this function OVERWRITES several signal handlers.
3898 * can we save them? and restore them later? In a way that
3899 * it works for the library too?
3901 TSXF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
3902 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
3904 #ifdef RESTORE_SIGNALS
3909 #endif /* defined(HAVE_LIBXXF86DGA) */
3911 /* *************************************
3912 16 / 15 bpp to palettized 8 bpp
3913 ************************************* */
3914 static void pixel_convert_16_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3915 unsigned char *c_src = (unsigned char *) src;
3916 unsigned short *c_dst = (unsigned short *) dst;
3919 if (palette != NULL) {
3920 const unsigned short * pal = (unsigned short *) palette->screen_palents;
3922 for (y = height; y--; ) {
3923 #if defined(__i386__) && defined(__GNUC__)
3924 /* gcc generates slightly inefficient code for the the copy / lookup,
3925 * it generates one excess memory access (to pal) per pixel. Since
3926 * we know that pal is not modified by the memory write we can
3927 * put it into a register and reduce the number of memory accesses
3928 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3929 * (This is not guaranteed to be the fastest method.)
3931 __asm__ __volatile__(
3935 " movw (%%edx,%%eax,2),%%ax\n"
3937 " xor %%eax,%%eax\n"
3939 : "=S" (c_src), "=D" (c_dst)
3940 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
3941 : "eax", "cc", "memory"
3943 c_src+=(pitch-width);
3945 unsigned char * srclineend = c_src+width;
3946 while (c_src < srclineend)
3947 *c_dst++ = pal[*c_src++];
3948 c_src+=(pitch-width);
3952 WARN("No palette set...\n");
3953 memset(dst, 0, width * height * 2);
3956 static void palette_convert_16_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3958 unsigned short *pal = (unsigned short *) screen_palette;
3960 for (i = 0; i < count; i++)
3961 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 8) |
3962 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3963 ((((unsigned short) palent[i].peGreen) & 0xFC) << 3));
3965 static void palette_convert_15_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
3967 unsigned short *pal = (unsigned short *) screen_palette;
3969 for (i = 0; i < count; i++)
3970 pal[start + i] = (((((unsigned short) palent[i].peRed) & 0xF8) << 7) |
3971 ((((unsigned short) palent[i].peBlue) & 0xF8) >> 3) |
3972 ((((unsigned short) palent[i].peGreen) & 0xF8) << 2));
3975 /* *************************************
3976 24 to palettized 8 bpp
3977 ************************************* */
3978 static void pixel_convert_24_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
3979 unsigned char *c_src = (unsigned char *) src;
3980 unsigned char *c_dst = (unsigned char *) dst;
3983 if (palette != NULL) {
3984 const unsigned int *pal = (unsigned int *) palette->screen_palents;
3986 for (y = height; y--; ) {
3987 unsigned char * srclineend = c_src+width;
3988 while (c_src < srclineend ) {
3989 register long pixel = pal[*c_src++];
3991 *c_dst++ = pixel>>8;
3992 *c_dst++ = pixel>>16;
3994 c_src+=(pitch-width);
3997 WARN("No palette set...\n");
3998 memset(dst, 0, width * height * 4);
4001 /* *************************************
4002 32 bpp to palettized 8 bpp
4003 ************************************* */
4004 static void pixel_convert_32_to_8(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4005 unsigned char *c_src = (unsigned char *) src;
4006 unsigned int *c_dst = (unsigned int *) dst;
4009 if (palette != NULL) {
4010 const unsigned int *pal = (unsigned int *) palette->screen_palents;
4012 for (y = height; y--; ) {
4013 #if defined(__i386__) && defined(__GNUC__)
4014 /* See comment in pixel_convert_16_to_8 */
4015 __asm__ __volatile__(
4019 " movl (%%edx,%%eax,4),%%eax\n"
4021 " xor %%eax,%%eax\n"
4023 : "=S" (c_src), "=D" (c_dst)
4024 : "S" (c_src), "D" (c_dst) , "c" (width), "d" (pal)
4025 : "eax", "cc", "memory"
4027 c_src+=(pitch-width);
4029 unsigned char * srclineend = c_src+width;
4030 while (c_src < srclineend )
4031 *c_dst++ = pal[*c_src++];
4032 c_src+=(pitch-width);
4036 WARN("No palette set...\n");
4037 memset(dst, 0, width * height * 4);
4041 static void palette_convert_24_to_8(LPPALETTEENTRY palent, void *screen_palette, DWORD start, DWORD count) {
4043 unsigned int *pal = (unsigned int *) screen_palette;
4045 for (i = 0; i < count; i++)
4046 pal[start + i] = ((((unsigned int) palent[i].peRed) << 16) |
4047 (((unsigned int) palent[i].peGreen) << 8) |
4048 ((unsigned int) palent[i].peBlue));
4051 /* *************************************
4053 ************************************* */
4054 static void pixel_convert_32_to_16(void *src, void *dst, DWORD width, DWORD height, LONG pitch, IDirectDrawPaletteImpl* palette) {
4055 unsigned short *c_src = (unsigned short *) src;
4056 unsigned int *c_dst = (unsigned int *) dst;
4059 for (y = height; y--; ) {
4060 unsigned short * srclineend = c_src+width;
4061 while (c_src < srclineend ) {
4062 *c_dst++ = (((*c_src & 0xF800) << 8) |
4063 ((*c_src & 0x07E0) << 5) |
4064 ((*c_src & 0x001F) << 3));
4067 c_src+=((pitch/2)-width);
4072 static HRESULT WINAPI Xlib_IDirectDrawImpl_SetDisplayMode(
4073 LPDIRECTDRAW iface,DWORD width,DWORD height,DWORD depth
4075 ICOM_THIS(IDirectDrawImpl,iface);
4080 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4081 This, width, height, depth);
4083 switch ((c = _common_depth_to_pixelformat(depth,
4084 &(This->d.directdraw_pixelformat),
4085 &(This->d.screen_pixelformat),
4086 &(This->d.pixmap_depth)))) {
4088 sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
4089 MessageBoxA(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
4090 return DDERR_UNSUPPORTEDMODE;
4094 This->d.pixel_convert = NULL;
4095 This->d.palette_convert = NULL;
4099 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth);
4101 /* Set the depth convertion routines */
4102 This->d.pixel_convert = ModeEmulations[c].funcs.pixel_convert;
4103 This->d.palette_convert = ModeEmulations[c].funcs.palette_convert;
4106 This->d.width = width;
4107 This->d.height = height;
4109 _common_IDirectDrawImpl_SetDisplayMode(This);
4111 tmpWnd = WIN_FindWndPtr(This->d.window);
4112 This->d.paintable = 1;
4113 This->d.drawable = ((X11DRV_WND_DATA *) tmpWnd->pDriverData)->window;
4114 WIN_ReleaseWndPtr(tmpWnd);
4116 /* We don't have a context for this window. Host off the desktop */
4117 if( !This->d.drawable )
4119 This->d.drawable = ((X11DRV_WND_DATA *) WIN_GetDesktop()->pDriverData)->window;
4120 WIN_ReleaseDesktop();
4122 TRACE("Setting drawable to %ld\n", This->d.drawable);
4124 if (get_option( "DXGrab", 0 )) {
4125 /* Confine cursor movement (risky, but the user asked for it) */
4126 TSXGrabPointer(display, This->d.drawable, True, 0, GrabModeAsync, GrabModeAsync, This->d.drawable, None, CurrentTime);
4132 #ifdef HAVE_LIBXXF86DGA
4133 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetCaps(
4134 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4136 ICOM_THIS(IDirectDraw2Impl,iface);
4137 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4138 if (!caps1 && !caps2)
4139 return DDERR_INVALIDPARAMS;
4141 caps1->dwVidMemTotal = This->e.dga.fb_memsize;
4142 caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4143 caps1->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4146 caps2->dwVidMemTotal = This->e.dga.fb_memsize;
4147 caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED); /* we can do anything */
4148 caps2->ddsCaps.dwCaps = 0xffffffff; /* we can do anything */
4152 #endif /* defined(HAVE_LIBXXF86DGA) */
4154 static void fill_caps(LPDDCAPS caps) {
4155 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4156 Need to be fixed, though.. */
4160 caps->dwSize = sizeof(*caps);
4161 caps->dwCaps = DDCAPS_ALPHA | DDCAPS_BLT | DDCAPS_BLTSTRETCH | DDCAPS_BLTCOLORFILL | DDCAPS_BLTDEPTHFILL | DDCAPS_CANBLTSYSMEM | DDCAPS_COLORKEY | DDCAPS_PALETTE | DDCAPS_NOHARDWARE;
4162 caps->dwCaps2 = DDCAPS2_CERTIFIED | DDCAPS2_NOPAGELOCKREQUIRED | DDCAPS2_WIDESURFACES;
4163 caps->dwCKeyCaps = 0xFFFFFFFF; /* Should put real caps here one day... */
4165 caps->dwFXAlphaCaps = 0;
4166 caps->dwPalCaps = DDPCAPS_8BIT | DDPCAPS_ALLOW256;
4168 caps->dwZBufferBitDepths = DDBD_16;
4169 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4170 to put textures in video memory.
4171 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4173 caps->dwVidMemTotal = 8192 * 1024;
4174 caps->dwVidMemFree = 8192 * 1024;
4175 /* These are all the supported capabilities of the surfaces */
4176 caps->ddsCaps.dwCaps = DDSCAPS_ALPHA | DDSCAPS_BACKBUFFER | DDSCAPS_COMPLEX | DDSCAPS_FLIP |
4177 DDSCAPS_FRONTBUFFER | DDSCAPS_LOCALVIDMEM | DDSCAPS_NONLOCALVIDMEM | DDSCAPS_OFFSCREENPLAIN |
4178 DDSCAPS_OVERLAY | DDSCAPS_PALETTE | DDSCAPS_PRIMARYSURFACE | DDSCAPS_SYSTEMMEMORY |
4179 DDSCAPS_VIDEOMEMORY | DDSCAPS_VISIBLE;
4181 caps->dwCaps |= DDCAPS_3D | DDCAPS_ZBLTS;
4182 caps->dwCaps2 |= DDCAPS2_NO2DDURING3DSCENE;
4183 caps->ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_TEXTURE | DDSCAPS_ZBUFFER;
4187 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetCaps(
4188 LPDIRECTDRAW2 iface,LPDDCAPS caps1,LPDDCAPS caps2
4190 ICOM_THIS(IDirectDraw2Impl,iface);
4191 TRACE("(%p)->GetCaps(%p,%p)\n",This,caps1,caps2);
4193 /* Put the same caps for the two capabilities */
4200 static HRESULT WINAPI IDirectDraw2Impl_CreateClipper(
4201 LPDIRECTDRAW2 iface,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
4203 ICOM_THIS(IDirectDraw2Impl,iface);
4204 IDirectDrawClipperImpl** ilpddclip=(IDirectDrawClipperImpl**)lpddclip;
4205 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4206 This,x,ilpddclip,lpunk
4208 *ilpddclip = (IDirectDrawClipperImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawClipperImpl));
4209 (*ilpddclip)->ref = 1;
4210 ICOM_VTBL(*ilpddclip) = &ddclipvt;
4214 static HRESULT WINAPI common_IDirectDraw2Impl_CreatePalette(
4215 IDirectDraw2Impl* This,DWORD dwFlags,LPPALETTEENTRY palent,IDirectDrawPaletteImpl **lpddpal,LPUNKNOWN lpunk,int *psize
4219 if (TRACE_ON(ddraw))
4220 _dump_paletteformat(dwFlags);
4222 *lpddpal = (IDirectDrawPaletteImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPaletteImpl));
4223 if (*lpddpal == NULL) return E_OUTOFMEMORY;
4224 (*lpddpal)->ref = 1;
4225 (*lpddpal)->ddraw = (IDirectDrawImpl*)This;
4226 (*lpddpal)->installed = 0;
4228 if (dwFlags & DDPCAPS_1BIT)
4230 else if (dwFlags & DDPCAPS_2BIT)
4232 else if (dwFlags & DDPCAPS_4BIT)
4234 else if (dwFlags & DDPCAPS_8BIT)
4237 ERR("unhandled palette format\n");
4242 /* Now, if we are in 'depth conversion mode', create the screen palette */
4243 if (This->d.palette_convert != NULL)
4244 This->d.palette_convert(palent, (*lpddpal)->screen_palents, 0, size);
4246 memcpy((*lpddpal)->palents, palent, size * sizeof(PALETTEENTRY));
4247 } else if (This->d.palette_convert != NULL) {
4248 /* In that case, put all 0xFF */
4249 memset((*lpddpal)->screen_palents, 0xFF, 256 * sizeof(int));
4255 #ifdef HAVE_LIBXXF86DGA
4256 static HRESULT WINAPI DGA_IDirectDraw2Impl_CreatePalette(
4257 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4259 ICOM_THIS(IDirectDraw2Impl,iface);
4260 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4264 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4265 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4266 if (res != 0) return res;
4267 ICOM_VTBL(*ilpddpal) = &dga_ddpalvt;
4268 if (This->d.directdraw_pixelformat.u.dwRGBBitCount<=8) {
4269 (*ilpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),X11DRV_GetVisual(),AllocAll);
4271 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4272 (*ilpddpal)->cm = 0;
4274 if (((*ilpddpal)->cm)&&xsize) {
4275 for (i=0;i<xsize;i++) {
4278 xc.red = (*ilpddpal)->palents[i].peRed<<8;
4279 xc.blue = (*ilpddpal)->palents[i].peBlue<<8;
4280 xc.green = (*ilpddpal)->palents[i].peGreen<<8;
4281 xc.flags = DoRed|DoBlue|DoGreen;
4283 TSXStoreColor(display,(*ilpddpal)->cm,&xc);
4288 #endif /* defined(HAVE_LIBXXF86DGA) */
4290 static HRESULT WINAPI Xlib_IDirectDraw2Impl_CreatePalette(
4291 LPDIRECTDRAW2 iface,DWORD dwFlags,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
4293 ICOM_THIS(IDirectDraw2Impl,iface);
4294 IDirectDrawPaletteImpl** ilpddpal=(IDirectDrawPaletteImpl**)lpddpal;
4298 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This,dwFlags,palent,ilpddpal,lpunk);
4299 res = common_IDirectDraw2Impl_CreatePalette(This,dwFlags,palent,ilpddpal,lpunk,&xsize);
4300 if (res != 0) return res;
4301 ICOM_VTBL(*ilpddpal) = &xlib_ddpalvt;
4305 #ifdef HAVE_LIBXXF86DGA
4306 static HRESULT WINAPI DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4307 ICOM_THIS(IDirectDraw2Impl,iface);
4308 TRACE("(%p)->()\n",This);
4310 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4311 #ifdef RESTORE_SIGNALS
4316 #endif /* defined(HAVE_LIBXXF86DGA) */
4318 static HRESULT WINAPI Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface) {
4319 ICOM_THIS(IDirectDraw2Impl,iface);
4320 TRACE("(%p)->RestoreDisplayMode()\n", This);
4325 static HRESULT WINAPI IDirectDraw2Impl_WaitForVerticalBlank(
4326 LPDIRECTDRAW2 iface,DWORD x,HANDLE h
4328 ICOM_THIS(IDirectDraw2Impl,iface);
4329 TRACE("(%p)->(0x%08lx,0x%08x)\n",This,x,h);
4333 static ULONG WINAPI IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface) {
4334 ICOM_THIS(IDirectDraw2Impl,iface);
4335 TRACE("(%p)->() incrementing from %lu.\n", This, This->ref );
4337 return ++(This->ref);
4340 #ifdef HAVE_LIBXXF86DGA
4341 static ULONG WINAPI DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4342 ICOM_THIS(IDirectDraw2Impl,iface);
4343 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4345 if (!--(This->ref)) {
4346 #ifdef HAVE_LIBXXF86DGA2
4347 if (This->e.dga.version == 2) {
4348 TRACE("Closing access to the FrameBuffer\n");
4349 TSXDGACloseFramebuffer(display, DefaultScreen(display));
4350 TRACE("Going back to normal X mode of operation\n");
4351 TSXDGASetMode(display, DefaultScreen(display), 0);
4353 /* Set the input handling back to absolute */
4354 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE);
4356 /* Remove the handling of DGA2 events */
4357 X11DRV_EVENT_SetDGAStatus(0, -1);
4359 /* Free the modes list */
4360 TSXFree(This->e.dga.modes);
4362 #endif /* defined(HAVE_LIBXXF86DGA2) */
4363 TSXF86DGADirectVideo(display,DefaultScreen(display),0);
4364 if (This->d.window && GetPropA(This->d.window,ddProp))
4365 DestroyWindow(This->d.window);
4366 #ifdef HAVE_LIBXXF86VM
4368 TSXF86VidModeSwitchToMode(
4370 DefaultScreen(display),
4372 if (orig_mode->privsize)
4373 TSXFree(orig_mode->private);
4379 #ifdef RESTORE_SIGNALS
4382 HeapFree(GetProcessHeap(),0,This);
4387 #endif /* defined(HAVE_LIBXXF86DGA) */
4389 static ULONG WINAPI Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface) {
4390 ICOM_THIS(IDirectDraw2Impl,iface);
4391 TRACE("(%p)->() decrementing from %lu.\n", This, This->ref );
4393 if (!--(This->ref)) {
4394 if (This->d.window && GetPropA(This->d.window,ddProp))
4395 DestroyWindow(This->d.window);
4396 HeapFree(GetProcessHeap(),0,This);
4399 /* FIXME: destroy window ... */
4403 #ifdef HAVE_LIBXXF86DGA
4404 static HRESULT WINAPI DGA_IDirectDraw2Impl_QueryInterface(
4405 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4407 ICOM_THIS(IDirectDraw2Impl,iface);
4409 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4410 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4412 IDirectDraw2_AddRef(iface);
4414 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4418 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4419 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_ddvt;
4420 IDirectDraw2_AddRef(iface);
4423 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4427 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4428 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd2vt;
4429 IDirectDraw2_AddRef(iface);
4432 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4436 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4437 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&dga_dd4vt;
4438 IDirectDraw2_AddRef(iface);
4441 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4445 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4448 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4450 d3d->ddraw = (IDirectDrawImpl*)This;
4451 IDirectDraw2_AddRef(iface);
4452 ICOM_VTBL(d3d) = &d3dvt;
4455 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4459 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4460 IDirect3D2Impl* d3d;
4462 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4464 d3d->ddraw = (IDirectDrawImpl*)This;
4465 IDirectDraw2_AddRef(iface);
4466 ICOM_VTBL(d3d) = &d3d2vt;
4469 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4473 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4474 return OLE_E_ENUM_NOMORE;
4476 #endif /* defined(HAVE_LIBXXF86DGA) */
4478 static HRESULT WINAPI Xlib_IDirectDraw2Impl_QueryInterface(
4479 LPDIRECTDRAW2 iface,REFIID refiid,LPVOID *obj
4481 ICOM_THIS(IDirectDraw2Impl,iface);
4483 TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(refiid),obj);
4484 if ( IsEqualGUID( &IID_IUnknown, refiid ) ) {
4486 IDirectDraw2_AddRef(iface);
4488 TRACE(" Creating IUnknown interface (%p)\n", *obj);
4492 if ( IsEqualGUID( &IID_IDirectDraw, refiid ) ) {
4493 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_ddvt;
4494 IDirectDraw2_AddRef(iface);
4497 TRACE(" Creating IDirectDraw interface (%p)\n", *obj);
4501 if ( IsEqualGUID( &IID_IDirectDraw2, refiid ) ) {
4502 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd2vt;
4503 IDirectDraw2_AddRef(iface);
4506 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj);
4510 if ( IsEqualGUID( &IID_IDirectDraw4, refiid ) ) {
4511 ICOM_VTBL(This) = (ICOM_VTABLE(IDirectDraw2)*)&xlib_dd4vt;
4512 IDirectDraw2_AddRef(iface);
4515 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj);
4519 if ( IsEqualGUID( &IID_IDirect3D, refiid ) ) {
4522 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4524 d3d->ddraw = (IDirectDrawImpl*)This;
4525 IDirectDraw2_AddRef(iface);
4526 ICOM_VTBL(d3d) = &d3dvt;
4529 TRACE(" Creating IDirect3D interface (%p)\n", *obj);
4533 if ( IsEqualGUID( &IID_IDirect3D2, refiid ) ) {
4534 IDirect3D2Impl* d3d;
4536 d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
4538 d3d->ddraw = (IDirectDrawImpl*)This;
4539 IDirectDraw2_AddRef(iface);
4540 ICOM_VTBL(d3d) = &d3d2vt;
4543 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj);
4547 WARN("(%p):interface for IID %s _NOT_ found!\n",This,debugstr_guid(refiid));
4548 return OLE_E_ENUM_NOMORE;
4551 static HRESULT WINAPI IDirectDraw2Impl_GetVerticalBlankStatus(
4552 LPDIRECTDRAW2 iface,BOOL *status
4554 ICOM_THIS(IDirectDraw2Impl,iface);
4555 TRACE("(%p)->(%p)\n",This,status);
4560 #ifdef HAVE_LIBXXF86DGA
4561 static HRESULT WINAPI DGA_IDirectDraw2Impl_EnumDisplayModes(
4562 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4564 ICOM_THIS(IDirectDraw2Impl,iface);
4565 DDSURFACEDESC ddsfd;
4568 } modes[5] = { /* some of the usual modes */
4575 static int depths[4] = {8,16,24,32};
4578 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4579 ddsfd.dwSize = sizeof(ddsfd);
4580 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4581 if (dwFlags & DDEDM_REFRESHRATES) {
4582 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4583 ddsfd.u.dwRefreshRate = 60;
4585 ddsfd.ddsCaps.dwCaps = 0;
4586 ddsfd.dwBackBufferCount = 1;
4588 #ifdef HAVE_LIBXXF86DGA2
4589 if (This->e.dga.version == 2) {
4590 XDGAMode *modes = This->e.dga.modes;
4592 ddsfd.dwFlags |= DDSD_PITCH;
4593 for (i = 0; i < This->e.dga.num_modes; i++) {
4594 if (TRACE_ON(ddraw)) {
4595 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4597 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
4598 modes[i].viewportWidth, modes[i].viewportHeight,
4600 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
4601 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
4602 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
4603 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
4604 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
4607 /* Fill the pixel format */
4608 ddsfd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
4609 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4610 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4611 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = modes[i].bitsPerPixel;
4612 if (modes[i].depth == 8) {
4613 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4614 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4615 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4616 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4617 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4619 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4620 ddsfd.ddpfPixelFormat.u1.dwRBitMask = modes[i].redMask;
4621 ddsfd.ddpfPixelFormat.u2.dwGBitMask = modes[i].greenMask;
4622 ddsfd.ddpfPixelFormat.u3.dwBBitMask = modes[i].blueMask;
4625 ddsfd.dwWidth = modes[i].viewportWidth;
4626 ddsfd.dwHeight = modes[i].viewportHeight;
4627 ddsfd.lPitch = modes[i].imageWidth;
4629 /* Send mode to the application */
4630 if (!modescb(&ddsfd,context)) return DD_OK;
4634 for (i=0;i<sizeof(depths)/sizeof(depths[0]);i++) {
4635 ddsfd.dwBackBufferCount = 1;
4636 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4637 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4638 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = depths[i];
4639 /* FIXME: those masks would have to be set in depth > 8 */
4641 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4642 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4643 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4644 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4645 ddsfd.ddsCaps.dwCaps=DDSCAPS_PALETTE;
4646 ddsfd.ddpfPixelFormat.dwFlags|=DDPF_PALETTEINDEXED8;
4648 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4650 /* FIXME: We should query those from X itself */
4651 switch (depths[i]) {
4653 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0xF800;
4654 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x07E0;
4655 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x001F;
4658 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4659 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4660 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4663 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0x00FF0000;
4664 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0x0000FF00;
4665 ddsfd.ddpfPixelFormat.u3.dwBBitMask= 0x000000FF;
4670 ddsfd.dwWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4671 ddsfd.dwHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4672 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4673 if (!modescb(&ddsfd,context)) return DD_OK;
4675 for (j=0;j<sizeof(modes)/sizeof(modes[0]);j++) {
4676 ddsfd.dwWidth = modes[j].w;
4677 ddsfd.dwHeight = modes[j].h;
4678 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd.dwWidth,ddsfd.dwHeight,depths[i]);
4679 if (!modescb(&ddsfd,context)) return DD_OK;
4682 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4683 /* modeX is not standard VGA */
4685 ddsfd.dwHeight = 200;
4686 ddsfd.dwWidth = 320;
4687 TRACE(" enumerating (320x200x%d)\n",depths[i]);
4688 if (!modescb(&ddsfd,context)) return DD_OK;
4691 #ifdef HAVE_LIBXXF86DGA2
4696 #endif /* defined(HAVE_LIBXXF86DGA) */
4698 static HRESULT WINAPI Xlib_IDirectDraw2Impl_EnumDisplayModes(
4699 LPDIRECTDRAW2 iface,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
4701 ICOM_THIS(IDirectDraw2Impl,iface);
4703 XPixmapFormatValues *pf;
4705 int xbpp = 1, nvisuals, npixmap, i, emu;
4706 int has_mode[] = { 0, 0, 0, 0 };
4707 int has_depth[] = { 8, 15, 16, 24 };
4708 DDSURFACEDESC ddsfd;
4711 } modes[] = { /* some of the usual modes */
4719 DWORD maxWidth, maxHeight;
4721 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This,dwFlags,lpddsfd,context,modescb);
4722 ddsfd.dwSize = sizeof(ddsfd);
4723 ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_PITCH;
4724 if (dwFlags & DDEDM_REFRESHRATES) {
4725 ddsfd.dwFlags |= DDSD_REFRESHRATE;
4726 ddsfd.u.dwRefreshRate = 60;
4728 maxWidth = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
4729 maxHeight = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
4731 vi = TSXGetVisualInfo(display, VisualNoMask, &vt, &nvisuals);
4732 pf = XListPixmapFormats(display, &npixmap);
4736 while ((i < npixmap) || (emu != 4)) {
4742 for (j = 0; j < 4; j++) {
4743 if (has_depth[j] == pf[i].depth) {
4754 if (has_mode[mode_index] == 0) {
4755 if (mode_index == 0) {
4758 ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
4759 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4760 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4761 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4762 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4763 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4764 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4765 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4766 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4770 has_mode[mode_index] = 1;
4772 /* All the 'true color' depths (15, 16 and 24)
4773 First, find the corresponding visual to extract the bit masks */
4774 for (j = 0; j < nvisuals; j++) {
4775 if (vi[j].depth == pf[i].depth) {
4776 ddsfd.ddsCaps.dwCaps = 0;
4777 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4778 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4779 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4780 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = pf[i].bits_per_pixel;
4781 ddsfd.ddpfPixelFormat.u1.dwRBitMask = vi[j].red_mask;
4782 ddsfd.ddpfPixelFormat.u2.dwGBitMask = vi[j].green_mask;
4783 ddsfd.ddpfPixelFormat.u3.dwBBitMask = vi[j].blue_mask;
4784 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4786 xbpp = pf[i].bits_per_pixel/8;
4789 has_mode[mode_index] = 1;
4794 ERR("Did not find visual corresponding the the pixmap format !\n");
4799 /* Now to emulated modes */
4800 if (has_mode[emu] == 0) {
4803 int depth = has_depth[emu];
4805 for (c = 0; (c < sizeof(ModeEmulations) / sizeof(Convert)) && (send_mode == 0); c++) {
4806 if (ModeEmulations[c].dest.depth == depth) {
4807 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4808 for (l = 0; (l < npixmap) && (send_mode == 0); l++) {
4809 if ((pf[l].depth == ModeEmulations[c].screen.depth) &&
4810 (pf[l].bits_per_pixel == ModeEmulations[c].screen.bpp)) {
4812 for (j = 0; (j < nvisuals) && (send_mode == 0); j++) {
4813 if ((vi[j].depth == pf[l].depth) &&
4814 (vi[j].red_mask == ModeEmulations[c].screen.rmask) &&
4815 (vi[j].green_mask == ModeEmulations[c].screen.gmask) &&
4816 (vi[j].blue_mask == ModeEmulations[c].screen.bmask)) {
4817 ddsfd.ddpfPixelFormat.dwSize = sizeof(ddsfd.ddpfPixelFormat);
4818 ddsfd.ddpfPixelFormat.dwFourCC = 0;
4820 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB|DDPF_PALETTEINDEXED8;
4821 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = 8;
4822 ddsfd.ddpfPixelFormat.u1.dwRBitMask = 0;
4823 ddsfd.ddpfPixelFormat.u2.dwGBitMask = 0;
4824 ddsfd.ddpfPixelFormat.u3.dwBBitMask = 0;
4826 ddsfd.ddpfPixelFormat.dwFlags = DDPF_RGB;
4827 ddsfd.ddpfPixelFormat.u.dwRGBBitCount = ModeEmulations[c].dest.bpp;
4828 ddsfd.ddpfPixelFormat.u1.dwRBitMask = ModeEmulations[c].dest.rmask;
4829 ddsfd.ddpfPixelFormat.u2.dwGBitMask = ModeEmulations[c].dest.gmask;
4830 ddsfd.ddpfPixelFormat.u3.dwBBitMask = ModeEmulations[c].dest.bmask;
4832 ddsfd.ddpfPixelFormat.u4.dwRGBAlphaBitMask= 0;
4837 ERR("No visual corresponding to pixmap format !\n");
4851 if (TRACE_ON(ddraw)) {
4852 TRACE("Enumerating with pixel format : \n");
4853 _dump_pixelformat(&(ddsfd.ddpfPixelFormat));
4857 for (mode = 0; mode < sizeof(modes)/sizeof(modes[0]); mode++) {
4858 /* Do not enumerate modes we cannot handle anyway */
4859 if ((modes[mode].w > maxWidth) || (modes[mode].h > maxHeight))
4862 ddsfd.dwWidth = modes[mode].w;
4863 ddsfd.dwHeight= modes[mode].h;
4864 ddsfd.lPitch = ddsfd.dwWidth * xbpp;
4866 /* Now, send the mode description to the application */
4867 TRACE(" - mode %4ld - %4ld\n", ddsfd.dwWidth, ddsfd.dwHeight);
4868 if (!modescb(&ddsfd, context))
4872 if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
4873 /* modeX is not standard VGA */
4874 ddsfd.dwWidth = 320;
4875 ddsfd.dwHeight = 200;
4876 ddsfd.lPitch = 320 * xbpp;
4877 if (!modescb(&ddsfd, context))
4889 #ifdef HAVE_LIBXXF86DGA
4890 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetDisplayMode(
4891 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4893 ICOM_THIS(IDirectDraw2Impl,iface);
4894 TRACE("(%p)->(%p)\n",This,lpddsfd);
4895 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4896 lpddsfd->dwHeight = This->d.height;
4897 lpddsfd->dwWidth = This->d.width;
4898 lpddsfd->lPitch = This->e.dga.fb_width*PFGET_BPP(This->d.directdraw_pixelformat);
4899 lpddsfd->dwBackBufferCount = 2;
4900 lpddsfd->u.dwRefreshRate = 60;
4901 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4902 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4903 if (TRACE_ON(ddraw)) {
4904 _dump_surface_desc(lpddsfd);
4908 #endif /* defined(HAVE_LIBXXF86DGA) */
4910 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetDisplayMode(
4911 LPDIRECTDRAW2 iface,LPDDSURFACEDESC lpddsfd
4913 ICOM_THIS(IDirectDraw2Impl,iface);
4914 TRACE("(%p)->GetDisplayMode(%p)\n",This,lpddsfd);
4915 lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
4916 lpddsfd->dwHeight = This->d.height;
4917 lpddsfd->dwWidth = This->d.width;
4918 lpddsfd->lPitch = lpddsfd->dwWidth * PFGET_BPP(This->d.directdraw_pixelformat);
4919 lpddsfd->dwBackBufferCount = 2;
4920 lpddsfd->u.dwRefreshRate = 60;
4921 lpddsfd->ddsCaps.dwCaps = DDSCAPS_PALETTE;
4922 lpddsfd->ddpfPixelFormat = This->d.directdraw_pixelformat;
4923 if (TRACE_ON(ddraw)) {
4924 _dump_surface_desc(lpddsfd);
4929 static HRESULT WINAPI IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface) {
4930 ICOM_THIS(IDirectDraw2Impl,iface);
4931 TRACE("(%p)->()\n",This);
4935 static HRESULT WINAPI IDirectDraw2Impl_GetMonitorFrequency(
4936 LPDIRECTDRAW2 iface,LPDWORD freq
4938 ICOM_THIS(IDirectDraw2Impl,iface);
4939 FIXME("(%p)->(%p) returns 60 Hz always\n",This,freq);
4940 *freq = 60*100; /* 60 Hz */
4944 /* what can we directly decompress? */
4945 static HRESULT WINAPI IDirectDraw2Impl_GetFourCCCodes(
4946 LPDIRECTDRAW2 iface,LPDWORD x,LPDWORD y
4948 ICOM_THIS(IDirectDraw2Impl,iface);
4949 FIXME("(%p,%p,%p), stub\n",This,x,y);
4953 static HRESULT WINAPI IDirectDraw2Impl_EnumSurfaces(
4954 LPDIRECTDRAW2 iface,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
4956 ICOM_THIS(IDirectDraw2Impl,iface);
4957 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This,x,ddsfd,context,ddsfcb);
4961 static HRESULT WINAPI IDirectDraw2Impl_Compact(
4962 LPDIRECTDRAW2 iface )
4964 ICOM_THIS(IDirectDraw2Impl,iface);
4965 FIXME("(%p)->()\n", This );
4970 static HRESULT WINAPI IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface,
4971 LPDIRECTDRAWSURFACE *lplpGDIDDSSurface) {
4972 ICOM_THIS(IDirectDraw2Impl,iface);
4973 FIXME("(%p)->(%p)\n", This, lplpGDIDDSSurface);
4978 static HRESULT WINAPI IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface,
4979 LPDWORD lpdwScanLine) {
4980 ICOM_THIS(IDirectDraw2Impl,iface);
4981 FIXME("(%p)->(%p)\n", This, lpdwScanLine);
4988 static HRESULT WINAPI IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface,
4990 ICOM_THIS(IDirectDraw2Impl,iface);
4991 FIXME("(%p)->(%p)\n", This, lpGUID);
4996 #ifdef HAVE_LIBXXF86DGA
4998 /* Note: Hack so we can reuse the old functions without compiler warnings */
4999 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5000 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
5002 # define XCAST(fun) (void *)
5005 static ICOM_VTABLE(IDirectDraw) dga_ddvt =
5007 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5008 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5009 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5010 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5011 XCAST(Compact)IDirectDraw2Impl_Compact,
5012 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5013 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5014 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5015 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5016 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5017 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5018 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5019 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5020 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5021 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5022 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5023 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5024 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5025 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5026 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5027 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5028 #ifdef HAVE_LIBXXF86DGA2
5029 XCAST(SetCooperativeLevel)DGA_IDirectDraw2Impl_SetCooperativeLevel,
5031 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5033 DGA_IDirectDrawImpl_SetDisplayMode,
5034 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5039 #endif /* defined(HAVE_LIBXXF86DGA) */
5041 /* Note: Hack so we can reuse the old functions without compiler warnings */
5042 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5043 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5045 # define XCAST(fun) (void *)
5048 static ICOM_VTABLE(IDirectDraw) xlib_ddvt =
5050 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5051 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5052 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5053 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5054 XCAST(Compact)IDirectDraw2Impl_Compact,
5055 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5056 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5057 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5058 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5059 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5060 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5061 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5062 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5063 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5064 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5065 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5066 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5067 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5068 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5069 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5070 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5071 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5072 Xlib_IDirectDrawImpl_SetDisplayMode,
5073 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5078 /*****************************************************************************
5083 #ifdef HAVE_LIBXXF86DGA
5084 static HRESULT WINAPI DGA_IDirectDraw2Impl_SetDisplayMode(
5085 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate, DWORD dwFlags
5087 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5088 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5090 #endif /* defined(HAVE_LIBXXF86DGA) */
5092 static HRESULT WINAPI Xlib_IDirectDraw2Impl_SetDisplayMode(
5093 LPDIRECTDRAW2 iface,DWORD width,DWORD height,DWORD depth,DWORD dwRefreshRate,DWORD dwFlags
5095 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate, dwFlags );
5096 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW)iface,width,height,depth);
5099 #ifdef HAVE_LIBXXF86DGA
5100 static HRESULT WINAPI DGA_IDirectDraw2Impl_GetAvailableVidMem(
5101 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5103 ICOM_THIS(IDirectDraw2Impl,iface);
5104 TRACE("(%p)->(%p,%p,%p)\n",
5105 This,ddscaps,total,free
5107 if (total) *total = This->e.dga.fb_memsize * 1024;
5108 if (free) *free = This->e.dga.fb_memsize * 1024;
5111 #endif /* defined(HAVE_LIBXXF86DGA) */
5113 static HRESULT WINAPI Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5114 LPDIRECTDRAW2 iface,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
5116 ICOM_THIS(IDirectDraw2Impl,iface);
5117 TRACE("(%p)->(%p,%p,%p)\n",
5118 This,ddscaps,total,free
5120 if (total) *total = 2048 * 1024;
5121 if (free) *free = 2048 * 1024;
5125 #ifdef HAVE_LIBXXF86DGA
5126 static ICOM_VTABLE(IDirectDraw2) dga_dd2vt =
5128 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5129 DGA_IDirectDraw2Impl_QueryInterface,
5130 IDirectDraw2Impl_AddRef,
5131 DGA_IDirectDraw2Impl_Release,
5132 IDirectDraw2Impl_Compact,
5133 IDirectDraw2Impl_CreateClipper,
5134 DGA_IDirectDraw2Impl_CreatePalette,
5135 DGA_IDirectDraw2Impl_CreateSurface,
5136 IDirectDraw2Impl_DuplicateSurface,
5137 DGA_IDirectDraw2Impl_EnumDisplayModes,
5138 IDirectDraw2Impl_EnumSurfaces,
5139 IDirectDraw2Impl_FlipToGDISurface,
5140 DGA_IDirectDraw2Impl_GetCaps,
5141 DGA_IDirectDraw2Impl_GetDisplayMode,
5142 IDirectDraw2Impl_GetFourCCCodes,
5143 IDirectDraw2Impl_GetGDISurface,
5144 IDirectDraw2Impl_GetMonitorFrequency,
5145 IDirectDraw2Impl_GetScanLine,
5146 IDirectDraw2Impl_GetVerticalBlankStatus,
5147 IDirectDraw2Impl_Initialize,
5148 DGA_IDirectDraw2Impl_RestoreDisplayMode,
5149 IDirectDraw2Impl_SetCooperativeLevel,
5150 DGA_IDirectDraw2Impl_SetDisplayMode,
5151 IDirectDraw2Impl_WaitForVerticalBlank,
5152 DGA_IDirectDraw2Impl_GetAvailableVidMem
5154 #endif /* defined(HAVE_LIBXXF86DGA) */
5156 static ICOM_VTABLE(IDirectDraw2) xlib_dd2vt =
5158 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5159 Xlib_IDirectDraw2Impl_QueryInterface,
5160 IDirectDraw2Impl_AddRef,
5161 Xlib_IDirectDraw2Impl_Release,
5162 IDirectDraw2Impl_Compact,
5163 IDirectDraw2Impl_CreateClipper,
5164 Xlib_IDirectDraw2Impl_CreatePalette,
5165 Xlib_IDirectDraw2Impl_CreateSurface,
5166 IDirectDraw2Impl_DuplicateSurface,
5167 Xlib_IDirectDraw2Impl_EnumDisplayModes,
5168 IDirectDraw2Impl_EnumSurfaces,
5169 IDirectDraw2Impl_FlipToGDISurface,
5170 Xlib_IDirectDraw2Impl_GetCaps,
5171 Xlib_IDirectDraw2Impl_GetDisplayMode,
5172 IDirectDraw2Impl_GetFourCCCodes,
5173 IDirectDraw2Impl_GetGDISurface,
5174 IDirectDraw2Impl_GetMonitorFrequency,
5175 IDirectDraw2Impl_GetScanLine,
5176 IDirectDraw2Impl_GetVerticalBlankStatus,
5177 IDirectDraw2Impl_Initialize,
5178 Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5179 IDirectDraw2Impl_SetCooperativeLevel,
5180 Xlib_IDirectDraw2Impl_SetDisplayMode,
5181 IDirectDraw2Impl_WaitForVerticalBlank,
5182 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5185 /*****************************************************************************
5190 static HRESULT WINAPI IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface,
5192 LPDIRECTDRAWSURFACE *lpDDS) {
5193 ICOM_THIS(IDirectDraw4Impl,iface);
5194 FIXME("(%p)->(%08ld,%p)\n", This, (DWORD) hdc, lpDDS);
5199 static HRESULT WINAPI IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface) {
5200 ICOM_THIS(IDirectDraw4Impl,iface);
5201 FIXME("(%p)->()\n", This);
5206 static HRESULT WINAPI IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface) {
5207 ICOM_THIS(IDirectDraw4Impl,iface);
5208 FIXME("(%p)->()\n", This);
5213 static HRESULT WINAPI IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface,
5214 LPDDDEVICEIDENTIFIER lpdddi,
5216 ICOM_THIS(IDirectDraw4Impl,iface);
5217 FIXME("(%p)->(%p,%08lx)\n", This, lpdddi, dwFlags);
5222 #ifdef HAVE_LIBXXF86DGA
5224 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5225 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5227 # define XCAST(fun) (void*)
5230 static ICOM_VTABLE(IDirectDraw4) dga_dd4vt =
5232 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5233 XCAST(QueryInterface)DGA_IDirectDraw2Impl_QueryInterface,
5234 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5235 XCAST(Release)DGA_IDirectDraw2Impl_Release,
5236 XCAST(Compact)IDirectDraw2Impl_Compact,
5237 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5238 XCAST(CreatePalette)DGA_IDirectDraw2Impl_CreatePalette,
5239 XCAST(CreateSurface)DGA_IDirectDraw2Impl_CreateSurface,
5240 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5241 XCAST(EnumDisplayModes)DGA_IDirectDraw2Impl_EnumDisplayModes,
5242 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5243 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5244 XCAST(GetCaps)DGA_IDirectDraw2Impl_GetCaps,
5245 XCAST(GetDisplayMode)DGA_IDirectDraw2Impl_GetDisplayMode,
5246 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5247 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5248 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5249 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5250 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5251 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5252 XCAST(RestoreDisplayMode)DGA_IDirectDraw2Impl_RestoreDisplayMode,
5253 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5254 XCAST(SetDisplayMode)DGA_IDirectDrawImpl_SetDisplayMode,
5255 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5256 XCAST(GetAvailableVidMem)DGA_IDirectDraw2Impl_GetAvailableVidMem,
5257 IDirectDraw4Impl_GetSurfaceFromDC,
5258 IDirectDraw4Impl_RestoreAllSurfaces,
5259 IDirectDraw4Impl_TestCooperativeLevel,
5260 IDirectDraw4Impl_GetDeviceIdentifier
5265 #endif /* defined(HAVE_LIBXXF86DGA) */
5267 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5268 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5270 # define XCAST(fun) (void*)
5273 static ICOM_VTABLE(IDirectDraw4) xlib_dd4vt =
5275 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5276 XCAST(QueryInterface)Xlib_IDirectDraw2Impl_QueryInterface,
5277 XCAST(AddRef)IDirectDraw2Impl_AddRef,
5278 XCAST(Release)Xlib_IDirectDraw2Impl_Release,
5279 XCAST(Compact)IDirectDraw2Impl_Compact,
5280 XCAST(CreateClipper)IDirectDraw2Impl_CreateClipper,
5281 XCAST(CreatePalette)Xlib_IDirectDraw2Impl_CreatePalette,
5282 XCAST(CreateSurface)Xlib_IDirectDraw2Impl_CreateSurface,
5283 XCAST(DuplicateSurface)IDirectDraw2Impl_DuplicateSurface,
5284 XCAST(EnumDisplayModes)Xlib_IDirectDraw2Impl_EnumDisplayModes,
5285 XCAST(EnumSurfaces)IDirectDraw2Impl_EnumSurfaces,
5286 XCAST(FlipToGDISurface)IDirectDraw2Impl_FlipToGDISurface,
5287 XCAST(GetCaps)Xlib_IDirectDraw2Impl_GetCaps,
5288 XCAST(GetDisplayMode)Xlib_IDirectDraw2Impl_GetDisplayMode,
5289 XCAST(GetFourCCCodes)IDirectDraw2Impl_GetFourCCCodes,
5290 XCAST(GetGDISurface)IDirectDraw2Impl_GetGDISurface,
5291 XCAST(GetMonitorFrequency)IDirectDraw2Impl_GetMonitorFrequency,
5292 XCAST(GetScanLine)IDirectDraw2Impl_GetScanLine,
5293 XCAST(GetVerticalBlankStatus)IDirectDraw2Impl_GetVerticalBlankStatus,
5294 XCAST(Initialize)IDirectDraw2Impl_Initialize,
5295 XCAST(RestoreDisplayMode)Xlib_IDirectDraw2Impl_RestoreDisplayMode,
5296 XCAST(SetCooperativeLevel)IDirectDraw2Impl_SetCooperativeLevel,
5297 XCAST(SetDisplayMode)Xlib_IDirectDrawImpl_SetDisplayMode,
5298 XCAST(WaitForVerticalBlank)IDirectDraw2Impl_WaitForVerticalBlank,
5299 XCAST(GetAvailableVidMem)Xlib_IDirectDraw2Impl_GetAvailableVidMem,
5300 IDirectDraw4Impl_GetSurfaceFromDC,
5301 IDirectDraw4Impl_RestoreAllSurfaces,
5302 IDirectDraw4Impl_TestCooperativeLevel,
5303 IDirectDraw4Impl_GetDeviceIdentifier
5308 /******************************************************************************
5312 static LRESULT WINAPI Xlib_DDWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
5315 IDirectDrawImpl* ddraw = NULL;
5318 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5320 SetLastError( ERROR_SUCCESS );
5321 ddraw = (IDirectDrawImpl*)GetPropA( hwnd, ddProp );
5322 if( (!ddraw) && ( ( lastError = GetLastError() ) != ERROR_SUCCESS ))
5324 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError );
5329 /* Perform any special direct draw functions */
5331 ddraw->d.paintable = 1;
5333 /* Now let the application deal with the rest of this */
5334 if( ddraw->d.mainWindow )
5337 /* Don't think that we actually need to call this but...
5338 might as well be on the safe side of things... */
5340 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5341 it should be the procedures of our fake window that gets called
5342 instead of those of the window provided by the application.
5343 And with this patch, mouse clicks work with Monkey Island III
5345 ret = DefWindowProcA( ddraw->d.mainWindow, msg, wParam, lParam );
5349 WND *tmpWnd =WIN_FindWndPtr(ddraw->d.mainWindow);
5350 /* We didn't handle the message - give it to the application */
5351 if (ddraw && ddraw->d.mainWindow && tmpWnd)
5353 ret = CallWindowProcA(tmpWnd->winproc,
5354 ddraw->d.mainWindow, msg, wParam, lParam );
5356 WIN_ReleaseWndPtr(tmpWnd);
5361 ret = DefWindowProcA(hwnd, msg, wParam, lParam );
5367 ret = DefWindowProcA(hwnd,msg,wParam,lParam);
5373 static HRESULT WINAPI DGA_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5374 #ifdef HAVE_LIBXXF86DGA
5375 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5376 int memsize,banksize,major,minor,flags;
5381 /* Get DGA availability / version */
5382 dga_version = DDRAW_DGA_Available();
5384 if (dga_version == 0) {
5385 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
5386 return DDERR_GENERIC;
5389 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5390 (*ilplpDD)->ref = 1;
5391 ICOM_VTBL(*ilplpDD) = &dga_ddvt;
5392 #ifdef HAVE_LIBXXF86DGA2
5393 if (dga_version == 1) {
5394 (*ilplpDD)->e.dga.version = 1;
5395 #endif /* defined(HAVE_LIBXXF86DGA2) */
5396 TSXF86DGAQueryVersion(display,&major,&minor);
5397 TRACE("XF86DGA is version %d.%d\n",major,minor);
5398 TSXF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
5399 if (!(flags & XF86DGADirectPresent))
5400 MESSAGE("direct video is NOT PRESENT.\n");
5401 TSXF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
5402 (*ilplpDD)->e.dga.fb_width = width;
5403 TSXF86DGAGetViewPortSize(display,DefaultScreen(display),&width,&height);
5404 TSXF86DGASetViewPort(display,DefaultScreen(display),0,0);
5405 (*ilplpDD)->e.dga.fb_height = height;
5406 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5407 addr,width,banksize,memsize
5409 TRACE("viewport height: %d\n",height);
5410 /* Get the screen dimensions as seen by Wine.
5411 In that case, it may be better to ignore the -desktop mode and return the
5412 real screen size => print a warning */
5413 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5414 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5415 if (((*ilplpDD)->d.height != height) ||
5416 ((*ilplpDD)->d.width != width))
5417 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5418 (*ilplpDD)->e.dga.fb_addr = addr;
5419 (*ilplpDD)->e.dga.fb_memsize = memsize;
5420 (*ilplpDD)->e.dga.vpmask = 0;
5422 /* just assume the default depth is the DGA depth too */
5423 _common_depth_to_pixelformat(X11DRV_GetDepth(), &((*ilplpDD)->d.directdraw_pixelformat),
5424 &((*ilplpDD)->d.screen_pixelformat), NULL);
5425 #ifdef RESTORE_SIGNALS
5428 #ifdef HAVE_LIBXXF86DGA2
5432 int mode_to_use = 0;
5434 (*ilplpDD)->e.dga.version = 2;
5436 TSXDGAQueryVersion(display,&major,&minor);
5437 TRACE("XDGA is version %d.%d\n",major,minor);
5439 TRACE("Opening the frame buffer.\n");
5440 if (!TSXDGAOpenFramebuffer(display, DefaultScreen(display))) {
5441 ERR("Error opening the frame buffer !!!\n");
5443 return DDERR_GENERIC;
5446 /* List all available modes */
5447 modes = TSXDGAQueryModes(display, DefaultScreen(display), &num_modes);
5448 (*ilplpDD)->e.dga.modes = modes;
5449 (*ilplpDD)->e.dga.num_modes = num_modes;
5450 if (TRACE_ON(ddraw)) {
5451 TRACE("Available modes :\n");
5452 for (i = 0; i < num_modes; i++) {
5453 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5455 modes[i].name, modes[i].imageWidth, modes[i].imageHeight,
5456 modes[i].viewportWidth, modes[i].viewportHeight,
5458 if (modes[i].flags & XDGAConcurrentAccess) DPRINTF(" XDGAConcurrentAccess ");
5459 if (modes[i].flags & XDGASolidFillRect) DPRINTF(" XDGASolidFillRect ");
5460 if (modes[i].flags & XDGABlitRect) DPRINTF(" XDGABlitRect ");
5461 if (modes[i].flags & XDGABlitTransRect) DPRINTF(" XDGABlitTransRect ");
5462 if (modes[i].flags & XDGAPixmap) DPRINTF(" XDGAPixmap ");
5465 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor) == modes[i].viewportHeight) &&
5466 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor) == modes[i].viewportWidth) &&
5467 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor) == modes[i].depth)) {
5468 mode_to_use = modes[i].num;
5472 if (mode_to_use == 0) {
5473 ERR("Could not find mode !\n");
5476 DPRINTF("Using mode number %d\n", mode_to_use);
5479 /* Initialize the frame buffer */
5480 _DGA_Initialize_FrameBuffer(*ilplpDD, mode_to_use);
5481 /* Set the input handling for relative mouse movements */
5482 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE);
5484 #endif /* defined(HAVE_LIBXXF86DGA2) */
5486 #else /* defined(HAVE_LIBXXF86DGA) */
5487 return DDERR_INVALIDDIRECTDRAWGUID;
5488 #endif /* defined(HAVE_LIBXXF86DGA) */
5492 DDRAW_XSHM_Available(void)
5494 #ifdef HAVE_LIBXXSHM
5495 if (get_option( "UseXShm", 1 ))
5497 if (TSXShmQueryExtension(display))
5501 if (TSXShmQueryVersion(display, &major, &minor, &shpix)) return TRUE;
5508 static HRESULT WINAPI Xlib_DirectDrawCreate( LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter) {
5509 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5511 *ilplpDD = (IDirectDrawImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawImpl));
5512 ICOM_VTBL(*ilplpDD) = &xlib_ddvt;
5513 (*ilplpDD)->ref = 1;
5514 (*ilplpDD)->d.drawable = 0; /* in SetDisplayMode */
5516 /* At DirectDraw creation, the depth is the default depth */
5517 _common_depth_to_pixelformat(X11DRV_GetDepth(),
5518 &((*ilplpDD)->d.directdraw_pixelformat),
5519 &((*ilplpDD)->d.screen_pixelformat),
5520 &((*ilplpDD)->d.pixmap_depth));
5521 (*ilplpDD)->d.height = MONITOR_GetHeight(&MONITOR_PrimaryMonitor);
5522 (*ilplpDD)->d.width = MONITOR_GetWidth(&MONITOR_PrimaryMonitor);
5524 #ifdef HAVE_LIBXXSHM
5525 /* Test if XShm is available. */
5526 if (((*ilplpDD)->e.xlib.xshm_active = DDRAW_XSHM_Available())) {
5527 (*ilplpDD)->e.xlib.xshm_compl = 0;
5528 TRACE("Using XShm extension.\n");
5535 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
5536 IDirectDrawImpl** ilplpDD=(IDirectDrawImpl**)lplpDD;
5538 /* WND* pParentWindow; */
5541 if (!HIWORD(lpGUID)) lpGUID = NULL;
5543 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID),ilplpDD,pUnkOuter);
5546 ( IsEqualGUID( &IID_IDirectDraw, lpGUID ) ) ||
5547 ( IsEqualGUID( &IID_IDirectDraw2, lpGUID ) ) ||
5548 ( IsEqualGUID( &IID_IDirectDraw4, lpGUID ) ) ) {
5549 /* if they didn't request a particular interface, use the best
5551 if (DDRAW_DGA_Available())
5552 lpGUID = &DGA_DirectDraw_GUID;
5554 lpGUID = &XLIB_DirectDraw_GUID;
5557 wc.style = CS_GLOBALCLASS;
5558 wc.lpfnWndProc = Xlib_DDWndProc;
5562 /* We can be a child of the desktop since we're really important */
5564 This code is not useful since hInstance is forced to 0 afterward
5565 pParentWindow = WIN_GetDesktop();
5566 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5572 wc.hCursor = (HCURSOR)IDC_ARROWA;
5573 wc.hbrBackground= NULL_BRUSH;
5574 wc.lpszMenuName = 0;
5575 wc.lpszClassName= "WINE_DirectDraw";
5576 RegisterClassA(&wc);
5578 if ( IsEqualGUID( &DGA_DirectDraw_GUID, lpGUID ) ) {
5579 ret = DGA_DirectDrawCreate(lplpDD, pUnkOuter);
5581 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID, &XLIB_DirectDraw_GUID ) ) {
5582 ret = Xlib_DirectDrawCreate(lplpDD, pUnkOuter);
5589 (*ilplpDD)->d.winclass = RegisterClassA(&wc);
5593 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
5594 debugstr_guid(lpGUID),lplpDD,pUnkOuter);
5595 return DDERR_INVALIDDIRECTDRAWGUID;
5598 /*******************************************************************************
5599 * DirectDraw ClassFactory
5601 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5606 /* IUnknown fields */
5607 ICOM_VFIELD(IClassFactory);
5609 } IClassFactoryImpl;
5611 static HRESULT WINAPI
5612 DDCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
5613 ICOM_THIS(IClassFactoryImpl,iface);
5615 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
5616 return E_NOINTERFACE;
5620 DDCF_AddRef(LPCLASSFACTORY iface) {
5621 ICOM_THIS(IClassFactoryImpl,iface);
5622 return ++(This->ref);
5625 static ULONG WINAPI DDCF_Release(LPCLASSFACTORY iface) {
5626 ICOM_THIS(IClassFactoryImpl,iface);
5627 /* static class, won't be freed */
5628 return --(This->ref);
5631 static HRESULT WINAPI DDCF_CreateInstance(
5632 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
5634 ICOM_THIS(IClassFactoryImpl,iface);
5636 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
5637 if ( ( IsEqualGUID( &IID_IDirectDraw, riid ) ) ||
5638 ( IsEqualGUID( &IID_IDirectDraw2, riid ) ) ||
5639 ( IsEqualGUID( &IID_IDirectDraw4, riid ) ) ) {
5640 /* FIXME: reuse already created DirectDraw if present? */
5641 return DirectDrawCreate((LPGUID) riid,(LPDIRECTDRAW*)ppobj,pOuter);
5643 return CLASS_E_CLASSNOTAVAILABLE;
5646 static HRESULT WINAPI DDCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
5647 ICOM_THIS(IClassFactoryImpl,iface);
5648 FIXME("(%p)->(%d),stub!\n",This,dolock);
5652 static ICOM_VTABLE(IClassFactory) DDCF_Vtbl =
5654 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5655 DDCF_QueryInterface,
5658 DDCF_CreateInstance,
5661 static IClassFactoryImpl DDRAW_CF = {&DDCF_Vtbl, 1 };
5663 /*******************************************************************************
5664 * DllGetClassObject [DDRAW.13]
5665 * Retrieves class object from a DLL object
5668 * Docs say returns STDAPI
5671 * rclsid [I] CLSID for the class object
5672 * riid [I] Reference to identifier of interface for class object
5673 * ppv [O] Address of variable to receive interface pointer for riid
5677 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5680 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
5682 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5683 if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
5684 *ppv = (LPVOID)&DDRAW_CF;
5685 IClassFactory_AddRef((IClassFactory*)*ppv);
5688 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
5689 return CLASS_E_CLASSNOTAVAILABLE;
5693 /*******************************************************************************
5694 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5700 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5702 FIXME("(void): stub\n");
5706 #else /* !defined(X_DISPLAY_MISSING) */
5713 typedef void *LPUNKNOWN;
5714 typedef void *LPDIRECTDRAW;
5715 typedef void *LPDIRECTDRAWCLIPPER;
5716 typedef void *LPDDENUMCALLBACKA;
5717 typedef void *LPDDENUMCALLBACKEXA;
5718 typedef void *LPDDENUMCALLBACKEXW;
5719 typedef void *LPDDENUMCALLBACKW;
5721 /***********************************************************************
5724 HRESULT WINAPI DSoundHelp(DWORD x, DWORD y, DWORD z)
5729 /***********************************************************************
5732 HRESULT WINAPI DirectDrawCreate(
5733 LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter)
5738 /***********************************************************************
5739 * DirectDrawCreateClipper
5741 HRESULT WINAPI DirectDrawCreateClipper(
5742 DWORD dwFlags, LPDIRECTDRAWCLIPPER *lplpDDClipper, LPUNKNOWN pUnkOuter)
5747 /***********************************************************************
5748 * DirectDrawEnumerateA
5750 HRESULT WINAPI DirectDrawEnumerateA(
5751 LPDDENUMCALLBACKA lpCallback, LPVOID lpContext)
5756 /***********************************************************************
5757 * DirectDrawEnumerateExA
5759 HRESULT WINAPI DirectDrawEnumerateExA(
5760 LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags)
5765 /***********************************************************************
5766 * DirectDrawEnumerateExW
5768 HRESULT WINAPI DirectDrawEnumerateExW(
5769 LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags)
5774 /***********************************************************************
5775 * DirectDrawEnumerateW
5777 HRESULT WINAPI DirectDrawEnumerateW(
5778 LPDDENUMCALLBACKW lpCallback, LPVOID lpContext)
5783 /***********************************************************************
5784 * DDRAW_DllGetClassObject
5786 DWORD WINAPI DDRAW_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
5788 return CLASS_E_CLASSNOTAVAILABLE;
5791 /***********************************************************************
5792 * DDRAW_DllCanUnloadNow
5794 DWORD WINAPI DDRAW_DllCanUnloadNow(void)
5799 #endif /* !defined(X_DISPLAY_MISSING) */