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;
178 DDRAW_DGA_Available(void)
180 #ifdef HAVE_LIBXXF86DGA
181 int fd
, evbase
, evret
, majver
, minver
;
182 static BYTE return_value
= 0xFF;
184 /* This prevents from probing X times for DGA */
185 if (return_value
!= 0xFF)
193 /* First, query the extenstion and its version */
194 if (!TSXF86DGAQueryExtension(display
,&evbase
,&evret
)) {
199 if (!TSXF86DGAQueryVersion(display
,&majver
,&minver
)) {
204 #ifdef HAVE_LIBXXF86DGA2
206 /* We have DGA 2.0 available ! */
207 if (TSXDGAOpenFramebuffer(display
, DefaultScreen(display
))) {
208 TSXDGACloseFramebuffer(display
, DefaultScreen(display
));
216 #endif /* defined(HAVE_LIBXXF86DGA2) */
218 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
219 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
220 /* others. --stephenc */
221 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
230 #ifdef HAVE_LIBXXF86DGA2
232 #endif /* defined(HAVE_LIBXXF86DGA2) */
233 #else /* defined(HAVE_LIBXXF86DGA) */
235 #endif /* defined(HAVE_LIBXXF86DGA) */
238 /**********************************************************************/
243 } DirectDrawEnumerateProcData
;
245 /***********************************************************************
246 * DirectDrawEnumerateExA (DDRAW.*)
248 HRESULT WINAPI
DirectDrawEnumerateExA(
249 LPDDENUMCALLBACKEXA lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
251 TRACE("(%p,%p, %08lx)\n", lpCallback
, lpContext
, dwFlags
);
253 if (TRACE_ON(ddraw
)) {
254 DPRINTF(" Flags : ");
255 if (dwFlags
& DDENUM_ATTACHEDSECONDARYDEVICES
)
256 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
257 if (dwFlags
& DDENUM_DETACHEDSECONDARYDEVICES
)
258 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
259 if (dwFlags
& DDENUM_NONDISPLAYDEVICES
)
260 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
264 if (dwFlags
== DDENUM_NONDISPLAYDEVICES
) {
265 /* For the moment, Wine does not support any 3D only accelerators */
268 if (dwFlags
== DDENUM_NONDISPLAYDEVICES
) {
269 /* For the moment, Wine does not support any attached secondary devices */
273 if (DDRAW_DGA_Available()) {
274 TRACE("Enumerating DGA interface\n");
275 if (!lpCallback(&DGA_DirectDraw_GUID
, "WINE with XFree86 DGA", "display", lpContext
, 0))
279 TRACE("Enumerating Xlib interface\n");
280 if (!lpCallback(&XLIB_DirectDraw_GUID
, "WINE with Xlib", "display", lpContext
, 0))
283 TRACE("Enumerating Default interface\n");
284 if (!lpCallback(NULL
,"WINE (default)", "display", lpContext
, 0))
290 /***********************************************************************
291 * DirectDrawEnumerateExW (DDRAW.*)
294 static BOOL CALLBACK
DirectDrawEnumerateExProcW(
295 GUID
*lpGUID
, LPSTR lpDriverDescription
, LPSTR lpDriverName
,
296 LPVOID lpContext
, HMONITOR hm
)
298 DirectDrawEnumerateProcData
*pEPD
=
299 (DirectDrawEnumerateProcData
*) lpContext
;
300 LPWSTR lpDriverDescriptionW
=
301 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription
);
302 LPWSTR lpDriverNameW
=
303 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName
);
305 BOOL bResult
= (*(LPDDENUMCALLBACKEXW
*) pEPD
->lpCallback
)(
306 lpGUID
, lpDriverDescriptionW
, lpDriverNameW
, pEPD
->lpContext
, hm
);
308 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW
);
309 HeapFree(GetProcessHeap(), 0, lpDriverNameW
);
314 /**********************************************************************/
316 HRESULT WINAPI
DirectDrawEnumerateExW(
317 LPDDENUMCALLBACKEXW lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
319 DirectDrawEnumerateProcData epd
;
320 epd
.lpCallback
= (LPVOID
) lpCallback
;
321 epd
.lpContext
= lpContext
;
323 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW
,
327 /***********************************************************************
328 * DirectDrawEnumerateA (DDRAW.*)
331 static BOOL CALLBACK
DirectDrawEnumerateProcA(
332 GUID
*lpGUID
, LPSTR lpDriverDescription
, LPSTR lpDriverName
,
333 LPVOID lpContext
, HMONITOR hm
)
335 DirectDrawEnumerateProcData
*pEPD
=
336 (DirectDrawEnumerateProcData
*) lpContext
;
338 return ((LPDDENUMCALLBACKA
) pEPD
->lpCallback
)(
339 lpGUID
, lpDriverDescription
, lpDriverName
, pEPD
->lpContext
);
342 /**********************************************************************/
344 HRESULT WINAPI
DirectDrawEnumerateA(
345 LPDDENUMCALLBACKA lpCallback
, LPVOID lpContext
)
347 DirectDrawEnumerateProcData epd
;
348 epd
.lpCallback
= (LPVOID
) lpCallback
;
349 epd
.lpContext
= lpContext
;
351 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA
,
355 /***********************************************************************
356 * DirectDrawEnumerateW (DDRAW.*)
359 static BOOL WINAPI
DirectDrawEnumerateProcW(
360 GUID
*lpGUID
, LPWSTR lpDriverDescription
, LPWSTR lpDriverName
,
361 LPVOID lpContext
, HMONITOR hm
)
363 DirectDrawEnumerateProcData
*pEPD
=
364 (DirectDrawEnumerateProcData
*) lpContext
;
366 return ((LPDDENUMCALLBACKW
) pEPD
->lpCallback
)(
367 lpGUID
, lpDriverDescription
, lpDriverName
,
371 /**********************************************************************/
373 HRESULT WINAPI
DirectDrawEnumerateW(
374 LPDDENUMCALLBACKW lpCallback
, LPVOID lpContext
)
376 DirectDrawEnumerateProcData epd
;
377 epd
.lpCallback
= (LPVOID
) lpCallback
;
378 epd
.lpContext
= lpContext
;
380 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW
,
384 /***********************************************************************
385 * DSoundHelp (DDRAW.?)
388 /* What is this doing here? */
390 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
391 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
395 /******************************************************************************
396 * internal helper functions
398 static void _dump_DDBLTFX(DWORD flagmask
) {
404 #define FE(x) { x, #x},
405 FE(DDBLTFX_ARITHSTRETCHY
)
406 FE(DDBLTFX_MIRRORLEFTRIGHT
)
407 FE(DDBLTFX_MIRRORUPDOWN
)
408 FE(DDBLTFX_NOTEARING
)
409 FE(DDBLTFX_ROTATE180
)
410 FE(DDBLTFX_ROTATE270
)
412 FE(DDBLTFX_ZBUFFERRANGE
)
413 FE(DDBLTFX_ZBUFFERBASEDEST
)
416 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
417 if (flags
[i
].mask
& flagmask
) {
418 DPRINTF("%s ",flags
[i
].name
);
425 static void _dump_DDBLTFAST(DWORD flagmask
) {
431 #define FE(x) { x, #x},
432 FE(DDBLTFAST_NOCOLORKEY
)
433 FE(DDBLTFAST_SRCCOLORKEY
)
434 FE(DDBLTFAST_DESTCOLORKEY
)
438 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
439 if (flags
[i
].mask
& flagmask
)
440 DPRINTF("%s ",flags
[i
].name
);
444 static void _dump_DDBLT(DWORD flagmask
) {
450 #define FE(x) { x, #x},
452 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
453 FE(DDBLT_ALPHADESTNEG
)
454 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
455 FE(DDBLT_ALPHAEDGEBLEND
)
457 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
458 FE(DDBLT_ALPHASRCNEG
)
459 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
465 FE(DDBLT_KEYDESTOVERRIDE
)
467 FE(DDBLT_KEYSRCOVERRIDE
)
469 FE(DDBLT_ROTATIONANGLE
)
471 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
472 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
473 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
474 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
479 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
480 if (flags
[i
].mask
& flagmask
)
481 DPRINTF("%s ",flags
[i
].name
);
485 static void _dump_DDSCAPS(void *in
) {
491 #define FE(x) { x, #x},
492 FE(DDSCAPS_RESERVED1
)
494 FE(DDSCAPS_BACKBUFFER
)
497 FE(DDSCAPS_FRONTBUFFER
)
498 FE(DDSCAPS_OFFSCREENPLAIN
)
501 FE(DDSCAPS_PRIMARYSURFACE
)
502 FE(DDSCAPS_PRIMARYSURFACELEFT
)
503 FE(DDSCAPS_SYSTEMMEMORY
)
506 FE(DDSCAPS_VIDEOMEMORY
)
508 FE(DDSCAPS_WRITEONLY
)
511 FE(DDSCAPS_LIVEVIDEO
)
515 FE(DDSCAPS_RESERVED2
)
516 FE(DDSCAPS_ALLOCONLOAD
)
517 FE(DDSCAPS_VIDEOPORT
)
518 FE(DDSCAPS_LOCALVIDMEM
)
519 FE(DDSCAPS_NONLOCALVIDMEM
)
520 FE(DDSCAPS_STANDARDVGAMODE
)
521 FE(DDSCAPS_OPTIMIZED
)
524 DWORD flagmask
= *((DWORD
*) in
);
525 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
526 if (flags
[i
].mask
& flagmask
)
527 DPRINTF("%s ",flags
[i
].name
);
530 static void _dump_pixelformat_flag(DWORD flagmask
) {
536 #define FE(x) { x, #x},
540 FE(DDPF_PALETTEINDEXED4
)
541 FE(DDPF_PALETTEINDEXEDTO8
)
542 FE(DDPF_PALETTEINDEXED8
)
548 FE(DDPF_PALETTEINDEXED1
)
549 FE(DDPF_PALETTEINDEXED2
)
553 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
554 if (flags
[i
].mask
& flagmask
)
555 DPRINTF("%s ",flags
[i
].name
);
558 static void _dump_paletteformat(DWORD dwFlags
) {
564 #define FE(x) { x, #x},
566 FE(DDPCAPS_8BITENTRIES
)
568 FE(DDPCAPS_INITIALIZE
)
569 FE(DDPCAPS_PRIMARYSURFACE
)
570 FE(DDPCAPS_PRIMARYSURFACELEFT
)
578 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
579 if (flags
[i
].mask
& dwFlags
)
580 DPRINTF("%s ",flags
[i
].name
);
584 static void _dump_pixelformat(void *in
) {
585 LPDDPIXELFORMAT pf
= (LPDDPIXELFORMAT
) in
;
589 _dump_pixelformat_flag(pf
->dwFlags
);
590 if (pf
->dwFlags
& DDPF_FOURCC
) {
591 DPRINTF(", dwFourCC : %ld", pf
->dwFourCC
);
593 if (pf
->dwFlags
& DDPF_RGB
) {
594 DPRINTF(", RGB bits: %ld, ", pf
->u
.dwRGBBitCount
);
595 switch (pf
->u
.dwRGBBitCount
) {
612 ERR("Unexpected bit depth !\n");
615 DPRINTF(" R "); DPRINTF(cmd
, pf
->u1
.dwRBitMask
);
616 DPRINTF(" G "); DPRINTF(cmd
, pf
->u2
.dwGBitMask
);
617 DPRINTF(" B "); DPRINTF(cmd
, pf
->u3
.dwBBitMask
);
618 if (pf
->dwFlags
& DDPF_ALPHAPIXELS
) {
619 DPRINTF(" A "); DPRINTF(cmd
, pf
->u4
.dwRGBAlphaBitMask
);
621 if (pf
->dwFlags
& DDPF_ZPIXELS
) {
622 DPRINTF(" Z "); DPRINTF(cmd
, pf
->u4
.dwRGBZBitMask
);
625 if (pf
->dwFlags
& DDPF_ZBUFFER
) {
626 DPRINTF(", Z bits : %ld", pf
->u
.dwZBufferBitDepth
);
628 if (pf
->dwFlags
& DDPF_ALPHA
) {
629 DPRINTF(", Alpha bits : %ld", pf
->u
.dwAlphaBitDepth
);
634 static void _dump_colorkeyflag(DWORD ck
) {
640 #define FE(x) { x, #x},
641 FE(DDCKEY_COLORSPACE
)
643 FE(DDCKEY_DESTOVERLAY
)
645 FE(DDCKEY_SRCOVERLAY
)
648 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
649 if (flags
[i
].mask
& ck
)
650 DPRINTF("%s ",flags
[i
].name
);
653 static void _dump_DWORD(void *in
) {
654 DPRINTF("%ld", *((DWORD
*) in
));
656 static void _dump_PTR(void *in
) {
657 DPRINTF("%p", *((void **) in
));
659 static void _dump_DDCOLORKEY(void *in
) {
660 DDCOLORKEY
*ddck
= (DDCOLORKEY
*) in
;
662 DPRINTF(" Low : %ld - High : %ld", ddck
->dwColorSpaceLowValue
, ddck
->dwColorSpaceHighValue
);
665 static void _dump_surface_desc(DDSURFACEDESC
*lpddsd
) {
670 void (*func
)(void *);
672 } flags
[16], *fe
= flags
;
673 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
674 FE(DDSD_CAPS
, _dump_DDSCAPS
, ddsCaps
);
675 FE(DDSD_HEIGHT
, _dump_DWORD
, dwHeight
);
676 FE(DDSD_WIDTH
, _dump_DWORD
, dwWidth
);
677 FE(DDSD_PITCH
, _dump_DWORD
, lPitch
);
678 FE(DDSD_BACKBUFFERCOUNT
, _dump_DWORD
, dwBackBufferCount
);
679 FE(DDSD_ZBUFFERBITDEPTH
, _dump_DWORD
, u
.dwZBufferBitDepth
);
680 FE(DDSD_ALPHABITDEPTH
, _dump_DWORD
, dwAlphaBitDepth
);
681 FE(DDSD_PIXELFORMAT
, _dump_pixelformat
, ddpfPixelFormat
);
682 FE(DDSD_CKDESTOVERLAY
, _dump_DDCOLORKEY
, ddckCKDestOverlay
);
683 FE(DDSD_CKDESTBLT
, _dump_DDCOLORKEY
, ddckCKDestBlt
);
684 FE(DDSD_CKSRCOVERLAY
, _dump_DDCOLORKEY
, ddckCKSrcOverlay
);
685 FE(DDSD_CKSRCBLT
, _dump_DDCOLORKEY
, ddckCKSrcBlt
);
686 FE(DDSD_MIPMAPCOUNT
, _dump_DWORD
, u
.dwMipMapCount
);
687 FE(DDSD_REFRESHRATE
, _dump_DWORD
, u
.dwRefreshRate
);
688 FE(DDSD_LINEARSIZE
, _dump_DWORD
, u1
.dwLinearSize
);
689 FE(DDSD_LPSURFACE
, _dump_PTR
, u1
.lpSurface
);
692 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
693 if (flags
[i
].mask
& lpddsd
->dwFlags
) {
694 DPRINTF(" - %s : ",flags
[i
].name
);
695 flags
[i
].func(flags
[i
].elt
);
701 /******************************************************************************
702 * IDirectDrawSurface methods
704 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
705 * DDS and DDS2 use those functions. (Function calls did not change (except
706 * using different DirectDrawSurfaceX version), just added flags and functions)
709 static HRESULT WINAPI
IDirectDrawSurface4Impl_Lock(
710 LPDIRECTDRAWSURFACE4 iface
,LPRECT lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE hnd
712 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
713 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
714 This
,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
715 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
716 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
717 This
,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
719 /* First, copy the Surface description */
720 *lpddsd
= This
->s
.surface_desc
;
721 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
722 lpddsd
->dwHeight
,lpddsd
->dwWidth
,lpddsd
->lPitch
);
724 /* If asked only for a part, change the surface pointer */
726 TRACE(" lprect: %dx%d-%dx%d\n",
727 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
729 if ((lprect
->top
< 0) ||
730 (lprect
->left
< 0) ||
731 (lprect
->bottom
< 0) ||
732 (lprect
->right
< 0)) {
733 ERR(" Negative values in LPRECT !!!\n");
734 return DDERR_INVALIDPARAMS
;
737 lpddsd
->u1
.lpSurface
= (LPVOID
) ((char *) This
->s
.surface_desc
.u1
.lpSurface
+
738 (lprect
->top
*This
->s
.surface_desc
.lPitch
) +
739 lprect
->left
*GET_BPP(This
->s
.surface_desc
));
741 assert(This
->s
.surface_desc
.u1
.lpSurface
);
744 /* wait for any previous operations to complete */
746 if (This
->t
.xlib
.image
&& (SDDSCAPS(This
) & DDSCAPS_VISIBLE
) &&
747 This
->s
.ddraw
->e
.xlib
.xshm_active
) {
749 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
750 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
752 X11DRV_EVENT_WaitShmCompletions( This
->s
.ddraw
->d
.drawable
);
758 #ifdef HAVE_LIBXXF86DGA
759 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_Unlock(
760 LPDIRECTDRAWSURFACE4 iface
,LPVOID surface
762 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
763 TRACE("(%p)->Unlock(%p)\n",This
,surface
);
766 #endif /* defined(HAVE_LIBXXF86DGA) */
768 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl
* This
) {
769 if (This
->s
.ddraw
->d
.pixel_convert
!= NULL
)
770 This
->s
.ddraw
->d
.pixel_convert(This
->s
.surface_desc
.u1
.lpSurface
,
771 This
->t
.xlib
.image
->data
,
772 This
->s
.surface_desc
.dwWidth
,
773 This
->s
.surface_desc
.dwHeight
,
774 This
->s
.surface_desc
.lPitch
,
778 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
780 X11DRV_EVENT_WaitReplaceShmCompletion( &This->s.ddraw->e.xlib.xshm_compl, This->s.ddraw->d.drawable );
782 /* let WaitShmCompletions track 'em for now */
783 /* (you may want to track it again whenever you implement DX7's partial surface locking,
784 where threads have concurrent access) */
785 X11DRV_EVENT_PrepareShmCompletion( This
->s
.ddraw
->d
.drawable
);
786 TSXShmPutImage(display
,
787 This
->s
.ddraw
->d
.drawable
,
788 DefaultGCOfScreen(X11DRV_GetXScreen()),
791 This
->t
.xlib
.image
->width
,
792 This
->t
.xlib
.image
->height
,
794 /* make sure the image is transferred ASAP */
799 TSXPutImage( display
,
800 This
->s
.ddraw
->d
.drawable
,
801 DefaultGCOfScreen(X11DRV_GetXScreen()),
804 This
->t
.xlib
.image
->width
,
805 This
->t
.xlib
.image
->height
);
808 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Unlock(
809 LPDIRECTDRAWSURFACE4 iface
,LPVOID surface
)
811 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
812 TRACE("(%p)->Unlock(%p)\n",This
,surface
);
814 if (!This
->s
.ddraw
->d
.paintable
)
817 /* Only redraw the screen when unlocking the buffer that is on screen */
818 if (This
->t
.xlib
.image
&& (SDDSCAPS(This
) & DDSCAPS_VISIBLE
)) {
819 Xlib_copy_surface_on_screen(This
);
821 if (This
->s
.palette
&& This
->s
.palette
->cm
)
822 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
827 static IDirectDrawSurface4Impl
* _common_find_flipto(
828 IDirectDrawSurface4Impl
* This
,IDirectDrawSurface4Impl
* flipto
831 struct _surface_chain
*chain
= This
->s
.chain
;
833 /* if there was no override flipto, look for current backbuffer */
835 /* walk the flip chain looking for backbuffer */
836 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
837 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
)
839 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_BACKBUFFER
)
840 flipto
= chain
->surfaces
[i
];
842 /* sanity checks ... */
845 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
846 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FRONTBUFFER
)
848 if (i
==chain
->nrofsurfaces
) {
849 /* we do not have a frontbuffer either */
850 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
851 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
) {
852 SDDSCAPS(chain
->surfaces
[i
])|=DDSCAPS_FRONTBUFFER
;
855 for (j
=i
+1;j
<i
+chain
->nrofsurfaces
+1;j
++) {
856 int k
= j
% chain
->nrofsurfaces
;
857 if (SDDSCAPS(chain
->surfaces
[k
]) & DDSCAPS_FLIP
) {
858 SDDSCAPS(chain
->surfaces
[k
])|=DDSCAPS_BACKBUFFER
;
859 flipto
= chain
->surfaces
[k
];
868 TRACE("flipping to %p\n",flipto
);
873 #ifdef HAVE_LIBXXF86DGA
874 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_Flip(
875 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
877 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
878 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
882 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
883 iflipto
= _common_find_flipto(This
,iflipto
);
886 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,iflipto
->t
.dga
.fb_height
);
887 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
888 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),iflipto
->s
.palette
->cm
);
889 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
892 /* We need to switch the lowlevel surfaces, for DGA this is: */
894 /* The height within the framebuffer */
895 xheight
= This
->t
.dga
.fb_height
;
896 This
->t
.dga
.fb_height
= iflipto
->t
.dga
.fb_height
;
897 iflipto
->t
.dga
.fb_height
= xheight
;
899 /* And the assciated surface pointer */
900 surf
= This
->s
.surface_desc
.u1
.lpSurface
;
901 This
->s
.surface_desc
.u1
.lpSurface
= iflipto
->s
.surface_desc
.u1
.lpSurface
;
902 iflipto
->s
.surface_desc
.u1
.lpSurface
= surf
;
906 #endif /* defined(HAVE_LIBXXF86DGA) */
908 #ifdef HAVE_LIBXXF86DGA2
909 static HRESULT WINAPI
DGA2_IDirectDrawSurface4Impl_Flip(
910 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
912 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
913 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
917 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
918 iflipto
= _common_find_flipto(This
,iflipto
);
921 TSXDGASetViewport(display
,DefaultScreen(display
),0,iflipto
->t
.dga
.fb_height
, XDGAFlipRetrace
);
922 TSXDGASync(display
,DefaultScreen(display
));
924 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
925 TSXDGAInstallColormap(display
,DefaultScreen(display
),iflipto
->s
.palette
->cm
);
926 /* We need to switch the lowlevel surfaces, for DGA this is: */
928 /* The height within the framebuffer */
929 xheight
= This
->t
.dga
.fb_height
;
930 This
->t
.dga
.fb_height
= iflipto
->t
.dga
.fb_height
;
931 iflipto
->t
.dga
.fb_height
= xheight
;
933 /* And the assciated surface pointer */
934 surf
= This
->s
.surface_desc
.u1
.lpSurface
;
935 This
->s
.surface_desc
.u1
.lpSurface
= iflipto
->s
.surface_desc
.u1
.lpSurface
;
936 iflipto
->s
.surface_desc
.u1
.lpSurface
= surf
;
940 #endif /* defined(HAVE_LIBXXF86DGA2) */
942 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Flip(
943 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
945 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
948 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
950 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
951 iflipto
= _common_find_flipto(This
,iflipto
);
953 #if defined(HAVE_MESAGL) && 0 /* does not work */
954 if (This
->s
.d3d_device
|| (iflipto
&& iflipto
->s
.d3d_device
)) {
955 TRACE(" - OpenGL flip\n");
957 glXSwapBuffers(display
, This
->s
.ddraw
->d
.drawable
);
962 #endif /* defined(HAVE_MESAGL) */
964 if (!This
->s
.ddraw
->d
.paintable
)
967 /* We need to switch the lowlevel surfaces, for xlib this is: */
968 /* The surface pointer */
969 surf
= This
->s
.surface_desc
.u1
.lpSurface
;
970 This
->s
.surface_desc
.u1
.lpSurface
= iflipto
->s
.surface_desc
.u1
.lpSurface
;
971 iflipto
->s
.surface_desc
.u1
.lpSurface
= surf
;
972 /* the associated ximage */
973 image
= This
->t
.xlib
.image
;
974 This
->t
.xlib
.image
= iflipto
->t
.xlib
.image
;
975 iflipto
->t
.xlib
.image
= image
;
978 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
980 int compl = InterlockedExchange( &This->s.ddraw->e.xlib.xshm_compl, 0 );
981 if (compl) X11DRV_EVENT_WaitShmCompletion( compl );
983 X11DRV_EVENT_WaitShmCompletions( This
->s
.ddraw
->d
.drawable
);
986 Xlib_copy_surface_on_screen(This
);
988 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
989 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,iflipto
->s
.palette
->cm
);
993 /* The IDirectDrawSurface4::SetPalette method attaches the specified
994 * DirectDrawPalette object to a surface. The surface uses this palette for all
995 * subsequent operations. The palette change takes place immediately.
997 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_SetPalette(
998 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
1000 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1001 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
1003 TRACE("(%p)->(%p)\n",This
,ipal
);
1006 if( This
->s
.palette
!= NULL
)
1007 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
1008 This
->s
.palette
= ipal
;
1013 if( !(ipal
->cm
) && (This
->s
.ddraw
->d
.screen_pixelformat
.u
.dwRGBBitCount
<=8))
1015 ipal
->cm
= TSXCreateColormap(display
,This
->s
.ddraw
->d
.drawable
,
1016 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
1018 if (!Options
.managed
)
1019 TSXInstallColormap(display
,ipal
->cm
);
1021 for (i
=0;i
<256;i
++) {
1024 xc
.red
= ipal
->palents
[i
].peRed
<<8;
1025 xc
.blue
= ipal
->palents
[i
].peBlue
<<8;
1026 xc
.green
= ipal
->palents
[i
].peGreen
<<8;
1027 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1029 TSXStoreColor(display
,ipal
->cm
,&xc
);
1031 TSXInstallColormap(display
,ipal
->cm
);
1034 /* According to spec, we are only supposed to
1035 * AddRef if this is not the same palette.
1037 if( This
->s
.palette
!= ipal
)
1040 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
1041 if( This
->s
.palette
!= NULL
)
1042 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
1043 This
->s
.palette
= ipal
;
1044 /* Perform the refresh */
1045 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
1050 #ifdef HAVE_LIBXXF86DGA
1051 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_SetPalette(
1052 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
1054 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1055 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
1056 TRACE("(%p)->(%p)\n",This
,ipal
);
1058 /* According to spec, we are only supposed to
1059 * AddRef if this is not the same palette.
1061 if( This
->s
.palette
!= ipal
)
1064 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
1065 if( This
->s
.palette
!= NULL
)
1066 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
1067 This
->s
.palette
= ipal
;
1068 #ifdef HAVE_LIBXXF86DGA2
1069 if (This
->s
.ddraw
->e
.dga
.version
== 2)
1070 TSXDGAInstallColormap(display
,DefaultScreen(display
),This
->s
.palette
->cm
);
1072 #endif /* defined(HAVE_LIBXXF86DGA2) */
1073 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->s
.palette
->cm
);
1077 #endif /* defined(HAVE_LIBXXF86DGA) */
1079 static HRESULT
_Blt_ColorFill(LPBYTE buf
, int width
, int height
, int bpp
, LONG lPitch
, DWORD color
)
1086 #define COLORFILL_ROW(type) { \
1087 type *d = (type *) buf; \
1088 for (x = 0; x < width; x++) \
1089 d[x] = (type) color; \
1094 case 1: COLORFILL_ROW(BYTE
)
1095 case 2: COLORFILL_ROW(WORD
)
1096 case 4: COLORFILL_ROW(DWORD
)
1098 FIXME("Color fill not implemented for bpp %d!\n", bpp
*8);
1099 return DDERR_UNSUPPORTED
;
1102 #undef COLORFILL_ROW
1104 /* Now copy first row */
1106 for (y
= 1; y
< height
; y
++) {
1108 memcpy(buf
, first
, width
* bpp
);
1114 static HRESULT WINAPI
IDirectDrawSurface4Impl_Blt(
1115 LPDIRECTDRAWSURFACE4 iface
,LPRECT rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
1117 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1119 DDSURFACEDESC ddesc
,sdesc
;
1120 HRESULT ret
= DD_OK
;
1121 int bpp
, srcheight
, srcwidth
, dstheight
, dstwidth
, width
;
1125 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This
,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
1127 if (src
) IDirectDrawSurface4_Lock(src
, NULL
, &sdesc
, 0, 0);
1128 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,0,0);
1130 if (TRACE_ON(ddraw
)) {
1131 if (rdst
) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
1132 if (rsrc
) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1134 _dump_DDBLT(dwFlags
);
1135 if (dwFlags
& DDBLT_DDFX
) {
1136 TRACE("\tblitfx: ");
1137 _dump_DDBLTFX(lpbltfx
->dwDDFX
);
1142 if ((rdst
->top
< 0) ||
1144 (rdst
->bottom
< 0) ||
1145 (rdst
->right
< 0)) {
1146 ERR(" Negative values in LPRECT !!!\n");
1149 memcpy(&xdst
,rdst
,sizeof(xdst
));
1152 xdst
.bottom
= ddesc
.dwHeight
;
1154 xdst
.right
= ddesc
.dwWidth
;
1158 if ((rsrc
->top
< 0) ||
1160 (rsrc
->bottom
< 0) ||
1161 (rsrc
->right
< 0)) {
1162 ERR(" Negative values in LPRECT !!!\n");
1165 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
1169 xsrc
.bottom
= sdesc
.dwHeight
;
1171 xsrc
.right
= sdesc
.dwWidth
;
1173 memset(&xsrc
,0,sizeof(xsrc
));
1177 bpp
= GET_BPP(ddesc
);
1178 srcheight
= xsrc
.bottom
- xsrc
.top
;
1179 srcwidth
= xsrc
.right
- xsrc
.left
;
1180 dstheight
= xdst
.bottom
- xdst
.top
;
1181 dstwidth
= xdst
.right
- xdst
.left
;
1182 width
= (xdst
.right
- xdst
.left
) * bpp
;
1183 dbuf
= (BYTE
*) ddesc
.u1
.lpSurface
+ (xdst
.top
* ddesc
.lPitch
) + (xdst
.left
* bpp
);
1185 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
1187 /* First, all the 'source-less' blits */
1188 if (dwFlags
& DDBLT_COLORFILL
) {
1189 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
,
1190 ddesc
.lPitch
, lpbltfx
->u4
.dwFillColor
);
1191 dwFlags
&= ~DDBLT_COLORFILL
;
1194 if (dwFlags
& DDBLT_DEPTHFILL
) {
1198 /* Clears the screen */
1199 TRACE(" Filling depth buffer with %ld\n", lpbltfx
->u4
.dwFillDepth
);
1200 glClearDepth(lpbltfx
->u4
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
1201 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
1202 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
1203 glClear(GL_DEPTH_BUFFER_BIT
);
1206 dwFlags
&= ~(DDBLT_DEPTHFILL
);
1207 #endif /* defined(HAVE_MESAGL) */
1210 if (dwFlags
& DDBLT_ROP
) {
1211 /* Catch some degenerate cases here */
1212 switch(lpbltfx
->dwROP
) {
1214 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, 0);
1216 case 0xAA0029: /* No-op */
1219 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, ~0);
1222 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx
->dwROP
, lpbltfx
->u4
.lpDDSPattern
);
1225 dwFlags
&= ~DDBLT_ROP
;
1228 if (dwFlags
& DDBLT_DDROPS
) {
1229 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx
->dwDDROP
, lpbltfx
->u4
.lpDDSPattern
);
1232 /* Now the 'with source' blits */
1235 int sx
, xinc
, sy
, yinc
;
1237 sbase
= (BYTE
*) sdesc
.u1
.lpSurface
+ (xsrc
.top
* sdesc
.lPitch
) + xsrc
.left
* bpp
;
1238 xinc
= (srcwidth
<< 16) / dstwidth
;
1239 yinc
= (srcheight
<< 16) / dstheight
;
1243 /* No effects, we can cheat here */
1244 if (dstwidth
== srcwidth
) {
1245 if (dstheight
== srcheight
) {
1246 /* No stretching in either direction. This needs to be as fast as possible */
1248 for (y
= 0; y
< dstheight
; y
++) {
1249 memcpy(dbuf
, sbuf
, width
);
1250 sbuf
+= sdesc
.lPitch
;
1251 dbuf
+= ddesc
.lPitch
;
1254 /* Stretching in Y direction only */
1255 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1256 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1257 memcpy(dbuf
, sbuf
, width
);
1258 dbuf
+= ddesc
.lPitch
;
1262 /* Stretching in X direction */
1264 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1265 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1267 if ((sy
>> 16) == (last_sy
>> 16)) {
1268 /* Same as last row - copy already stretched row */
1269 memcpy(dbuf
, dbuf
- ddesc
.lPitch
, width
);
1272 #define STRETCH_ROW(type) { \
1273 type *s = (type *) sbuf, *d = (type *) dbuf; \
1274 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1275 d[x] = s[sx >> 16]; \
1279 case 1: STRETCH_ROW(BYTE
)
1280 case 2: STRETCH_ROW(WORD
)
1281 case 4: STRETCH_ROW(DWORD
)
1284 for (x
= sx
= 0; x
< dstwidth
; x
++, sx
+= xinc
) {
1287 s
= sbuf
+3*(sx
>>16);
1289 pixel
= (s
[0]<<16)|(s
[1]<<8)|s
[2];
1290 d
[0] = (pixel
>>16)&0xff;
1291 d
[1] = (pixel
>> 8)&0xff;
1292 d
[2] = (pixel
)&0xff;
1297 FIXME("Stretched blit not implemented for bpp %d!\n", bpp
*8);
1298 ret
= DDERR_UNSUPPORTED
;
1306 dbuf
+= ddesc
.lPitch
;
1309 } else if (dwFlags
& (DDBLT_KEYSRC
| DDBLT_KEYDEST
)) {
1310 DWORD keylow
, keyhigh
;
1312 if (dwFlags
& DDBLT_KEYSRC
) {
1313 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1314 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1316 /* I'm not sure if this is correct */
1317 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1318 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1319 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1323 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1324 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1326 #define COPYROW_COLORKEY(type) { \
1327 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1328 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1329 tmp = s[sx >> 16]; \
1330 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1335 case 1: COPYROW_COLORKEY(BYTE
)
1336 case 2: COPYROW_COLORKEY(WORD
)
1337 case 4: COPYROW_COLORKEY(DWORD
)
1339 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1340 (dwFlags
& DDBLT_KEYSRC
) ? "Source" : "Destination", bpp
*8);
1341 ret
= DDERR_UNSUPPORTED
;
1344 dbuf
+= ddesc
.lPitch
;
1347 #undef COPYROW_COLORKEY
1349 dwFlags
&= ~(DDBLT_KEYSRC
| DDBLT_KEYDEST
);
1356 if (dwFlags
&& FIXME_ON(ddraw
)) {
1357 FIXME("\tUnsupported flags: ");
1358 _dump_DDBLT(dwFlags
);
1362 IDirectDrawSurface4_Unlock(iface
,ddesc
.u1
.lpSurface
);
1363 if (src
) IDirectDrawSurface4_Unlock(src
,sdesc
.u1
.lpSurface
);
1368 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltFast(
1369 LPDIRECTDRAWSURFACE4 iface
,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD trans
1371 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1372 int bpp
, w
, h
, x
, y
;
1373 DDSURFACEDESC ddesc
,sdesc
;
1374 HRESULT ret
= DD_OK
;
1379 if (TRACE_ON(ddraw
)) {
1380 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1381 This
,dstx
,dsty
,src
,rsrc
,trans
1384 if (FIXME_ON(ddraw
))
1385 _dump_DDBLTFAST(trans
);
1387 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1389 FIXME(" srcrect: NULL\n");
1392 /* We need to lock the surfaces, or we won't get refreshes when done. */
1393 IDirectDrawSurface4_Lock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
1394 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
1397 WARN("rsrc is NULL!\n");
1399 rsrc
->left
= rsrc
->top
= 0;
1400 rsrc
->right
= sdesc
.dwWidth
;
1401 rsrc
->bottom
= sdesc
.dwHeight
;
1404 bpp
= GET_BPP(This
->s
.surface_desc
);
1405 sbuf
= (BYTE
*) sdesc
.u1
.lpSurface
+ (rsrc
->top
* sdesc
.lPitch
) + rsrc
->left
* bpp
;
1406 dbuf
= (BYTE
*) ddesc
.u1
.lpSurface
+ (dsty
* ddesc
.lPitch
) + dstx
* bpp
;
1409 h
=rsrc
->bottom
-rsrc
->top
;
1410 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
1411 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
1414 w
=rsrc
->right
-rsrc
->left
;
1415 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
1416 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
1419 if (trans
& (DDBLTFAST_SRCCOLORKEY
| DDBLTFAST_DESTCOLORKEY
)) {
1420 DWORD keylow
, keyhigh
;
1421 if (trans
& DDBLTFAST_SRCCOLORKEY
) {
1422 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1423 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1425 /* I'm not sure if this is correct */
1426 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1427 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1428 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1431 #define COPYBOX_COLORKEY(type) { \
1432 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1433 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1434 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1435 for (y = 0; y < h; y++) { \
1436 for (x = 0; x < w; x++) { \
1438 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1440 (LPBYTE)s += sdesc.lPitch; \
1441 (LPBYTE)d += ddesc.lPitch; \
1447 case 1: COPYBOX_COLORKEY(BYTE
)
1448 case 2: COPYBOX_COLORKEY(WORD
)
1449 case 4: COPYBOX_COLORKEY(DWORD
)
1451 FIXME("Source color key blitting not supported for bpp %d\n", bpp
*8);
1452 ret
= DDERR_UNSUPPORTED
;
1456 #undef COPYBOX_COLORKEY
1459 int width
= w
* bpp
;
1461 for (y
= 0; y
< h
; y
++) {
1462 memcpy(dbuf
, sbuf
, width
);
1463 sbuf
+= sdesc
.lPitch
;
1464 dbuf
+= ddesc
.lPitch
;
1470 IDirectDrawSurface4_Unlock(iface
,ddesc
.u1
.lpSurface
);
1471 IDirectDrawSurface4_Unlock(src
,sdesc
.u1
.lpSurface
);
1475 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltBatch(
1476 LPDIRECTDRAWSURFACE4 iface
,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
1478 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1479 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1485 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetCaps(
1486 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS caps
1488 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1489 TRACE("(%p)->GetCaps(%p)\n",This
,caps
);
1490 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
1494 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetSurfaceDesc(
1495 LPDIRECTDRAWSURFACE4 iface
,LPDDSURFACEDESC ddsd
1497 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1498 TRACE("(%p)->GetSurfaceDesc(%p)\n", This
,ddsd
);
1500 /* Simply copy the surface description stored in the object */
1501 *ddsd
= This
->s
.surface_desc
;
1503 if (TRACE_ON(ddraw
)) { _dump_surface_desc(ddsd
); }
1508 static ULONG WINAPI
IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface
) {
1509 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1510 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
1511 return ++(This
->ref
);
1514 #ifdef HAVE_LIBXXF86DGA
1515 static ULONG WINAPI
DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1516 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1518 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1523 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1524 /* clear out of surface list */
1525 if (This
->t
.dga
.fb_height
== -1)
1526 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1528 This
->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(This
->t
.dga
.fb_height
/This
->s
.ddraw
->e
.dga
.fb_height
));
1530 /* Free the DIBSection (if any) */
1531 if (This
->s
.hdc
!= 0) {
1532 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1533 DeleteDC(This
->s
.hdc
);
1534 DeleteObject(This
->s
.DIBsection
);
1537 /* Free the clipper if attached to this surface */
1538 if( This
->s
.lpClipper
)
1539 IDirectDrawClipper_Release(This
->s
.lpClipper
);
1541 HeapFree(GetProcessHeap(),0,This
);
1544 #endif /* defined(HAVE_LIBXXF86DGA) */
1546 static ULONG WINAPI
Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1547 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1549 TRACE( "(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1554 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1556 if (This
->t
.xlib
.image
!= NULL
) {
1557 if (This
->s
.ddraw
->d
.pixel_convert
!= NULL
) {
1558 /* In pixel conversion mode, there are 2 buffers to release. */
1559 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1561 #ifdef HAVE_LIBXXSHM
1562 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1563 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1564 TSXDestroyImage(This
->t
.xlib
.image
);
1565 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1568 HeapFree(GetProcessHeap(),0,This
->t
.xlib
.image
->data
);
1569 This
->t
.xlib
.image
->data
= NULL
;
1570 TSXDestroyImage(This
->t
.xlib
.image
);
1571 #ifdef HAVE_LIBXXSHM
1575 This
->t
.xlib
.image
->data
= NULL
;
1577 #ifdef HAVE_LIBXXSHM
1578 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1579 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1580 TSXDestroyImage(This
->t
.xlib
.image
);
1581 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1584 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1585 TSXDestroyImage(This
->t
.xlib
.image
);
1586 #ifdef HAVE_LIBXXSHM
1590 This
->t
.xlib
.image
= 0;
1592 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1595 if (This
->s
.palette
)
1596 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
1598 /* Free the DIBSection (if any) */
1599 if (This
->s
.hdc
!= 0) {
1600 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1601 DeleteDC(This
->s
.hdc
);
1602 DeleteObject(This
->s
.DIBsection
);
1605 /* Free the clipper if present */
1606 if( This
->s
.lpClipper
)
1607 IDirectDrawClipper_Release(This
->s
.lpClipper
);
1609 HeapFree(GetProcessHeap(),0,This
);
1613 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetAttachedSurface(
1614 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1616 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1617 int i
,found
= 0,xstart
;
1618 struct _surface_chain
*chain
;
1620 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This
, lpddsd
, lpdsf
);
1621 if (TRACE_ON(ddraw
)) {
1622 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd
->dwCaps
));
1625 chain
= This
->s
.chain
;
1627 return DDERR_NOTFOUND
;
1629 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1630 if (chain
->surfaces
[i
] == This
)
1634 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1635 if ((SDDSCAPS(chain
->surfaces
[(xstart
+i
)%chain
->nrofsurfaces
])&lpddsd
->dwCaps
) == lpddsd
->dwCaps
) {
1637 if (found
) /* may not find the same caps twice, (doc) */
1638 return DDERR_INVALIDPARAMS
;/*FIXME: correct? */
1640 found
= (i
+1)+xstart
;
1644 return DDERR_NOTFOUND
;
1645 *lpdsf
= (LPDIRECTDRAWSURFACE4
)chain
->surfaces
[found
-1-xstart
];
1646 /* FIXME: AddRef? */
1647 TRACE("found %p\n",*lpdsf
);
1651 static HRESULT WINAPI
IDirectDrawSurface4Impl_Initialize(
1652 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1654 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1655 TRACE("(%p)->(%p, %p)\n",This
,ddraw
,lpdsfd
);
1657 return DDERR_ALREADYINITIALIZED
;
1660 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPixelFormat(
1661 LPDIRECTDRAWSURFACE4 iface
,LPDDPIXELFORMAT pf
1663 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1664 TRACE("(%p)->(%p)\n",This
,pf
);
1666 *pf
= This
->s
.surface_desc
.ddpfPixelFormat
;
1667 if (TRACE_ON(ddraw
)) { _dump_pixelformat(pf
); DPRINTF("\n"); }
1671 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface
,DWORD dwFlags
) {
1672 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1673 FIXME("(%p)->(0x%08lx),stub!\n",This
,dwFlags
);
1677 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetOverlayPosition(
1678 LPDIRECTDRAWSURFACE4 iface
,LPLONG x1
,LPLONG x2
1680 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1681 FIXME("(%p)->(%p,%p),stub!\n",This
,x1
,x2
);
1685 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetClipper(
1686 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWCLIPPER lpClipper
1688 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1689 TRACE("(%p)->(%p)!\n",This
,lpClipper
);
1691 if (This
->s
.lpClipper
) IDirectDrawClipper_Release( This
->s
.lpClipper
);
1692 This
->s
.lpClipper
= lpClipper
;
1693 if (lpClipper
) IDirectDrawClipper_AddRef( lpClipper
);
1697 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddAttachedSurface(
1698 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 surf
1700 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1701 IDirectDrawSurface4Impl
*isurf
= (IDirectDrawSurface4Impl
*)surf
;
1703 struct _surface_chain
*chain
;
1705 FIXME("(%p)->(%p)\n",This
,surf
);
1706 chain
= This
->s
.chain
;
1708 /* IDirectDrawSurface4_AddRef(surf); */
1711 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1712 if (chain
->surfaces
[i
] == isurf
)
1713 FIXME("attaching already attached surface %p to %p!\n",iface
,isurf
);
1715 chain
= HeapAlloc(GetProcessHeap(),0,sizeof(*chain
));
1716 chain
->nrofsurfaces
= 1;
1717 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1718 chain
->surfaces
[0] = This
;
1719 This
->s
.chain
= chain
;
1722 if (chain
->surfaces
)
1723 chain
->surfaces
= HeapReAlloc(
1727 sizeof(chain
->surfaces
[0])*(chain
->nrofsurfaces
+1)
1730 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1731 isurf
->s
.chain
= chain
;
1732 chain
->surfaces
[chain
->nrofsurfaces
++] = isurf
;
1736 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface
,HDC
* lphdc
) {
1737 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1742 FIXME("(%p)->GetDC(%p)\n",This
,lphdc
);
1744 /* Creates a DIB Section of the same size / format as the surface */
1745 IDirectDrawSurface4_Lock(iface
,NULL
,&desc
,0,0);
1747 if (This
->s
.hdc
== 0) {
1748 switch (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
) {
1751 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1752 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 3 * sizeof(DWORD
));
1757 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
));
1761 b_info
= (BITMAPINFO
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1762 sizeof(BITMAPINFOHEADER
) + sizeof(RGBQUAD
) * (2 << desc
.ddpfPixelFormat
.u
.dwRGBBitCount
));
1766 b_info
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
1767 b_info
->bmiHeader
.biWidth
= desc
.dwWidth
;
1768 b_info
->bmiHeader
.biHeight
= desc
.dwHeight
;
1769 b_info
->bmiHeader
.biPlanes
= 1;
1770 b_info
->bmiHeader
.biBitCount
= desc
.ddpfPixelFormat
.u
.dwRGBBitCount
;
1772 if ((desc
.ddpfPixelFormat
.u
.dwRGBBitCount
!= 16) &&
1773 (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
!= 32))
1775 b_info
->bmiHeader
.biCompression
= BI_RGB
;
1778 b_info
->bmiHeader
.biCompression
= BI_BITFIELDS
;
1780 b_info
->bmiHeader
.biSizeImage
= (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
/ 8) * desc
.dwWidth
* desc
.dwHeight
;
1781 b_info
->bmiHeader
.biXPelsPerMeter
= 0;
1782 b_info
->bmiHeader
.biYPelsPerMeter
= 0;
1783 b_info
->bmiHeader
.biClrUsed
= 0;
1784 b_info
->bmiHeader
.biClrImportant
= 0;
1786 switch (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
) {
1791 DWORD
*masks
= (DWORD
*) &(b_info
->bmiColors
);
1794 masks
[0] = desc
.ddpfPixelFormat
.u1
.dwRBitMask
;
1795 masks
[1] = desc
.ddpfPixelFormat
.u2
.dwGBitMask
;
1796 masks
[2] = desc
.ddpfPixelFormat
.u3
.dwBBitMask
;
1802 usage
= DIB_RGB_COLORS
;
1808 /* Fill the palette */
1809 usage
= DIB_RGB_COLORS
;
1811 if (This
->s
.palette
== NULL
) {
1812 ERR("Bad palette !!!\n");
1814 RGBQUAD
*rgb
= (RGBQUAD
*) &(b_info
->bmiColors
);
1815 PALETTEENTRY
*pent
= (PALETTEENTRY
*)&(This
->s
.palette
->palents
);
1817 for (i
=0;i
<(1<<desc
.ddpfPixelFormat
.u
.dwRGBBitCount
);i
++) {
1818 rgb
[i
].rgbBlue
= pent
[i
].peBlue
;
1819 rgb
[i
].rgbRed
= pent
[i
].peRed
;
1820 rgb
[i
].rgbGreen
= pent
[i
].peGreen
;
1826 This
->s
.DIBsection
= CreateDIBSection(BeginPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
),
1829 &(This
->s
.bitmap_data
),
1833 EndPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
);
1834 TRACE("DIBSection at : %p\n", This
->s
.bitmap_data
);
1836 /* b_info is not useful anymore */
1837 HeapFree(GetProcessHeap(), 0, b_info
);
1840 This
->s
.hdc
= CreateCompatibleDC(0);
1841 This
->s
.holdbitmap
= SelectObject(This
->s
.hdc
, This
->s
.DIBsection
);
1844 /* Copy our surface in the DIB section */
1845 if ((GET_BPP(desc
) * desc
.dwWidth
) == desc
.lPitch
)
1846 memcpy(This
->s
.bitmap_data
,desc
.u1
.lpSurface
,desc
.lPitch
*desc
.dwHeight
);
1849 FIXME("This case has to be done :/\n");
1851 TRACE("HDC : %08lx\n", (DWORD
) This
->s
.hdc
);
1852 *lphdc
= This
->s
.hdc
;
1857 static HRESULT WINAPI
IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface
,HDC hdc
) {
1858 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1860 FIXME("(%p)->(0x%08lx),stub!\n",This
,(long)hdc
);
1861 TRACE( "Copying DIBSection at : %p\n", This
->s
.bitmap_data
);
1862 /* Copy the DIB section to our surface */
1863 if ((GET_BPP(This
->s
.surface_desc
) * This
->s
.surface_desc
.dwWidth
) == This
->s
.surface_desc
.lPitch
) {
1864 memcpy(This
->s
.surface_desc
.u1
.lpSurface
, This
->s
.bitmap_data
, This
->s
.surface_desc
.lPitch
* This
->s
.surface_desc
.dwHeight
);
1867 FIXME("This case has to be done :/\n");
1869 /* Unlock the surface */
1870 IDirectDrawSurface4_Unlock(iface
,This
->s
.surface_desc
.u1
.lpSurface
);
1874 static HRESULT WINAPI
IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface
,REFIID refiid
,LPVOID
*obj
) {
1875 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1877 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(refiid
),obj
);
1879 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1880 * the same interface. And IUnknown does that too of course.
1882 if ( IsEqualGUID( &IID_IDirectDrawSurface4
, refiid
) ||
1883 IsEqualGUID( &IID_IDirectDrawSurface3
, refiid
) ||
1884 IsEqualGUID( &IID_IDirectDrawSurface2
, refiid
) ||
1885 IsEqualGUID( &IID_IDirectDrawSurface
, refiid
) ||
1886 IsEqualGUID( &IID_IUnknown
, refiid
)
1889 IDirectDrawSurface4_AddRef(iface
);
1891 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj
);
1894 else if ( IsEqualGUID( &IID_IDirect3DTexture2
, refiid
) )
1896 /* Texture interface */
1897 *obj
= d3dtexture2_create(This
);
1898 IDirectDrawSurface4_AddRef(iface
);
1899 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1902 else if ( IsEqualGUID( &IID_IDirect3DTexture
, refiid
) )
1904 /* Texture interface */
1905 *obj
= d3dtexture_create(This
);
1906 IDirectDrawSurface4_AddRef(iface
);
1908 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj
);
1912 else if (is_OpenGL_dx3(refiid
, (IDirectDrawSurfaceImpl
*)This
, (IDirect3DDeviceImpl
**) obj
)) {
1913 /* It is the OpenGL Direct3D Device */
1914 IDirectDrawSurface4_AddRef(iface
);
1915 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj
);
1919 FIXME("(%p):interface for IID %s NOT found!\n",This
,debugstr_guid(refiid
));
1920 return OLE_E_ENUM_NOMORE
;
1923 static HRESULT WINAPI
IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface
) {
1924 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1925 TRACE("(%p)->(), stub!\n",This
);
1926 return DD_OK
; /* hmm */
1929 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface
,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1930 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1932 struct _surface_chain
*chain
= This
->s
.chain
;
1934 TRACE("(%p)->(%p,%p)\n",This
,context
,esfcb
);
1935 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1936 TRACE( "Enumerating attached surface (%p)\n", chain
->surfaces
[i
]);
1937 if (esfcb((LPDIRECTDRAWSURFACE
) chain
->surfaces
[i
], &(chain
->surfaces
[i
]->s
.surface_desc
), context
) == DDENUMRET_CANCEL
)
1938 return DD_OK
; /* FIXME: return value correct? */
1943 static HRESULT WINAPI
IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface
) {
1944 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1945 FIXME("(%p)->(),stub!\n",This
);
1949 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetColorKey(
1950 LPDIRECTDRAWSURFACE4 iface
, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1952 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1953 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,ckey
);
1954 if (TRACE_ON(ddraw
)) {
1955 _dump_colorkeyflag(dwFlags
);
1957 _dump_DDCOLORKEY((void *) ckey
);
1961 /* If this surface was loaded as a texture, call also the texture
1962 SetColorKey callback */
1963 if (This
->s
.texture
) {
1964 This
->s
.SetColorKey_cb(This
->s
.texture
, dwFlags
, ckey
);
1967 if( dwFlags
& DDCKEY_SRCBLT
)
1969 dwFlags
&= ~DDCKEY_SRCBLT
;
1970 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1971 memcpy( &(This
->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1974 if( dwFlags
& DDCKEY_DESTBLT
)
1976 dwFlags
&= ~DDCKEY_DESTBLT
;
1977 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1978 memcpy( &(This
->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1981 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1983 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1984 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1985 memcpy( &(This
->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1988 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1990 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1991 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1992 memcpy( &(This
->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1997 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
2004 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddOverlayDirtyRect(
2005 LPDIRECTDRAWSURFACE4 iface
,
2008 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2009 FIXME("(%p)->(%p),stub!\n",This
,lpRect
);
2014 static HRESULT WINAPI
IDirectDrawSurface4Impl_DeleteAttachedSurface(
2015 LPDIRECTDRAWSURFACE4 iface
,
2017 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
2019 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2021 struct _surface_chain
*chain
;
2023 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,lpDDSAttachedSurface
);
2024 chain
= This
->s
.chain
;
2025 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
2026 if ((IDirectDrawSurface4Impl
*)lpDDSAttachedSurface
==chain
->surfaces
[i
]){
2027 IDirectDrawSurface4_Release(lpDDSAttachedSurface
);
2029 chain
->surfaces
[i
]->s
.chain
= NULL
;
2030 memcpy( chain
->surfaces
+i
,
2031 chain
->surfaces
+(i
+1),
2032 (chain
->nrofsurfaces
-i
-1)*sizeof(chain
->surfaces
[i
])
2034 chain
->surfaces
= HeapReAlloc(
2038 sizeof(chain
->surfaces
[i
])*(chain
->nrofsurfaces
-1)
2040 chain
->nrofsurfaces
--;
2047 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumOverlayZOrders(
2048 LPDIRECTDRAWSURFACE4 iface
,
2051 LPDDENUMSURFACESCALLBACK lpfnCallback
)
2053 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2054 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This
,dwFlags
,
2055 lpContext
, lpfnCallback
);
2060 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetClipper(
2061 LPDIRECTDRAWSURFACE4 iface
,
2062 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
2064 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2065 FIXME("(%p)->(%p),stub!\n", This
, lplpDDClipper
);
2070 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetColorKey(
2071 LPDIRECTDRAWSURFACE4 iface
,
2073 LPDDCOLORKEY lpDDColorKey
)
2075 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2076 TRACE("(%p)->(0x%08lx,%p)\n", This
, dwFlags
, lpDDColorKey
);
2078 if( dwFlags
& DDCKEY_SRCBLT
) {
2079 dwFlags
&= ~DDCKEY_SRCBLT
;
2080 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
2083 if( dwFlags
& DDCKEY_DESTBLT
)
2085 dwFlags
&= ~DDCKEY_DESTBLT
;
2086 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
2089 if( dwFlags
& DDCKEY_SRCOVERLAY
)
2091 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
2092 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
2095 if( dwFlags
& DDCKEY_DESTOVERLAY
)
2097 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
2098 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
2103 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
2109 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetFlipStatus(
2110 LPDIRECTDRAWSURFACE4 iface
,
2113 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2114 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2119 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPalette(
2120 LPDIRECTDRAWSURFACE4 iface
,
2121 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
2123 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2124 TRACE("(%p)->(%p),stub!\n", This
, lplpDDPalette
);
2126 if (This
->s
.palette
!= NULL
) {
2127 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*) This
->s
.palette
);
2129 *lplpDDPalette
= (IDirectDrawPalette
*) This
->s
.palette
;
2132 return DDERR_NOPALETTEATTACHED
;
2136 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetOverlayPosition(
2137 LPDIRECTDRAWSURFACE4 iface
,
2141 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2142 FIXME("(%p)->(%ld,%ld),stub!\n", This
, lX
, lY
);
2147 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlay(
2148 LPDIRECTDRAWSURFACE4 iface
,
2150 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
2153 LPDDOVERLAYFX lpDDOverlayFx
)
2155 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2156 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This
,
2157 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
2162 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayDisplay(
2163 LPDIRECTDRAWSURFACE4 iface
,
2166 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2167 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2172 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2173 LPDIRECTDRAWSURFACE4 iface
,
2175 LPDIRECTDRAWSURFACE4 lpDDSReference
)
2177 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2178 FIXME("(%p)->(0x%08lx,%p),stub!\n", This
, dwFlags
, lpDDSReference
);
2183 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDDInterface(
2184 LPDIRECTDRAWSURFACE4 iface
,
2187 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2188 FIXME("(%p)->(%p),stub!\n", This
, lplpDD
);
2190 /* Not sure about that... */
2191 *lplpDD
= (void *) This
->s
.ddraw
;
2196 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageLock(
2197 LPDIRECTDRAWSURFACE4 iface
,
2200 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2201 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2206 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageUnlock(
2207 LPDIRECTDRAWSURFACE4 iface
,
2210 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2211 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2216 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetSurfaceDesc(
2217 LPDIRECTDRAWSURFACE4 iface
,
2218 LPDDSURFACEDESC lpDDSD
,
2221 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2222 FIXME("(%p)->(%p,0x%08lx),stub!\n", This
, lpDDSD
, dwFlags
);
2227 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2232 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2233 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This
, guidTag
, lpData
, cbSize
, dwFlags
);
2238 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2241 LPDWORD lpcbBufferSize
) {
2242 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2243 FIXME("(%p)->(%p,%p,%p)\n", This
, guidTag
, lpBuffer
, lpcbBufferSize
);
2248 static HRESULT WINAPI
IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface
,
2250 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2251 FIXME("(%p)->(%p)\n", This
, guidTag
);
2256 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface
,
2258 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2259 FIXME("(%p)->(%p)\n", This
, lpValue
);
2264 static HRESULT WINAPI
IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface
) {
2265 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2266 FIXME("(%p)\n", This
);
2271 #ifdef HAVE_LIBXXF86DGA
2272 static ICOM_VTABLE(IDirectDrawSurface4
) dga_dds4vt
=
2274 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2275 IDirectDrawSurface4Impl_QueryInterface
,
2276 IDirectDrawSurface4Impl_AddRef
,
2277 DGA_IDirectDrawSurface4Impl_Release
,
2278 IDirectDrawSurface4Impl_AddAttachedSurface
,
2279 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2280 IDirectDrawSurface4Impl_Blt
,
2281 IDirectDrawSurface4Impl_BltBatch
,
2282 IDirectDrawSurface4Impl_BltFast
,
2283 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2284 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2285 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2286 DGA_IDirectDrawSurface4Impl_Flip
,
2287 IDirectDrawSurface4Impl_GetAttachedSurface
,
2288 IDirectDrawSurface4Impl_GetBltStatus
,
2289 IDirectDrawSurface4Impl_GetCaps
,
2290 IDirectDrawSurface4Impl_GetClipper
,
2291 IDirectDrawSurface4Impl_GetColorKey
,
2292 IDirectDrawSurface4Impl_GetDC
,
2293 IDirectDrawSurface4Impl_GetFlipStatus
,
2294 IDirectDrawSurface4Impl_GetOverlayPosition
,
2295 IDirectDrawSurface4Impl_GetPalette
,
2296 IDirectDrawSurface4Impl_GetPixelFormat
,
2297 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2298 IDirectDrawSurface4Impl_Initialize
,
2299 IDirectDrawSurface4Impl_IsLost
,
2300 IDirectDrawSurface4Impl_Lock
,
2301 IDirectDrawSurface4Impl_ReleaseDC
,
2302 IDirectDrawSurface4Impl_Restore
,
2303 IDirectDrawSurface4Impl_SetClipper
,
2304 IDirectDrawSurface4Impl_SetColorKey
,
2305 IDirectDrawSurface4Impl_SetOverlayPosition
,
2306 DGA_IDirectDrawSurface4Impl_SetPalette
,
2307 DGA_IDirectDrawSurface4Impl_Unlock
,
2308 IDirectDrawSurface4Impl_UpdateOverlay
,
2309 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2310 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2311 IDirectDrawSurface4Impl_GetDDInterface
,
2312 IDirectDrawSurface4Impl_PageLock
,
2313 IDirectDrawSurface4Impl_PageUnlock
,
2314 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2315 IDirectDrawSurface4Impl_SetPrivateData
,
2316 IDirectDrawSurface4Impl_GetPrivateData
,
2317 IDirectDrawSurface4Impl_FreePrivateData
,
2318 IDirectDrawSurface4Impl_GetUniquenessValue
,
2319 IDirectDrawSurface4Impl_ChangeUniquenessValue
2321 #endif /* defined(HAVE_LIBXXF86DGA) */
2323 #ifdef HAVE_LIBXXF86DGA2
2324 static ICOM_VTABLE(IDirectDrawSurface4
) dga2_dds4vt
=
2326 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2327 IDirectDrawSurface4Impl_QueryInterface
,
2328 IDirectDrawSurface4Impl_AddRef
,
2329 DGA_IDirectDrawSurface4Impl_Release
,
2330 IDirectDrawSurface4Impl_AddAttachedSurface
,
2331 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2332 IDirectDrawSurface4Impl_Blt
,
2333 IDirectDrawSurface4Impl_BltBatch
,
2334 IDirectDrawSurface4Impl_BltFast
,
2335 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2336 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2337 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2338 DGA2_IDirectDrawSurface4Impl_Flip
,
2339 IDirectDrawSurface4Impl_GetAttachedSurface
,
2340 IDirectDrawSurface4Impl_GetBltStatus
,
2341 IDirectDrawSurface4Impl_GetCaps
,
2342 IDirectDrawSurface4Impl_GetClipper
,
2343 IDirectDrawSurface4Impl_GetColorKey
,
2344 IDirectDrawSurface4Impl_GetDC
,
2345 IDirectDrawSurface4Impl_GetFlipStatus
,
2346 IDirectDrawSurface4Impl_GetOverlayPosition
,
2347 IDirectDrawSurface4Impl_GetPalette
,
2348 IDirectDrawSurface4Impl_GetPixelFormat
,
2349 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2350 IDirectDrawSurface4Impl_Initialize
,
2351 IDirectDrawSurface4Impl_IsLost
,
2352 IDirectDrawSurface4Impl_Lock
,
2353 IDirectDrawSurface4Impl_ReleaseDC
,
2354 IDirectDrawSurface4Impl_Restore
,
2355 IDirectDrawSurface4Impl_SetClipper
,
2356 IDirectDrawSurface4Impl_SetColorKey
,
2357 IDirectDrawSurface4Impl_SetOverlayPosition
,
2358 DGA_IDirectDrawSurface4Impl_SetPalette
,
2359 DGA_IDirectDrawSurface4Impl_Unlock
,
2360 IDirectDrawSurface4Impl_UpdateOverlay
,
2361 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2362 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2363 IDirectDrawSurface4Impl_GetDDInterface
,
2364 IDirectDrawSurface4Impl_PageLock
,
2365 IDirectDrawSurface4Impl_PageUnlock
,
2366 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2367 IDirectDrawSurface4Impl_SetPrivateData
,
2368 IDirectDrawSurface4Impl_GetPrivateData
,
2369 IDirectDrawSurface4Impl_FreePrivateData
,
2370 IDirectDrawSurface4Impl_GetUniquenessValue
,
2371 IDirectDrawSurface4Impl_ChangeUniquenessValue
2373 #endif /* defined(HAVE_LIBXXF86DGA2) */
2375 static ICOM_VTABLE(IDirectDrawSurface4
) xlib_dds4vt
=
2377 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2378 IDirectDrawSurface4Impl_QueryInterface
,
2379 IDirectDrawSurface4Impl_AddRef
,
2380 Xlib_IDirectDrawSurface4Impl_Release
,
2381 IDirectDrawSurface4Impl_AddAttachedSurface
,
2382 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2383 IDirectDrawSurface4Impl_Blt
,
2384 IDirectDrawSurface4Impl_BltBatch
,
2385 IDirectDrawSurface4Impl_BltFast
,
2386 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2387 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2388 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2389 Xlib_IDirectDrawSurface4Impl_Flip
,
2390 IDirectDrawSurface4Impl_GetAttachedSurface
,
2391 IDirectDrawSurface4Impl_GetBltStatus
,
2392 IDirectDrawSurface4Impl_GetCaps
,
2393 IDirectDrawSurface4Impl_GetClipper
,
2394 IDirectDrawSurface4Impl_GetColorKey
,
2395 IDirectDrawSurface4Impl_GetDC
,
2396 IDirectDrawSurface4Impl_GetFlipStatus
,
2397 IDirectDrawSurface4Impl_GetOverlayPosition
,
2398 IDirectDrawSurface4Impl_GetPalette
,
2399 IDirectDrawSurface4Impl_GetPixelFormat
,
2400 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2401 IDirectDrawSurface4Impl_Initialize
,
2402 IDirectDrawSurface4Impl_IsLost
,
2403 IDirectDrawSurface4Impl_Lock
,
2404 IDirectDrawSurface4Impl_ReleaseDC
,
2405 IDirectDrawSurface4Impl_Restore
,
2406 IDirectDrawSurface4Impl_SetClipper
,
2407 IDirectDrawSurface4Impl_SetColorKey
,
2408 IDirectDrawSurface4Impl_SetOverlayPosition
,
2409 Xlib_IDirectDrawSurface4Impl_SetPalette
,
2410 Xlib_IDirectDrawSurface4Impl_Unlock
,
2411 IDirectDrawSurface4Impl_UpdateOverlay
,
2412 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2413 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2414 IDirectDrawSurface4Impl_GetDDInterface
,
2415 IDirectDrawSurface4Impl_PageLock
,
2416 IDirectDrawSurface4Impl_PageUnlock
,
2417 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2418 IDirectDrawSurface4Impl_SetPrivateData
,
2419 IDirectDrawSurface4Impl_GetPrivateData
,
2420 IDirectDrawSurface4Impl_FreePrivateData
,
2421 IDirectDrawSurface4Impl_GetUniquenessValue
,
2422 IDirectDrawSurface4Impl_ChangeUniquenessValue
2425 /******************************************************************************
2426 * DirectDrawCreateClipper (DDRAW.7)
2428 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
2429 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
2430 LPUNKNOWN pUnkOuter
)
2432 IDirectDrawClipperImpl
** ilplpDDClipper
=(IDirectDrawClipperImpl
**)lplpDDClipper
;
2433 TRACE("(%08lx,%p,%p)\n", dwFlags
, ilplpDDClipper
, pUnkOuter
);
2435 *ilplpDDClipper
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
2436 ICOM_VTBL(*ilplpDDClipper
) = &ddclipvt
;
2437 (*ilplpDDClipper
)->ref
= 1;
2439 (*ilplpDDClipper
)->hWnd
= 0;
2444 /******************************************************************************
2445 * IDirectDrawClipper
2447 static HRESULT WINAPI
IDirectDrawClipperImpl_SetHwnd(
2448 LPDIRECTDRAWCLIPPER iface
, DWORD dwFlags
, HWND hWnd
2450 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2452 TRACE("(%p)->SetHwnd(0x%08lx,0x%08lx)\n",This
,dwFlags
,(DWORD
)hWnd
);
2454 FIXME("dwFlags = 0x%08lx, not supported.\n",dwFlags
);
2455 return DDERR_INVALIDPARAMS
;
2462 static ULONG WINAPI
IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface
) {
2463 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2464 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2469 HeapFree(GetProcessHeap(),0,This
);
2473 static HRESULT WINAPI
IDirectDrawClipperImpl_GetClipList(
2474 LPDIRECTDRAWCLIPPER iface
,LPRECT rects
,LPRGNDATA lprgn
,LPDWORD hmm
2476 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2477 FIXME("(%p,%p,%p,%p),stub!\n",This
,rects
,lprgn
,hmm
);
2482 static HRESULT WINAPI
IDirectDrawClipperImpl_SetClipList(
2483 LPDIRECTDRAWCLIPPER iface
,LPRGNDATA lprgn
,DWORD hmm
2485 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2486 FIXME("(%p,%p,%ld),stub!\n",This
,lprgn
,hmm
);
2490 static HRESULT WINAPI
IDirectDrawClipperImpl_QueryInterface(
2491 LPDIRECTDRAWCLIPPER iface
,
2495 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2496 FIXME("(%p)->(%p,%p),stub!\n",This
,riid
,ppvObj
);
2497 return OLE_E_ENUM_NOMORE
;
2500 static ULONG WINAPI
IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface
)
2502 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2503 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2504 return ++(This
->ref
);
2507 static HRESULT WINAPI
IDirectDrawClipperImpl_GetHWnd(
2508 LPDIRECTDRAWCLIPPER iface
,
2511 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2512 FIXME("(%p)->(%p),stub!\n",This
,hWndPtr
);
2514 *hWndPtr
= This
->hWnd
;
2519 static HRESULT WINAPI
IDirectDrawClipperImpl_Initialize(
2520 LPDIRECTDRAWCLIPPER iface
,
2524 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2525 FIXME("(%p)->(%p,0x%08lx),stub!\n",This
,lpDD
,dwFlags
);
2529 static HRESULT WINAPI
IDirectDrawClipperImpl_IsClipListChanged(
2530 LPDIRECTDRAWCLIPPER iface
,
2533 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2534 FIXME("(%p)->(%p),stub!\n",This
,lpbChanged
);
2538 static ICOM_VTABLE(IDirectDrawClipper
) ddclipvt
=
2540 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2541 IDirectDrawClipperImpl_QueryInterface
,
2542 IDirectDrawClipperImpl_AddRef
,
2543 IDirectDrawClipperImpl_Release
,
2544 IDirectDrawClipperImpl_GetClipList
,
2545 IDirectDrawClipperImpl_GetHWnd
,
2546 IDirectDrawClipperImpl_Initialize
,
2547 IDirectDrawClipperImpl_IsClipListChanged
,
2548 IDirectDrawClipperImpl_SetClipList
,
2549 IDirectDrawClipperImpl_SetHwnd
2553 /******************************************************************************
2554 * IDirectDrawPalette
2556 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetEntries(
2557 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2559 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2562 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2563 This
,x
,start
,count
,palent
);
2565 /* No palette created and not in depth-convertion mode -> BUG ! */
2566 if ((This
->cm
== None
) &&
2567 (This
->ddraw
->d
.palette_convert
== NULL
))
2569 FIXME("app tried to read colormap for non-palettized mode\n");
2570 return DDERR_GENERIC
;
2572 for (i
=0;i
<count
;i
++) {
2573 palent
[i
].peRed
= This
->palents
[start
+i
].peRed
;
2574 palent
[i
].peBlue
= This
->palents
[start
+i
].peBlue
;
2575 palent
[i
].peGreen
= This
->palents
[start
+i
].peGreen
;
2576 palent
[i
].peFlags
= This
->palents
[start
+i
].peFlags
;
2582 static HRESULT WINAPI
Xlib_IDirectDrawPaletteImpl_SetEntries(
2583 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2585 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2589 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2590 This
,x
,start
,count
,palent
2592 for (i
=0;i
<count
;i
++) {
2593 xc
.red
= palent
[i
].peRed
<<8;
2594 xc
.blue
= palent
[i
].peBlue
<<8;
2595 xc
.green
= palent
[i
].peGreen
<<8;
2596 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2600 TSXStoreColor(display
,This
->cm
,&xc
);
2602 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2603 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2604 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2605 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2608 /* Now, if we are in 'depth conversion mode', update the screen palette */
2609 /* FIXME: we need to update the image or we won't get palette fading. */
2610 if (This
->ddraw
->d
.palette_convert
!= NULL
)
2611 This
->ddraw
->d
.palette_convert(palent
, This
->screen_palents
, start
, count
);
2616 #ifdef HAVE_LIBXXF86DGA
2617 static HRESULT WINAPI
DGA_IDirectDrawPaletteImpl_SetEntries(
2618 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2620 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2625 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2626 This
,x
,start
,count
,palent
2628 if (!This
->cm
) /* should not happen */ {
2629 FIXME("app tried to set colormap in non-palettized mode\n");
2630 return DDERR_GENERIC
;
2632 /* FIXME: free colorcells instead of freeing whole map */
2634 This
->cm
= TSXCopyColormapAndFree(display
,This
->cm
);
2635 TSXFreeColormap(display
,cm
);
2637 for (i
=0;i
<count
;i
++) {
2638 xc
.red
= palent
[i
].peRed
<<8;
2639 xc
.blue
= palent
[i
].peBlue
<<8;
2640 xc
.green
= palent
[i
].peGreen
<<8;
2641 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2644 TSXStoreColor(display
,This
->cm
,&xc
);
2646 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2647 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2648 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2649 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2651 #ifdef HAVE_LIBXXF86DGA2
2652 if (This
->ddraw
->e
.dga
.version
== 2)
2653 TSXDGAInstallColormap(display
,DefaultScreen(display
),This
->cm
);
2655 #endif /* defined(HAVE_LIBXXF86DGA2) */
2656 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->cm
);
2659 #endif /* defined(HAVE_LIBXXF86DGA) */
2661 static ULONG WINAPI
IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface
) {
2662 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2663 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2664 if (!--(This
->ref
)) {
2666 TSXFreeColormap(display
,This
->cm
);
2669 HeapFree(GetProcessHeap(),0,This
);
2675 static ULONG WINAPI
IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface
) {
2676 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2678 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2679 return ++(This
->ref
);
2682 static HRESULT WINAPI
IDirectDrawPaletteImpl_Initialize(
2683 LPDIRECTDRAWPALETTE iface
,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
2685 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2686 TRACE("(%p)->(%p,%ld,%p)\n", This
, ddraw
, x
, palent
);
2688 return DDERR_ALREADYINITIALIZED
;
2691 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetCaps(
2692 LPDIRECTDRAWPALETTE iface
, LPDWORD lpdwCaps
)
2694 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2695 FIXME("(%p)->(%p) stub.\n", This
, lpdwCaps
);
2699 static HRESULT WINAPI
IDirectDrawPaletteImpl_QueryInterface(
2700 LPDIRECTDRAWPALETTE iface
,REFIID refiid
,LPVOID
*obj
)
2702 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2704 FIXME("(%p)->(%s,%p) stub.\n",This
,debugstr_guid(refiid
),obj
);
2709 #ifdef HAVE_LIBXXF86DGA
2710 static ICOM_VTABLE(IDirectDrawPalette
) dga_ddpalvt
=
2712 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2713 IDirectDrawPaletteImpl_QueryInterface
,
2714 IDirectDrawPaletteImpl_AddRef
,
2715 IDirectDrawPaletteImpl_Release
,
2716 IDirectDrawPaletteImpl_GetCaps
,
2717 IDirectDrawPaletteImpl_GetEntries
,
2718 IDirectDrawPaletteImpl_Initialize
,
2719 DGA_IDirectDrawPaletteImpl_SetEntries
2721 #endif /* defined(HAVE_LIBXXF86DGA) */
2723 static ICOM_VTABLE(IDirectDrawPalette
) xlib_ddpalvt
=
2725 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2726 IDirectDrawPaletteImpl_QueryInterface
,
2727 IDirectDrawPaletteImpl_AddRef
,
2728 IDirectDrawPaletteImpl_Release
,
2729 IDirectDrawPaletteImpl_GetCaps
,
2730 IDirectDrawPaletteImpl_GetEntries
,
2731 IDirectDrawPaletteImpl_Initialize
,
2732 Xlib_IDirectDrawPaletteImpl_SetEntries
2735 /*******************************************************************************
2738 static HRESULT WINAPI
IDirect3DImpl_QueryInterface(
2739 LPDIRECT3D iface
,REFIID refiid
,LPVOID
*obj
2741 ICOM_THIS(IDirect3DImpl
,iface
);
2742 /* FIXME: Not sure if this is correct */
2744 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(refiid
),obj
);
2745 if ( ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) ||
2746 ( IsEqualGUID (&IID_IDirectDraw2
, refiid
) ) ||
2747 ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) ) {
2749 IDirect3D_AddRef(iface
);
2751 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2755 if ( ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) ||
2756 ( IsEqualGUID( &IID_IUnknown
, refiid
) ) ) {
2758 IDirect3D_AddRef(iface
);
2760 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2764 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
2765 IDirect3D2Impl
* d3d
;
2767 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2769 d3d
->ddraw
= This
->ddraw
;
2770 IDirect3D_AddRef(iface
);
2771 ICOM_VTBL(d3d
) = &d3d2vt
;
2774 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2778 FIXME("(%p):interface for IID %s NOT found!\n",This
,debugstr_guid(refiid
));
2779 return OLE_E_ENUM_NOMORE
;
2782 static ULONG WINAPI
IDirect3DImpl_AddRef(LPDIRECT3D iface
) {
2783 ICOM_THIS(IDirect3DImpl
,iface
);
2784 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2786 return ++(This
->ref
);
2789 static ULONG WINAPI
IDirect3DImpl_Release(LPDIRECT3D iface
)
2791 ICOM_THIS(IDirect3DImpl
,iface
);
2792 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2794 if (!--(This
->ref
)) {
2795 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2796 HeapFree(GetProcessHeap(),0,This
);
2802 static HRESULT WINAPI
IDirect3DImpl_Initialize(
2803 LPDIRECT3D iface
, REFIID refiid
)
2805 ICOM_THIS(IDirect3DImpl
,iface
);
2806 /* FIXME: Not sure if this is correct */
2808 FIXME("(%p)->(%s):stub.\n",This
,debugstr_guid(refiid
));
2810 return DDERR_ALREADYINITIALIZED
;
2813 static HRESULT WINAPI
IDirect3DImpl_EnumDevices(LPDIRECT3D iface
,
2814 LPD3DENUMDEVICESCALLBACK cb
,
2816 ICOM_THIS(IDirect3DImpl
,iface
);
2817 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2819 /* Call functions defined in d3ddevices.c */
2820 if (!d3d_OpenGL_dx3(cb
, context
))
2826 static HRESULT WINAPI
IDirect3DImpl_CreateLight(LPDIRECT3D iface
,
2827 LPDIRECT3DLIGHT
*lplight
,
2830 ICOM_THIS(IDirect3DImpl
,iface
);
2831 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2833 /* Call the creation function that is located in d3dlight.c */
2834 *lplight
= d3dlight_create_dx3(This
);
2839 static HRESULT WINAPI
IDirect3DImpl_CreateMaterial(LPDIRECT3D iface
,
2840 LPDIRECT3DMATERIAL
*lpmaterial
,
2843 ICOM_THIS(IDirect3DImpl
,iface
);
2844 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2846 /* Call the creation function that is located in d3dviewport.c */
2847 *lpmaterial
= d3dmaterial_create(This
);
2852 static HRESULT WINAPI
IDirect3DImpl_CreateViewport(LPDIRECT3D iface
,
2853 LPDIRECT3DVIEWPORT
*lpviewport
,
2856 ICOM_THIS(IDirect3DImpl
,iface
);
2857 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
2859 /* Call the creation function that is located in d3dviewport.c */
2860 *lpviewport
= d3dviewport_create(This
);
2865 static HRESULT WINAPI
IDirect3DImpl_FindDevice(LPDIRECT3D iface
,
2866 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2867 LPD3DFINDDEVICERESULT lpfinddevrst
)
2869 ICOM_THIS(IDirect3DImpl
,iface
);
2870 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
2875 static ICOM_VTABLE(IDirect3D
) d3dvt
=
2877 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2878 IDirect3DImpl_QueryInterface
,
2879 IDirect3DImpl_AddRef
,
2880 IDirect3DImpl_Release
,
2881 IDirect3DImpl_Initialize
,
2882 IDirect3DImpl_EnumDevices
,
2883 IDirect3DImpl_CreateLight
,
2884 IDirect3DImpl_CreateMaterial
,
2885 IDirect3DImpl_CreateViewport
,
2886 IDirect3DImpl_FindDevice
2889 /*******************************************************************************
2892 static HRESULT WINAPI
IDirect3D2Impl_QueryInterface(
2893 LPDIRECT3D2 iface
,REFIID refiid
,LPVOID
*obj
) {
2894 ICOM_THIS(IDirect3D2Impl
,iface
);
2896 /* FIXME: Not sure if this is correct */
2898 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(refiid
),obj
);
2899 if ( ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) ||
2900 ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) ||
2901 ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) ) {
2903 IDirect3D2_AddRef(iface
);
2905 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2909 if ( ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) ||
2910 ( IsEqualGUID( &IID_IUnknown
, refiid
) ) ) {
2912 IDirect3D2_AddRef(iface
);
2914 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2918 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
2921 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2923 d3d
->ddraw
= This
->ddraw
;
2924 IDirect3D2_AddRef(iface
);
2925 ICOM_VTBL(d3d
) = &d3dvt
;
2928 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2932 FIXME("(%p):interface for IID %s NOT found!\n",This
,debugstr_guid(refiid
));
2933 return OLE_E_ENUM_NOMORE
;
2936 static ULONG WINAPI
IDirect3D2Impl_AddRef(LPDIRECT3D2 iface
) {
2937 ICOM_THIS(IDirect3D2Impl
,iface
);
2938 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2940 return ++(This
->ref
);
2943 static ULONG WINAPI
IDirect3D2Impl_Release(LPDIRECT3D2 iface
) {
2944 ICOM_THIS(IDirect3D2Impl
,iface
);
2945 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2947 if (!--(This
->ref
)) {
2948 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2949 HeapFree(GetProcessHeap(),0,This
);
2955 static HRESULT WINAPI
IDirect3D2Impl_EnumDevices(
2956 LPDIRECT3D2 iface
,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2958 ICOM_THIS(IDirect3D2Impl
,iface
);
2959 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2961 /* Call functions defined in d3ddevices.c */
2962 if (!d3d_OpenGL(cb
, context
))
2968 static HRESULT WINAPI
IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface
,
2969 LPDIRECT3DLIGHT
*lplight
,
2972 ICOM_THIS(IDirect3D2Impl
,iface
);
2973 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2975 /* Call the creation function that is located in d3dlight.c */
2976 *lplight
= d3dlight_create(This
);
2981 static HRESULT WINAPI
IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface
,
2982 LPDIRECT3DMATERIAL2
*lpmaterial
,
2985 ICOM_THIS(IDirect3D2Impl
,iface
);
2986 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2988 /* Call the creation function that is located in d3dviewport.c */
2989 *lpmaterial
= d3dmaterial2_create(This
);
2994 static HRESULT WINAPI
IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface
,
2995 LPDIRECT3DVIEWPORT2
*lpviewport
,
2998 ICOM_THIS(IDirect3D2Impl
,iface
);
2999 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
3001 /* Call the creation function that is located in d3dviewport.c */
3002 *lpviewport
= d3dviewport2_create(This
);
3007 static HRESULT WINAPI
IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface
,
3008 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
3009 LPD3DFINDDEVICERESULT lpfinddevrst
)
3011 ICOM_THIS(IDirect3D2Impl
,iface
);
3012 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
3017 static HRESULT WINAPI
IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface
,
3019 LPDIRECTDRAWSURFACE surface
,
3020 LPDIRECT3DDEVICE2
*device
)
3022 ICOM_THIS(IDirect3D2Impl
,iface
);
3024 FIXME("(%p)->(%s,%p,%p): stub\n",This
,debugstr_guid(rguid
),surface
,device
);
3026 if (is_OpenGL(rguid
, (IDirectDrawSurfaceImpl
*)surface
, (IDirect3DDevice2Impl
**)device
, This
)) {
3027 IDirect3D2_AddRef(iface
);
3031 return DDERR_INVALIDPARAMS
;
3034 static ICOM_VTABLE(IDirect3D2
) d3d2vt
=
3036 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
3037 IDirect3D2Impl_QueryInterface
,
3038 IDirect3D2Impl_AddRef
,
3039 IDirect3D2Impl_Release
,
3040 IDirect3D2Impl_EnumDevices
,
3041 IDirect3D2Impl_CreateLight
,
3042 IDirect3D2Impl_CreateMaterial
,
3043 IDirect3D2Impl_CreateViewport
,
3044 IDirect3D2Impl_FindDevice
,
3045 IDirect3D2Impl_CreateDevice
3048 /*******************************************************************************
3052 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
3053 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
3055 static HRESULT
common_off_screen_CreateSurface(IDirectDraw2Impl
* This
,
3056 IDirectDrawSurfaceImpl
* lpdsf
)
3060 /* The surface was already allocated when entering in this function */
3061 TRACE("using system memory for a surface (%p) \n", lpdsf
);
3063 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
3064 /* This is a Z Buffer */
3065 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf
->s
.surface_desc
.u
.dwZBufferBitDepth
);
3066 bpp
= lpdsf
->s
.surface_desc
.u
.dwZBufferBitDepth
/ 8;
3068 /* This is a standard image */
3069 if (!(lpdsf
->s
.surface_desc
.dwFlags
& DDSD_PIXELFORMAT
)) {
3070 /* No pixel format => use DirectDraw's format */
3071 lpdsf
->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
3072 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
3074 bpp
= GET_BPP(lpdsf
->s
.surface_desc
);
3077 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_LPSURFACE
) {
3078 /* The surface was preallocated : seems that we have nothing to do :-) */
3079 ERR("Creates a surface that is already allocated : assuming this is an application bug !\n");
3083 FIXME("using w=%ld, h=%ld, bpp=%d\n",lpdsf
->s
.surface_desc
.dwWidth
,lpdsf
->s
.surface_desc
.dwHeight
,bpp
);
3085 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PITCH
|DDSD_LPSURFACE
;
3086 lpdsf
->s
.surface_desc
.u1
.lpSurface
=
3087 (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpdsf
->s
.surface_desc
.dwWidth
* lpdsf
->s
.surface_desc
.dwHeight
* bpp
);
3088 lpdsf
->s
.surface_desc
.lPitch
= lpdsf
->s
.surface_desc
.dwWidth
* bpp
;
3093 #ifdef HAVE_LIBXXF86DGA
3094 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreateSurface(
3095 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
3097 ICOM_THIS(IDirectDraw2Impl
,iface
);
3098 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
3099 int i
, fbheight
= This
->e
.dga
.fb_height
;
3101 TRACE("(%p)->(%p,%p,%p)\n",This
,lpddsd
,ilpdsf
,lpunk
);
3102 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
3104 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
3107 sizeof(IDirectDrawSurfaceImpl
)
3109 IDirectDraw2_AddRef(iface
);
3112 #ifdef HAVE_LIBXXF86DGA2
3113 if (This
->e
.dga
.version
== 2)
3114 ICOM_VTBL(*ilpdsf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&dga2_dds4vt
;
3116 #endif /* defined(HAVE_LIBXXF86DGA2) */
3117 ICOM_VTBL(*ilpdsf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&dga_dds4vt
;
3118 (*ilpdsf
)->s
.ddraw
= This
;
3119 (*ilpdsf
)->s
.palette
= NULL
;
3120 (*ilpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
3121 (*ilpdsf
)->s
.lpClipper
= NULL
;
3123 /* Copy the surface description */
3124 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
3126 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
3127 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3128 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
3129 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3131 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
3133 /* Check if this a 'primary surface' or not */
3134 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
3135 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
3136 /* This is THE primary surface => there is DGA-specific code */
3138 /* First, store the surface description */
3139 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
3141 /* Find a viewport */
3143 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
3145 TRACE("using viewport %d for a primary surface\n",i
);
3146 /* if i == 32 or maximum ... return error */
3147 This
->e
.dga
.vpmask
|=(1<<i
);
3148 lpddsd
->lPitch
= (*ilpdsf
)->s
.surface_desc
.lPitch
=
3149 This
->e
.dga
.fb_width
*PFGET_BPP(This
->d
.directdraw_pixelformat
);
3151 (*ilpdsf
)->s
.surface_desc
.u1
.lpSurface
=
3152 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
3154 (*ilpdsf
)->t
.dga
.fb_height
= i
*fbheight
;
3156 /* Add flags if there were not present */
3157 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
3158 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3159 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3160 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This
->d
.width
,This
->d
.height
,lpddsd
->lPitch
);
3161 /* We put our surface always in video memory */
3162 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
3163 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
3164 (*ilpdsf
)->s
.chain
= NULL
;
3166 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
3167 IDirectDrawSurface4Impl
* back
;
3170 for (bbc
=lpddsd
->dwBackBufferCount
;bbc
--;) {
3173 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
3176 sizeof(IDirectDrawSurface4Impl
)
3178 IDirectDraw2_AddRef(iface
);
3180 ICOM_VTBL(back
) = (ICOM_VTABLE(IDirectDrawSurface4
)*)&dga_dds4vt
;
3182 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
3184 TRACE("using viewport %d for backbuffer %d\n",i
, bbc
);
3185 /* if i == 32 or maximum ... return error */
3186 This
->e
.dga
.vpmask
|=(1<<i
);
3187 back
->t
.dga
.fb_height
= i
*fbheight
;
3188 /* Copy the surface description from the front buffer */
3189 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
3190 /* Change the parameters that are not the same */
3191 back
->s
.surface_desc
.u1
.lpSurface
=
3192 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
3194 back
->s
.ddraw
= This
;
3195 /* Add relevant info to front and back buffers */
3196 /* FIXME: backbuffer/frontbuffer handling broken here, but
3197 * will be fixed up in _Flip().
3199 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
3200 SDDSCAPS(back
) |= DDSCAPS_FLIP
|DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
;
3201 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
3202 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
3203 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
3207 /* There is no DGA-specific code here...
3208 Go to the common surface creation function */
3209 return common_off_screen_CreateSurface(This
, *ilpdsf
);
3213 #endif /* defined(HAVE_LIBXXF86DGA) */
3215 #ifdef HAVE_LIBXXSHM
3216 /* Error handlers for Image creation */
3217 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
3222 static XImage
*create_xshmimage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
3224 int (*WineXHandler
)(Display
*, XErrorEvent
*);
3226 img
= TSXShmCreateImage(display
,
3227 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3228 This
->d
.pixmap_depth
,
3231 &(lpdsf
->t
.xlib
.shminfo
),
3232 lpdsf
->s
.surface_desc
.dwWidth
,
3233 lpdsf
->s
.surface_desc
.dwHeight
3237 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3238 This
->e
.xlib
.xshm_active
= 0;
3242 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
3243 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
3244 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3245 This
->e
.xlib
.xshm_active
= 0;
3246 TSXDestroyImage(img
);
3250 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
3252 if (img
->data
== (char *) -1) {
3253 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3254 This
->e
.xlib
.xshm_active
= 0;
3255 TSXDestroyImage(img
);
3256 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3259 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
3261 /* This is where things start to get trickier....
3262 * First, we flush the current X connections to be sure to catch all
3263 * non-XShm related errors
3265 TSXSync(display
, False
);
3266 /* Then we enter in the non-thread safe part of the tests */
3267 EnterCriticalSection( &X11DRV_CritSection
);
3269 /* Reset the error flag, sets our new error handler and try to attach
3273 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3274 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
3275 XSync(display
, False
);
3277 /* Check the error flag */
3278 if (XShmErrorFlag
) {
3279 /* An error occured */
3283 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
3284 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3285 XSetErrorHandler(WineXHandler
);
3287 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3288 This
->e
.xlib
.xshm_active
= 0;
3290 /* Leave the critical section */
3291 LeaveCriticalSection( &X11DRV_CritSection
);
3294 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3295 * this works, but it may be a bit overkill....
3297 XSetErrorHandler(WineXHandler
);
3298 LeaveCriticalSection( &X11DRV_CritSection
);
3300 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3302 if (This
->d
.pixel_convert
!= NULL
) {
3303 lpdsf
->s
.surface_desc
.u1
.lpSurface
= HeapAlloc(
3306 lpdsf
->s
.surface_desc
.dwWidth
*
3307 lpdsf
->s
.surface_desc
.dwHeight
*
3308 PFGET_BPP(This
->d
.directdraw_pixelformat
)
3311 lpdsf
->s
.surface_desc
.u1
.lpSurface
= img
->data
;
3315 #endif /* HAVE_LIBXXSHM */
3317 static XImage
*create_ximage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
3321 #ifdef HAVE_LIBXXSHM
3322 if (This
->e
.xlib
.xshm_active
)
3323 img
= create_xshmimage(This
, lpdsf
);
3327 /* Allocate surface memory */
3328 lpdsf
->s
.surface_desc
.u1
.lpSurface
= HeapAlloc(
3329 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3330 lpdsf
->s
.surface_desc
.dwWidth
*
3331 lpdsf
->s
.surface_desc
.dwHeight
*
3332 PFGET_BPP(This
->d
.directdraw_pixelformat
)
3335 if (This
->d
.pixel_convert
!= NULL
) {
3336 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
3337 lpdsf
->s
.surface_desc
.dwWidth
*
3338 lpdsf
->s
.surface_desc
.dwHeight
*
3339 PFGET_BPP(This
->d
.screen_pixelformat
)
3342 img_data
= lpdsf
->s
.surface_desc
.u1
.lpSurface
;
3345 /* In this case, create an XImage */
3346 img
= TSXCreateImage(display
,
3347 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3348 This
->d
.pixmap_depth
,
3352 lpdsf
->s
.surface_desc
.dwWidth
,
3353 lpdsf
->s
.surface_desc
.dwHeight
,
3355 lpdsf
->s
.surface_desc
.dwWidth
* PFGET_BPP(This
->d
.screen_pixelformat
)
3357 #ifdef HAVE_LIBXXSHM
3360 if (This
->d
.pixel_convert
!= NULL
)
3361 lpdsf
->s
.surface_desc
.lPitch
= PFGET_BPP(This
->d
.directdraw_pixelformat
) * lpdsf
->s
.surface_desc
.dwWidth
;
3363 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
3367 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreateSurface(
3368 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
3370 ICOM_THIS(IDirectDraw2Impl
,iface
);
3371 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
3373 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This
,lpddsd
,ilpdsf
,lpunk
);
3375 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
3377 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
3378 GetProcessHeap(),HEAP_ZERO_MEMORY
, sizeof(IDirectDrawSurfaceImpl
)
3381 IDirectDraw2_AddRef(iface
);
3383 (*ilpdsf
)->s
.ddraw
= This
;
3385 ICOM_VTBL(*ilpdsf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&xlib_dds4vt
;
3386 (*ilpdsf
)->s
.palette
= NULL
;
3387 (*ilpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
3388 (*ilpdsf
)->s
.lpClipper
= NULL
;
3390 /* Copy the surface description */
3391 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
3393 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
3394 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3395 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
3396 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3397 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
3399 /* Check if this a 'primary surface' or not */
3400 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
3401 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
3404 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf
);
3405 /* Create the XImage */
3406 img
= create_ximage(This
, (IDirectDrawSurface4Impl
*) *ilpdsf
);
3408 return DDERR_OUTOFMEMORY
;
3409 (*ilpdsf
)->t
.xlib
.image
= img
;
3411 /* Add flags if there were not present */
3412 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
3413 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3414 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3415 (*ilpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
3416 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
3418 /* Check for backbuffers */
3419 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
3420 IDirectDrawSurface4Impl
* back
;
3424 for (i
=lpddsd
->dwBackBufferCount
;i
--;) {
3425 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
3426 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3427 sizeof(IDirectDrawSurface4Impl
)
3430 TRACE("allocated back-buffer (%p)\n", back
);
3432 IDirectDraw2_AddRef(iface
);
3433 back
->s
.ddraw
= This
;
3436 ICOM_VTBL(back
) = (ICOM_VTABLE(IDirectDrawSurface4
)*)&xlib_dds4vt
;
3437 /* Copy the surface description from the front buffer */
3438 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
3440 /* Create the XImage */
3441 img
= create_ximage(This
, back
);
3443 return DDERR_OUTOFMEMORY
;
3444 back
->t
.xlib
.image
= img
;
3446 /* Add relevant info to front and back buffers */
3447 /* FIXME: backbuffer/frontbuffer handling broken here, but
3448 * will be fixed up in _Flip().
3450 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
3451 SDDSCAPS(back
) |= DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
|DDSCAPS_FLIP
;
3452 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
3453 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
3454 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
3458 /* There is no Xlib-specific code here...
3459 Go to the common surface creation function */
3460 return common_off_screen_CreateSurface(This
, *ilpdsf
);
3465 static HRESULT WINAPI
IDirectDraw2Impl_DuplicateSurface(
3466 LPDIRECTDRAW2 iface
,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
3468 ICOM_THIS(IDirectDraw2Impl
,iface
);
3469 FIXME("(%p)->(%p,%p) simply copies\n",This
,src
,dst
);
3470 *dst
= src
; /* FIXME */
3475 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3476 * even when the approbiate bitmasks are not specified.
3478 static HRESULT WINAPI
IDirectDraw2Impl_SetCooperativeLevel(
3479 LPDIRECTDRAW2 iface
,HWND hwnd
,DWORD cooplevel
3481 ICOM_THIS(IDirectDraw2Impl
,iface
);
3487 #define FE(x) { x, #x},
3488 FE(DDSCL_FULLSCREEN
)
3489 FE(DDSCL_ALLOWREBOOT
)
3490 FE(DDSCL_NOWINDOWCHANGES
)
3492 FE(DDSCL_ALLOWMODEX
)
3494 FE(DDSCL_SETFOCUSWINDOW
)
3495 FE(DDSCL_SETDEVICEWINDOW
)
3496 FE(DDSCL_CREATEDEVICEWINDOW
)
3500 FIXME("(%p)->(%08lx,%08lx)\n",This
,(DWORD
)hwnd
,cooplevel
);
3501 if (TRACE_ON(ddraw
)) {
3503 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++) {
3504 if (flags
[i
].mask
& cooplevel
) {
3505 DPRINTF("%s ",flags
[i
].name
);
3510 This
->d
.mainWindow
= hwnd
;
3512 /* This will be overwritten in the case of Full Screen mode.
3513 Windowed games could work with that :-) */
3516 WND
*tmpWnd
= WIN_FindWndPtr(hwnd
);
3517 This
->d
.drawable
= X11DRV_WND_GetXWindow(tmpWnd
);
3518 WIN_ReleaseWndPtr(tmpWnd
);
3520 if( !This
->d
.drawable
) {
3521 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
3522 WIN_ReleaseDesktop();
3524 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
3530 #ifdef HAVE_LIBXXF86DGA2
3531 static HRESULT WINAPI
DGA_IDirectDraw2Impl_SetCooperativeLevel(
3532 LPDIRECTDRAW2 iface
,HWND hwnd
,DWORD cooplevel
3534 ICOM_THIS(IDirectDraw2Impl
,iface
);
3538 ret
= IDirectDraw2Impl_SetCooperativeLevel(iface
, hwnd
, cooplevel
);
3540 if (This
->e
.dga
.version
!= 2) {
3546 TSXDGAQueryExtension(display
, &evbase
, &erbase
);
3548 /* Now, start handling of DGA events giving the handle to the DDraw window
3549 as the window for which the event will be reported */
3550 TSXDGASelectInput(display
, DefaultScreen(display
),
3551 KeyPressMask
|KeyReleaseMask
|ButtonPressMask
|ButtonReleaseMask
|PointerMotionMask
);
3552 X11DRV_EVENT_SetDGAStatus(hwnd
, evbase
);
3559 /* Small helper to either use the cooperative window or create a new
3560 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3562 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl
* This
) {
3565 /* Do destroy only our window */
3566 if (This
->d
.window
&& GetPropA(This
->d
.window
,ddProp
)) {
3567 DestroyWindow(This
->d
.window
);
3570 /* Sanity check cooperative window before assigning it to drawing. */
3571 if ( IsWindow(This
->d
.mainWindow
) &&
3572 IsWindowVisible(This
->d
.mainWindow
)
3574 /* if it does not fit, resize the cooperative window.
3575 * and hope the app likes it
3577 GetWindowRect(This
->d
.mainWindow
,&rect
);
3578 if ((((rect
.right
-rect
.left
) >= This
->d
.width
) &&
3579 ((rect
.bottom
-rect
.top
) >= This
->d
.height
))
3581 This
->d
.window
= This
->d
.mainWindow
;
3582 /* SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOOWNERZORDER); */
3583 This
->d
.paintable
= 1;
3586 /* ... failed, create new one. */
3587 if (!This
->d
.window
) {
3588 This
->d
.window
= CreateWindowExA(
3592 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
3601 /*Store THIS with the window. We'll use it in the window procedure*/
3602 SetPropA(This
->d
.window
,ddProp
,(LONG
)This
);
3603 ShowWindow(This
->d
.window
,TRUE
);
3604 UpdateWindow(This
->d
.window
);
3606 SetFocus(This
->d
.window
);
3609 static int _common_depth_to_pixelformat(DWORD depth
,
3610 DDPIXELFORMAT
*pixelformat
,
3611 DDPIXELFORMAT
*screen_pixelformat
,
3614 XPixmapFormatValues
*pf
;
3616 int nvisuals
, npixmap
, i
;
3620 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
3621 pf
= XListPixmapFormats(display
, &npixmap
);
3623 for (i
= 0; i
< npixmap
; i
++) {
3624 if (pf
[i
].depth
== depth
) {
3627 for (j
= 0; j
< nvisuals
; j
++) {
3628 if (vi
[j
].depth
== pf
[i
].depth
) {
3629 pixelformat
->dwSize
= sizeof(*pixelformat
);
3631 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
|DDPF_RGB
;
3632 pixelformat
->u1
.dwRBitMask
= 0;
3633 pixelformat
->u2
.dwGBitMask
= 0;
3634 pixelformat
->u3
.dwBBitMask
= 0;
3636 pixelformat
->dwFlags
= DDPF_RGB
;
3637 pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
3638 pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
3639 pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
3641 pixelformat
->dwFourCC
= 0;
3642 pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3643 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3645 *screen_pixelformat
= *pixelformat
;
3647 if (pix_depth
!= NULL
)
3648 *pix_depth
= vi
[j
].depth
;
3653 goto clean_up_and_exit
;
3657 ERR("No visual corresponding to pixmap format !\n");
3662 /* We try now to find an emulated mode */
3665 for (c
= 0; c
< sizeof(ModeEmulations
) / sizeof(Convert
); c
++) {
3666 if (ModeEmulations
[c
].dest
.depth
== depth
) {
3667 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3668 for (i
= 0; i
< npixmap
; i
++) {
3669 if ((pf
[i
].depth
== ModeEmulations
[c
].screen
.depth
) &&
3670 (pf
[i
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
3673 for (j
= 0; j
< nvisuals
; j
++) {
3674 if (vi
[j
].depth
== pf
[i
].depth
) {
3675 screen_pixelformat
->dwSize
= sizeof(*screen_pixelformat
);
3676 screen_pixelformat
->dwFlags
= DDPF_RGB
;
3677 screen_pixelformat
->dwFourCC
= 0;
3678 screen_pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3679 screen_pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
3680 screen_pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
3681 screen_pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
3682 screen_pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3684 pixelformat
->dwSize
= sizeof(*pixelformat
);
3685 pixelformat
->dwFourCC
= 0;
3687 pixelformat
->dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
3688 pixelformat
->u
.dwRGBBitCount
= 8;
3689 pixelformat
->u1
.dwRBitMask
= 0;
3690 pixelformat
->u2
.dwGBitMask
= 0;
3691 pixelformat
->u3
.dwBBitMask
= 0;
3693 pixelformat
->dwFlags
= DDPF_RGB
;
3694 pixelformat
->u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
3695 pixelformat
->u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
3696 pixelformat
->u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
3697 pixelformat
->u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
3699 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3701 if (pix_depth
!= NULL
)
3702 *pix_depth
= vi
[j
].depth
;
3707 goto clean_up_and_exit
;
3710 ERR("No visual corresponding to pixmap format !\n");
3725 #ifdef HAVE_LIBXXF86DGA2
3726 static void _DGA_Initialize_FrameBuffer(IDirectDrawImpl
*This
, int mode
) {
3727 DDPIXELFORMAT
*pf
= &(This
->d
.directdraw_pixelformat
);
3729 /* Now, get the device / mode description */
3730 This
->e
.dga
.dev
= TSXDGASetMode(display
, DefaultScreen(display
), mode
);
3732 This
->e
.dga
.fb_width
= This
->e
.dga
.dev
->mode
.imageWidth
;
3733 TSXDGASetViewport(display
,DefaultScreen(display
),0,0, XDGAFlipImmediate
);
3734 This
->e
.dga
.fb_height
= This
->e
.dga
.dev
->mode
.viewportHeight
;
3735 TRACE("video framebuffer: begin %p, width %d, memsize %d\n",
3736 This
->e
.dga
.dev
->data
,
3737 This
->e
.dga
.dev
->mode
.imageWidth
,
3738 (This
->e
.dga
.dev
->mode
.imageWidth
*
3739 This
->e
.dga
.dev
->mode
.imageHeight
*
3740 (This
->e
.dga
.dev
->mode
.bitsPerPixel
/ 8))
3742 TRACE("viewport height: %d\n", This
->e
.dga
.dev
->mode
.viewportHeight
);
3743 /* Get the screen dimensions as seen by Wine.
3744 In that case, it may be better to ignore the -desktop mode and return the
3745 real screen size => print a warning */
3746 This
->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3747 This
->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3748 This
->e
.dga
.fb_addr
= This
->e
.dga
.dev
->data
;
3749 This
->e
.dga
.fb_memsize
= (This
->e
.dga
.dev
->mode
.imageWidth
*
3750 This
->e
.dga
.dev
->mode
.imageHeight
*
3751 (This
->e
.dga
.dev
->mode
.bitsPerPixel
/ 8));
3752 This
->e
.dga
.vpmask
= 0;
3754 /* Fill the screen pixelformat */
3755 pf
->dwSize
= sizeof(DDPIXELFORMAT
);
3757 pf
->u
.dwRGBBitCount
= This
->e
.dga
.dev
->mode
.bitsPerPixel
;
3758 if (This
->e
.dga
.dev
->mode
.depth
== 8) {
3759 pf
->dwFlags
= DDPF_PALETTEINDEXED8
|DDPF_RGB
;
3760 pf
->u1
.dwRBitMask
= 0;
3761 pf
->u2
.dwGBitMask
= 0;
3762 pf
->u3
.dwBBitMask
= 0;
3764 pf
->dwFlags
= DDPF_RGB
;
3765 pf
->u1
.dwRBitMask
= This
->e
.dga
.dev
->mode
.redMask
;
3766 pf
->u2
.dwGBitMask
= This
->e
.dga
.dev
->mode
.greenMask
;
3767 pf
->u3
.dwBBitMask
= This
->e
.dga
.dev
->mode
.blueMask
;
3769 pf
->u4
.dwRGBAlphaBitMask
= 0;
3771 This
->d
.screen_pixelformat
= *pf
;
3773 #endif /* defined(HAVE_LIBXXF86DGA2) */
3775 #ifdef HAVE_LIBXXF86DGA
3776 static HRESULT WINAPI
DGA_IDirectDrawImpl_SetDisplayMode(
3777 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
3779 ICOM_THIS(IDirectDrawImpl
,iface
);
3782 TRACE("(%p)->(%ld,%ld,%ld)\n", This
, width
, height
, depth
);
3784 #ifdef HAVE_LIBXXF86DGA2
3785 if (This
->e
.dga
.version
== 2) {
3786 XDGAMode
*modes
= This
->e
.dga
.modes
;
3787 int mode_to_use
= -1;
3789 /* Search in the list a display mode that corresponds to what is requested */
3790 for (i
= 0; i
< This
->e
.dga
.num_modes
; i
++) {
3791 if ((height
== modes
[i
].viewportHeight
) &&
3792 (width
== modes
[i
].viewportWidth
) &&
3793 (depth
== modes
[i
].depth
)) {
3794 mode_to_use
= modes
[i
].num
;
3798 if (mode_to_use
< 0) {
3799 ERR("Could not find matching mode !!!\n");
3800 return DDERR_UNSUPPORTEDMODE
;
3802 TRACE("Using mode number %d\n", mode_to_use
);
3804 TSXDGACloseFramebuffer(display
, DefaultScreen(display
));
3806 if (!TSXDGAOpenFramebuffer(display
, DefaultScreen(display
))) {
3807 ERR("Error opening the frame buffer !!!\n");
3809 return DDERR_GENERIC
;
3812 /* Initialize the frame buffer */
3813 _DGA_Initialize_FrameBuffer(This
, mode_to_use
);
3815 /* Re-get (if necessary) the DGA events */
3816 TSXDGASelectInput(display
, DefaultScreen(display
),
3817 KeyPressMask
|KeyReleaseMask
|ButtonPressMask
|ButtonReleaseMask
|PointerMotionMask
);
3822 #endif /* defined(HAVE_LIBXXF86DGA2) */
3824 /* We hope getting the asked for depth */
3825 if (_common_depth_to_pixelformat(depth
, &(This
->d
.directdraw_pixelformat
), &(This
->d
.screen_pixelformat
), NULL
) != -1) {
3826 /* I.e. no visual found or emulated */
3827 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
3828 return DDERR_UNSUPPORTEDMODE
;
3831 if (This
->d
.width
< width
) {
3832 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,This
->d
.width
);
3833 return DDERR_UNSUPPORTEDMODE
;
3835 This
->d
.width
= width
;
3836 This
->d
.height
= height
;
3838 /* adjust fb_height, so we don't overlap */
3839 if (This
->e
.dga
.fb_height
< height
)
3840 This
->e
.dga
.fb_height
= height
;
3841 _common_IDirectDrawImpl_SetDisplayMode(This
);
3843 #ifdef HAVE_LIBXXF86VM
3844 #ifdef HAVE_LIBXXF86DGA2
3845 if (This
->e
.dga
.version
== 1) /* Only for DGA 1.0, it crashes with DGA 2.0 */
3846 #endif /* defined(HAVE_LIBXXF86DGA2) */
3848 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
3849 XF86VidModeModeLine mod_tmp
;
3850 /* int dotclock_tmp; */
3852 /* save original video mode and set fullscreen if available*/
3853 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
3854 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
3855 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
3856 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
3857 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
3858 orig_mode
->htotal
= mod_tmp
.htotal
;
3859 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
3860 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
3861 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
3862 orig_mode
->vtotal
= mod_tmp
.vtotal
;
3863 orig_mode
->flags
= mod_tmp
.flags
;
3864 orig_mode
->private = mod_tmp
.private;
3866 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
3867 for (i
=0;i
<mode_count
;i
++)
3869 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
3871 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
3872 *vidmode
= *(all_modes
[i
]);
3875 TSXFree(all_modes
[i
]->private);
3877 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
3881 WARN("Fullscreen mode not available!\n");
3885 TRACE("SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
3886 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
3887 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3888 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
3894 /* FIXME: this function OVERWRITES several signal handlers.
3895 * can we save them? and restore them later? In a way that
3896 * it works for the library too?
3898 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
3899 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
3901 #ifdef RESTORE_SIGNALS
3906 #endif /* defined(HAVE_LIBXXF86DGA) */
3908 /* *************************************
3909 16 / 15 bpp to palettized 8 bpp
3910 ************************************* */
3911 static void pixel_convert_16_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3912 unsigned char *c_src
= (unsigned char *) src
;
3913 unsigned short *c_dst
= (unsigned short *) dst
;
3916 if (palette
!= NULL
) {
3917 const unsigned short * pal
= (unsigned short *) palette
->screen_palents
;
3919 for (y
= height
; y
--; ) {
3920 #if defined(__i386__) && defined(__GNUC__)
3921 /* gcc generates slightly inefficient code for the the copy / lookup,
3922 * it generates one excess memory access (to pal) per pixel. Since
3923 * we know that pal is not modified by the memory write we can
3924 * put it into a register and reduce the number of memory accesses
3925 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3926 * (This is not guaranteed to be the fastest method.)
3928 __asm__
__volatile__(
3932 " movw (%%edx,%%eax,2),%%ax\n"
3934 " xor %%eax,%%eax\n"
3936 : "=S" (c_src
), "=D" (c_dst
)
3937 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
3938 : "eax", "cc", "memory"
3940 c_src
+=(pitch
-width
);
3942 unsigned char * srclineend
= c_src
+width
;
3943 while (c_src
< srclineend
)
3944 *c_dst
++ = pal
[*c_src
++];
3945 c_src
+=(pitch
-width
);
3949 WARN("No palette set...\n");
3950 memset(dst
, 0, width
* height
* 2);
3953 static void palette_convert_16_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3955 unsigned short *pal
= (unsigned short *) screen_palette
;
3957 for (i
= 0; i
< count
; i
++)
3958 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
3959 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3960 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
3962 static void palette_convert_15_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3964 unsigned short *pal
= (unsigned short *) screen_palette
;
3966 for (i
= 0; i
< count
; i
++)
3967 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 7) |
3968 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3969 ((((unsigned short) palent
[i
].peGreen
) & 0xF8) << 2));
3972 /* *************************************
3973 24 to palettized 8 bpp
3974 ************************************* */
3975 static void pixel_convert_24_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3976 unsigned char *c_src
= (unsigned char *) src
;
3977 unsigned char *c_dst
= (unsigned char *) dst
;
3980 if (palette
!= NULL
) {
3981 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
3983 for (y
= height
; y
--; ) {
3984 unsigned char * srclineend
= c_src
+width
;
3985 while (c_src
< srclineend
) {
3986 register long pixel
= pal
[*c_src
++];
3988 *c_dst
++ = pixel
>>8;
3989 *c_dst
++ = pixel
>>16;
3991 c_src
+=(pitch
-width
);
3994 WARN("No palette set...\n");
3995 memset(dst
, 0, width
* height
* 4);
3998 /* *************************************
3999 32 bpp to palettized 8 bpp
4000 ************************************* */
4001 static void pixel_convert_32_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
4002 unsigned char *c_src
= (unsigned char *) src
;
4003 unsigned int *c_dst
= (unsigned int *) dst
;
4006 if (palette
!= NULL
) {
4007 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
4009 for (y
= height
; y
--; ) {
4010 #if defined(__i386__) && defined(__GNUC__)
4011 /* See comment in pixel_convert_16_to_8 */
4012 __asm__
__volatile__(
4016 " movl (%%edx,%%eax,4),%%eax\n"
4018 " xor %%eax,%%eax\n"
4020 : "=S" (c_src
), "=D" (c_dst
)
4021 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
4022 : "eax", "cc", "memory"
4024 c_src
+=(pitch
-width
);
4026 unsigned char * srclineend
= c_src
+width
;
4027 while (c_src
< srclineend
)
4028 *c_dst
++ = pal
[*c_src
++];
4029 c_src
+=(pitch
-width
);
4033 WARN("No palette set...\n");
4034 memset(dst
, 0, width
* height
* 4);
4038 static void palette_convert_24_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
4040 unsigned int *pal
= (unsigned int *) screen_palette
;
4042 for (i
= 0; i
< count
; i
++)
4043 pal
[start
+ i
] = ((((unsigned int) palent
[i
].peRed
) << 16) |
4044 (((unsigned int) palent
[i
].peGreen
) << 8) |
4045 ((unsigned int) palent
[i
].peBlue
));
4048 /* *************************************
4050 ************************************* */
4051 static void pixel_convert_32_to_16(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
4052 unsigned short *c_src
= (unsigned short *) src
;
4053 unsigned int *c_dst
= (unsigned int *) dst
;
4056 for (y
= height
; y
--; ) {
4057 unsigned short * srclineend
= c_src
+width
;
4058 while (c_src
< srclineend
) {
4059 *c_dst
++ = (((*c_src
& 0xF800) << 8) |
4060 ((*c_src
& 0x07E0) << 5) |
4061 ((*c_src
& 0x001F) << 3));
4064 c_src
+=((pitch
/2)-width
);
4069 static HRESULT WINAPI
Xlib_IDirectDrawImpl_SetDisplayMode(
4070 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
4072 ICOM_THIS(IDirectDrawImpl
,iface
);
4077 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
4078 This
, width
, height
, depth
);
4080 switch ((c
= _common_depth_to_pixelformat(depth
,
4081 &(This
->d
.directdraw_pixelformat
),
4082 &(This
->d
.screen_pixelformat
),
4083 &(This
->d
.pixmap_depth
)))) {
4085 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
4086 MessageBoxA(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
4087 return DDERR_UNSUPPORTEDMODE
;
4091 This
->d
.pixel_convert
= NULL
;
4092 This
->d
.palette_convert
= NULL
;
4096 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
4098 /* Set the depth convertion routines */
4099 This
->d
.pixel_convert
= ModeEmulations
[c
].funcs
.pixel_convert
;
4100 This
->d
.palette_convert
= ModeEmulations
[c
].funcs
.palette_convert
;
4103 This
->d
.width
= width
;
4104 This
->d
.height
= height
;
4106 _common_IDirectDrawImpl_SetDisplayMode(This
);
4108 tmpWnd
= WIN_FindWndPtr(This
->d
.window
);
4109 This
->d
.paintable
= 1;
4110 This
->d
.drawable
= ((X11DRV_WND_DATA
*) tmpWnd
->pDriverData
)->window
;
4111 WIN_ReleaseWndPtr(tmpWnd
);
4113 /* We don't have a context for this window. Host off the desktop */
4114 if( !This
->d
.drawable
)
4116 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
4117 WIN_ReleaseDesktop();
4119 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
4121 if (Options
.DXGrab
) {
4122 /* Confine cursor movement (risky, but the user asked for it) */
4123 TSXGrabPointer(display
, This
->d
.drawable
, True
, 0, GrabModeAsync
, GrabModeAsync
, This
->d
.drawable
, None
, CurrentTime
);
4129 #ifdef HAVE_LIBXXF86DGA
4130 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetCaps(
4131 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
4133 ICOM_THIS(IDirectDraw2Impl
,iface
);
4134 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
4135 if (!caps1
&& !caps2
)
4136 return DDERR_INVALIDPARAMS
;
4138 caps1
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
4139 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
4140 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
4143 caps2
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
4144 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
4145 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
4149 #endif /* defined(HAVE_LIBXXF86DGA) */
4151 static void fill_caps(LPDDCAPS caps
) {
4152 /* This function tries to fill the capabilities of Wine's DDraw implementation.
4153 Need to be fixed, though.. */
4157 caps
->dwSize
= sizeof(*caps
);
4158 caps
->dwCaps
= DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
| DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
| DDCAPS_NOHARDWARE
;
4159 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NOPAGELOCKREQUIRED
| DDCAPS2_WIDESURFACES
;
4160 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
4162 caps
->dwFXAlphaCaps
= 0;
4163 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
4165 caps
->dwZBufferBitDepths
= DDBD_16
;
4166 /* I put here 8 Mo so that D3D applications will believe they have enough memory
4167 to put textures in video memory.
4168 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
4170 caps
->dwVidMemTotal
= 8192 * 1024;
4171 caps
->dwVidMemFree
= 8192 * 1024;
4172 /* These are all the supported capabilities of the surfaces */
4173 caps
->ddsCaps
.dwCaps
= DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
4174 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
4175 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
|
4176 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
;
4178 caps
->dwCaps
|= DDCAPS_3D
| DDCAPS_ZBLTS
;
4179 caps
->dwCaps2
|= DDCAPS2_NO2DDURING3DSCENE
;
4180 caps
->ddsCaps
.dwCaps
|= DDSCAPS_3DDEVICE
| DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
| DDSCAPS_ZBUFFER
;
4184 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetCaps(
4185 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
4187 ICOM_THIS(IDirectDraw2Impl
,iface
);
4188 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
4190 /* Put the same caps for the two capabilities */
4197 static HRESULT WINAPI
IDirectDraw2Impl_CreateClipper(
4198 LPDIRECTDRAW2 iface
,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
4200 ICOM_THIS(IDirectDraw2Impl
,iface
);
4201 IDirectDrawClipperImpl
** ilpddclip
=(IDirectDrawClipperImpl
**)lpddclip
;
4202 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
4203 This
,x
,ilpddclip
,lpunk
4205 *ilpddclip
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
4206 (*ilpddclip
)->ref
= 1;
4207 ICOM_VTBL(*ilpddclip
) = &ddclipvt
;
4211 static HRESULT WINAPI
common_IDirectDraw2Impl_CreatePalette(
4212 IDirectDraw2Impl
* This
,DWORD dwFlags
,LPPALETTEENTRY palent
,IDirectDrawPaletteImpl
**lpddpal
,LPUNKNOWN lpunk
,int *psize
4216 if (TRACE_ON(ddraw
))
4217 _dump_paletteformat(dwFlags
);
4219 *lpddpal
= (IDirectDrawPaletteImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPaletteImpl
));
4220 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
4221 (*lpddpal
)->ref
= 1;
4222 (*lpddpal
)->ddraw
= (IDirectDrawImpl
*)This
;
4223 (*lpddpal
)->installed
= 0;
4225 if (dwFlags
& DDPCAPS_1BIT
)
4227 else if (dwFlags
& DDPCAPS_2BIT
)
4229 else if (dwFlags
& DDPCAPS_4BIT
)
4231 else if (dwFlags
& DDPCAPS_8BIT
)
4234 ERR("unhandled palette format\n");
4239 /* Now, if we are in 'depth conversion mode', create the screen palette */
4240 if (This
->d
.palette_convert
!= NULL
)
4241 This
->d
.palette_convert(palent
, (*lpddpal
)->screen_palents
, 0, size
);
4243 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
4244 } else if (This
->d
.palette_convert
!= NULL
) {
4245 /* In that case, put all 0xFF */
4246 memset((*lpddpal
)->screen_palents
, 0xFF, 256 * sizeof(int));
4252 #ifdef HAVE_LIBXXF86DGA
4253 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreatePalette(
4254 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
4256 ICOM_THIS(IDirectDraw2Impl
,iface
);
4257 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
4261 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
4262 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
4263 if (res
!= 0) return res
;
4264 ICOM_VTBL(*ilpddpal
) = &dga_ddpalvt
;
4265 if (This
->d
.directdraw_pixelformat
.u
.dwRGBBitCount
<=8) {
4266 (*ilpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
4268 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
4269 (*ilpddpal
)->cm
= 0;
4271 if (((*ilpddpal
)->cm
)&&xsize
) {
4272 for (i
=0;i
<xsize
;i
++) {
4275 xc
.red
= (*ilpddpal
)->palents
[i
].peRed
<<8;
4276 xc
.blue
= (*ilpddpal
)->palents
[i
].peBlue
<<8;
4277 xc
.green
= (*ilpddpal
)->palents
[i
].peGreen
<<8;
4278 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
4280 TSXStoreColor(display
,(*ilpddpal
)->cm
,&xc
);
4285 #endif /* defined(HAVE_LIBXXF86DGA) */
4287 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreatePalette(
4288 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
4290 ICOM_THIS(IDirectDraw2Impl
,iface
);
4291 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
4295 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
4296 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
4297 if (res
!= 0) return res
;
4298 ICOM_VTBL(*ilpddpal
) = &xlib_ddpalvt
;
4302 #ifdef HAVE_LIBXXF86DGA
4303 static HRESULT WINAPI
DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
4304 ICOM_THIS(IDirectDraw2Impl
,iface
);
4305 TRACE("(%p)->()\n",This
);
4307 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
4308 #ifdef RESTORE_SIGNALS
4313 #endif /* defined(HAVE_LIBXXF86DGA) */
4315 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
4316 ICOM_THIS(IDirectDraw2Impl
,iface
);
4317 TRACE("(%p)->RestoreDisplayMode()\n", This
);
4322 static HRESULT WINAPI
IDirectDraw2Impl_WaitForVerticalBlank(
4323 LPDIRECTDRAW2 iface
,DWORD x
,HANDLE h
4325 ICOM_THIS(IDirectDraw2Impl
,iface
);
4326 TRACE("(%p)->(0x%08lx,0x%08x)\n",This
,x
,h
);
4330 static ULONG WINAPI
IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface
) {
4331 ICOM_THIS(IDirectDraw2Impl
,iface
);
4332 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
4334 return ++(This
->ref
);
4337 #ifdef HAVE_LIBXXF86DGA
4338 static ULONG WINAPI
DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
4339 ICOM_THIS(IDirectDraw2Impl
,iface
);
4340 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
4342 if (!--(This
->ref
)) {
4343 #ifdef HAVE_LIBXXF86DGA2
4344 if (This
->e
.dga
.version
== 2) {
4345 TRACE("Closing access to the FrameBuffer\n");
4346 TSXDGACloseFramebuffer(display
, DefaultScreen(display
));
4347 TRACE("Going back to normal X mode of operation\n");
4348 TSXDGASetMode(display
, DefaultScreen(display
), 0);
4350 /* Set the input handling back to absolute */
4351 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_ABSOLUTE
);
4353 /* Remove the handling of DGA2 events */
4354 X11DRV_EVENT_SetDGAStatus(0, -1);
4356 /* Free the modes list */
4357 TSXFree(This
->e
.dga
.modes
);
4359 #endif /* defined(HAVE_LIBXXF86DGA2) */
4360 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
4361 if (This
->d
.window
&& GetPropA(This
->d
.window
,ddProp
))
4362 DestroyWindow(This
->d
.window
);
4363 #ifdef HAVE_LIBXXF86VM
4365 TSXF86VidModeSwitchToMode(
4367 DefaultScreen(display
),
4369 if (orig_mode
->privsize
)
4370 TSXFree(orig_mode
->private);
4376 #ifdef RESTORE_SIGNALS
4379 HeapFree(GetProcessHeap(),0,This
);
4384 #endif /* defined(HAVE_LIBXXF86DGA) */
4386 static ULONG WINAPI
Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
4387 ICOM_THIS(IDirectDraw2Impl
,iface
);
4388 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
4390 if (!--(This
->ref
)) {
4391 if (This
->d
.window
&& GetPropA(This
->d
.window
,ddProp
))
4392 DestroyWindow(This
->d
.window
);
4393 HeapFree(GetProcessHeap(),0,This
);
4396 /* FIXME: destroy window ... */
4400 #ifdef HAVE_LIBXXF86DGA
4401 static HRESULT WINAPI
DGA_IDirectDraw2Impl_QueryInterface(
4402 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
4404 ICOM_THIS(IDirectDraw2Impl
,iface
);
4406 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(refiid
),obj
);
4407 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
4409 IDirectDraw2_AddRef(iface
);
4411 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4415 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
4416 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_ddvt
;
4417 IDirectDraw2_AddRef(iface
);
4420 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4424 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
4425 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd2vt
;
4426 IDirectDraw2_AddRef(iface
);
4429 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4433 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
4434 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd4vt
;
4435 IDirectDraw2_AddRef(iface
);
4438 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4442 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
4445 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4447 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4448 IDirectDraw2_AddRef(iface
);
4449 ICOM_VTBL(d3d
) = &d3dvt
;
4452 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4456 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
4457 IDirect3D2Impl
* d3d
;
4459 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4461 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4462 IDirectDraw2_AddRef(iface
);
4463 ICOM_VTBL(d3d
) = &d3d2vt
;
4466 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4470 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,debugstr_guid(refiid
));
4471 return OLE_E_ENUM_NOMORE
;
4473 #endif /* defined(HAVE_LIBXXF86DGA) */
4475 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_QueryInterface(
4476 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
4478 ICOM_THIS(IDirectDraw2Impl
,iface
);
4480 TRACE("(%p)->(%s,%p)\n",This
,debugstr_guid(refiid
),obj
);
4481 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
4483 IDirectDraw2_AddRef(iface
);
4485 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4489 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
4490 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_ddvt
;
4491 IDirectDraw2_AddRef(iface
);
4494 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4498 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
4499 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd2vt
;
4500 IDirectDraw2_AddRef(iface
);
4503 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4507 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
4508 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd4vt
;
4509 IDirectDraw2_AddRef(iface
);
4512 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4516 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
4519 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4521 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4522 IDirectDraw2_AddRef(iface
);
4523 ICOM_VTBL(d3d
) = &d3dvt
;
4526 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4530 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
4531 IDirect3D2Impl
* d3d
;
4533 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4535 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4536 IDirectDraw2_AddRef(iface
);
4537 ICOM_VTBL(d3d
) = &d3d2vt
;
4540 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4544 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,debugstr_guid(refiid
));
4545 return OLE_E_ENUM_NOMORE
;
4548 static HRESULT WINAPI
IDirectDraw2Impl_GetVerticalBlankStatus(
4549 LPDIRECTDRAW2 iface
,BOOL
*status
4551 ICOM_THIS(IDirectDraw2Impl
,iface
);
4552 TRACE("(%p)->(%p)\n",This
,status
);
4557 #ifdef HAVE_LIBXXF86DGA
4558 static HRESULT WINAPI
DGA_IDirectDraw2Impl_EnumDisplayModes(
4559 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4561 ICOM_THIS(IDirectDraw2Impl
,iface
);
4562 DDSURFACEDESC ddsfd
;
4565 } modes
[5] = { /* some of the usual modes */
4572 static int depths
[4] = {8,16,24,32};
4575 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4576 ddsfd
.dwSize
= sizeof(ddsfd
);
4577 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4578 if (dwFlags
& DDEDM_REFRESHRATES
) {
4579 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4580 ddsfd
.u
.dwRefreshRate
= 60;
4582 ddsfd
.ddsCaps
.dwCaps
= 0;
4583 ddsfd
.dwBackBufferCount
= 1;
4585 #ifdef HAVE_LIBXXF86DGA2
4586 if (This
->e
.dga
.version
== 2) {
4587 XDGAMode
*modes
= This
->e
.dga
.modes
;
4589 ddsfd
.dwFlags
|= DDSD_PITCH
;
4590 for (i
= 0; i
< This
->e
.dga
.num_modes
; i
++) {
4591 if (TRACE_ON(ddraw
)) {
4592 DPRINTF(" Enumerating mode %d : %s (FB: %dx%d / VP: %dx%d) - depth %d -",
4594 modes
[i
].name
, modes
[i
].imageWidth
, modes
[i
].imageHeight
,
4595 modes
[i
].viewportWidth
, modes
[i
].viewportHeight
,
4597 if (modes
[i
].flags
& XDGAConcurrentAccess
) DPRINTF(" XDGAConcurrentAccess ");
4598 if (modes
[i
].flags
& XDGASolidFillRect
) DPRINTF(" XDGASolidFillRect ");
4599 if (modes
[i
].flags
& XDGABlitRect
) DPRINTF(" XDGABlitRect ");
4600 if (modes
[i
].flags
& XDGABlitTransRect
) DPRINTF(" XDGABlitTransRect ");
4601 if (modes
[i
].flags
& XDGAPixmap
) DPRINTF(" XDGAPixmap ");
4604 /* Fill the pixel format */
4605 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(DDPIXELFORMAT
);
4606 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4607 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4608 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= modes
[i
].bitsPerPixel
;
4609 if (modes
[i
].depth
== 8) {
4610 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
4611 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4612 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4613 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4614 ddsfd
.ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4616 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4617 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= modes
[i
].redMask
;
4618 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= modes
[i
].greenMask
;
4619 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= modes
[i
].blueMask
;
4622 ddsfd
.dwWidth
= modes
[i
].viewportWidth
;
4623 ddsfd
.dwHeight
= modes
[i
].viewportHeight
;
4624 ddsfd
.lPitch
= modes
[i
].imageWidth
;
4626 /* Send mode to the application */
4627 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4631 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
4632 ddsfd
.dwBackBufferCount
= 1;
4633 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4634 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4635 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= depths
[i
];
4636 /* FIXME: those masks would have to be set in depth > 8 */
4638 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4639 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4640 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4641 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4642 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
4643 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
4645 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4647 /* FIXME: We should query those from X itself */
4648 switch (depths
[i
]) {
4650 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0xF800;
4651 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x07E0;
4652 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x001F;
4655 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
4656 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
4657 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
4660 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
4661 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
4662 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
4667 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4668 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4669 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4670 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4672 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
4673 ddsfd
.dwWidth
= modes
[j
].w
;
4674 ddsfd
.dwHeight
= modes
[j
].h
;
4675 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4676 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4679 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4680 /* modeX is not standard VGA */
4682 ddsfd
.dwHeight
= 200;
4683 ddsfd
.dwWidth
= 320;
4684 TRACE(" enumerating (320x200x%d)\n",depths
[i
]);
4685 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4688 #ifdef HAVE_LIBXXF86DGA2
4693 #endif /* defined(HAVE_LIBXXF86DGA) */
4695 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_EnumDisplayModes(
4696 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4698 ICOM_THIS(IDirectDraw2Impl
,iface
);
4700 XPixmapFormatValues
*pf
;
4702 int xbpp
= 1, nvisuals
, npixmap
, i
, emu
;
4703 int has_mode
[] = { 0, 0, 0, 0 };
4704 int has_depth
[] = { 8, 15, 16, 24 };
4705 DDSURFACEDESC ddsfd
;
4708 } modes
[] = { /* some of the usual modes */
4716 DWORD maxWidth
, maxHeight
;
4718 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4719 ddsfd
.dwSize
= sizeof(ddsfd
);
4720 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
|DDSD_CAPS
|DDSD_PITCH
;
4721 if (dwFlags
& DDEDM_REFRESHRATES
) {
4722 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4723 ddsfd
.u
.dwRefreshRate
= 60;
4725 maxWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4726 maxHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4728 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
4729 pf
= XListPixmapFormats(display
, &npixmap
);
4733 while ((i
< npixmap
) || (emu
!= 4)) {
4739 for (j
= 0; j
< 4; j
++) {
4740 if (has_depth
[j
] == pf
[i
].depth
) {
4751 if (has_mode
[mode_index
] == 0) {
4752 if (mode_index
== 0) {
4755 ddsfd
.ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4756 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4757 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
4758 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4759 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
4760 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4761 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4762 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4763 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4767 has_mode
[mode_index
] = 1;
4769 /* All the 'true color' depths (15, 16 and 24)
4770 First, find the corresponding visual to extract the bit masks */
4771 for (j
= 0; j
< nvisuals
; j
++) {
4772 if (vi
[j
].depth
== pf
[i
].depth
) {
4773 ddsfd
.ddsCaps
.dwCaps
= 0;
4774 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4775 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4776 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4777 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
4778 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= vi
[j
].red_mask
;
4779 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= vi
[j
].green_mask
;
4780 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= vi
[j
].blue_mask
;
4781 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4783 xbpp
= pf
[i
].bits_per_pixel
/8;
4786 has_mode
[mode_index
] = 1;
4791 ERR("Did not find visual corresponding the the pixmap format !\n");
4796 /* Now to emulated modes */
4797 if (has_mode
[emu
] == 0) {
4800 int depth
= has_depth
[emu
];
4802 for (c
= 0; (c
< sizeof(ModeEmulations
) / sizeof(Convert
)) && (send_mode
== 0); c
++) {
4803 if (ModeEmulations
[c
].dest
.depth
== depth
) {
4804 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4805 for (l
= 0; (l
< npixmap
) && (send_mode
== 0); l
++) {
4806 if ((pf
[l
].depth
== ModeEmulations
[c
].screen
.depth
) &&
4807 (pf
[l
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
4809 for (j
= 0; (j
< nvisuals
) && (send_mode
== 0); j
++) {
4810 if ((vi
[j
].depth
== pf
[l
].depth
) &&
4811 (vi
[j
].red_mask
== ModeEmulations
[c
].screen
.rmask
) &&
4812 (vi
[j
].green_mask
== ModeEmulations
[c
].screen
.gmask
) &&
4813 (vi
[j
].blue_mask
== ModeEmulations
[c
].screen
.bmask
)) {
4814 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4815 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4817 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
4818 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
4819 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4820 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4821 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4823 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4824 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
4825 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
4826 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
4827 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
4829 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4834 ERR("No visual corresponding to pixmap format !\n");
4848 if (TRACE_ON(ddraw
)) {
4849 TRACE("Enumerating with pixel format : \n");
4850 _dump_pixelformat(&(ddsfd
.ddpfPixelFormat
));
4854 for (mode
= 0; mode
< sizeof(modes
)/sizeof(modes
[0]); mode
++) {
4855 /* Do not enumerate modes we cannot handle anyway */
4856 if ((modes
[mode
].w
> maxWidth
) || (modes
[mode
].h
> maxHeight
))
4859 ddsfd
.dwWidth
= modes
[mode
].w
;
4860 ddsfd
.dwHeight
= modes
[mode
].h
;
4861 ddsfd
.lPitch
= ddsfd
.dwWidth
* xbpp
;
4863 /* Now, send the mode description to the application */
4864 TRACE(" - mode %4ld - %4ld\n", ddsfd
.dwWidth
, ddsfd
.dwHeight
);
4865 if (!modescb(&ddsfd
, context
))
4869 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4870 /* modeX is not standard VGA */
4871 ddsfd
.dwWidth
= 320;
4872 ddsfd
.dwHeight
= 200;
4873 ddsfd
.lPitch
= 320 * xbpp
;
4874 if (!modescb(&ddsfd
, context
))
4886 #ifdef HAVE_LIBXXF86DGA
4887 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetDisplayMode(
4888 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4890 ICOM_THIS(IDirectDraw2Impl
,iface
);
4891 TRACE("(%p)->(%p)\n",This
,lpddsfd
);
4892 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4893 lpddsfd
->dwHeight
= This
->d
.height
;
4894 lpddsfd
->dwWidth
= This
->d
.width
;
4895 lpddsfd
->lPitch
= This
->e
.dga
.fb_width
*PFGET_BPP(This
->d
.directdraw_pixelformat
);
4896 lpddsfd
->dwBackBufferCount
= 2;
4897 lpddsfd
->u
.dwRefreshRate
= 60;
4898 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4899 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4900 if (TRACE_ON(ddraw
)) {
4901 _dump_surface_desc(lpddsfd
);
4905 #endif /* defined(HAVE_LIBXXF86DGA) */
4907 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetDisplayMode(
4908 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4910 ICOM_THIS(IDirectDraw2Impl
,iface
);
4911 TRACE("(%p)->GetDisplayMode(%p)\n",This
,lpddsfd
);
4912 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4913 lpddsfd
->dwHeight
= This
->d
.height
;
4914 lpddsfd
->dwWidth
= This
->d
.width
;
4915 lpddsfd
->lPitch
= lpddsfd
->dwWidth
* PFGET_BPP(This
->d
.directdraw_pixelformat
);
4916 lpddsfd
->dwBackBufferCount
= 2;
4917 lpddsfd
->u
.dwRefreshRate
= 60;
4918 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4919 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4920 if (TRACE_ON(ddraw
)) {
4921 _dump_surface_desc(lpddsfd
);
4926 static HRESULT WINAPI
IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface
) {
4927 ICOM_THIS(IDirectDraw2Impl
,iface
);
4928 TRACE("(%p)->()\n",This
);
4932 static HRESULT WINAPI
IDirectDraw2Impl_GetMonitorFrequency(
4933 LPDIRECTDRAW2 iface
,LPDWORD freq
4935 ICOM_THIS(IDirectDraw2Impl
,iface
);
4936 FIXME("(%p)->(%p) returns 60 Hz always\n",This
,freq
);
4937 *freq
= 60*100; /* 60 Hz */
4941 /* what can we directly decompress? */
4942 static HRESULT WINAPI
IDirectDraw2Impl_GetFourCCCodes(
4943 LPDIRECTDRAW2 iface
,LPDWORD x
,LPDWORD y
4945 ICOM_THIS(IDirectDraw2Impl
,iface
);
4946 FIXME("(%p,%p,%p), stub\n",This
,x
,y
);
4950 static HRESULT WINAPI
IDirectDraw2Impl_EnumSurfaces(
4951 LPDIRECTDRAW2 iface
,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
4953 ICOM_THIS(IDirectDraw2Impl
,iface
);
4954 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This
,x
,ddsfd
,context
,ddsfcb
);
4958 static HRESULT WINAPI
IDirectDraw2Impl_Compact(
4959 LPDIRECTDRAW2 iface
)
4961 ICOM_THIS(IDirectDraw2Impl
,iface
);
4962 FIXME("(%p)->()\n", This
);
4967 static HRESULT WINAPI
IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface
,
4968 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
4969 ICOM_THIS(IDirectDraw2Impl
,iface
);
4970 FIXME("(%p)->(%p)\n", This
, lplpGDIDDSSurface
);
4975 static HRESULT WINAPI
IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface
,
4976 LPDWORD lpdwScanLine
) {
4977 ICOM_THIS(IDirectDraw2Impl
,iface
);
4978 FIXME("(%p)->(%p)\n", This
, lpdwScanLine
);
4985 static HRESULT WINAPI
IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface
,
4987 ICOM_THIS(IDirectDraw2Impl
,iface
);
4988 FIXME("(%p)->(%p)\n", This
, lpGUID
);
4993 #ifdef HAVE_LIBXXF86DGA
4995 /* Note: Hack so we can reuse the old functions without compiler warnings */
4996 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4997 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4999 # define XCAST(fun) (void *)
5002 static ICOM_VTABLE(IDirectDraw
) dga_ddvt
=
5004 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5005 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
5006 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
5007 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
5008 XCAST(Compact
)IDirectDraw2Impl_Compact
,
5009 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
5010 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
5011 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
5012 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
5013 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
5014 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
5015 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
5016 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
5017 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
5018 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
5019 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
5020 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
5021 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
5022 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
5023 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
5024 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
5025 #ifdef HAVE_LIBXXF86DGA2
5026 XCAST(SetCooperativeLevel
)DGA_IDirectDraw2Impl_SetCooperativeLevel
,
5028 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
5030 DGA_IDirectDrawImpl_SetDisplayMode
,
5031 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
5036 #endif /* defined(HAVE_LIBXXF86DGA) */
5038 /* Note: Hack so we can reuse the old functions without compiler warnings */
5039 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5040 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
5042 # define XCAST(fun) (void *)
5045 static ICOM_VTABLE(IDirectDraw
) xlib_ddvt
=
5047 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5048 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
5049 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
5050 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
5051 XCAST(Compact
)IDirectDraw2Impl_Compact
,
5052 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
5053 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
5054 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
5055 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
5056 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
5057 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
5058 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
5059 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
5060 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
5061 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
5062 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
5063 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
5064 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
5065 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
5066 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
5067 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
5068 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
5069 Xlib_IDirectDrawImpl_SetDisplayMode
,
5070 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
5075 /*****************************************************************************
5080 #ifdef HAVE_LIBXXF86DGA
5081 static HRESULT WINAPI
DGA_IDirectDraw2Impl_SetDisplayMode(
5082 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD dwRefreshRate
, DWORD dwFlags
5084 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate
, dwFlags
);
5085 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
5087 #endif /* defined(HAVE_LIBXXF86DGA) */
5089 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_SetDisplayMode(
5090 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD dwRefreshRate
,DWORD dwFlags
5092 FIXME( "Ignored parameters (0x%08lx,0x%08lx)\n", dwRefreshRate
, dwFlags
);
5093 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
5096 #ifdef HAVE_LIBXXF86DGA
5097 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetAvailableVidMem(
5098 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
5100 ICOM_THIS(IDirectDraw2Impl
,iface
);
5101 TRACE("(%p)->(%p,%p,%p)\n",
5102 This
,ddscaps
,total
,free
5104 if (total
) *total
= This
->e
.dga
.fb_memsize
* 1024;
5105 if (free
) *free
= This
->e
.dga
.fb_memsize
* 1024;
5108 #endif /* defined(HAVE_LIBXXF86DGA) */
5110 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetAvailableVidMem(
5111 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
5113 ICOM_THIS(IDirectDraw2Impl
,iface
);
5114 TRACE("(%p)->(%p,%p,%p)\n",
5115 This
,ddscaps
,total
,free
5117 if (total
) *total
= 2048 * 1024;
5118 if (free
) *free
= 2048 * 1024;
5122 #ifdef HAVE_LIBXXF86DGA
5123 static ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
=
5125 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5126 DGA_IDirectDraw2Impl_QueryInterface
,
5127 IDirectDraw2Impl_AddRef
,
5128 DGA_IDirectDraw2Impl_Release
,
5129 IDirectDraw2Impl_Compact
,
5130 IDirectDraw2Impl_CreateClipper
,
5131 DGA_IDirectDraw2Impl_CreatePalette
,
5132 DGA_IDirectDraw2Impl_CreateSurface
,
5133 IDirectDraw2Impl_DuplicateSurface
,
5134 DGA_IDirectDraw2Impl_EnumDisplayModes
,
5135 IDirectDraw2Impl_EnumSurfaces
,
5136 IDirectDraw2Impl_FlipToGDISurface
,
5137 DGA_IDirectDraw2Impl_GetCaps
,
5138 DGA_IDirectDraw2Impl_GetDisplayMode
,
5139 IDirectDraw2Impl_GetFourCCCodes
,
5140 IDirectDraw2Impl_GetGDISurface
,
5141 IDirectDraw2Impl_GetMonitorFrequency
,
5142 IDirectDraw2Impl_GetScanLine
,
5143 IDirectDraw2Impl_GetVerticalBlankStatus
,
5144 IDirectDraw2Impl_Initialize
,
5145 DGA_IDirectDraw2Impl_RestoreDisplayMode
,
5146 IDirectDraw2Impl_SetCooperativeLevel
,
5147 DGA_IDirectDraw2Impl_SetDisplayMode
,
5148 IDirectDraw2Impl_WaitForVerticalBlank
,
5149 DGA_IDirectDraw2Impl_GetAvailableVidMem
5151 #endif /* defined(HAVE_LIBXXF86DGA) */
5153 static ICOM_VTABLE(IDirectDraw2
) xlib_dd2vt
=
5155 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5156 Xlib_IDirectDraw2Impl_QueryInterface
,
5157 IDirectDraw2Impl_AddRef
,
5158 Xlib_IDirectDraw2Impl_Release
,
5159 IDirectDraw2Impl_Compact
,
5160 IDirectDraw2Impl_CreateClipper
,
5161 Xlib_IDirectDraw2Impl_CreatePalette
,
5162 Xlib_IDirectDraw2Impl_CreateSurface
,
5163 IDirectDraw2Impl_DuplicateSurface
,
5164 Xlib_IDirectDraw2Impl_EnumDisplayModes
,
5165 IDirectDraw2Impl_EnumSurfaces
,
5166 IDirectDraw2Impl_FlipToGDISurface
,
5167 Xlib_IDirectDraw2Impl_GetCaps
,
5168 Xlib_IDirectDraw2Impl_GetDisplayMode
,
5169 IDirectDraw2Impl_GetFourCCCodes
,
5170 IDirectDraw2Impl_GetGDISurface
,
5171 IDirectDraw2Impl_GetMonitorFrequency
,
5172 IDirectDraw2Impl_GetScanLine
,
5173 IDirectDraw2Impl_GetVerticalBlankStatus
,
5174 IDirectDraw2Impl_Initialize
,
5175 Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
5176 IDirectDraw2Impl_SetCooperativeLevel
,
5177 Xlib_IDirectDraw2Impl_SetDisplayMode
,
5178 IDirectDraw2Impl_WaitForVerticalBlank
,
5179 Xlib_IDirectDraw2Impl_GetAvailableVidMem
5182 /*****************************************************************************
5187 static HRESULT WINAPI
IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface
,
5189 LPDIRECTDRAWSURFACE
*lpDDS
) {
5190 ICOM_THIS(IDirectDraw4Impl
,iface
);
5191 FIXME("(%p)->(%08ld,%p)\n", This
, (DWORD
) hdc
, lpDDS
);
5196 static HRESULT WINAPI
IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface
) {
5197 ICOM_THIS(IDirectDraw4Impl
,iface
);
5198 FIXME("(%p)->()\n", This
);
5203 static HRESULT WINAPI
IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface
) {
5204 ICOM_THIS(IDirectDraw4Impl
,iface
);
5205 FIXME("(%p)->()\n", This
);
5210 static HRESULT WINAPI
IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface
,
5211 LPDDDEVICEIDENTIFIER lpdddi
,
5213 ICOM_THIS(IDirectDraw4Impl
,iface
);
5214 FIXME("(%p)->(%p,%08lx)\n", This
, lpdddi
, dwFlags
);
5219 #ifdef HAVE_LIBXXF86DGA
5221 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5222 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
5224 # define XCAST(fun) (void*)
5227 static ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
=
5229 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5230 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
5231 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
5232 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
5233 XCAST(Compact
)IDirectDraw2Impl_Compact
,
5234 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
5235 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
5236 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
5237 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
5238 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
5239 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
5240 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
5241 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
5242 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
5243 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
5244 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
5245 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
5246 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
5247 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
5248 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
5249 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
5250 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
5251 XCAST(SetDisplayMode
)DGA_IDirectDrawImpl_SetDisplayMode
,
5252 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
5253 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2Impl_GetAvailableVidMem
,
5254 IDirectDraw4Impl_GetSurfaceFromDC
,
5255 IDirectDraw4Impl_RestoreAllSurfaces
,
5256 IDirectDraw4Impl_TestCooperativeLevel
,
5257 IDirectDraw4Impl_GetDeviceIdentifier
5262 #endif /* defined(HAVE_LIBXXF86DGA) */
5264 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
5265 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
5267 # define XCAST(fun) (void*)
5270 static ICOM_VTABLE(IDirectDraw4
) xlib_dd4vt
=
5272 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5273 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
5274 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
5275 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
5276 XCAST(Compact
)IDirectDraw2Impl_Compact
,
5277 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
5278 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
5279 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
5280 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
5281 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
5282 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
5283 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
5284 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
5285 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
5286 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
5287 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
5288 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
5289 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
5290 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
5291 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
5292 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
5293 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
5294 XCAST(SetDisplayMode
)Xlib_IDirectDrawImpl_SetDisplayMode
,
5295 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
5296 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2Impl_GetAvailableVidMem
,
5297 IDirectDraw4Impl_GetSurfaceFromDC
,
5298 IDirectDraw4Impl_RestoreAllSurfaces
,
5299 IDirectDraw4Impl_TestCooperativeLevel
,
5300 IDirectDraw4Impl_GetDeviceIdentifier
5305 /******************************************************************************
5309 static LRESULT WINAPI
Xlib_DDWndProc(HWND hwnd
,UINT msg
,WPARAM wParam
,LPARAM lParam
)
5312 IDirectDrawImpl
* ddraw
= NULL
;
5315 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
5317 SetLastError( ERROR_SUCCESS
);
5318 ddraw
= (IDirectDrawImpl
*)GetPropA( hwnd
, ddProp
);
5319 if( (!ddraw
) && ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
))
5321 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
5326 /* Perform any special direct draw functions */
5328 ddraw
->d
.paintable
= 1;
5330 /* Now let the application deal with the rest of this */
5331 if( ddraw
->d
.mainWindow
)
5334 /* Don't think that we actually need to call this but...
5335 might as well be on the safe side of things... */
5337 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
5338 it should be the procedures of our fake window that gets called
5339 instead of those of the window provided by the application.
5340 And with this patch, mouse clicks work with Monkey Island III
5342 ret
= DefWindowProcA( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
5346 WND
*tmpWnd
=WIN_FindWndPtr(ddraw
->d
.mainWindow
);
5347 /* We didn't handle the message - give it to the application */
5348 if (ddraw
&& ddraw
->d
.mainWindow
&& tmpWnd
)
5350 ret
= CallWindowProcA(tmpWnd
->winproc
,
5351 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
5353 WIN_ReleaseWndPtr(tmpWnd
);
5358 ret
= DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
5364 ret
= DefWindowProcA(hwnd
,msg
,wParam
,lParam
);
5370 static HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
5371 #ifdef HAVE_LIBXXF86DGA
5372 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
5373 int memsize
,banksize
,major
,minor
,flags
;
5379 /* Get DGA availability / version */
5380 dga_version
= DDRAW_DGA_Available();
5382 if (dga_version
== 0) {
5383 MessageBoxA(0,"Unable to initialize DGA.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
5384 return DDERR_GENERIC
;
5387 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
5388 (*ilplpDD
)->ref
= 1;
5389 ICOM_VTBL(*ilplpDD
) = &dga_ddvt
;
5390 #ifdef HAVE_LIBXXF86DGA2
5391 if (dga_version
== 1) {
5392 (*ilplpDD
)->e
.dga
.version
= 1;
5393 #endif /* defined(HAVE_LIBXXF86DGA2) */
5394 TSXF86DGAQueryVersion(display
,&major
,&minor
);
5395 TRACE("XF86DGA is version %d.%d\n",major
,minor
);
5396 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
5397 if (!(flags
& XF86DGADirectPresent
))
5398 MESSAGE("direct video is NOT PRESENT.\n");
5399 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
5400 (*ilplpDD
)->e
.dga
.fb_width
= width
;
5401 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
5402 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
5403 (*ilplpDD
)->e
.dga
.fb_height
= height
;
5404 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
5405 addr
,width
,banksize
,memsize
5407 TRACE("viewport height: %d\n",height
);
5408 /* Get the screen dimensions as seen by Wine.
5409 In that case, it may be better to ignore the -desktop mode and return the
5410 real screen size => print a warning */
5411 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
5412 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
5413 if (((*ilplpDD
)->d
.height
!= height
) ||
5414 ((*ilplpDD
)->d
.width
!= width
))
5415 WARN("You seem to be running in -desktop mode. This may prove dangerous in DGA mode...\n");
5416 (*ilplpDD
)->e
.dga
.fb_addr
= addr
;
5417 (*ilplpDD
)->e
.dga
.fb_memsize
= memsize
;
5418 (*ilplpDD
)->e
.dga
.vpmask
= 0;
5420 /* just assume the default depth is the DGA depth too */
5421 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
5422 _common_depth_to_pixelformat(depth
, &((*ilplpDD
)->d
.directdraw_pixelformat
), &((*ilplpDD
)->d
.screen_pixelformat
), NULL
);
5423 #ifdef RESTORE_SIGNALS
5426 #ifdef HAVE_LIBXXF86DGA2
5430 int mode_to_use
= 0;
5432 (*ilplpDD
)->e
.dga
.version
= 2;
5434 TSXDGAQueryVersion(display
,&major
,&minor
);
5435 TRACE("XDGA is version %d.%d\n",major
,minor
);
5437 TRACE("Opening the frame buffer.\n");
5438 if (!TSXDGAOpenFramebuffer(display
, DefaultScreen(display
))) {
5439 ERR("Error opening the frame buffer !!!\n");
5441 return DDERR_GENERIC
;
5444 /* List all available modes */
5445 modes
= TSXDGAQueryModes(display
, DefaultScreen(display
), &num_modes
);
5446 (*ilplpDD
)->e
.dga
.modes
= modes
;
5447 (*ilplpDD
)->e
.dga
.num_modes
= num_modes
;
5448 if (TRACE_ON(ddraw
)) {
5449 TRACE("Available modes :\n");
5450 for (i
= 0; i
< num_modes
; i
++) {
5451 DPRINTF(" %d) - %s (FB: %dx%d / VP: %dx%d) - depth %d -",
5453 modes
[i
].name
, modes
[i
].imageWidth
, modes
[i
].imageHeight
,
5454 modes
[i
].viewportWidth
, modes
[i
].viewportHeight
,
5456 if (modes
[i
].flags
& XDGAConcurrentAccess
) DPRINTF(" XDGAConcurrentAccess ");
5457 if (modes
[i
].flags
& XDGASolidFillRect
) DPRINTF(" XDGASolidFillRect ");
5458 if (modes
[i
].flags
& XDGABlitRect
) DPRINTF(" XDGABlitRect ");
5459 if (modes
[i
].flags
& XDGABlitTransRect
) DPRINTF(" XDGABlitTransRect ");
5460 if (modes
[i
].flags
& XDGAPixmap
) DPRINTF(" XDGAPixmap ");
5463 if ((MONITOR_GetHeight(&MONITOR_PrimaryMonitor
) == modes
[i
].viewportHeight
) &&
5464 (MONITOR_GetWidth(&MONITOR_PrimaryMonitor
) == modes
[i
].viewportWidth
) &&
5465 (MONITOR_GetDepth(&MONITOR_PrimaryMonitor
) == modes
[i
].depth
)) {
5466 mode_to_use
= modes
[i
].num
;
5470 if (mode_to_use
== 0) {
5471 ERR("Could not find mode !\n");
5474 DPRINTF("Using mode number %d\n", mode_to_use
);
5477 /* Initialize the frame buffer */
5478 _DGA_Initialize_FrameBuffer(*ilplpDD
, mode_to_use
);
5479 /* Set the input handling for relative mouse movements */
5480 X11DRV_EVENT_SetInputMehod(X11DRV_INPUT_RELATIVE
);
5482 #endif /* defined(HAVE_LIBXXF86DGA2) */
5484 #else /* defined(HAVE_LIBXXF86DGA) */
5485 return DDERR_INVALIDDIRECTDRAWGUID
;
5486 #endif /* defined(HAVE_LIBXXF86DGA) */
5490 DDRAW_XSHM_Available(void)
5492 #ifdef HAVE_LIBXXSHM
5493 if (TSXShmQueryExtension(display
))
5498 if ((TSXShmQueryVersion(display
, &major
, &minor
, &shpix
)) &&
5499 (Options
.noXSHM
!= 1))
5511 static HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
5512 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
5515 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
5516 ICOM_VTBL(*ilplpDD
) = &xlib_ddvt
;
5517 (*ilplpDD
)->ref
= 1;
5518 (*ilplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
5520 /* At DirectDraw creation, the depth is the default depth */
5521 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
5522 _common_depth_to_pixelformat(depth
,
5523 &((*ilplpDD
)->d
.directdraw_pixelformat
),
5524 &((*ilplpDD
)->d
.screen_pixelformat
),
5525 &((*ilplpDD
)->d
.pixmap_depth
));
5526 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
5527 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
5529 #ifdef HAVE_LIBXXSHM
5530 /* Test if XShm is available. */
5531 if (((*ilplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available())) {
5532 (*ilplpDD
)->e
.xlib
.xshm_compl
= 0;
5533 TRACE("Using XShm extension.\n");
5540 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
5541 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
5543 /* WND* pParentWindow; */
5546 if (!HIWORD(lpGUID
)) lpGUID
= NULL
;
5548 TRACE("(%s,%p,%p)\n",debugstr_guid(lpGUID
),ilplpDD
,pUnkOuter
);
5551 ( IsEqualGUID( &IID_IDirectDraw
, lpGUID
) ) ||
5552 ( IsEqualGUID( &IID_IDirectDraw2
, lpGUID
) ) ||
5553 ( IsEqualGUID( &IID_IDirectDraw4
, lpGUID
) ) ) {
5554 /* if they didn't request a particular interface, use the best
5556 if (DDRAW_DGA_Available())
5557 lpGUID
= &DGA_DirectDraw_GUID
;
5559 lpGUID
= &XLIB_DirectDraw_GUID
;
5562 wc
.style
= CS_GLOBALCLASS
;
5563 wc
.lpfnWndProc
= Xlib_DDWndProc
;
5567 /* We can be a child of the desktop since we're really important */
5569 This code is not useful since hInstance is forced to 0 afterward
5570 pParentWindow = WIN_GetDesktop();
5571 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5577 wc
.hCursor
= (HCURSOR
)IDC_ARROWA
;
5578 wc
.hbrBackground
= NULL_BRUSH
;
5579 wc
.lpszMenuName
= 0;
5580 wc
.lpszClassName
= "WINE_DirectDraw";
5581 RegisterClassA(&wc
);
5583 if ( IsEqualGUID( &DGA_DirectDraw_GUID
, lpGUID
) ) {
5584 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
5586 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID
, &XLIB_DirectDraw_GUID
) ) {
5587 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
5594 (*ilplpDD
)->d
.winclass
= RegisterClassA(&wc
);
5598 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",
5599 debugstr_guid(lpGUID
),lplpDD
,pUnkOuter
);
5600 return DDERR_INVALIDDIRECTDRAWGUID
;
5603 /*******************************************************************************
5604 * DirectDraw ClassFactory
5606 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5611 /* IUnknown fields */
5612 ICOM_VFIELD(IClassFactory
);
5614 } IClassFactoryImpl
;
5616 static HRESULT WINAPI
5617 DDCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
) {
5618 ICOM_THIS(IClassFactoryImpl
,iface
);
5620 FIXME("(%p)->(%s,%p),stub!\n",This
,debugstr_guid(riid
),ppobj
);
5621 return E_NOINTERFACE
;
5625 DDCF_AddRef(LPCLASSFACTORY iface
) {
5626 ICOM_THIS(IClassFactoryImpl
,iface
);
5627 return ++(This
->ref
);
5630 static ULONG WINAPI
DDCF_Release(LPCLASSFACTORY iface
) {
5631 ICOM_THIS(IClassFactoryImpl
,iface
);
5632 /* static class, won't be freed */
5633 return --(This
->ref
);
5636 static HRESULT WINAPI
DDCF_CreateInstance(
5637 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
5639 ICOM_THIS(IClassFactoryImpl
,iface
);
5641 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,debugstr_guid(riid
),ppobj
);
5642 if ( ( IsEqualGUID( &IID_IDirectDraw
, riid
) ) ||
5643 ( IsEqualGUID( &IID_IDirectDraw2
, riid
) ) ||
5644 ( IsEqualGUID( &IID_IDirectDraw4
, riid
) ) ) {
5645 /* FIXME: reuse already created DirectDraw if present? */
5646 return DirectDrawCreate((LPGUID
) riid
,(LPDIRECTDRAW
*)ppobj
,pOuter
);
5648 return CLASS_E_CLASSNOTAVAILABLE
;
5651 static HRESULT WINAPI
DDCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
5652 ICOM_THIS(IClassFactoryImpl
,iface
);
5653 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
5657 static ICOM_VTABLE(IClassFactory
) DDCF_Vtbl
=
5659 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5660 DDCF_QueryInterface
,
5663 DDCF_CreateInstance
,
5666 static IClassFactoryImpl DDRAW_CF
= {&DDCF_Vtbl
, 1 };
5668 /*******************************************************************************
5669 * DllGetClassObject [DDRAW.13]
5670 * Retrieves class object from a DLL object
5673 * Docs say returns STDAPI
5676 * rclsid [I] CLSID for the class object
5677 * riid [I] Reference to identifier of interface for class object
5678 * ppv [O] Address of variable to receive interface pointer for riid
5682 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5685 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
,REFIID riid
,LPVOID
*ppv
)
5687 TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
5688 if ( IsEqualCLSID( &IID_IClassFactory
, riid
) ) {
5689 *ppv
= (LPVOID
)&DDRAW_CF
;
5690 IClassFactory_AddRef((IClassFactory
*)*ppv
);
5693 FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
5694 return CLASS_E_CLASSNOTAVAILABLE
;
5698 /*******************************************************************************
5699 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5705 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5707 FIXME("(void): stub\n");
5711 #else /* !defined(X_DISPLAY_MISSING) */
5718 typedef void *LPUNKNOWN
;
5719 typedef void *LPDIRECTDRAW
;
5720 typedef void *LPDIRECTDRAWCLIPPER
;
5721 typedef void *LPDDENUMCALLBACKA
;
5722 typedef void *LPDDENUMCALLBACKEXA
;
5723 typedef void *LPDDENUMCALLBACKEXW
;
5724 typedef void *LPDDENUMCALLBACKW
;
5726 HRESULT WINAPI
DSoundHelp(DWORD x
, DWORD y
, DWORD z
)
5731 HRESULT WINAPI
DirectDrawCreate(
5732 LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
)
5737 HRESULT WINAPI
DirectDrawCreateClipper(
5738 DWORD dwFlags
, LPDIRECTDRAWCLIPPER
*lplpDDClipper
, LPUNKNOWN pUnkOuter
)
5743 HRESULT WINAPI
DirectDrawEnumerateA(
5744 LPDDENUMCALLBACKA lpCallback
, LPVOID lpContext
)
5749 HRESULT WINAPI
DirectDrawEnumerateExA(
5750 LPDDENUMCALLBACKEXA lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5755 HRESULT WINAPI
DirectDrawEnumerateExW(
5756 LPDDENUMCALLBACKEXW lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5761 HRESULT WINAPI
DirectDrawEnumerateW(
5762 LPDDENUMCALLBACKW lpCallback
, LPVOID lpContext
)
5767 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
5769 return CLASS_E_CLASSNOTAVAILABLE
;
5772 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5777 #endif /* !defined(X_DISPLAY_MISSING) */