1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997-1999 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
19 #ifndef X_DISPLAY_MISSING
25 #include <sys/types.h>
29 #endif /* defined(HAVE_LIBXXSHM) */
31 #ifdef HAVE_LIBXXF86DGA
32 #include "ts_xf86dga.h"
33 #endif /* defined(HAVE_LIBXXF86DGA) */
35 #ifdef HAVE_LIBXXF86VM
36 #include "ts_xf86vmode.h"
37 #endif /* defined(HAVE_LIBXXF86VM) */
43 #include <sys/signal.h>
53 #include "wine/exception.h"
56 #include "debugtools.h"
62 /* This for all the enumeration and creation of D3D-related objects */
63 #include "ddraw_private.h"
64 #include "d3d_private.h"
66 DEFAULT_DEBUG_CHANNEL(ddraw
)
68 /* Restore signal handlers overwritten by XF86DGA
70 #define RESTORE_SIGNALS
72 /* Get DDSCAPS of surface (shortcutmacro) */
73 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
76 /* Get the number of bytes per pixel for a given surface */
77 #define GET_BPP(desc) (desc.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8 ? \
79 desc.ddpfPixelFormat.x.dwRGBBitCount / 8)
81 /* Where do these GUIDs come from? mkuuid.
82 * They exist solely to distinguish between the targets Wine support,
83 * and should be different than any other GUIDs in existence.
85 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
89 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
92 static GUID XLIB_DirectDraw_GUID
= { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
96 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
99 #ifdef HAVE_LIBXXF86DGA
100 static struct ICOM_VTABLE(IDirectDrawSurface4
) dga_dds4vt
;
101 static struct ICOM_VTABLE(IDirectDraw
) dga_ddvt
;
102 static struct ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
;
103 static struct ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
;
104 static struct ICOM_VTABLE(IDirectDrawPalette
) dga_ddpalvt
;
105 #endif /* defined(HAVE_LIBXXF86DGA) */
107 static struct ICOM_VTABLE(IDirectDrawSurface4
) xlib_dds4vt
;
108 static struct ICOM_VTABLE(IDirectDraw
) xlib_ddvt
;
109 static struct ICOM_VTABLE(IDirectDraw2
) xlib_dd2vt
;
110 static struct ICOM_VTABLE(IDirectDraw4
) xlib_dd4vt
;
111 static struct ICOM_VTABLE(IDirectDrawPalette
) xlib_ddpalvt
;
113 static struct ICOM_VTABLE(IDirectDrawClipper
) ddclipvt
;
114 static struct ICOM_VTABLE(IDirect3D
) d3dvt
;
115 static struct ICOM_VTABLE(IDirect3D2
) d3d2vt
;
117 /* This is for mode-emulation */
119 static void pixel_convert_16_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
120 static void palette_convert_16_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) ;
121 static void palette_convert_15_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) ;
122 static void pixel_convert_24_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
123 static void pixel_convert_32_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
124 static void palette_convert_24_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) ;
125 static void pixel_convert_32_to_16(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
129 unsigned short depth
;
136 void (*pixel_convert
)(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
);
137 void (*palette_convert
)(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
);
141 ConvertMode screen
, dest
;
145 static Convert ModeEmulations
[] = {
146 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8
, palette_convert_24_to_8
} },
147 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16
, NULL
} },
148 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8
, palette_convert_24_to_8
} },
149 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8
, palette_convert_16_to_8
} },
150 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8
, palette_convert_15_to_8
} },
153 #ifdef HAVE_LIBXXF86VM
154 static XF86VidModeModeInfo
*orig_mode
= NULL
;
158 static int XShmErrorFlag
= 0;
162 DDRAW_DGA_Available(void)
164 #ifdef HAVE_LIBXXF86DGA
165 int evbase
, evret
, fd
;
170 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
171 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
172 /* others. --stephenc */
173 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
176 return (fd
!= -1) && TSXF86DGAQueryExtension(display
,&evbase
,&evret
);
177 #else /* defined(HAVE_LIBXXF86DGA) */
179 #endif /* defined(HAVE_LIBXXF86DGA) */
182 /**********************************************************************/
187 } DirectDrawEnumerateProcData
;
189 /***********************************************************************
190 * DirectDrawEnumerateExA (DDRAW.*)
192 HRESULT WINAPI
DirectDrawEnumerateExA(
193 LPDDENUMCALLBACKEXA lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
195 TRACE("(%p,%p, %08lx)\n", lpCallback
, lpContext
, dwFlags
);
197 if (TRACE_ON(ddraw
)) {
198 DPRINTF(" Flags : ");
199 if (dwFlags
& DDENUM_ATTACHEDSECONDARYDEVICES
)
200 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
201 if (dwFlags
& DDENUM_DETACHEDSECONDARYDEVICES
)
202 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
203 if (dwFlags
& DDENUM_NONDISPLAYDEVICES
)
204 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
208 if (dwFlags
== DDENUM_NONDISPLAYDEVICES
) {
209 /* For the moment, Wine does not support any 3D only accelerators */
213 if (DDRAW_DGA_Available()) {
214 TRACE("Enumerating DGA interface\n");
215 if (!lpCallback(&DGA_DirectDraw_GUID
, "WINE with XFree86 DGA", "display", lpContext
, 0))
219 TRACE("Enumerating Xlib interface\n");
220 if (!lpCallback(&XLIB_DirectDraw_GUID
, "WINE with Xlib", "display", lpContext
, 0))
223 TRACE("Enumerating Default interface\n");
224 if (!lpCallback(NULL
,"WINE (default)", "display", lpContext
, 0))
230 /***********************************************************************
231 * DirectDrawEnumerateExW (DDRAW.*)
234 static BOOL CALLBACK
DirectDrawEnumerateExProcW(
235 GUID
*lpGUID
, LPSTR lpDriverDescription
, LPSTR lpDriverName
,
236 LPVOID lpContext
, HMONITOR hm
)
238 DirectDrawEnumerateProcData
*pEPD
=
239 (DirectDrawEnumerateProcData
*) lpContext
;
240 LPWSTR lpDriverDescriptionW
=
241 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription
);
242 LPWSTR lpDriverNameW
=
243 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName
);
245 BOOL bResult
= (*(LPDDENUMCALLBACKEXW
*) pEPD
->lpCallback
)(
246 lpGUID
, lpDriverDescriptionW
, lpDriverNameW
, pEPD
->lpContext
, hm
);
248 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW
);
249 HeapFree(GetProcessHeap(), 0, lpDriverNameW
);
254 /**********************************************************************/
256 HRESULT WINAPI
DirectDrawEnumerateExW(
257 LPDDENUMCALLBACKEXW lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
259 DirectDrawEnumerateProcData epd
;
260 epd
.lpCallback
= (LPVOID
) lpCallback
;
261 epd
.lpContext
= lpContext
;
263 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW
,
267 /***********************************************************************
268 * DirectDrawEnumerateA (DDRAW.*)
271 static BOOL CALLBACK
DirectDrawEnumerateProcA(
272 GUID
*lpGUID
, LPSTR lpDriverDescription
, LPSTR lpDriverName
,
273 LPVOID lpContext
, HMONITOR hm
)
275 DirectDrawEnumerateProcData
*pEPD
=
276 (DirectDrawEnumerateProcData
*) lpContext
;
278 return ((LPDDENUMCALLBACKA
) pEPD
->lpCallback
)(
279 lpGUID
, lpDriverDescription
, lpDriverName
, pEPD
->lpContext
);
282 /**********************************************************************/
284 HRESULT WINAPI
DirectDrawEnumerateA(
285 LPDDENUMCALLBACKA lpCallback
, LPVOID lpContext
)
287 DirectDrawEnumerateProcData epd
;
288 epd
.lpCallback
= (LPVOID
) lpCallback
;
289 epd
.lpContext
= lpContext
;
291 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA
,
295 /***********************************************************************
296 * DirectDrawEnumerateW (DDRAW.*)
299 static BOOL WINAPI
DirectDrawEnumerateProcW(
300 GUID
*lpGUID
, LPWSTR lpDriverDescription
, LPWSTR lpDriverName
,
301 LPVOID lpContext
, HMONITOR hm
)
303 DirectDrawEnumerateProcData
*pEPD
=
304 (DirectDrawEnumerateProcData
*) lpContext
;
306 return ((LPDDENUMCALLBACKW
) pEPD
->lpCallback
)(
307 lpGUID
, lpDriverDescription
, lpDriverName
,
311 /**********************************************************************/
313 HRESULT WINAPI
DirectDrawEnumerateW(
314 LPDDENUMCALLBACKW lpCallback
, LPVOID lpContext
)
316 DirectDrawEnumerateProcData epd
;
317 epd
.lpCallback
= (LPVOID
) lpCallback
;
318 epd
.lpContext
= lpContext
;
320 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW
,
324 /***********************************************************************
325 * DSoundHelp (DDRAW.?)
328 /* What is this doing here? */
330 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
331 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
335 /******************************************************************************
336 * internal helper functions
338 static void _dump_DDBLTFX(DWORD flagmask
) {
344 #define FE(x) { x, #x},
345 FE(DDBLTFX_ARITHSTRETCHY
)
346 FE(DDBLTFX_MIRRORLEFTRIGHT
)
347 FE(DDBLTFX_MIRRORUPDOWN
)
348 FE(DDBLTFX_NOTEARING
)
349 FE(DDBLTFX_ROTATE180
)
350 FE(DDBLTFX_ROTATE270
)
352 FE(DDBLTFX_ZBUFFERRANGE
)
353 FE(DDBLTFX_ZBUFFERBASEDEST
)
356 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
357 if (flags
[i
].mask
& flagmask
) {
358 DPRINTF("%s ",flags
[i
].name
);
365 static void _dump_DDBLTFAST(DWORD flagmask
) {
371 #define FE(x) { x, #x},
372 FE(DDBLTFAST_NOCOLORKEY
)
373 FE(DDBLTFAST_SRCCOLORKEY
)
374 FE(DDBLTFAST_DESTCOLORKEY
)
378 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
379 if (flags
[i
].mask
& flagmask
)
380 DPRINTF("%s ",flags
[i
].name
);
384 static void _dump_DDBLT(DWORD flagmask
) {
390 #define FE(x) { x, #x},
392 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
393 FE(DDBLT_ALPHADESTNEG
)
394 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
395 FE(DDBLT_ALPHAEDGEBLEND
)
397 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
398 FE(DDBLT_ALPHASRCNEG
)
399 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
405 FE(DDBLT_KEYDESTOVERRIDE
)
407 FE(DDBLT_KEYSRCOVERRIDE
)
409 FE(DDBLT_ROTATIONANGLE
)
411 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
412 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
413 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
414 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
419 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
420 if (flags
[i
].mask
& flagmask
)
421 DPRINTF("%s ",flags
[i
].name
);
425 static void _dump_DDSCAPS(void *in
) {
431 #define FE(x) { x, #x},
432 FE(DDSCAPS_RESERVED1
)
434 FE(DDSCAPS_BACKBUFFER
)
437 FE(DDSCAPS_FRONTBUFFER
)
438 FE(DDSCAPS_OFFSCREENPLAIN
)
441 FE(DDSCAPS_PRIMARYSURFACE
)
442 FE(DDSCAPS_PRIMARYSURFACELEFT
)
443 FE(DDSCAPS_SYSTEMMEMORY
)
446 FE(DDSCAPS_VIDEOMEMORY
)
448 FE(DDSCAPS_WRITEONLY
)
451 FE(DDSCAPS_LIVEVIDEO
)
455 FE(DDSCAPS_RESERVED2
)
456 FE(DDSCAPS_ALLOCONLOAD
)
457 FE(DDSCAPS_VIDEOPORT
)
458 FE(DDSCAPS_LOCALVIDMEM
)
459 FE(DDSCAPS_NONLOCALVIDMEM
)
460 FE(DDSCAPS_STANDARDVGAMODE
)
461 FE(DDSCAPS_OPTIMIZED
)
464 DWORD flagmask
= *((DWORD
*) in
);
465 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
466 if (flags
[i
].mask
& flagmask
)
467 DPRINTF("%s ",flags
[i
].name
);
470 static void _dump_pixelformat_flag(DWORD flagmask
) {
476 #define FE(x) { x, #x},
480 FE(DDPF_PALETTEINDEXED4
)
481 FE(DDPF_PALETTEINDEXEDTO8
)
482 FE(DDPF_PALETTEINDEXED8
)
488 FE(DDPF_PALETTEINDEXED1
)
489 FE(DDPF_PALETTEINDEXED2
)
493 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
494 if (flags
[i
].mask
& flagmask
)
495 DPRINTF("%s ",flags
[i
].name
);
498 static void _dump_paletteformat(DWORD dwFlags
) {
504 #define FE(x) { x, #x},
506 FE(DDPCAPS_8BITENTRIES
)
508 FE(DDPCAPS_INITIALIZE
)
509 FE(DDPCAPS_PRIMARYSURFACE
)
510 FE(DDPCAPS_PRIMARYSURFACELEFT
)
518 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
519 if (flags
[i
].mask
& dwFlags
)
520 DPRINTF("%s ",flags
[i
].name
);
524 static void _dump_pixelformat(void *in
) {
525 LPDDPIXELFORMAT pf
= (LPDDPIXELFORMAT
) in
;
529 _dump_pixelformat_flag(pf
->dwFlags
);
530 if (pf
->dwFlags
& DDPF_FOURCC
) {
531 DPRINTF(", dwFourCC : %ld", pf
->dwFourCC
);
533 if (pf
->dwFlags
& DDPF_RGB
) {
534 DPRINTF(", RGB bits: %ld, ", pf
->x
.dwRGBBitCount
);
535 switch (pf
->x
.dwRGBBitCount
) {
552 ERR("Unexpected bit depth !\n");
555 DPRINTF(" R "); DPRINTF(cmd
, pf
->y
.dwRBitMask
);
556 DPRINTF(" G "); DPRINTF(cmd
, pf
->z
.dwGBitMask
);
557 DPRINTF(" B "); DPRINTF(cmd
, pf
->xx
.dwBBitMask
);
558 if (pf
->dwFlags
& DDPF_ALPHAPIXELS
) {
559 DPRINTF(" A "); DPRINTF(cmd
, pf
->xy
.dwRGBAlphaBitMask
);
561 if (pf
->dwFlags
& DDPF_ZPIXELS
) {
562 DPRINTF(" Z "); DPRINTF(cmd
, pf
->xy
.dwRGBZBitMask
);
565 if (pf
->dwFlags
& DDPF_ZBUFFER
) {
566 DPRINTF(", Z bits : %ld", pf
->x
.dwZBufferBitDepth
);
568 if (pf
->dwFlags
& DDPF_ALPHA
) {
569 DPRINTF(", Alpha bits : %ld", pf
->x
.dwAlphaBitDepth
);
574 static void _dump_colorkeyflag(DWORD ck
) {
580 #define FE(x) { x, #x},
581 FE(DDCKEY_COLORSPACE
)
583 FE(DDCKEY_DESTOVERLAY
)
585 FE(DDCKEY_SRCOVERLAY
)
588 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
589 if (flags
[i
].mask
& ck
)
590 DPRINTF("%s ",flags
[i
].name
);
593 static void _dump_DWORD(void *in
) {
594 DPRINTF("%ld", *((DWORD
*) in
));
596 static void _dump_PTR(void *in
) {
597 DPRINTF("%p", *((void **) in
));
599 static void _dump_DDCOLORKEY(void *in
) {
600 DDCOLORKEY
*ddck
= (DDCOLORKEY
*) in
;
602 DPRINTF(" Low : %ld - High : %ld", ddck
->dwColorSpaceLowValue
, ddck
->dwColorSpaceHighValue
);
605 static void _dump_surface_desc(DDSURFACEDESC
*lpddsd
) {
610 void (*func
)(void *);
612 } flags
[16], *fe
= flags
;
613 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
614 FE(DDSD_CAPS
, _dump_DDSCAPS
, ddsCaps
);
615 FE(DDSD_HEIGHT
, _dump_DWORD
, dwHeight
);
616 FE(DDSD_WIDTH
, _dump_DWORD
, dwWidth
);
617 FE(DDSD_PITCH
, _dump_DWORD
, lPitch
);
618 FE(DDSD_BACKBUFFERCOUNT
, _dump_DWORD
, dwBackBufferCount
);
619 FE(DDSD_ZBUFFERBITDEPTH
, _dump_DWORD
, x
.dwZBufferBitDepth
);
620 FE(DDSD_ALPHABITDEPTH
, _dump_DWORD
, dwAlphaBitDepth
);
621 FE(DDSD_PIXELFORMAT
, _dump_pixelformat
, ddpfPixelFormat
);
622 FE(DDSD_CKDESTOVERLAY
, _dump_DDCOLORKEY
, ddckCKDestOverlay
);
623 FE(DDSD_CKDESTBLT
, _dump_DDCOLORKEY
, ddckCKDestBlt
);
624 FE(DDSD_CKSRCOVERLAY
, _dump_DDCOLORKEY
, ddckCKSrcOverlay
);
625 FE(DDSD_CKSRCBLT
, _dump_DDCOLORKEY
, ddckCKSrcBlt
);
626 FE(DDSD_MIPMAPCOUNT
, _dump_DWORD
, x
.dwMipMapCount
);
627 FE(DDSD_REFRESHRATE
, _dump_DWORD
, x
.dwRefreshRate
);
628 FE(DDSD_LINEARSIZE
, _dump_DWORD
, y
.dwLinearSize
);
629 FE(DDSD_LPSURFACE
, _dump_PTR
, y
.lpSurface
);
632 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
633 if (flags
[i
].mask
& lpddsd
->dwFlags
) {
634 DPRINTF(" - %s : ",flags
[i
].name
);
635 flags
[i
].func(flags
[i
].elt
);
641 /******************************************************************************
642 * IDirectDrawSurface methods
644 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
645 * DDS and DDS2 use those functions. (Function calls did not change (except
646 * using different DirectDrawSurfaceX version), just added flags and functions)
649 static HRESULT WINAPI
IDirectDrawSurface4Impl_Lock(
650 LPDIRECTDRAWSURFACE4 iface
,LPRECT lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE hnd
652 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
653 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
654 This
,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
655 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
656 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
657 This
,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
659 /* First, copy the Surface description */
660 *lpddsd
= This
->s
.surface_desc
;
661 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
662 lpddsd
->dwHeight
,lpddsd
->dwWidth
,lpddsd
->lPitch
);
664 /* If asked only for a part, change the surface pointer */
666 TRACE(" lprect: %dx%d-%dx%d\n",
667 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
669 if ((lprect
->top
< 0) ||
670 (lprect
->left
< 0) ||
671 (lprect
->bottom
< 0) ||
672 (lprect
->right
< 0)) {
673 ERR(" Negative values in LPRECT !!!\n");
674 return DDERR_INVALIDPARAMS
;
677 lpddsd
->y
.lpSurface
= (LPVOID
) ((char *) This
->s
.surface_desc
.y
.lpSurface
+
678 (lprect
->top
*This
->s
.surface_desc
.lPitch
) +
679 (lprect
->left
*(This
->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8)));
681 assert(This
->s
.surface_desc
.y
.lpSurface
);
686 #ifdef HAVE_LIBXXF86DGA
687 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_Unlock(
688 LPDIRECTDRAWSURFACE4 iface
,LPVOID surface
690 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
691 TRACE("(%p)->Unlock(%p)\n",This
,surface
);
694 #endif /* defined(HAVE_LIBXXF86DGA) */
696 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl
* This
) {
697 if (This
->s
.ddraw
->d
.pixel_convert
!= NULL
)
698 This
->s
.ddraw
->d
.pixel_convert(This
->s
.surface_desc
.y
.lpSurface
,
699 This
->t
.xlib
.image
->data
,
700 This
->s
.surface_desc
.dwWidth
,
701 This
->s
.surface_desc
.dwHeight
,
702 This
->s
.surface_desc
.lPitch
,
706 if (This
->s
.ddraw
->e
.xlib
.xshm_active
)
707 TSXShmPutImage(display
,
708 This
->s
.ddraw
->d
.drawable
,
709 DefaultGCOfScreen(X11DRV_GetXScreen()),
712 This
->t
.xlib
.image
->width
,
713 This
->t
.xlib
.image
->height
,
717 TSXPutImage( display
,
718 This
->s
.ddraw
->d
.drawable
,
719 DefaultGCOfScreen(X11DRV_GetXScreen()),
722 This
->t
.xlib
.image
->width
,
723 This
->t
.xlib
.image
->height
);
726 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Unlock(
727 LPDIRECTDRAWSURFACE4 iface
,LPVOID surface
)
729 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
730 TRACE("(%p)->Unlock(%p)\n",This
,surface
);
732 if (!This
->s
.ddraw
->d
.paintable
)
735 /* Only redraw the screen when unlocking the buffer that is on screen */
736 if (This
->t
.xlib
.image
&& (SDDSCAPS(This
) & DDSCAPS_VISIBLE
)) {
737 Xlib_copy_surface_on_screen(This
);
739 if (This
->s
.palette
&& This
->s
.palette
->cm
)
740 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
745 static IDirectDrawSurface4Impl
* _common_find_flipto(
746 IDirectDrawSurface4Impl
* This
,IDirectDrawSurface4Impl
* flipto
749 struct _surface_chain
*chain
= This
->s
.chain
;
751 /* if there was no override flipto, look for current backbuffer */
753 /* walk the flip chain looking for backbuffer */
754 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
755 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
)
757 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_BACKBUFFER
)
758 flipto
= chain
->surfaces
[i
];
760 /* sanity checks ... */
763 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
764 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FRONTBUFFER
)
766 if (i
==chain
->nrofsurfaces
) {
767 /* we do not have a frontbuffer either */
768 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
769 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
) {
770 SDDSCAPS(chain
->surfaces
[i
])|=DDSCAPS_FRONTBUFFER
;
773 for (j
=i
+1;j
<i
+chain
->nrofsurfaces
+1;j
++) {
774 int k
= j
% chain
->nrofsurfaces
;
775 if (SDDSCAPS(chain
->surfaces
[k
]) & DDSCAPS_FLIP
) {
776 SDDSCAPS(chain
->surfaces
[k
])|=DDSCAPS_BACKBUFFER
;
777 flipto
= chain
->surfaces
[k
];
786 TRACE("flipping to %p\n",flipto
);
791 #ifdef HAVE_LIBXXF86DGA
792 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_Flip(
793 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
795 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
796 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
800 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
801 iflipto
= _common_find_flipto(This
,iflipto
);
804 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,iflipto
->t
.dga
.fb_height
);
805 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
806 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),iflipto
->s
.palette
->cm
);
807 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
810 /* We need to switch the lowlevel surfaces, for DGA this is: */
812 /* The height within the framebuffer */
813 xheight
= This
->t
.dga
.fb_height
;
814 This
->t
.dga
.fb_height
= iflipto
->t
.dga
.fb_height
;
815 iflipto
->t
.dga
.fb_height
= xheight
;
817 /* And the assciated surface pointer */
818 surf
= This
->s
.surface_desc
.y
.lpSurface
;
819 This
->s
.surface_desc
.y
.lpSurface
= iflipto
->s
.surface_desc
.y
.lpSurface
;
820 iflipto
->s
.surface_desc
.y
.lpSurface
= surf
;
824 #endif /* defined(HAVE_LIBXXF86DGA) */
826 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Flip(
827 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
829 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
832 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
834 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
835 iflipto
= _common_find_flipto(This
,iflipto
);
837 #if defined(HAVE_MESAGL) && 0 /* does not work */
838 if (This
->s
.d3d_device
|| (iflipto
&& iflipto
->s
.d3d_device
)) {
839 TRACE(" - OpenGL flip\n");
841 glXSwapBuffers(display
, This
->s
.ddraw
->d
.drawable
);
846 #endif /* defined(HAVE_MESAGL) */
848 if (!This
->s
.ddraw
->d
.paintable
)
851 /* We need to switch the lowlevel surfaces, for xlib this is: */
852 /* The surface pointer */
853 surf
= This
->s
.surface_desc
.y
.lpSurface
;
854 This
->s
.surface_desc
.y
.lpSurface
= iflipto
->s
.surface_desc
.y
.lpSurface
;
855 iflipto
->s
.surface_desc
.y
.lpSurface
= surf
;
856 /* the associated ximage */
857 image
= This
->t
.xlib
.image
;
858 This
->t
.xlib
.image
= iflipto
->t
.xlib
.image
;
859 iflipto
->t
.xlib
.image
= image
;
861 Xlib_copy_surface_on_screen(This
);
863 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
864 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,iflipto
->s
.palette
->cm
);
868 /* The IDirectDrawSurface4::SetPalette method attaches the specified
869 * DirectDrawPalette object to a surface. The surface uses this palette for all
870 * subsequent operations. The palette change takes place immediately.
872 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_SetPalette(
873 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
875 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
876 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
878 TRACE("(%p)->(%p)\n",This
,ipal
);
881 if( This
->s
.palette
!= NULL
)
882 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
883 This
->s
.palette
= ipal
;
888 if( !(ipal
->cm
) && (This
->s
.ddraw
->d
.screen_pixelformat
.x
.dwRGBBitCount
<=8))
890 ipal
->cm
= TSXCreateColormap(display
,This
->s
.ddraw
->d
.drawable
,
891 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
893 if (!Options
.managed
)
894 TSXInstallColormap(display
,ipal
->cm
);
896 for (i
=0;i
<256;i
++) {
899 xc
.red
= ipal
->palents
[i
].peRed
<<8;
900 xc
.blue
= ipal
->palents
[i
].peBlue
<<8;
901 xc
.green
= ipal
->palents
[i
].peGreen
<<8;
902 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
904 TSXStoreColor(display
,ipal
->cm
,&xc
);
906 TSXInstallColormap(display
,ipal
->cm
);
909 /* According to spec, we are only supposed to
910 * AddRef if this is not the same palette.
912 if( This
->s
.palette
!= ipal
)
915 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
916 if( This
->s
.palette
!= NULL
)
917 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
918 This
->s
.palette
= ipal
;
919 /* Perform the refresh */
920 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
925 #ifdef HAVE_LIBXXF86DGA
926 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_SetPalette(
927 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
929 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
930 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
931 TRACE("(%p)->(%p)\n",This
,ipal
);
933 /* According to spec, we are only supposed to
934 * AddRef if this is not the same palette.
936 if( This
->s
.palette
!= ipal
)
939 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
940 if( This
->s
.palette
!= NULL
)
941 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
942 This
->s
.palette
= ipal
;
943 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->s
.palette
->cm
);
947 #endif /* defined(HAVE_LIBXXF86DGA) */
949 static HRESULT
_Blt_ColorFill(LPBYTE buf
, int width
, int height
, int bpp
, LONG lPitch
, DWORD color
)
956 #define COLORFILL_ROW(type) { \
957 type *d = (type *) buf; \
958 for (x = 0; x < width; x++) \
959 d[x] = (type) color; \
964 case 1: COLORFILL_ROW(BYTE
)
965 case 2: COLORFILL_ROW(WORD
)
966 case 4: COLORFILL_ROW(DWORD
)
968 FIXME("Color fill not implemented for bpp %d!\n", bpp
*8);
969 return DDERR_UNSUPPORTED
;
974 /* Now copy first row */
976 for (y
= 1; y
< height
; y
++) {
978 memcpy(buf
, first
, width
* bpp
);
984 static HRESULT WINAPI
IDirectDrawSurface4Impl_Blt(
985 LPDIRECTDRAWSURFACE4 iface
,LPRECT rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
987 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
989 DDSURFACEDESC ddesc
,sdesc
;
991 int bpp
, srcheight
, srcwidth
, dstheight
, dstwidth
, width
;
995 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This
,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
997 if (src
) IDirectDrawSurface4_Lock(src
, NULL
, &sdesc
, 0, 0);
998 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,0,0);
1000 if (TRACE_ON(ddraw
)) {
1001 if (rdst
) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
1002 if (rsrc
) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1004 _dump_DDBLT(dwFlags
);
1005 if (dwFlags
& DDBLT_DDFX
) {
1006 TRACE("\tblitfx: ");
1007 _dump_DDBLTFX(lpbltfx
->dwDDFX
);
1012 memcpy(&xdst
,rdst
,sizeof(xdst
));
1015 xdst
.bottom
= ddesc
.dwHeight
;
1017 xdst
.right
= ddesc
.dwWidth
;
1021 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
1025 xsrc
.bottom
= sdesc
.dwHeight
;
1027 xsrc
.right
= sdesc
.dwWidth
;
1029 memset(&xsrc
,0,sizeof(xsrc
));
1033 bpp
= GET_BPP(ddesc
);
1034 srcheight
= xsrc
.bottom
- xsrc
.top
;
1035 srcwidth
= xsrc
.right
- xsrc
.left
;
1036 dstheight
= xdst
.bottom
- xdst
.top
;
1037 dstwidth
= xdst
.right
- xdst
.left
;
1038 width
= (xdst
.right
- xdst
.left
) * bpp
;
1039 dbuf
= (BYTE
*) ddesc
.y
.lpSurface
+ (xdst
.top
* ddesc
.lPitch
) + (xdst
.left
* bpp
);
1041 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
1043 /* First, all the 'source-less' blits */
1044 if (dwFlags
& DDBLT_COLORFILL
) {
1045 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
,
1046 ddesc
.lPitch
, lpbltfx
->b
.dwFillColor
);
1047 dwFlags
&= ~DDBLT_COLORFILL
;
1050 if (dwFlags
& DDBLT_DEPTHFILL
) {
1054 /* Clears the screen */
1055 TRACE(" Filling depth buffer with %ld\n", lpbltfx
->b
.dwFillDepth
);
1056 glClearDepth(lpbltfx
->b
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
1057 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
1058 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
1059 glClear(GL_DEPTH_BUFFER_BIT
);
1062 dwFlags
&= ~(DDBLT_DEPTHFILL
);
1063 #endif /* defined(HAVE_MESAGL) */
1066 if (dwFlags
& DDBLT_ROP
) {
1067 /* Catch some degenerate cases here */
1068 switch(lpbltfx
->dwROP
) {
1070 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, 0);
1072 case 0xAA0029: /* No-op */
1075 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, ~0);
1078 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx
->dwROP
, lpbltfx
->b
.lpDDSPattern
);
1081 dwFlags
&= ~DDBLT_ROP
;
1084 if (dwFlags
& DDBLT_DDROPS
) {
1085 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx
->dwDDROP
, lpbltfx
->b
.lpDDSPattern
);
1088 /* Now the 'with source' blits */
1091 int sx
, xinc
, sy
, yinc
;
1093 sbase
= (BYTE
*) sdesc
.y
.lpSurface
+ (xsrc
.top
* sdesc
.lPitch
) + xsrc
.left
* bpp
;
1094 xinc
= (srcwidth
<< 16) / dstwidth
;
1095 yinc
= (srcheight
<< 16) / dstheight
;
1099 /* No effects, we can cheat here */
1100 if (dstwidth
== srcwidth
) {
1101 if (dstheight
== srcheight
) {
1102 /* No stretching in either direction. This needs to be as fast as possible */
1104 for (y
= 0; y
< dstheight
; y
++) {
1105 memcpy(dbuf
, sbuf
, width
);
1106 sbuf
+= sdesc
.lPitch
;
1107 dbuf
+= ddesc
.lPitch
;
1110 /* Stretching in Y direction only */
1111 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1112 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1113 memcpy(dbuf
, sbuf
, width
);
1114 dbuf
+= ddesc
.lPitch
;
1118 /* Stretching in X direction */
1120 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1121 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1123 if ((sy
>> 16) == (last_sy
>> 16)) {
1124 /* Same as last row - copy already stretched row */
1125 memcpy(dbuf
, dbuf
- ddesc
.lPitch
, width
);
1128 #define STRETCH_ROW(type) { \
1129 type *s = (type *) sbuf, *d = (type *) dbuf; \
1130 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1131 d[x] = s[sx >> 16]; \
1135 case 1: STRETCH_ROW(BYTE
)
1136 case 2: STRETCH_ROW(WORD
)
1137 case 4: STRETCH_ROW(DWORD
)
1139 FIXME("Stretched blit not implemented for bpp %d!\n", bpp
*8);
1140 ret
= DDERR_UNSUPPORTED
;
1148 dbuf
+= ddesc
.lPitch
;
1151 } else if (dwFlags
& (DDBLT_KEYSRC
| DDBLT_KEYDEST
)) {
1152 DWORD keylow
, keyhigh
;
1154 if (dwFlags
& DDBLT_KEYSRC
) {
1155 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1156 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1158 /* I'm not sure if this is correct */
1159 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1160 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1161 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1165 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1166 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1168 #define COPYROW_COLORKEY(type) { \
1169 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1170 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1171 tmp = s[sx >> 16]; \
1172 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1177 case 1: COPYROW_COLORKEY(BYTE
)
1178 case 2: COPYROW_COLORKEY(WORD
)
1179 case 4: COPYROW_COLORKEY(DWORD
)
1181 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1182 (dwFlags
& DDBLT_KEYSRC
) ? "Source" : "Destination", bpp
*8);
1183 ret
= DDERR_UNSUPPORTED
;
1186 dbuf
+= ddesc
.lPitch
;
1189 #undef COPYROW_COLORKEY
1191 dwFlags
&= ~(DDBLT_KEYSRC
| DDBLT_KEYDEST
);
1198 if (dwFlags
&& FIXME_ON(ddraw
)) {
1199 FIXME("\tUnsupported flags: ");
1200 _dump_DDBLT(dwFlags
);
1203 IDirectDrawSurface4_Unlock(iface
,ddesc
.y
.lpSurface
);
1204 if (src
) IDirectDrawSurface4_Unlock(src
,sdesc
.y
.lpSurface
);
1209 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltFast(
1210 LPDIRECTDRAWSURFACE4 iface
,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD trans
1212 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1213 int bpp
, w
, h
, x
, y
;
1214 DDSURFACEDESC ddesc
,sdesc
;
1215 HRESULT ret
= DD_OK
;
1219 if (TRACE_ON(ddraw
)) {
1220 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1221 This
,dstx
,dsty
,src
,rsrc
,trans
1224 if (FIXME_ON(ddraw
))
1225 _dump_DDBLTFAST(trans
);
1226 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1228 /* We need to lock the surfaces, or we won't get refreshes when done. */
1229 IDirectDrawSurface4_Lock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
1230 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
1232 bpp
= GET_BPP(This
->s
.surface_desc
);
1233 sbuf
= (BYTE
*) sdesc
.y
.lpSurface
+ (rsrc
->top
* sdesc
.lPitch
) + rsrc
->left
* bpp
;
1234 dbuf
= (BYTE
*) ddesc
.y
.lpSurface
+ (dsty
* ddesc
.lPitch
) + dstx
* bpp
;
1237 h
=rsrc
->bottom
-rsrc
->top
;
1238 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
1239 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
1242 w
=rsrc
->right
-rsrc
->left
;
1243 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
1244 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
1247 if (trans
& (DDBLTFAST_SRCCOLORKEY
| DDBLTFAST_DESTCOLORKEY
)) {
1248 DWORD keylow
, keyhigh
;
1249 if (trans
& DDBLTFAST_SRCCOLORKEY
) {
1250 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1251 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1253 /* I'm not sure if this is correct */
1254 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1255 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1256 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1259 #define COPYBOX_COLORKEY(type) { \
1260 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1261 s = (type *) ((BYTE *) sdesc.y.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1262 d = (type *) ((BYTE *) ddesc.y.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1263 for (y = 0; y < h; y++) { \
1264 for (x = 0; x < w; x++) { \
1266 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1268 (LPBYTE)s += sdesc.lPitch; \
1269 (LPBYTE)d += ddesc.lPitch; \
1275 case 1: COPYBOX_COLORKEY(BYTE
)
1276 case 2: COPYBOX_COLORKEY(WORD
)
1277 case 4: COPYBOX_COLORKEY(DWORD
)
1279 FIXME("Source color key blitting not supported for bpp %d\n", bpp
*8);
1280 ret
= DDERR_UNSUPPORTED
;
1284 #undef COPYBOX_COLORKEY
1287 int width
= w
* bpp
;
1289 for (y
= 0; y
< h
; y
++) {
1290 memcpy(dbuf
, sbuf
, width
);
1291 sbuf
+= sdesc
.lPitch
;
1292 dbuf
+= ddesc
.lPitch
;
1298 IDirectDrawSurface4_Unlock(iface
,ddesc
.y
.lpSurface
);
1299 IDirectDrawSurface4_Unlock(src
,sdesc
.y
.lpSurface
);
1303 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltBatch(
1304 LPDIRECTDRAWSURFACE4 iface
,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
1306 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1307 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1313 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetCaps(
1314 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS caps
1316 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1317 TRACE("(%p)->GetCaps(%p)\n",This
,caps
);
1318 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
1322 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetSurfaceDesc(
1323 LPDIRECTDRAWSURFACE4 iface
,LPDDSURFACEDESC ddsd
1325 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1326 TRACE("(%p)->GetSurfaceDesc(%p)\n", This
,ddsd
);
1328 /* Simply copy the surface description stored in the object */
1329 *ddsd
= This
->s
.surface_desc
;
1331 if (TRACE_ON(ddraw
)) { _dump_surface_desc(ddsd
); }
1336 static ULONG WINAPI
IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface
) {
1337 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1338 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
1339 return ++(This
->ref
);
1342 #ifdef HAVE_LIBXXF86DGA
1343 static ULONG WINAPI
DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1344 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1346 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1351 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1352 /* clear out of surface list */
1353 if (This
->t
.dga
.fb_height
== -1)
1354 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.y
.lpSurface
);
1356 This
->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(This
->t
.dga
.fb_height
/This
->s
.ddraw
->e
.dga
.fb_height
));
1358 /* Free the DIBSection (if any) */
1359 if (This
->s
.hdc
!= 0) {
1360 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1361 DeleteDC(This
->s
.hdc
);
1362 DeleteObject(This
->s
.DIBsection
);
1365 HeapFree(GetProcessHeap(),0,This
);
1368 #endif /* defined(HAVE_LIBXXF86DGA) */
1370 static ULONG WINAPI
Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1371 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1373 TRACE( "(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1378 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1380 if (This
->t
.xlib
.image
!= NULL
) {
1381 if (This
->s
.ddraw
->d
.pixel_convert
!= NULL
) {
1382 /* In pixel conversion mode, there are 2 buffers to release. */
1383 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.y
.lpSurface
);
1385 #ifdef HAVE_LIBXXSHM
1386 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1387 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1388 TSXDestroyImage(This
->t
.xlib
.image
);
1389 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1392 HeapFree(GetProcessHeap(),0,This
->t
.xlib
.image
->data
);
1393 This
->t
.xlib
.image
->data
= NULL
;
1394 TSXDestroyImage(This
->t
.xlib
.image
);
1395 #ifdef HAVE_LIBXXSHM
1399 This
->t
.xlib
.image
->data
= NULL
;
1401 #ifdef HAVE_LIBXXSHM
1402 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1403 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1404 TSXDestroyImage(This
->t
.xlib
.image
);
1405 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1408 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.y
.lpSurface
);
1409 TSXDestroyImage(This
->t
.xlib
.image
);
1410 #ifdef HAVE_LIBXXSHM
1414 This
->t
.xlib
.image
= 0;
1416 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.y
.lpSurface
);
1419 if (This
->s
.palette
)
1420 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
1422 /* Free the DIBSection (if any) */
1423 if (This
->s
.hdc
!= 0) {
1424 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1425 DeleteDC(This
->s
.hdc
);
1426 DeleteObject(This
->s
.DIBsection
);
1429 HeapFree(GetProcessHeap(),0,This
);
1433 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetAttachedSurface(
1434 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1436 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1437 int i
,found
= 0,xstart
;
1438 struct _surface_chain
*chain
;
1440 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This
, lpddsd
, lpdsf
);
1441 if (TRACE_ON(ddraw
)) {
1442 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd
->dwCaps
));
1444 chain
= This
->s
.chain
;
1446 return DDERR_NOTFOUND
;
1448 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1449 if (chain
->surfaces
[i
] == This
)
1453 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1454 if ((SDDSCAPS(chain
->surfaces
[(xstart
+i
)%chain
->nrofsurfaces
])&lpddsd
->dwCaps
) == lpddsd
->dwCaps
) {
1456 if (found
) /* may not find the same caps twice, (doc) */
1457 return DDERR_INVALIDPARAMS
;/*FIXME: correct? */
1459 found
= (i
+1)+xstart
;
1463 return DDERR_NOTFOUND
;
1464 *lpdsf
= (LPDIRECTDRAWSURFACE4
)chain
->surfaces
[found
-1-xstart
];
1465 /* FIXME: AddRef? */
1466 TRACE("found %p\n",*lpdsf
);
1470 static HRESULT WINAPI
IDirectDrawSurface4Impl_Initialize(
1471 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1473 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1474 TRACE("(%p)->(%p, %p)\n",This
,ddraw
,lpdsfd
);
1476 return DDERR_ALREADYINITIALIZED
;
1479 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPixelFormat(
1480 LPDIRECTDRAWSURFACE4 iface
,LPDDPIXELFORMAT pf
1482 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1483 TRACE("(%p)->(%p)\n",This
,pf
);
1485 *pf
= This
->s
.surface_desc
.ddpfPixelFormat
;
1486 if (TRACE_ON(ddraw
)) { _dump_pixelformat(pf
); DPRINTF("\n"); }
1490 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface
,DWORD dwFlags
) {
1491 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1492 FIXME("(%p)->(0x%08lx),stub!\n",This
,dwFlags
);
1496 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetOverlayPosition(
1497 LPDIRECTDRAWSURFACE4 iface
,LPLONG x1
,LPLONG x2
1499 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1500 FIXME("(%p)->(%p,%p),stub!\n",This
,x1
,x2
);
1504 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetClipper(
1505 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWCLIPPER clipper
1507 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1508 FIXME("(%p)->(%p),stub!\n",This
,clipper
);
1512 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddAttachedSurface(
1513 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 surf
1515 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1516 IDirectDrawSurface4Impl
*isurf
= (IDirectDrawSurface4Impl
*)surf
;
1518 struct _surface_chain
*chain
;
1520 IDirectDrawSurface4_AddRef(iface
);
1522 FIXME("(%p)->(%p)\n",This
,surf
);
1523 chain
= This
->s
.chain
;
1526 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1527 if (chain
->surfaces
[i
] == isurf
)
1528 FIXME("attaching already attached surface %p to %p!\n",iface
,isurf
);
1530 chain
= HeapAlloc(GetProcessHeap(),0,sizeof(*chain
));
1531 chain
->nrofsurfaces
= 1;
1532 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1533 chain
->surfaces
[0] = This
;
1534 This
->s
.chain
= chain
;
1537 if (chain
->surfaces
)
1538 chain
->surfaces
= HeapReAlloc(
1542 sizeof(chain
->surfaces
[0])*(chain
->nrofsurfaces
+1)
1545 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1546 isurf
->s
.chain
= chain
;
1547 chain
->surfaces
[chain
->nrofsurfaces
++] = isurf
;
1551 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface
,HDC
* lphdc
) {
1552 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1557 FIXME("(%p)->GetDC(%p)\n",This
,lphdc
);
1559 /* Creates a DIB Section of the same size / format as the surface */
1560 IDirectDrawSurface4_Lock(iface
,NULL
,&desc
,0,0);
1562 if (This
->s
.hdc
== 0) {
1563 switch (desc
.ddpfPixelFormat
.x
.dwRGBBitCount
) {
1566 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1567 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 3 * sizeof(DWORD
));
1572 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
));
1576 b_info
= (BITMAPINFO
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1577 sizeof(BITMAPINFOHEADER
) + sizeof(RGBQUAD
) * (2 << desc
.ddpfPixelFormat
.x
.dwRGBBitCount
));
1581 b_info
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
1582 b_info
->bmiHeader
.biWidth
= desc
.dwWidth
;
1583 b_info
->bmiHeader
.biHeight
= desc
.dwHeight
;
1584 b_info
->bmiHeader
.biPlanes
= 1;
1585 b_info
->bmiHeader
.biBitCount
= desc
.ddpfPixelFormat
.x
.dwRGBBitCount
;
1587 if ((desc
.ddpfPixelFormat
.x
.dwRGBBitCount
!= 16) &&
1588 (desc
.ddpfPixelFormat
.x
.dwRGBBitCount
!= 32))
1590 b_info
->bmiHeader
.biCompression
= BI_RGB
;
1593 b_info
->bmiHeader
.biCompression
= BI_BITFIELDS
;
1595 b_info
->bmiHeader
.biSizeImage
= (desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8) * desc
.dwWidth
* desc
.dwHeight
;
1596 b_info
->bmiHeader
.biXPelsPerMeter
= 0;
1597 b_info
->bmiHeader
.biYPelsPerMeter
= 0;
1598 b_info
->bmiHeader
.biClrUsed
= 0;
1599 b_info
->bmiHeader
.biClrImportant
= 0;
1601 switch (desc
.ddpfPixelFormat
.x
.dwRGBBitCount
) {
1606 DWORD
*masks
= (DWORD
*) &(b_info
->bmiColors
);
1609 masks
[0] = desc
.ddpfPixelFormat
.y
.dwRBitMask
;
1610 masks
[1] = desc
.ddpfPixelFormat
.z
.dwGBitMask
;
1611 masks
[2] = desc
.ddpfPixelFormat
.xx
.dwBBitMask
;
1617 usage
= DIB_RGB_COLORS
;
1623 /* Fill the palette */
1624 usage
= DIB_RGB_COLORS
;
1626 if (This
->s
.palette
== NULL
) {
1627 ERR("Bad palette !!!\n");
1629 RGBQUAD
*rgb
= (RGBQUAD
*) &(b_info
->bmiColors
);
1630 PALETTEENTRY
*pent
= (PALETTEENTRY
*)&(This
->s
.palette
->palents
);
1632 for (i
=0;i
<(1<<desc
.ddpfPixelFormat
.x
.dwRGBBitCount
);i
++) {
1633 rgb
[i
].rgbBlue
= pent
[i
].peBlue
;
1634 rgb
[i
].rgbRed
= pent
[i
].peRed
;
1635 rgb
[i
].rgbGreen
= pent
[i
].peGreen
;
1641 This
->s
.DIBsection
= CreateDIBSection(BeginPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
),
1644 &(This
->s
.bitmap_data
),
1648 EndPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
);
1649 TRACE("DIBSection at : %p\n", This
->s
.bitmap_data
);
1651 /* b_info is not useful anymore */
1652 HeapFree(GetProcessHeap(), 0, b_info
);
1655 This
->s
.hdc
= CreateCompatibleDC(0);
1656 This
->s
.holdbitmap
= SelectObject(This
->s
.hdc
, This
->s
.DIBsection
);
1659 /* Copy our surface in the DIB section */
1660 if ((GET_BPP(desc
) * desc
.dwWidth
) == desc
.lPitch
)
1661 memcpy(This
->s
.bitmap_data
,desc
.y
.lpSurface
,desc
.lPitch
*desc
.dwHeight
);
1664 FIXME("This case has to be done :/\n");
1666 TRACE("HDC : %08lx\n", (DWORD
) This
->s
.hdc
);
1667 *lphdc
= This
->s
.hdc
;
1672 static HRESULT WINAPI
IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface
,HDC hdc
) {
1673 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1675 FIXME("(%p)->(0x%08lx),stub!\n",This
,(long)hdc
);
1676 TRACE( "Copying DIBSection at : %p\n", This
->s
.bitmap_data
);
1677 /* Copy the DIB section to our surface */
1678 if ((GET_BPP(This
->s
.surface_desc
) * This
->s
.surface_desc
.dwWidth
) == This
->s
.surface_desc
.lPitch
) {
1679 memcpy(This
->s
.surface_desc
.y
.lpSurface
, This
->s
.bitmap_data
, This
->s
.surface_desc
.lPitch
* This
->s
.surface_desc
.dwHeight
);
1682 FIXME("This case has to be done :/\n");
1684 /* Unlock the surface */
1685 IDirectDrawSurface4_Unlock(iface
,This
->s
.surface_desc
.y
.lpSurface
);
1689 static HRESULT WINAPI
IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface
,REFIID refiid
,LPVOID
*obj
) {
1690 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1693 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1694 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
1696 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1697 * the same interface. And IUnknown does that too of course.
1699 if ( !memcmp(&IID_IDirectDrawSurface4
,refiid
,sizeof(IID
)) ||
1700 !memcmp(&IID_IDirectDrawSurface3
,refiid
,sizeof(IID
)) ||
1701 !memcmp(&IID_IDirectDrawSurface2
,refiid
,sizeof(IID
)) ||
1702 !memcmp(&IID_IDirectDrawSurface
,refiid
,sizeof(IID
)) ||
1703 !memcmp(&IID_IUnknown
,refiid
,sizeof(IID
))
1706 IDirectDrawSurface4_AddRef(iface
);
1708 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj
);
1711 else if (!memcmp(&IID_IDirect3DTexture2
,refiid
,sizeof(IID
)))
1713 /* Texture interface */
1714 *obj
= d3dtexture2_create(This
);
1715 IDirectDrawSurface4_AddRef(iface
);
1716 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1719 else if (!memcmp(&IID_IDirect3DTexture
,refiid
,sizeof(IID
)))
1721 /* Texture interface */
1722 *obj
= d3dtexture_create(This
);
1723 IDirectDrawSurface4_AddRef(iface
);
1725 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj
);
1729 else if (is_OpenGL_dx3(refiid
, (IDirectDrawSurfaceImpl
*)This
, (IDirect3DDeviceImpl
**) obj
)) {
1730 /* It is the OpenGL Direct3D Device */
1731 IDirectDrawSurface4_AddRef(iface
);
1732 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj
);
1736 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
1737 return OLE_E_ENUM_NOMORE
;
1740 static HRESULT WINAPI
IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface
) {
1741 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1742 TRACE("(%p)->(), stub!\n",This
);
1743 return DD_OK
; /* hmm */
1746 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface
,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1747 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1749 struct _surface_chain
*chain
= This
->s
.chain
;
1751 TRACE("(%p)->(%p,%p)\n",This
,context
,esfcb
);
1752 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1753 TRACE( "Enumerating attached surface (%p)\n", chain
->surfaces
[i
]);
1754 if (esfcb((LPDIRECTDRAWSURFACE
) chain
->surfaces
[i
], &(chain
->surfaces
[i
]->s
.surface_desc
), context
) == DDENUMRET_CANCEL
)
1755 return DD_OK
; /* FIXME: return value correct? */
1760 static HRESULT WINAPI
IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface
) {
1761 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1762 FIXME("(%p)->(),stub!\n",This
);
1766 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetColorKey(
1767 LPDIRECTDRAWSURFACE4 iface
, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1769 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1770 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,ckey
);
1771 if (TRACE_ON(ddraw
)) {
1772 _dump_colorkeyflag(dwFlags
);
1774 _dump_DDCOLORKEY((void *) ckey
);
1778 /* If this surface was loaded as a texture, call also the texture
1779 SetColorKey callback */
1780 if (This
->s
.texture
) {
1781 This
->s
.SetColorKey_cb(This
->s
.texture
, dwFlags
, ckey
);
1784 if( dwFlags
& DDCKEY_SRCBLT
)
1786 dwFlags
&= ~DDCKEY_SRCBLT
;
1787 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1788 memcpy( &(This
->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1791 if( dwFlags
& DDCKEY_DESTBLT
)
1793 dwFlags
&= ~DDCKEY_DESTBLT
;
1794 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1795 memcpy( &(This
->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1798 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1800 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1801 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1802 memcpy( &(This
->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1805 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1807 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1808 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1809 memcpy( &(This
->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1814 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
1821 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1822 LPDIRECTDRAWSURFACE4 iface
,
1825 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1826 FIXME("(%p)->(%p),stub!\n",This
,lpRect
);
1831 static HRESULT WINAPI
IDirectDrawSurface4Impl_DeleteAttachedSurface(
1832 LPDIRECTDRAWSURFACE4 iface
,
1834 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
1836 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1838 struct _surface_chain
*chain
;
1840 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,lpDDSAttachedSurface
);
1841 chain
= This
->s
.chain
;
1842 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1843 if ((IDirectDrawSurface4Impl
*)lpDDSAttachedSurface
==chain
->surfaces
[i
]){
1844 IDirectDrawSurface4_Release(lpDDSAttachedSurface
);
1846 chain
->surfaces
[i
]->s
.chain
= NULL
;
1847 memcpy( chain
->surfaces
+i
,
1848 chain
->surfaces
+(i
+1),
1849 (chain
->nrofsurfaces
-i
-1)*sizeof(chain
->surfaces
[i
])
1851 chain
->surfaces
= HeapReAlloc(
1855 sizeof(chain
->surfaces
[i
])*(chain
->nrofsurfaces
-1)
1857 chain
->nrofsurfaces
--;
1864 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumOverlayZOrders(
1865 LPDIRECTDRAWSURFACE4 iface
,
1868 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1870 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1871 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This
,dwFlags
,
1872 lpContext
, lpfnCallback
);
1877 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetClipper(
1878 LPDIRECTDRAWSURFACE4 iface
,
1879 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1881 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1882 FIXME("(%p)->(%p),stub!\n", This
, lplpDDClipper
);
1887 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetColorKey(
1888 LPDIRECTDRAWSURFACE4 iface
,
1890 LPDDCOLORKEY lpDDColorKey
)
1892 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1893 TRACE("(%p)->(0x%08lx,%p)\n", This
, dwFlags
, lpDDColorKey
);
1895 if( dwFlags
& DDCKEY_SRCBLT
) {
1896 dwFlags
&= ~DDCKEY_SRCBLT
;
1897 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
1900 if( dwFlags
& DDCKEY_DESTBLT
)
1902 dwFlags
&= ~DDCKEY_DESTBLT
;
1903 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
1906 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1908 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1909 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
1912 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1914 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1915 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
1920 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
1926 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetFlipStatus(
1927 LPDIRECTDRAWSURFACE4 iface
,
1930 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1931 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
1936 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPalette(
1937 LPDIRECTDRAWSURFACE4 iface
,
1938 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1940 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1941 FIXME("(%p)->(%p),stub!\n", This
, lplpDDPalette
);
1946 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetOverlayPosition(
1947 LPDIRECTDRAWSURFACE4 iface
,
1951 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1952 FIXME("(%p)->(%ld,%ld),stub!\n", This
, lX
, lY
);
1957 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlay(
1958 LPDIRECTDRAWSURFACE4 iface
,
1960 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
1963 LPDDOVERLAYFX lpDDOverlayFx
)
1965 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1966 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This
,
1967 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1972 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1973 LPDIRECTDRAWSURFACE4 iface
,
1976 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1977 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
1982 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1983 LPDIRECTDRAWSURFACE4 iface
,
1985 LPDIRECTDRAWSURFACE4 lpDDSReference
)
1987 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1988 FIXME("(%p)->(0x%08lx,%p),stub!\n", This
, dwFlags
, lpDDSReference
);
1993 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDDInterface(
1994 LPDIRECTDRAWSURFACE4 iface
,
1997 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1998 FIXME("(%p)->(%p),stub!\n", This
, lplpDD
);
2000 /* Not sure about that... */
2001 *lplpDD
= (void *) This
->s
.ddraw
;
2006 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageLock(
2007 LPDIRECTDRAWSURFACE4 iface
,
2010 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2011 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2016 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageUnlock(
2017 LPDIRECTDRAWSURFACE4 iface
,
2020 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2021 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2026 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetSurfaceDesc(
2027 LPDIRECTDRAWSURFACE4 iface
,
2028 LPDDSURFACEDESC lpDDSD
,
2031 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2032 FIXME("(%p)->(%p,0x%08lx),stub!\n", This
, lpDDSD
, dwFlags
);
2037 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2042 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2043 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This
, guidTag
, lpData
, cbSize
, dwFlags
);
2048 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2051 LPDWORD lpcbBufferSize
) {
2052 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2053 FIXME("(%p)->(%p,%p,%p)\n", This
, guidTag
, lpBuffer
, lpcbBufferSize
);
2058 static HRESULT WINAPI
IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface
,
2060 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2061 FIXME("(%p)->(%p)\n", This
, guidTag
);
2066 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface
,
2068 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2069 FIXME("(%p)->(%p)\n", This
, lpValue
);
2074 static HRESULT WINAPI
IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface
) {
2075 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2076 FIXME("(%p)\n", This
);
2081 #ifdef HAVE_LIBXXF86DGA
2082 static ICOM_VTABLE(IDirectDrawSurface4
) dga_dds4vt
=
2084 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2085 IDirectDrawSurface4Impl_QueryInterface
,
2086 IDirectDrawSurface4Impl_AddRef
,
2087 DGA_IDirectDrawSurface4Impl_Release
,
2088 IDirectDrawSurface4Impl_AddAttachedSurface
,
2089 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2090 IDirectDrawSurface4Impl_Blt
,
2091 IDirectDrawSurface4Impl_BltBatch
,
2092 IDirectDrawSurface4Impl_BltFast
,
2093 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2094 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2095 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2096 DGA_IDirectDrawSurface4Impl_Flip
,
2097 IDirectDrawSurface4Impl_GetAttachedSurface
,
2098 IDirectDrawSurface4Impl_GetBltStatus
,
2099 IDirectDrawSurface4Impl_GetCaps
,
2100 IDirectDrawSurface4Impl_GetClipper
,
2101 IDirectDrawSurface4Impl_GetColorKey
,
2102 IDirectDrawSurface4Impl_GetDC
,
2103 IDirectDrawSurface4Impl_GetFlipStatus
,
2104 IDirectDrawSurface4Impl_GetOverlayPosition
,
2105 IDirectDrawSurface4Impl_GetPalette
,
2106 IDirectDrawSurface4Impl_GetPixelFormat
,
2107 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2108 IDirectDrawSurface4Impl_Initialize
,
2109 IDirectDrawSurface4Impl_IsLost
,
2110 IDirectDrawSurface4Impl_Lock
,
2111 IDirectDrawSurface4Impl_ReleaseDC
,
2112 IDirectDrawSurface4Impl_Restore
,
2113 IDirectDrawSurface4Impl_SetClipper
,
2114 IDirectDrawSurface4Impl_SetColorKey
,
2115 IDirectDrawSurface4Impl_SetOverlayPosition
,
2116 DGA_IDirectDrawSurface4Impl_SetPalette
,
2117 DGA_IDirectDrawSurface4Impl_Unlock
,
2118 IDirectDrawSurface4Impl_UpdateOverlay
,
2119 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2120 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2121 IDirectDrawSurface4Impl_GetDDInterface
,
2122 IDirectDrawSurface4Impl_PageLock
,
2123 IDirectDrawSurface4Impl_PageUnlock
,
2124 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2125 IDirectDrawSurface4Impl_SetPrivateData
,
2126 IDirectDrawSurface4Impl_GetPrivateData
,
2127 IDirectDrawSurface4Impl_FreePrivateData
,
2128 IDirectDrawSurface4Impl_GetUniquenessValue
,
2129 IDirectDrawSurface4Impl_ChangeUniquenessValue
2131 #endif /* defined(HAVE_LIBXXF86DGA) */
2133 static ICOM_VTABLE(IDirectDrawSurface4
) xlib_dds4vt
=
2135 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2136 IDirectDrawSurface4Impl_QueryInterface
,
2137 IDirectDrawSurface4Impl_AddRef
,
2138 Xlib_IDirectDrawSurface4Impl_Release
,
2139 IDirectDrawSurface4Impl_AddAttachedSurface
,
2140 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2141 IDirectDrawSurface4Impl_Blt
,
2142 IDirectDrawSurface4Impl_BltBatch
,
2143 IDirectDrawSurface4Impl_BltFast
,
2144 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2145 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2146 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2147 Xlib_IDirectDrawSurface4Impl_Flip
,
2148 IDirectDrawSurface4Impl_GetAttachedSurface
,
2149 IDirectDrawSurface4Impl_GetBltStatus
,
2150 IDirectDrawSurface4Impl_GetCaps
,
2151 IDirectDrawSurface4Impl_GetClipper
,
2152 IDirectDrawSurface4Impl_GetColorKey
,
2153 IDirectDrawSurface4Impl_GetDC
,
2154 IDirectDrawSurface4Impl_GetFlipStatus
,
2155 IDirectDrawSurface4Impl_GetOverlayPosition
,
2156 IDirectDrawSurface4Impl_GetPalette
,
2157 IDirectDrawSurface4Impl_GetPixelFormat
,
2158 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2159 IDirectDrawSurface4Impl_Initialize
,
2160 IDirectDrawSurface4Impl_IsLost
,
2161 IDirectDrawSurface4Impl_Lock
,
2162 IDirectDrawSurface4Impl_ReleaseDC
,
2163 IDirectDrawSurface4Impl_Restore
,
2164 IDirectDrawSurface4Impl_SetClipper
,
2165 IDirectDrawSurface4Impl_SetColorKey
,
2166 IDirectDrawSurface4Impl_SetOverlayPosition
,
2167 Xlib_IDirectDrawSurface4Impl_SetPalette
,
2168 Xlib_IDirectDrawSurface4Impl_Unlock
,
2169 IDirectDrawSurface4Impl_UpdateOverlay
,
2170 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2171 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2172 IDirectDrawSurface4Impl_GetDDInterface
,
2173 IDirectDrawSurface4Impl_PageLock
,
2174 IDirectDrawSurface4Impl_PageUnlock
,
2175 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2176 IDirectDrawSurface4Impl_SetPrivateData
,
2177 IDirectDrawSurface4Impl_GetPrivateData
,
2178 IDirectDrawSurface4Impl_FreePrivateData
,
2179 IDirectDrawSurface4Impl_GetUniquenessValue
,
2180 IDirectDrawSurface4Impl_ChangeUniquenessValue
2183 /******************************************************************************
2184 * DirectDrawCreateClipper (DDRAW.7)
2186 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
2187 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
2188 LPUNKNOWN pUnkOuter
)
2190 IDirectDrawClipperImpl
** ilplpDDClipper
=(IDirectDrawClipperImpl
**)lplpDDClipper
;
2191 TRACE("(%08lx,%p,%p)\n", dwFlags
, ilplpDDClipper
, pUnkOuter
);
2193 *ilplpDDClipper
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
2194 (*ilplpDDClipper
)->lpvtbl
= &ddclipvt
;
2195 (*ilplpDDClipper
)->ref
= 1;
2200 /******************************************************************************
2201 * IDirectDrawClipper
2203 static HRESULT WINAPI
IDirectDrawClipperImpl_SetHwnd(
2204 LPDIRECTDRAWCLIPPER iface
,DWORD x
,HWND hwnd
2206 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2207 FIXME("(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This
,x
,(DWORD
)hwnd
);
2211 static ULONG WINAPI
IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface
) {
2212 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2213 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2218 HeapFree(GetProcessHeap(),0,This
);
2222 static HRESULT WINAPI
IDirectDrawClipperImpl_GetClipList(
2223 LPDIRECTDRAWCLIPPER iface
,LPRECT rects
,LPRGNDATA lprgn
,LPDWORD hmm
2225 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2226 FIXME("(%p,%p,%p,%p),stub!\n",This
,rects
,lprgn
,hmm
);
2231 static HRESULT WINAPI
IDirectDrawClipperImpl_SetClipList(
2232 LPDIRECTDRAWCLIPPER iface
,LPRGNDATA lprgn
,DWORD hmm
2234 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2235 FIXME("(%p,%p,%ld),stub!\n",This
,lprgn
,hmm
);
2239 static HRESULT WINAPI
IDirectDrawClipperImpl_QueryInterface(
2240 LPDIRECTDRAWCLIPPER iface
,
2244 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2245 FIXME("(%p)->(%p,%p),stub!\n",This
,riid
,ppvObj
);
2246 return OLE_E_ENUM_NOMORE
;
2249 static ULONG WINAPI
IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface
)
2251 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2252 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2253 return ++(This
->ref
);
2256 static HRESULT WINAPI
IDirectDrawClipperImpl_GetHWnd(
2257 LPDIRECTDRAWCLIPPER iface
,
2260 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2261 FIXME("(%p)->(%p),stub!\n",This
,HWndPtr
);
2265 static HRESULT WINAPI
IDirectDrawClipperImpl_Initialize(
2266 LPDIRECTDRAWCLIPPER iface
,
2270 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2271 FIXME("(%p)->(%p,0x%08lx),stub!\n",This
,lpDD
,dwFlags
);
2275 static HRESULT WINAPI
IDirectDrawClipperImpl_IsClipListChanged(
2276 LPDIRECTDRAWCLIPPER iface
,
2279 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2280 FIXME("(%p)->(%p),stub!\n",This
,lpbChanged
);
2284 static ICOM_VTABLE(IDirectDrawClipper
) ddclipvt
=
2286 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2287 IDirectDrawClipperImpl_QueryInterface
,
2288 IDirectDrawClipperImpl_AddRef
,
2289 IDirectDrawClipperImpl_Release
,
2290 IDirectDrawClipperImpl_GetClipList
,
2291 IDirectDrawClipperImpl_GetHWnd
,
2292 IDirectDrawClipperImpl_Initialize
,
2293 IDirectDrawClipperImpl_IsClipListChanged
,
2294 IDirectDrawClipperImpl_SetClipList
,
2295 IDirectDrawClipperImpl_SetHwnd
2299 /******************************************************************************
2300 * IDirectDrawPalette
2302 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetEntries(
2303 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2305 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2308 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2309 This
,x
,start
,count
,palent
);
2311 /* No palette created and not in depth-convertion mode -> BUG ! */
2312 if ((This
->cm
== None
) &&
2313 (This
->ddraw
->d
.palette_convert
== NULL
))
2315 FIXME("app tried to read colormap for non-palettized mode\n");
2316 return DDERR_GENERIC
;
2318 for (i
=0;i
<count
;i
++) {
2319 palent
[i
].peRed
= This
->palents
[start
+i
].peRed
;
2320 palent
[i
].peBlue
= This
->palents
[start
+i
].peBlue
;
2321 palent
[i
].peGreen
= This
->palents
[start
+i
].peGreen
;
2322 palent
[i
].peFlags
= This
->palents
[start
+i
].peFlags
;
2328 static HRESULT WINAPI
Xlib_IDirectDrawPaletteImpl_SetEntries(
2329 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2331 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2335 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2336 This
,x
,start
,count
,palent
2338 for (i
=0;i
<count
;i
++) {
2339 xc
.red
= palent
[i
].peRed
<<8;
2340 xc
.blue
= palent
[i
].peBlue
<<8;
2341 xc
.green
= palent
[i
].peGreen
<<8;
2342 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2346 TSXStoreColor(display
,This
->cm
,&xc
);
2348 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2349 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2350 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2351 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2354 /* Now, if we are in 'depth conversion mode', update the screen palette */
2355 /* FIXME: we need to update the image or we won't get palette fading. */
2356 if (This
->ddraw
->d
.palette_convert
!= NULL
)
2357 This
->ddraw
->d
.palette_convert(palent
, This
->screen_palents
, start
, count
);
2362 #ifdef HAVE_LIBXXF86DGA
2363 static HRESULT WINAPI
DGA_IDirectDrawPaletteImpl_SetEntries(
2364 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2366 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2371 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2372 This
,x
,start
,count
,palent
2374 if (!This
->cm
) /* should not happen */ {
2375 FIXME("app tried to set colormap in non-palettized mode\n");
2376 return DDERR_GENERIC
;
2378 /* FIXME: free colorcells instead of freeing whole map */
2380 This
->cm
= TSXCopyColormapAndFree(display
,This
->cm
);
2381 TSXFreeColormap(display
,cm
);
2383 for (i
=0;i
<count
;i
++) {
2384 xc
.red
= palent
[i
].peRed
<<8;
2385 xc
.blue
= palent
[i
].peBlue
<<8;
2386 xc
.green
= palent
[i
].peGreen
<<8;
2387 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2390 TSXStoreColor(display
,This
->cm
,&xc
);
2392 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2393 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2394 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2395 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2397 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->cm
);
2400 #endif /* defined(HAVE_LIBXXF86DGA) */
2402 static ULONG WINAPI
IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface
) {
2403 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2404 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2405 if (!--(This
->ref
)) {
2407 TSXFreeColormap(display
,This
->cm
);
2410 HeapFree(GetProcessHeap(),0,This
);
2416 static ULONG WINAPI
IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface
) {
2417 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2419 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2420 return ++(This
->ref
);
2423 static HRESULT WINAPI
IDirectDrawPaletteImpl_Initialize(
2424 LPDIRECTDRAWPALETTE iface
,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
2426 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2427 TRACE("(%p)->(%p,%ld,%p)\n", This
, ddraw
, x
, palent
);
2429 return DDERR_ALREADYINITIALIZED
;
2432 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetCaps(
2433 LPDIRECTDRAWPALETTE iface
, LPDWORD lpdwCaps
)
2435 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2436 FIXME("(%p)->(%p) stub.\n", This
, lpdwCaps
);
2440 static HRESULT WINAPI
IDirectDrawPaletteImpl_QueryInterface(
2441 LPDIRECTDRAWPALETTE iface
,REFIID refiid
,LPVOID
*obj
)
2443 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2446 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2447 FIXME("(%p)->(%s,%p) stub.\n",This
,xrefiid
,obj
);
2452 #ifdef HAVE_LIBXXF86DGA
2453 static ICOM_VTABLE(IDirectDrawPalette
) dga_ddpalvt
=
2455 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2456 IDirectDrawPaletteImpl_QueryInterface
,
2457 IDirectDrawPaletteImpl_AddRef
,
2458 IDirectDrawPaletteImpl_Release
,
2459 IDirectDrawPaletteImpl_GetCaps
,
2460 IDirectDrawPaletteImpl_GetEntries
,
2461 IDirectDrawPaletteImpl_Initialize
,
2462 DGA_IDirectDrawPaletteImpl_SetEntries
2464 #endif /* defined(HAVE_LIBXXF86DGA) */
2466 static ICOM_VTABLE(IDirectDrawPalette
) xlib_ddpalvt
=
2468 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2469 IDirectDrawPaletteImpl_QueryInterface
,
2470 IDirectDrawPaletteImpl_AddRef
,
2471 IDirectDrawPaletteImpl_Release
,
2472 IDirectDrawPaletteImpl_GetCaps
,
2473 IDirectDrawPaletteImpl_GetEntries
,
2474 IDirectDrawPaletteImpl_Initialize
,
2475 Xlib_IDirectDrawPaletteImpl_SetEntries
2478 /*******************************************************************************
2481 static HRESULT WINAPI
IDirect3DImpl_QueryInterface(
2482 LPDIRECT3D iface
,REFIID refiid
,LPVOID
*obj
2484 ICOM_THIS(IDirect3DImpl
,iface
);
2485 /* FIXME: Not sure if this is correct */
2488 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2489 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
2490 if ((!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) ||
2491 (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) ||
2492 (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
)))) {
2494 IDirect3D_AddRef(iface
);
2496 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2500 if ((!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) ||
2501 (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
)))) {
2503 IDirect3D_AddRef(iface
);
2505 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2509 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
2510 IDirect3D2Impl
* d3d
;
2512 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2514 d3d
->ddraw
= This
->ddraw
;
2515 IDirect3D_AddRef(iface
);
2516 d3d
->lpvtbl
= &d3d2vt
;
2519 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2523 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
2524 return OLE_E_ENUM_NOMORE
;
2527 static ULONG WINAPI
IDirect3DImpl_AddRef(LPDIRECT3D iface
) {
2528 ICOM_THIS(IDirect3DImpl
,iface
);
2529 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2531 return ++(This
->ref
);
2534 static ULONG WINAPI
IDirect3DImpl_Release(LPDIRECT3D iface
)
2536 ICOM_THIS(IDirect3DImpl
,iface
);
2537 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2539 if (!--(This
->ref
)) {
2540 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2541 HeapFree(GetProcessHeap(),0,This
);
2547 static HRESULT WINAPI
IDirect3DImpl_Initialize(
2548 LPDIRECT3D iface
, REFIID refiid
)
2550 ICOM_THIS(IDirect3DImpl
,iface
);
2551 /* FIXME: Not sure if this is correct */
2554 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2555 FIXME("(%p)->(%s):stub.\n",This
,xrefiid
);
2557 return DDERR_ALREADYINITIALIZED
;
2560 static HRESULT WINAPI
IDirect3DImpl_EnumDevices(LPDIRECT3D iface
,
2561 LPD3DENUMDEVICESCALLBACK cb
,
2563 ICOM_THIS(IDirect3DImpl
,iface
);
2564 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2566 /* Call functions defined in d3ddevices.c */
2567 if (!d3d_OpenGL_dx3(cb
, context
))
2573 static HRESULT WINAPI
IDirect3DImpl_CreateLight(LPDIRECT3D iface
,
2574 LPDIRECT3DLIGHT
*lplight
,
2577 ICOM_THIS(IDirect3DImpl
,iface
);
2578 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2580 /* Call the creation function that is located in d3dlight.c */
2581 *lplight
= d3dlight_create_dx3(This
);
2586 static HRESULT WINAPI
IDirect3DImpl_CreateMaterial(LPDIRECT3D iface
,
2587 LPDIRECT3DMATERIAL
*lpmaterial
,
2590 ICOM_THIS(IDirect3DImpl
,iface
);
2591 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2593 /* Call the creation function that is located in d3dviewport.c */
2594 *lpmaterial
= d3dmaterial_create(This
);
2599 static HRESULT WINAPI
IDirect3DImpl_CreateViewport(LPDIRECT3D iface
,
2600 LPDIRECT3DVIEWPORT
*lpviewport
,
2603 ICOM_THIS(IDirect3DImpl
,iface
);
2604 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
2606 /* Call the creation function that is located in d3dviewport.c */
2607 *lpviewport
= d3dviewport_create(This
);
2612 static HRESULT WINAPI
IDirect3DImpl_FindDevice(LPDIRECT3D iface
,
2613 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2614 LPD3DFINDDEVICERESULT lpfinddevrst
)
2616 ICOM_THIS(IDirect3DImpl
,iface
);
2617 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
2622 static ICOM_VTABLE(IDirect3D
) d3dvt
=
2624 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2625 IDirect3DImpl_QueryInterface
,
2626 IDirect3DImpl_AddRef
,
2627 IDirect3DImpl_Release
,
2628 IDirect3DImpl_Initialize
,
2629 IDirect3DImpl_EnumDevices
,
2630 IDirect3DImpl_CreateLight
,
2631 IDirect3DImpl_CreateMaterial
,
2632 IDirect3DImpl_CreateViewport
,
2633 IDirect3DImpl_FindDevice
2636 /*******************************************************************************
2639 static HRESULT WINAPI
IDirect3D2Impl_QueryInterface(
2640 LPDIRECT3D2 iface
,REFIID refiid
,LPVOID
*obj
) {
2641 ICOM_THIS(IDirect3D2Impl
,iface
);
2643 /* FIXME: Not sure if this is correct */
2646 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2647 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
2648 if ((!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) ||
2649 (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) ||
2650 (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
)))) {
2652 IDirect3D2_AddRef(iface
);
2654 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2658 if ((!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) ||
2659 (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
)))) {
2661 IDirect3D2_AddRef(iface
);
2663 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2667 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
2670 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2672 d3d
->ddraw
= This
->ddraw
;
2673 IDirect3D2_AddRef(iface
);
2674 d3d
->lpvtbl
= &d3dvt
;
2677 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2681 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
2682 return OLE_E_ENUM_NOMORE
;
2685 static ULONG WINAPI
IDirect3D2Impl_AddRef(LPDIRECT3D2 iface
) {
2686 ICOM_THIS(IDirect3D2Impl
,iface
);
2687 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2689 return ++(This
->ref
);
2692 static ULONG WINAPI
IDirect3D2Impl_Release(LPDIRECT3D2 iface
) {
2693 ICOM_THIS(IDirect3D2Impl
,iface
);
2694 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2696 if (!--(This
->ref
)) {
2697 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2698 HeapFree(GetProcessHeap(),0,This
);
2704 static HRESULT WINAPI
IDirect3D2Impl_EnumDevices(
2705 LPDIRECT3D2 iface
,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2707 ICOM_THIS(IDirect3D2Impl
,iface
);
2708 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2710 /* Call functions defined in d3ddevices.c */
2711 if (!d3d_OpenGL(cb
, context
))
2717 static HRESULT WINAPI
IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface
,
2718 LPDIRECT3DLIGHT
*lplight
,
2721 ICOM_THIS(IDirect3D2Impl
,iface
);
2722 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2724 /* Call the creation function that is located in d3dlight.c */
2725 *lplight
= d3dlight_create(This
);
2730 static HRESULT WINAPI
IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface
,
2731 LPDIRECT3DMATERIAL2
*lpmaterial
,
2734 ICOM_THIS(IDirect3D2Impl
,iface
);
2735 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2737 /* Call the creation function that is located in d3dviewport.c */
2738 *lpmaterial
= d3dmaterial2_create(This
);
2743 static HRESULT WINAPI
IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface
,
2744 LPDIRECT3DVIEWPORT2
*lpviewport
,
2747 ICOM_THIS(IDirect3D2Impl
,iface
);
2748 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
2750 /* Call the creation function that is located in d3dviewport.c */
2751 *lpviewport
= d3dviewport2_create(This
);
2756 static HRESULT WINAPI
IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface
,
2757 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2758 LPD3DFINDDEVICERESULT lpfinddevrst
)
2760 ICOM_THIS(IDirect3D2Impl
,iface
);
2761 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
2766 static HRESULT WINAPI
IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface
,
2768 LPDIRECTDRAWSURFACE surface
,
2769 LPDIRECT3DDEVICE2
*device
)
2771 ICOM_THIS(IDirect3D2Impl
,iface
);
2774 WINE_StringFromCLSID(rguid
,xbuf
);
2775 FIXME("(%p)->(%s,%p,%p): stub\n",This
,xbuf
,surface
,device
);
2777 if (is_OpenGL(rguid
, (IDirectDrawSurfaceImpl
*)surface
, (IDirect3DDevice2Impl
**)device
, This
)) {
2778 IDirect3D2_AddRef(iface
);
2782 return DDERR_INVALIDPARAMS
;
2785 static ICOM_VTABLE(IDirect3D2
) d3d2vt
=
2787 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2788 IDirect3D2Impl_QueryInterface
,
2789 IDirect3D2Impl_AddRef
,
2790 IDirect3D2Impl_Release
,
2791 IDirect3D2Impl_EnumDevices
,
2792 IDirect3D2Impl_CreateLight
,
2793 IDirect3D2Impl_CreateMaterial
,
2794 IDirect3D2Impl_CreateViewport
,
2795 IDirect3D2Impl_FindDevice
,
2796 IDirect3D2Impl_CreateDevice
2799 /*******************************************************************************
2803 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2804 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2806 static INT ddrawXlibThisOffset
= 0;
2808 static HRESULT
common_off_screen_CreateSurface(IDirectDraw2Impl
* This
,
2809 IDirectDrawSurfaceImpl
* lpdsf
)
2813 /* The surface was already allocated when entering in this function */
2814 TRACE("using system memory for a surface (%p) \n", lpdsf
);
2816 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
2817 /* This is a Z Buffer */
2818 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf
->s
.surface_desc
.x
.dwZBufferBitDepth
);
2819 bpp
= lpdsf
->s
.surface_desc
.x
.dwZBufferBitDepth
/ 8;
2821 /* This is a standard image */
2822 if (!(lpdsf
->s
.surface_desc
.dwFlags
& DDSD_PIXELFORMAT
)) {
2823 /* No pixel format => use DirectDraw's format */
2824 lpdsf
->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
2825 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
2828 bpp
= GET_BPP(lpdsf
->s
.surface_desc
);
2831 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_LPSURFACE
) {
2832 /* The surface was preallocated : seems that we have nothing to do :-) */
2833 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
2836 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PITCH
|DDSD_LPSURFACE
;
2837 lpdsf
->s
.surface_desc
.y
.lpSurface
=
2838 (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpdsf
->s
.surface_desc
.dwWidth
* lpdsf
->s
.surface_desc
.dwHeight
* bpp
);
2839 lpdsf
->s
.surface_desc
.lPitch
= lpdsf
->s
.surface_desc
.dwWidth
* bpp
;
2844 #ifdef HAVE_LIBXXF86DGA
2845 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreateSurface(
2846 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2848 ICOM_THIS(IDirectDraw2Impl
,iface
);
2849 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
2850 int i
, fbheight
= This
->e
.dga
.fb_height
;
2852 TRACE("(%p)->(%p,%p,%p)\n",This
,lpddsd
,ilpdsf
,lpunk
);
2853 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
2855 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
2858 sizeof(IDirectDrawSurfaceImpl
)
2860 IDirectDraw2_AddRef(iface
);
2863 (*ilpdsf
)->lpvtbl
= (ICOM_VTABLE(IDirectDrawSurface
)*)&dga_dds4vt
;
2864 (*ilpdsf
)->s
.ddraw
= This
;
2865 (*ilpdsf
)->s
.palette
= NULL
;
2866 (*ilpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
2868 /* Copy the surface description */
2869 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
2871 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2872 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
2873 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2874 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
2876 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
2878 /* Check if this a 'primary surface' or not */
2879 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2880 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2881 /* This is THE primary surface => there is DGA-specific code */
2883 /* First, store the surface description */
2884 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
2886 /* Find a viewport */
2888 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
2890 TRACE("using viewport %d for a primary surface\n",i
);
2891 /* if i == 32 or maximum ... return error */
2892 This
->e
.dga
.vpmask
|=(1<<i
);
2893 lpddsd
->lPitch
= (*ilpdsf
)->s
.surface_desc
.lPitch
=
2894 This
->e
.dga
.fb_width
*
2895 (This
->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8);
2897 (*ilpdsf
)->s
.surface_desc
.y
.lpSurface
=
2898 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
2900 (*ilpdsf
)->t
.dga
.fb_height
= i
*fbheight
;
2902 /* Add flags if there were not present */
2903 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
2904 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
2905 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
2906 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This
->d
.width
,This
->d
.height
,lpddsd
->lPitch
);
2907 /* We put our surface always in video memory */
2908 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2909 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
2910 (*ilpdsf
)->s
.chain
= NULL
;
2912 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2913 IDirectDrawSurface4Impl
* back
;
2916 for (bbc
=lpddsd
->dwBackBufferCount
;bbc
--;) {
2919 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
2922 sizeof(IDirectDrawSurface4Impl
)
2924 IDirectDraw2_AddRef(iface
);
2926 back
->lpvtbl
= (ICOM_VTABLE(IDirectDrawSurface4
)*)&dga_dds4vt
;
2928 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
2930 TRACE("using viewport %d for backbuffer %d\n",i
, bbc
);
2931 /* if i == 32 or maximum ... return error */
2932 This
->e
.dga
.vpmask
|=(1<<i
);
2933 back
->t
.dga
.fb_height
= i
*fbheight
;
2934 /* Copy the surface description from the front buffer */
2935 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
2936 /* Change the parameters that are not the same */
2937 back
->s
.surface_desc
.y
.lpSurface
=
2938 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
2940 back
->s
.ddraw
= This
;
2941 /* Add relevant info to front and back buffers */
2942 /* FIXME: backbuffer/frontbuffer handling broken here, but
2943 * will be fixed up in _Flip().
2945 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
2946 SDDSCAPS(back
) |= DDSCAPS_FLIP
|DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
;
2947 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2948 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
2949 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
2953 /* There is no DGA-specific code here...
2954 Go to the common surface creation function */
2955 return common_off_screen_CreateSurface(This
, *ilpdsf
);
2959 #endif /* defined(HAVE_LIBXXF86DGA) */
2961 #ifdef HAVE_LIBXXSHM
2962 /* Error handlers for Image creation */
2963 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
2968 static XImage
*create_xshmimage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
2970 int (*WineXHandler
)(Display
*, XErrorEvent
*);
2972 img
= TSXShmCreateImage(display
,
2973 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2974 This
->d
.pixmap_depth
,
2977 &(lpdsf
->t
.xlib
.shminfo
),
2978 lpdsf
->s
.surface_desc
.dwWidth
,
2979 lpdsf
->s
.surface_desc
.dwHeight
2983 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2984 This
->e
.xlib
.xshm_active
= 0;
2988 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
2989 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
2990 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2991 This
->e
.xlib
.xshm_active
= 0;
2992 TSXDestroyImage(img
);
2996 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
2998 if (img
->data
== (char *) -1) {
2999 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3000 This
->e
.xlib
.xshm_active
= 0;
3001 TSXDestroyImage(img
);
3002 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3005 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
3007 /* This is where things start to get trickier....
3008 * First, we flush the current X connections to be sure to catch all
3009 * non-XShm related errors
3011 TSXSync(display
, False
);
3012 /* Then we enter in the non-thread safe part of the tests */
3013 EnterCriticalSection( &X11DRV_CritSection
);
3015 /* Reset the error flag, sets our new error handler and try to attach
3019 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3020 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
3021 XSync(display
, False
);
3023 /* Check the error flag */
3024 if (XShmErrorFlag
) {
3025 /* An error occured */
3029 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
3030 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3031 XSetErrorHandler(WineXHandler
);
3033 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3034 This
->e
.xlib
.xshm_active
= 0;
3036 /* Leave the critical section */
3037 LeaveCriticalSection( &X11DRV_CritSection
);
3040 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3041 * this works, but it may be a bit overkill....
3043 XSetErrorHandler(WineXHandler
);
3044 LeaveCriticalSection( &X11DRV_CritSection
);
3046 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3048 if (This
->d
.pixel_convert
!= NULL
) {
3049 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(
3052 lpdsf
->s
.surface_desc
.dwWidth
*
3053 lpdsf
->s
.surface_desc
.dwHeight
*
3054 (This
->d
.directdraw_pixelformat
.x
.dwRGBBitCount
)
3057 lpdsf
->s
.surface_desc
.y
.lpSurface
= img
->data
;
3061 #endif /* HAVE_LIBXXSHM */
3063 static XImage
*create_ximage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
3067 #ifdef HAVE_LIBXXSHM
3068 if (This
->e
.xlib
.xshm_active
)
3069 img
= create_xshmimage(This
, lpdsf
);
3073 /* Allocate surface memory */
3074 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(
3075 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3076 lpdsf
->s
.surface_desc
.dwWidth
*
3077 lpdsf
->s
.surface_desc
.dwHeight
*
3078 (This
->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/ 8)
3081 if (This
->d
.pixel_convert
!= NULL
) {
3082 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
3083 lpdsf
->s
.surface_desc
.dwWidth
*
3084 lpdsf
->s
.surface_desc
.dwHeight
*
3085 (This
->d
.screen_pixelformat
.x
.dwRGBBitCount
/ 8)
3088 img_data
= lpdsf
->s
.surface_desc
.y
.lpSurface
;
3091 /* In this case, create an XImage */
3092 img
= TSXCreateImage(display
,
3093 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3094 This
->d
.pixmap_depth
,
3098 lpdsf
->s
.surface_desc
.dwWidth
,
3099 lpdsf
->s
.surface_desc
.dwHeight
,
3101 lpdsf
->s
.surface_desc
.dwWidth
* (This
->d
.screen_pixelformat
.x
.dwRGBBitCount
/ 8)
3103 #ifdef HAVE_LIBXXSHM
3106 if (This
->d
.pixel_convert
!= NULL
) {
3107 lpdsf
->s
.surface_desc
.lPitch
= (This
->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/ 8) * lpdsf
->s
.surface_desc
.dwWidth
;
3109 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
3114 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreateSurface(
3115 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
3117 ICOM_THIS(IDirectDraw2Impl
,iface
);
3118 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
3120 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This
,lpddsd
,ilpdsf
,lpunk
);
3122 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
3124 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
3125 GetProcessHeap(),HEAP_ZERO_MEMORY
, sizeof(IDirectDrawSurfaceImpl
)
3128 IDirectDraw2_AddRef(iface
);
3130 (*ilpdsf
)->s
.ddraw
= This
;
3132 (*ilpdsf
)->lpvtbl
= (ICOM_VTABLE(IDirectDrawSurface
)*)&xlib_dds4vt
;
3133 (*ilpdsf
)->s
.palette
= NULL
;
3134 (*ilpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
3136 /* Copy the surface description */
3137 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
3139 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
3140 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3141 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
3142 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3143 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
3145 /* Check if this a 'primary surface' or not */
3146 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
3147 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
3150 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf
);
3151 /* Create the XImage */
3152 img
= create_ximage(This
, (IDirectDrawSurface4Impl
*) *ilpdsf
);
3154 return DDERR_OUTOFMEMORY
;
3155 (*ilpdsf
)->t
.xlib
.image
= img
;
3157 /* Add flags if there were not present */
3158 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
3159 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3160 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3161 (*ilpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
3162 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
3164 /* Check for backbuffers */
3165 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
3166 IDirectDrawSurface4Impl
* back
;
3170 for (i
=lpddsd
->dwBackBufferCount
;i
--;) {
3171 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
3172 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3173 sizeof(IDirectDrawSurface4Impl
)
3176 TRACE("allocated back-buffer (%p)\n", back
);
3178 IDirectDraw2_AddRef(iface
);
3179 back
->s
.ddraw
= This
;
3182 back
->lpvtbl
= (ICOM_VTABLE(IDirectDrawSurface4
)*)&xlib_dds4vt
;
3183 /* Copy the surface description from the front buffer */
3184 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
3186 /* Create the XImage */
3187 img
= create_ximage(This
, back
);
3189 return DDERR_OUTOFMEMORY
;
3190 back
->t
.xlib
.image
= img
;
3192 /* Add relevant info to front and back buffers */
3193 /* FIXME: backbuffer/frontbuffer handling broken here, but
3194 * will be fixed up in _Flip().
3196 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
3197 SDDSCAPS(back
) |= DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
|DDSCAPS_FLIP
;
3198 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
3199 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
3200 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
3204 /* There is no Xlib-specific code here...
3205 Go to the common surface creation function */
3206 return common_off_screen_CreateSurface(This
, *ilpdsf
);
3211 static HRESULT WINAPI
IDirectDraw2Impl_DuplicateSurface(
3212 LPDIRECTDRAW2 iface
,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
3214 ICOM_THIS(IDirectDraw2Impl
,iface
);
3215 FIXME("(%p)->(%p,%p) simply copies\n",This
,src
,dst
);
3216 *dst
= src
; /* FIXME */
3221 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3222 * even when the approbiate bitmasks are not specified.
3224 static HRESULT WINAPI
IDirectDraw2Impl_SetCooperativeLevel(
3225 LPDIRECTDRAW2 iface
,HWND hwnd
,DWORD cooplevel
3227 ICOM_THIS(IDirectDraw2Impl
,iface
);
3234 #define FE(x) { x, #x},
3235 FE(DDSCL_FULLSCREEN)
3236 FE(DDSCL_ALLOWREBOOT)
3237 FE(DDSCL_NOWINDOWCHANGES)
3239 FE(DDSCL_ALLOWMODEX)
3241 FE(DDSCL_SETFOCUSWINDOW)
3242 FE(DDSCL_SETDEVICEWINDOW)
3243 FE(DDSCL_CREATEDEVICEWINDOW)
3248 FIXME("(%p)->(%08lx,%08lx)\n",This
,(DWORD
)hwnd
,cooplevel
);
3249 This
->d
.mainWindow
= hwnd
;
3251 /* This will be overwritten in the case of Full Screen mode.
3252 Windowed games could work with that :-) */
3255 WND
*tmpWnd
= WIN_FindWndPtr(hwnd
);
3256 This
->d
.drawable
= X11DRV_WND_GetXWindow(tmpWnd
);
3257 WIN_ReleaseWndPtr(tmpWnd
);
3259 if( !This
->d
.drawable
) {
3260 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
3261 WIN_ReleaseDesktop();
3263 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
3269 /* Small helper to either use the cooperative window or create a new
3270 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3272 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl
* This
) {
3275 /* Do not destroy the application supplied cooperative window */
3276 if (This
->d
.window
&& This
->d
.window
!= This
->d
.mainWindow
) {
3277 DestroyWindow(This
->d
.window
);
3280 /* Sanity check cooperative window before assigning it to drawing. */
3281 if ( IsWindow(This
->d
.mainWindow
) &&
3282 IsWindowVisible(This
->d
.mainWindow
)
3284 /* if it does not fit, resize the cooperative window.
3285 * and hope the app likes it
3287 GetWindowRect(This
->d
.mainWindow
,&rect
);
3288 if ((((rect
.right
-rect
.left
) >= This
->d
.width
) &&
3289 ((rect
.bottom
-rect
.top
) >= This
->d
.height
))
3291 This
->d
.window
= This
->d
.mainWindow
;
3292 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3296 /* ... failed, create new one. */
3297 if (!This
->d
.window
) {
3298 This
->d
.window
= CreateWindowExA(
3302 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
3311 /*Store THIS with the window. We'll use it in the window procedure*/
3312 SetWindowLongA(This
->d
.window
,ddrawXlibThisOffset
,(LONG
)This
);
3313 ShowWindow(This
->d
.window
,TRUE
);
3314 UpdateWindow(This
->d
.window
);
3316 SetFocus(This
->d
.window
);
3319 static int _common_depth_to_pixelformat(DWORD depth
,
3320 DDPIXELFORMAT
*pixelformat
,
3321 DDPIXELFORMAT
*screen_pixelformat
,
3324 XPixmapFormatValues
*pf
;
3326 int nvisuals
, npixmap
, i
;
3330 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
3331 pf
= XListPixmapFormats(display
, &npixmap
);
3333 for (i
= 0; i
< npixmap
; i
++) {
3334 if (pf
[i
].depth
== depth
) {
3337 for (j
= 0; j
< nvisuals
; j
++) {
3338 if (vi
[j
].depth
== pf
[i
].depth
) {
3339 pixelformat
->dwSize
= sizeof(*pixelformat
);
3341 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
3342 pixelformat
->y
.dwRBitMask
= 0;
3343 pixelformat
->z
.dwGBitMask
= 0;
3344 pixelformat
->xx
.dwBBitMask
= 0;
3346 pixelformat
->dwFlags
= DDPF_RGB
;
3347 pixelformat
->y
.dwRBitMask
= vi
[j
].red_mask
;
3348 pixelformat
->z
.dwGBitMask
= vi
[j
].green_mask
;
3349 pixelformat
->xx
.dwBBitMask
= vi
[j
].blue_mask
;
3351 pixelformat
->dwFourCC
= 0;
3352 pixelformat
->x
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3353 pixelformat
->xy
.dwRGBAlphaBitMask
= 0;
3355 *screen_pixelformat
= *pixelformat
;
3357 if (pix_depth
!= NULL
)
3358 *pix_depth
= vi
[j
].depth
;
3363 goto clean_up_and_exit
;
3367 ERR("No visual corresponding to pixmap format !\n");
3372 /* We try now to find an emulated mode */
3375 for (c
= 0; c
< sizeof(ModeEmulations
) / sizeof(Convert
); c
++) {
3376 if (ModeEmulations
[c
].dest
.depth
== depth
) {
3377 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3378 for (i
= 0; i
< npixmap
; i
++) {
3379 if ((pf
[i
].depth
== ModeEmulations
[c
].screen
.depth
) &&
3380 (pf
[i
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
3383 for (j
= 0; j
< nvisuals
; j
++) {
3384 if (vi
[j
].depth
== pf
[i
].depth
) {
3385 screen_pixelformat
->dwSize
= sizeof(*screen_pixelformat
);
3386 screen_pixelformat
->dwFlags
= DDPF_RGB
;
3387 screen_pixelformat
->dwFourCC
= 0;
3388 screen_pixelformat
->x
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3389 screen_pixelformat
->y
.dwRBitMask
= vi
[j
].red_mask
;
3390 screen_pixelformat
->z
.dwGBitMask
= vi
[j
].green_mask
;
3391 screen_pixelformat
->xx
.dwBBitMask
= vi
[j
].blue_mask
;
3392 screen_pixelformat
->xy
.dwRGBAlphaBitMask
= 0;
3394 pixelformat
->dwSize
= sizeof(*pixelformat
);
3395 pixelformat
->dwFourCC
= 0;
3397 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
3398 pixelformat
->x
.dwRGBBitCount
= 8;
3399 pixelformat
->y
.dwRBitMask
= 0;
3400 pixelformat
->z
.dwGBitMask
= 0;
3401 pixelformat
->xx
.dwBBitMask
= 0;
3403 pixelformat
->dwFlags
= DDPF_RGB
;
3404 pixelformat
->x
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
3405 pixelformat
->y
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
3406 pixelformat
->z
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
3407 pixelformat
->xx
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
3409 pixelformat
->xy
.dwRGBAlphaBitMask
= 0;
3411 if (pix_depth
!= NULL
)
3412 *pix_depth
= vi
[j
].depth
;
3417 goto clean_up_and_exit
;
3420 ERR("No visual corresponding to pixmap format !\n");
3435 #ifdef HAVE_LIBXXF86DGA
3436 static HRESULT WINAPI
DGA_IDirectDrawImpl_SetDisplayMode(
3437 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
3439 ICOM_THIS(IDirectDrawImpl
,iface
);
3442 TRACE("(%p)->(%ld,%ld,%ld)\n", This
, width
, height
, depth
);
3444 /* We hope getting the asked for depth */
3445 if (_common_depth_to_pixelformat(depth
, &(This
->d
.directdraw_pixelformat
), &(This
->d
.screen_pixelformat
), NULL
) != -1) {
3446 /* I.e. no visual found or emulated */
3447 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
3448 return DDERR_UNSUPPORTEDMODE
;
3451 if (This
->d
.width
< width
) {
3452 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,This
->d
.width
);
3453 return DDERR_UNSUPPORTEDMODE
;
3455 This
->d
.width
= width
;
3456 This
->d
.height
= height
;
3458 /* adjust fb_height, so we don't overlap */
3459 if (This
->e
.dga
.fb_height
< height
)
3460 This
->e
.dga
.fb_height
= height
;
3461 _common_IDirectDrawImpl_SetDisplayMode(This
);
3463 #ifdef HAVE_LIBXXF86VM
3465 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
3466 XF86VidModeModeLine mod_tmp
;
3467 /* int dotclock_tmp; */
3469 /* save original video mode and set fullscreen if available*/
3470 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
3471 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
3472 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
3473 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
3474 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
3475 orig_mode
->htotal
= mod_tmp
.htotal
;
3476 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
3477 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
3478 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
3479 orig_mode
->vtotal
= mod_tmp
.vtotal
;
3480 orig_mode
->flags
= mod_tmp
.flags
;
3481 orig_mode
->private = mod_tmp
.private;
3483 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
3484 for (i
=0;i
<mode_count
;i
++)
3486 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
3488 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
3489 *vidmode
= *(all_modes
[i
]);
3492 TSXFree(all_modes
[i
]->private);
3494 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
3498 WARN("Fullscreen mode not available!\n");
3502 TRACE("SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
3503 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
3504 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3505 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
3511 /* FIXME: this function OVERWRITES several signal handlers.
3512 * can we save them? and restore them later? In a way that
3513 * it works for the library too?
3515 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
3516 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
3518 #ifdef RESTORE_SIGNALS
3523 #endif /* defined(HAVE_LIBXXF86DGA) */
3525 /* *************************************
3526 16 / 15 bpp to palettized 8 bpp
3527 ************************************* */
3528 static void pixel_convert_16_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3529 unsigned char *c_src
= (unsigned char *) src
;
3530 unsigned short *c_dst
= (unsigned short *) dst
;
3533 if (palette
!= NULL
) {
3534 const unsigned short * pal
= (unsigned short *) palette
->screen_palents
;
3536 for (y
= height
; y
--; ) {
3537 #if defined(__i386__) && defined(__GNUC__)
3538 /* gcc generates slightly inefficient code for the the copy / lookup,
3539 * it generates one excess memory access (to pal) per pixel. Since
3540 * we know that pal is not modified by the memory write we can
3541 * put it into a register and reduce the number of memory accesses
3542 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3543 * (This is not guaranteed to be the fastest method.)
3545 __asm__
__volatile__(
3549 " movw (%%edx,%%eax,2),%%ax\n"
3551 " xor %%eax,%%eax\n"
3553 : "=S" (c_src
), "=D" (c_dst
)
3554 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
3555 : "eax", "cc", "memory"
3557 c_src
+=(pitch
-width
);
3559 unsigned char * srclineend
= c_src
+width
;
3560 while (c_src
< srclineend
)
3561 *c_dst
++ = pal
[*c_src
++];
3562 c_src
+=(pitch
-width
);
3566 WARN("No palette set...\n");
3567 memset(dst
, 0, width
* height
* 2);
3570 static void palette_convert_16_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3572 unsigned short *pal
= (unsigned short *) screen_palette
;
3574 for (i
= 0; i
< count
; i
++)
3575 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
3576 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3577 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
3579 static void palette_convert_15_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3581 unsigned short *pal
= (unsigned short *) screen_palette
;
3583 for (i
= 0; i
< count
; i
++)
3584 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 7) |
3585 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3586 ((((unsigned short) palent
[i
].peGreen
) & 0xF8) << 2));
3589 /* *************************************
3590 24 to palettized 8 bpp
3591 ************************************* */
3592 static void pixel_convert_24_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3593 unsigned char *c_src
= (unsigned char *) src
;
3594 unsigned char *c_dst
= (unsigned char *) dst
;
3597 if (palette
!= NULL
) {
3598 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
3600 for (y
= height
; y
--; ) {
3601 unsigned char * srclineend
= c_src
+width
;
3602 while (c_src
< srclineend
) {
3603 register long pixel
= pal
[*c_src
++];
3605 *c_dst
++ = pixel
>>8;
3606 *c_dst
++ = pixel
>>16;
3608 c_src
+=(pitch
-width
);
3611 WARN("No palette set...\n");
3612 memset(dst
, 0, width
* height
* 4);
3615 /* *************************************
3616 32 bpp to palettized 8 bpp
3617 ************************************* */
3618 static void pixel_convert_32_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3619 unsigned char *c_src
= (unsigned char *) src
;
3620 unsigned int *c_dst
= (unsigned int *) dst
;
3623 if (palette
!= NULL
) {
3624 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
3626 for (y
= height
; y
--; ) {
3627 #if defined(__i386__) && defined(__GNUC__)
3628 /* See comment in pixel_convert_16_to_8 */
3629 __asm__
__volatile__(
3633 " movl (%%edx,%%eax,4),%%eax\n"
3635 " xor %%eax,%%eax\n"
3637 : "=S" (c_src
), "=D" (c_dst
)
3638 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
3639 : "eax", "cc", "memory"
3641 c_src
+=(pitch
-width
);
3643 unsigned char * srclineend
= c_src
+width
;
3644 while (c_src
< srclineend
)
3645 *c_dst
++ = pal
[*c_src
++];
3646 c_src
+=(pitch
-width
);
3650 WARN("No palette set...\n");
3651 memset(dst
, 0, width
* height
* 4);
3655 static void palette_convert_24_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3657 unsigned int *pal
= (unsigned int *) screen_palette
;
3659 for (i
= 0; i
< count
; i
++)
3660 pal
[start
+ i
] = ((((unsigned int) palent
[i
].peRed
) << 16) |
3661 (((unsigned int) palent
[i
].peGreen
) << 8) |
3662 ((unsigned int) palent
[i
].peBlue
));
3665 /* *************************************
3667 ************************************* */
3668 static void pixel_convert_32_to_16(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3669 unsigned short *c_src
= (unsigned short *) src
;
3670 unsigned int *c_dst
= (unsigned int *) dst
;
3673 for (y
= height
; y
--; ) {
3674 unsigned short * srclineend
= c_src
+width
;
3675 while (c_src
< srclineend
) {
3676 *c_dst
++ = (((*c_src
& 0xF800) << 8) |
3677 ((*c_src
& 0x07E0) << 5) |
3678 ((*c_src
& 0x001F) << 3));
3681 c_src
+=((pitch
/2)-width
);
3686 static HRESULT WINAPI
Xlib_IDirectDrawImpl_SetDisplayMode(
3687 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
3689 ICOM_THIS(IDirectDrawImpl
,iface
);
3694 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3695 This
, width
, height
, depth
);
3697 switch ((c
= _common_depth_to_pixelformat(depth
,
3698 &(This
->d
.directdraw_pixelformat
),
3699 &(This
->d
.screen_pixelformat
),
3700 &(This
->d
.pixmap_depth
)))) {
3702 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
3703 MessageBoxA(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
3704 return DDERR_UNSUPPORTEDMODE
;
3708 This
->d
.pixel_convert
= NULL
;
3709 This
->d
.palette_convert
= NULL
;
3713 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
3715 /* Set the depth convertion routines */
3716 This
->d
.pixel_convert
= ModeEmulations
[c
].funcs
.pixel_convert
;
3717 This
->d
.palette_convert
= ModeEmulations
[c
].funcs
.palette_convert
;
3720 This
->d
.width
= width
;
3721 This
->d
.height
= height
;
3723 _common_IDirectDrawImpl_SetDisplayMode(This
);
3725 tmpWnd
= WIN_FindWndPtr(This
->d
.window
);
3726 This
->d
.paintable
= 1;
3727 This
->d
.drawable
= ((X11DRV_WND_DATA
*) tmpWnd
->pDriverData
)->window
;
3728 WIN_ReleaseWndPtr(tmpWnd
);
3730 /* We don't have a context for this window. Host off the desktop */
3731 if( !This
->d
.drawable
)
3733 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
3734 WIN_ReleaseDesktop();
3736 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
3741 #ifdef HAVE_LIBXXF86DGA
3742 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetCaps(
3743 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
3745 ICOM_THIS(IDirectDraw2Impl
,iface
);
3746 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
3747 if (!caps1
&& !caps2
)
3748 return DDERR_INVALIDPARAMS
;
3750 caps1
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
3751 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
3752 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
3755 caps2
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
3756 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
3757 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
3761 #endif /* defined(HAVE_LIBXXF86DGA) */
3763 static void fill_caps(LPDDCAPS caps
) {
3764 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3765 Need to be fixed, though.. */
3769 caps
->dwSize
= sizeof(*caps
);
3770 caps
->dwCaps
= DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
| DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
| DDCAPS_NOHARDWARE
;
3771 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NOPAGELOCKREQUIRED
| DDCAPS2_WIDESURFACES
;
3772 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
3774 caps
->dwFXAlphaCaps
= 0;
3775 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
3777 caps
->dwZBufferBitDepths
= DDBD_16
;
3778 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3779 to put textures in video memory.
3780 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3782 caps
->dwVidMemTotal
= 8192 * 1024;
3783 caps
->dwVidMemFree
= 8192 * 1024;
3784 /* These are all the supported capabilities of the surfaces */
3785 caps
->ddsCaps
.dwCaps
= DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
3786 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
3787 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
|
3788 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
;
3790 caps
->dwCaps
|= DDCAPS_3D
| DDCAPS_ZBLTS
;
3791 caps
->dwCaps2
|= DDCAPS2_NO2DDURING3DSCENE
;
3792 caps
->ddsCaps
.dwCaps
|= DDSCAPS_3DDEVICE
| DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
| DDSCAPS_ZBUFFER
;
3796 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetCaps(
3797 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
3799 ICOM_THIS(IDirectDraw2Impl
,iface
);
3800 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
3802 /* Put the same caps for the two capabilities */
3809 static HRESULT WINAPI
IDirectDraw2Impl_CreateClipper(
3810 LPDIRECTDRAW2 iface
,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
3812 ICOM_THIS(IDirectDraw2Impl
,iface
);
3813 IDirectDrawClipperImpl
** ilpddclip
=(IDirectDrawClipperImpl
**)lpddclip
;
3814 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
3815 This
,x
,ilpddclip
,lpunk
3817 *ilpddclip
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
3818 (*ilpddclip
)->ref
= 1;
3819 (*ilpddclip
)->lpvtbl
= &ddclipvt
;
3823 static HRESULT WINAPI
common_IDirectDraw2Impl_CreatePalette(
3824 IDirectDraw2Impl
* This
,DWORD dwFlags
,LPPALETTEENTRY palent
,IDirectDrawPaletteImpl
**lpddpal
,LPUNKNOWN lpunk
,int *psize
3828 if (TRACE_ON(ddraw
))
3829 _dump_paletteformat(dwFlags
);
3831 *lpddpal
= (IDirectDrawPaletteImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPaletteImpl
));
3832 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
3833 (*lpddpal
)->ref
= 1;
3834 (*lpddpal
)->ddraw
= (IDirectDrawImpl
*)This
;
3835 (*lpddpal
)->installed
= 0;
3837 if (dwFlags
& DDPCAPS_1BIT
)
3839 else if (dwFlags
& DDPCAPS_2BIT
)
3841 else if (dwFlags
& DDPCAPS_4BIT
)
3843 else if (dwFlags
& DDPCAPS_8BIT
)
3846 ERR("unhandled palette format\n");
3851 /* Now, if we are in 'depth conversion mode', create the screen palette */
3852 if (This
->d
.palette_convert
!= NULL
)
3853 This
->d
.palette_convert(palent
, (*lpddpal
)->screen_palents
, 0, size
);
3855 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
3856 } else if (This
->d
.palette_convert
!= NULL
) {
3857 /* In that case, put all 0xFF */
3858 memset((*lpddpal
)->screen_palents
, 0xFF, 256 * sizeof(int));
3864 #ifdef HAVE_LIBXXF86DGA
3865 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreatePalette(
3866 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3868 ICOM_THIS(IDirectDraw2Impl
,iface
);
3869 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
3873 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
3874 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
3875 if (res
!= 0) return res
;
3876 (*ilpddpal
)->lpvtbl
= &dga_ddpalvt
;
3877 if (This
->d
.directdraw_pixelformat
.x
.dwRGBBitCount
<=8) {
3878 (*ilpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
3880 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
3881 (*ilpddpal
)->cm
= 0;
3883 if (((*ilpddpal
)->cm
)&&xsize
) {
3884 for (i
=0;i
<xsize
;i
++) {
3887 xc
.red
= (*ilpddpal
)->palents
[i
].peRed
<<8;
3888 xc
.blue
= (*ilpddpal
)->palents
[i
].peBlue
<<8;
3889 xc
.green
= (*ilpddpal
)->palents
[i
].peGreen
<<8;
3890 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
3892 TSXStoreColor(display
,(*ilpddpal
)->cm
,&xc
);
3897 #endif /* defined(HAVE_LIBXXF86DGA) */
3899 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreatePalette(
3900 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3902 ICOM_THIS(IDirectDraw2Impl
,iface
);
3903 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
3907 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
3908 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
3909 if (res
!= 0) return res
;
3910 (*ilpddpal
)->lpvtbl
= &xlib_ddpalvt
;
3914 #ifdef HAVE_LIBXXF86DGA
3915 static HRESULT WINAPI
DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
3916 ICOM_THIS(IDirectDraw2Impl
,iface
);
3917 TRACE("(%p)->()\n",This
);
3919 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3920 #ifdef RESTORE_SIGNALS
3925 #endif /* defined(HAVE_LIBXXF86DGA) */
3927 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
3928 ICOM_THIS(IDirectDraw2Impl
,iface
);
3929 TRACE("(%p)->RestoreDisplayMode()\n", This
);
3934 static HRESULT WINAPI
IDirectDraw2Impl_WaitForVerticalBlank(
3935 LPDIRECTDRAW2 iface
,DWORD x
,HANDLE h
3937 ICOM_THIS(IDirectDraw2Impl
,iface
);
3938 TRACE("(%p)->(0x%08lx,0x%08x)\n",This
,x
,h
);
3942 static ULONG WINAPI
IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface
) {
3943 ICOM_THIS(IDirectDraw2Impl
,iface
);
3944 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
3946 return ++(This
->ref
);
3949 #ifdef HAVE_LIBXXF86DGA
3950 static ULONG WINAPI
DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
3951 ICOM_THIS(IDirectDraw2Impl
,iface
);
3952 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
3954 if (!--(This
->ref
)) {
3955 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3956 if (This
->d
.window
&& (This
->d
.mainWindow
!= This
->d
.window
))
3957 DestroyWindow(This
->d
.window
);
3958 #ifdef HAVE_LIBXXF86VM
3960 TSXF86VidModeSwitchToMode(
3962 DefaultScreen(display
),
3964 if (orig_mode
->privsize
)
3965 TSXFree(orig_mode
->private);
3971 #ifdef RESTORE_SIGNALS
3974 HeapFree(GetProcessHeap(),0,This
);
3979 #endif /* defined(HAVE_LIBXXF86DGA) */
3981 static ULONG WINAPI
Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
3982 ICOM_THIS(IDirectDraw2Impl
,iface
);
3983 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
3985 if (!--(This
->ref
)) {
3986 if (This
->d
.window
&& (This
->d
.mainWindow
!= This
->d
.window
))
3987 DestroyWindow(This
->d
.window
);
3988 HeapFree(GetProcessHeap(),0,This
);
3991 /* FIXME: destroy window ... */
3995 #ifdef HAVE_LIBXXF86DGA
3996 static HRESULT WINAPI
DGA_IDirectDraw2Impl_QueryInterface(
3997 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
3999 ICOM_THIS(IDirectDraw2Impl
,iface
);
4002 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
4003 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
4004 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
4006 IDirectDraw2_AddRef(iface
);
4008 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4012 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
4013 This
->lpvtbl
= (ICOM_VTABLE(IDirectDraw2
)*)&dga_ddvt
;
4014 IDirectDraw2_AddRef(iface
);
4017 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4021 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
4022 This
->lpvtbl
= (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd2vt
;
4023 IDirectDraw2_AddRef(iface
);
4026 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4030 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
4031 This
->lpvtbl
= (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd4vt
;
4032 IDirectDraw2_AddRef(iface
);
4035 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4039 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
4042 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4044 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4045 IDirectDraw2_AddRef(iface
);
4046 d3d
->lpvtbl
= &d3dvt
;
4049 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4053 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
4054 IDirect3D2Impl
* d3d
;
4056 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4058 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4059 IDirectDraw2_AddRef(iface
);
4060 d3d
->lpvtbl
= &d3d2vt
;
4063 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4067 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,xrefiid
);
4068 return OLE_E_ENUM_NOMORE
;
4070 #endif /* defined(HAVE_LIBXXF86DGA) */
4072 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_QueryInterface(
4073 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
4075 ICOM_THIS(IDirectDraw2Impl
,iface
);
4078 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
4079 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
4080 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
4082 IDirectDraw2_AddRef(iface
);
4084 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4088 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
4089 This
->lpvtbl
= (ICOM_VTABLE(IDirectDraw2
)*)&xlib_ddvt
;
4090 IDirectDraw2_AddRef(iface
);
4093 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4097 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
4098 This
->lpvtbl
= (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd2vt
;
4099 IDirectDraw2_AddRef(iface
);
4102 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4106 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
4107 This
->lpvtbl
= (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd4vt
;
4108 IDirectDraw2_AddRef(iface
);
4111 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4115 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
4118 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4120 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4121 IDirectDraw2_AddRef(iface
);
4122 d3d
->lpvtbl
= &d3dvt
;
4125 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4129 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
4130 IDirect3D2Impl
* d3d
;
4132 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4134 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4135 IDirectDraw2_AddRef(iface
);
4136 d3d
->lpvtbl
= &d3d2vt
;
4139 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4143 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,xrefiid
);
4144 return OLE_E_ENUM_NOMORE
;
4147 static HRESULT WINAPI
IDirectDraw2Impl_GetVerticalBlankStatus(
4148 LPDIRECTDRAW2 iface
,BOOL
*status
4150 ICOM_THIS(IDirectDraw2Impl
,iface
);
4151 TRACE("(%p)->(%p)\n",This
,status
);
4156 #ifdef HAVE_LIBXXF86DGA
4157 static HRESULT WINAPI
DGA_IDirectDraw2Impl_EnumDisplayModes(
4158 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4160 ICOM_THIS(IDirectDraw2Impl
,iface
);
4161 DDSURFACEDESC ddsfd
;
4164 } modes
[5] = { /* some of the usual modes */
4171 static int depths
[4] = {8,16,24,32};
4174 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4175 ddsfd
.dwSize
= sizeof(ddsfd
);
4176 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4177 if (dwFlags
& DDEDM_REFRESHRATES
) {
4178 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4179 ddsfd
.x
.dwRefreshRate
= 60;
4182 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
4183 ddsfd
.dwBackBufferCount
= 1;
4184 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4185 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4186 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= depths
[i
];
4187 /* FIXME: those masks would have to be set in depth > 8 */
4189 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
4190 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
4191 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
4192 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
4193 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
4194 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
4196 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
4198 /* FIXME: We should query those from X itself */
4199 switch (depths
[i
]) {
4201 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0xF800;
4202 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x07E0;
4203 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x001F;
4206 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
4207 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
4208 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
4211 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
4212 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
4213 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
4218 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4219 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4220 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4221 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4223 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
4224 ddsfd
.dwWidth
= modes
[j
].w
;
4225 ddsfd
.dwHeight
= modes
[j
].h
;
4226 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4227 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4230 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4231 /* modeX is not standard VGA */
4233 ddsfd
.dwHeight
= 200;
4234 ddsfd
.dwWidth
= 320;
4235 TRACE(" enumerating (320x200x%d)\n",depths
[i
]);
4236 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4241 #endif /* defined(HAVE_LIBXXF86DGA) */
4243 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_EnumDisplayModes(
4244 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4246 ICOM_THIS(IDirectDraw2Impl
,iface
);
4248 XPixmapFormatValues
*pf
;
4250 int nvisuals
, npixmap
, i
, emu
;
4251 int has_mode
[] = { 0, 0, 0, 0 };
4252 int has_depth
[] = { 8, 15, 16, 24 };
4253 DDSURFACEDESC ddsfd
;
4256 } modes
[] = { /* some of the usual modes */
4264 DWORD maxWidth
, maxHeight
;
4266 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4267 ddsfd
.dwSize
= sizeof(ddsfd
);
4268 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4269 if (dwFlags
& DDEDM_REFRESHRATES
) {
4270 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4271 ddsfd
.x
.dwRefreshRate
= 60;
4273 maxWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4274 maxHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4276 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
4277 pf
= XListPixmapFormats(display
, &npixmap
);
4281 while ((i
< npixmap
) ||
4288 for (j
= 0; j
< 4; j
++) {
4289 if (has_depth
[j
] == pf
[i
].depth
) {
4300 if (has_mode
[mode_index
] == 0) {
4301 if (mode_index
== 0) {
4304 ddsfd
.ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4305 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4306 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
;
4307 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4308 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= 8;
4309 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
4310 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
4311 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
4312 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
4314 has_mode
[mode_index
] = 1;
4316 /* All the 'true color' depths (15, 16 and 24)
4317 First, find the corresponding visual to extract the bit masks */
4318 for (j
= 0; j
< nvisuals
; j
++) {
4319 if (vi
[j
].depth
== pf
[i
].depth
) {
4320 ddsfd
.ddsCaps
.dwCaps
= 0;
4321 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4322 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4323 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4324 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
4325 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= vi
[j
].red_mask
;
4326 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= vi
[j
].green_mask
;
4327 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= vi
[j
].blue_mask
;
4328 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
4331 has_mode
[mode_index
] = 1;
4337 ERR("Did not find visual corresponding the the pixmap format !\n");
4343 /* Now to emulated modes */
4344 if (has_mode
[emu
] == 0) {
4347 int depth
= has_depth
[emu
];
4349 for (c
= 0; (c
< sizeof(ModeEmulations
) / sizeof(Convert
)) && (send_mode
== 0); c
++) {
4350 if (ModeEmulations
[c
].dest
.depth
== depth
) {
4351 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4352 for (l
= 0; (l
< npixmap
) && (send_mode
== 0); l
++) {
4353 if ((pf
[l
].depth
== ModeEmulations
[c
].screen
.depth
) &&
4354 (pf
[l
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
4356 for (j
= 0; (j
< nvisuals
) && (send_mode
== 0); j
++) {
4357 if ((vi
[j
].depth
== pf
[l
].depth
) &&
4358 (vi
[j
].red_mask
== ModeEmulations
[c
].screen
.rmask
) &&
4359 (vi
[j
].green_mask
== ModeEmulations
[c
].screen
.gmask
) &&
4360 (vi
[j
].blue_mask
== ModeEmulations
[c
].screen
.bmask
)) {
4361 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4362 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4364 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
;
4365 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= 8;
4366 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
4367 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
4368 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
4370 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4371 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
4372 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
4373 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
4374 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
4376 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
4381 ERR("No visual corresponding to pixmap format !\n");
4395 if (TRACE_ON(ddraw
)) {
4396 TRACE("Enumerating with pixel format : \n");
4397 _dump_pixelformat(&(ddsfd
.ddpfPixelFormat
));
4401 for (mode
= 0; mode
< sizeof(modes
)/sizeof(modes
[0]); mode
++) {
4402 /* Do not enumerate modes we cannot handle anyway */
4403 if ((modes
[mode
].w
> maxWidth
) || (modes
[mode
].h
> maxHeight
))
4406 ddsfd
.dwWidth
= modes
[mode
].w
;
4407 ddsfd
.dwHeight
= modes
[mode
].h
;
4409 /* Now, send the mode description to the application */
4410 TRACE(" - mode %4ld - %4ld\n", ddsfd
.dwWidth
, ddsfd
.dwHeight
);
4411 if (!modescb(&ddsfd
, context
))
4415 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4416 /* modeX is not standard VGA */
4417 ddsfd
.dwWidth
= 320;
4418 ddsfd
.dwHeight
= 200;
4419 if (!modescb(&ddsfd
, context
))
4432 #ifdef HAVE_LIBXXF86DGA
4433 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetDisplayMode(
4434 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4436 ICOM_THIS(IDirectDraw2Impl
,iface
);
4437 TRACE("(%p)->(%p)\n",This
,lpddsfd
);
4438 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4439 lpddsfd
->dwHeight
= This
->d
.height
;
4440 lpddsfd
->dwWidth
= This
->d
.width
;
4441 lpddsfd
->lPitch
= This
->e
.dga
.fb_width
*This
->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8;
4442 lpddsfd
->dwBackBufferCount
= 1;
4443 lpddsfd
->x
.dwRefreshRate
= 60;
4444 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4445 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4448 #endif /* defined(HAVE_LIBXXF86DGA) */
4450 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetDisplayMode(
4451 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4453 ICOM_THIS(IDirectDraw2Impl
,iface
);
4454 TRACE("(%p)->GetDisplayMode(%p)\n",This
,lpddsfd
);
4455 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4456 lpddsfd
->dwHeight
= This
->d
.height
;
4457 lpddsfd
->dwWidth
= This
->d
.width
;
4458 lpddsfd
->lPitch
= lpddsfd
->dwWidth
* This
->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8;
4459 lpddsfd
->dwBackBufferCount
= 1;
4460 lpddsfd
->x
.dwRefreshRate
= 60;
4461 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4462 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4466 static HRESULT WINAPI
IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface
) {
4467 ICOM_THIS(IDirectDraw2Impl
,iface
);
4468 TRACE("(%p)->()\n",This
);
4472 static HRESULT WINAPI
IDirectDraw2Impl_GetMonitorFrequency(
4473 LPDIRECTDRAW2 iface
,LPDWORD freq
4475 ICOM_THIS(IDirectDraw2Impl
,iface
);
4476 FIXME("(%p)->(%p) returns 60 Hz always\n",This
,freq
);
4477 *freq
= 60*100; /* 60 Hz */
4481 /* what can we directly decompress? */
4482 static HRESULT WINAPI
IDirectDraw2Impl_GetFourCCCodes(
4483 LPDIRECTDRAW2 iface
,LPDWORD x
,LPDWORD y
4485 ICOM_THIS(IDirectDraw2Impl
,iface
);
4486 FIXME("(%p,%p,%p), stub\n",This
,x
,y
);
4490 static HRESULT WINAPI
IDirectDraw2Impl_EnumSurfaces(
4491 LPDIRECTDRAW2 iface
,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
4493 ICOM_THIS(IDirectDraw2Impl
,iface
);
4494 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This
,x
,ddsfd
,context
,ddsfcb
);
4498 static HRESULT WINAPI
IDirectDraw2Impl_Compact(
4499 LPDIRECTDRAW2 iface
)
4501 ICOM_THIS(IDirectDraw2Impl
,iface
);
4502 FIXME("(%p)->()\n", This
);
4507 static HRESULT WINAPI
IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface
,
4508 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
4509 ICOM_THIS(IDirectDraw2Impl
,iface
);
4510 FIXME("(%p)->(%p)\n", This
, lplpGDIDDSSurface
);
4515 static HRESULT WINAPI
IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface
,
4516 LPDWORD lpdwScanLine
) {
4517 ICOM_THIS(IDirectDraw2Impl
,iface
);
4518 FIXME("(%p)->(%p)\n", This
, lpdwScanLine
);
4523 static HRESULT WINAPI
IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface
,
4525 ICOM_THIS(IDirectDraw2Impl
,iface
);
4526 FIXME("(%p)->(%p)\n", This
, lpGUID
);
4531 #ifdef HAVE_LIBXXF86DGA
4533 /* Note: Hack so we can reuse the old functions without compiler warnings */
4534 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4535 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4537 # define XCAST(fun) (void *)
4540 static ICOM_VTABLE(IDirectDraw
) dga_ddvt
=
4542 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4543 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
4544 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4545 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
4546 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4547 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4548 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
4549 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
4550 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4551 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
4552 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4553 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4554 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
4555 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
4556 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4557 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4558 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4559 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4560 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4561 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4562 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4563 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4564 DGA_IDirectDrawImpl_SetDisplayMode
,
4565 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4570 #endif /* defined(HAVE_LIBXXF86DGA) */
4572 /* Note: Hack so we can reuse the old functions without compiler warnings */
4573 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4574 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4576 # define XCAST(fun) (void *)
4579 static ICOM_VTABLE(IDirectDraw
) xlib_ddvt
=
4581 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4582 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
4583 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4584 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
4585 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4586 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4587 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
4588 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
4589 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4590 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4591 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4592 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4593 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
4594 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
4595 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4596 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4597 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4598 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4599 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4600 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4601 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4602 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4603 Xlib_IDirectDrawImpl_SetDisplayMode
,
4604 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4609 /*****************************************************************************
4615 #ifdef HAVE_LIBXXF86DGA
4616 static HRESULT WINAPI
DGA_IDirectDraw2Impl_SetDisplayMode(
4617 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
4619 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
4621 #endif /* defined(HAVE_LIBXXF86DGA) */
4623 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_SetDisplayMode(
4624 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
4626 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
4629 #ifdef HAVE_LIBXXF86DGA
4630 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetAvailableVidMem(
4631 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
4633 ICOM_THIS(IDirectDraw2Impl
,iface
);
4634 TRACE("(%p)->(%p,%p,%p)\n",
4635 This
,ddscaps
,total
,free
4637 if (total
) *total
= This
->e
.dga
.fb_memsize
* 1024;
4638 if (free
) *free
= This
->e
.dga
.fb_memsize
* 1024;
4641 #endif /* defined(HAVE_LIBXXF86DGA) */
4643 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4644 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
4646 ICOM_THIS(IDirectDraw2Impl
,iface
);
4647 TRACE("(%p)->(%p,%p,%p)\n",
4648 This
,ddscaps
,total
,free
4650 if (total
) *total
= 2048 * 1024;
4651 if (free
) *free
= 2048 * 1024;
4655 #ifdef HAVE_LIBXXF86DGA
4656 static ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
=
4658 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4659 DGA_IDirectDraw2Impl_QueryInterface
,
4660 IDirectDraw2Impl_AddRef
,
4661 DGA_IDirectDraw2Impl_Release
,
4662 IDirectDraw2Impl_Compact
,
4663 IDirectDraw2Impl_CreateClipper
,
4664 DGA_IDirectDraw2Impl_CreatePalette
,
4665 DGA_IDirectDraw2Impl_CreateSurface
,
4666 IDirectDraw2Impl_DuplicateSurface
,
4667 DGA_IDirectDraw2Impl_EnumDisplayModes
,
4668 IDirectDraw2Impl_EnumSurfaces
,
4669 IDirectDraw2Impl_FlipToGDISurface
,
4670 DGA_IDirectDraw2Impl_GetCaps
,
4671 DGA_IDirectDraw2Impl_GetDisplayMode
,
4672 IDirectDraw2Impl_GetFourCCCodes
,
4673 IDirectDraw2Impl_GetGDISurface
,
4674 IDirectDraw2Impl_GetMonitorFrequency
,
4675 IDirectDraw2Impl_GetScanLine
,
4676 IDirectDraw2Impl_GetVerticalBlankStatus
,
4677 IDirectDraw2Impl_Initialize
,
4678 DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4679 IDirectDraw2Impl_SetCooperativeLevel
,
4680 DGA_IDirectDraw2Impl_SetDisplayMode
,
4681 IDirectDraw2Impl_WaitForVerticalBlank
,
4682 DGA_IDirectDraw2Impl_GetAvailableVidMem
4684 #endif /* defined(HAVE_LIBXXF86DGA) */
4686 static ICOM_VTABLE(IDirectDraw2
) xlib_dd2vt
=
4688 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4689 Xlib_IDirectDraw2Impl_QueryInterface
,
4690 IDirectDraw2Impl_AddRef
,
4691 Xlib_IDirectDraw2Impl_Release
,
4692 IDirectDraw2Impl_Compact
,
4693 IDirectDraw2Impl_CreateClipper
,
4694 Xlib_IDirectDraw2Impl_CreatePalette
,
4695 Xlib_IDirectDraw2Impl_CreateSurface
,
4696 IDirectDraw2Impl_DuplicateSurface
,
4697 Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4698 IDirectDraw2Impl_EnumSurfaces
,
4699 IDirectDraw2Impl_FlipToGDISurface
,
4700 Xlib_IDirectDraw2Impl_GetCaps
,
4701 Xlib_IDirectDraw2Impl_GetDisplayMode
,
4702 IDirectDraw2Impl_GetFourCCCodes
,
4703 IDirectDraw2Impl_GetGDISurface
,
4704 IDirectDraw2Impl_GetMonitorFrequency
,
4705 IDirectDraw2Impl_GetScanLine
,
4706 IDirectDraw2Impl_GetVerticalBlankStatus
,
4707 IDirectDraw2Impl_Initialize
,
4708 Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4709 IDirectDraw2Impl_SetCooperativeLevel
,
4710 Xlib_IDirectDraw2Impl_SetDisplayMode
,
4711 IDirectDraw2Impl_WaitForVerticalBlank
,
4712 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4715 /*****************************************************************************
4720 static HRESULT WINAPI
IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface
,
4722 LPDIRECTDRAWSURFACE
*lpDDS
) {
4723 ICOM_THIS(IDirectDraw4Impl
,iface
);
4724 FIXME("(%p)->(%08ld,%p)\n", This
, (DWORD
) hdc
, lpDDS
);
4729 static HRESULT WINAPI
IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface
) {
4730 ICOM_THIS(IDirectDraw4Impl
,iface
);
4731 FIXME("(%p)->()\n", This
);
4736 static HRESULT WINAPI
IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface
) {
4737 ICOM_THIS(IDirectDraw4Impl
,iface
);
4738 FIXME("(%p)->()\n", This
);
4743 static HRESULT WINAPI
IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface
,
4744 LPDDDEVICEIDENTIFIER lpdddi
,
4746 ICOM_THIS(IDirectDraw4Impl
,iface
);
4747 FIXME("(%p)->(%p,%08lx)\n", This
, lpdddi
, dwFlags
);
4752 #ifdef HAVE_LIBXXF86DGA
4754 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4755 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4757 # define XCAST(fun) (void*)
4760 static ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
=
4762 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4763 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
4764 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4765 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
4766 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4767 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4768 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
4769 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
4770 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4771 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
4772 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4773 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4774 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
4775 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
4776 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4777 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4778 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4779 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4780 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4781 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4782 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4783 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4784 XCAST(SetDisplayMode
)DGA_IDirectDrawImpl_SetDisplayMode
,
4785 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4786 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2Impl_GetAvailableVidMem
,
4787 IDirectDraw4Impl_GetSurfaceFromDC
,
4788 IDirectDraw4Impl_RestoreAllSurfaces
,
4789 IDirectDraw4Impl_TestCooperativeLevel
,
4790 IDirectDraw4Impl_GetDeviceIdentifier
4795 #endif /* defined(HAVE_LIBXXF86DGA) */
4797 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4798 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
4800 # define XCAST(fun) (void*)
4803 static ICOM_VTABLE(IDirectDraw4
) xlib_dd4vt
=
4805 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4806 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
4807 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4808 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
4809 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4810 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4811 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
4812 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
4813 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4814 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4815 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4816 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4817 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
4818 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
4819 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4820 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4821 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4822 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4823 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4824 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4825 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4826 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4827 XCAST(SetDisplayMode
)Xlib_IDirectDrawImpl_SetDisplayMode
,
4828 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4829 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2Impl_GetAvailableVidMem
,
4830 IDirectDraw4Impl_GetSurfaceFromDC
,
4831 IDirectDraw4Impl_RestoreAllSurfaces
,
4832 IDirectDraw4Impl_TestCooperativeLevel
,
4833 IDirectDraw4Impl_GetDeviceIdentifier
4838 /******************************************************************************
4842 static LRESULT WINAPI
Xlib_DDWndProc(HWND hwnd
,UINT msg
,WPARAM wParam
,LPARAM lParam
)
4845 IDirectDrawImpl
* ddraw
= NULL
;
4848 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4850 SetLastError( ERROR_SUCCESS
);
4851 ddraw
= (IDirectDrawImpl
*)GetWindowLongA( hwnd
, ddrawXlibThisOffset
);
4853 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
4856 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
4861 /* Perform any special direct draw functions */
4863 ddraw
->d
.paintable
= 1;
4865 /* Now let the application deal with the rest of this */
4866 if( ddraw
->d
.mainWindow
)
4869 /* Don't think that we actually need to call this but...
4870 might as well be on the safe side of things... */
4872 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4873 it should be the procedures of our fake window that gets called
4874 instead of those of the window provided by the application.
4875 And with this patch, mouse clicks work with Monkey Island III
4877 ret
= DefWindowProcA( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
4881 WND
*tmpWnd
=WIN_FindWndPtr(ddraw
->d
.mainWindow
);
4882 /* We didn't handle the message - give it to the application */
4883 if (ddraw
&& ddraw
->d
.mainWindow
&& tmpWnd
)
4885 ret
= CallWindowProcA(tmpWnd
->winproc
,
4886 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
4888 WIN_ReleaseWndPtr(tmpWnd
);
4893 ret
= DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
4899 ret
= DefWindowProcA(hwnd
,msg
,wParam
,lParam
);
4905 static HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4906 #ifdef HAVE_LIBXXF86DGA
4907 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
4908 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
4913 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4914 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
4918 MESSAGE("Must be able to access /dev/mem to use XF86DGA!\n");
4919 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
4920 return E_UNEXPECTED
;
4922 if (!DDRAW_DGA_Available()) {
4923 TRACE("No XF86DGA detected.\n");
4924 return DDERR_GENERIC
;
4926 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
4927 (*ilplpDD
)->lpvtbl
= &dga_ddvt
;
4928 (*ilplpDD
)->ref
= 1;
4929 TSXF86DGAQueryVersion(display
,&major
,&minor
);
4930 TRACE("XF86DGA is version %d.%d\n",major
,minor
);
4931 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
4932 if (!(flags
& XF86DGADirectPresent
))
4933 MESSAGE("direct video is NOT PRESENT.\n");
4934 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
4935 (*ilplpDD
)->e
.dga
.fb_width
= width
;
4936 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
4937 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
4938 (*ilplpDD
)->e
.dga
.fb_height
= height
;
4939 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4940 addr
,width
,banksize
,memsize
4942 TRACE("viewport height: %d\n",height
);
4944 /* Get the screen dimensions as seen by Wine.
4945 In that case, it may be better to ignore the -desktop mode and return the
4946 real screen size => print a warning */
4947 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4948 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4949 if (((*ilplpDD
)->d
.height
!= height
) ||
4950 ((*ilplpDD
)->d
.width
!= width
))
4951 WARN("You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4952 (*ilplpDD
)->e
.dga
.fb_addr
= addr
;
4953 (*ilplpDD
)->e
.dga
.fb_memsize
= memsize
;
4954 (*ilplpDD
)->e
.dga
.fb_banksize
= banksize
;
4955 (*ilplpDD
)->e
.dga
.vpmask
= 0;
4957 /* just assume the default depth is the DGA depth too */
4958 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
4959 _common_depth_to_pixelformat(depth
, &((*ilplpDD
)->d
.directdraw_pixelformat
), &((*ilplpDD
)->d
.screen_pixelformat
), NULL
);
4960 #ifdef RESTORE_SIGNALS
4965 #else /* defined(HAVE_LIBXXF86DGA) */
4966 return DDERR_INVALIDDIRECTDRAWGUID
;
4967 #endif /* defined(HAVE_LIBXXF86DGA) */
4971 DDRAW_XSHM_Available(void)
4973 #ifdef HAVE_LIBXXSHM
4974 if (TSXShmQueryExtension(display
))
4979 if ((TSXShmQueryVersion(display
, &major
, &minor
, &shpix
)) &&
4980 (Options
.noXSHM
!= 1))
4992 static HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4993 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
4996 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
4997 (*ilplpDD
)->lpvtbl
= &xlib_ddvt
;
4998 (*ilplpDD
)->ref
= 1;
4999 (*ilplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
5001 /* At DirectDraw creation, the depth is the default depth */
5002 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
5003 _common_depth_to_pixelformat(depth
,
5004 &((*ilplpDD
)->d
.directdraw_pixelformat
),
5005 &((*ilplpDD
)->d
.screen_pixelformat
),
5006 &((*ilplpDD
)->d
.pixmap_depth
));
5007 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
5008 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
5010 #ifdef HAVE_LIBXXSHM
5011 /* Test if XShm is available. */
5012 if (((*ilplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available()))
5013 TRACE("Using XShm extension.\n");
5019 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
5020 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
5023 /* WND* pParentWindow; */
5027 WINE_StringFromCLSID(lpGUID
,xclsid
);
5029 sprintf(xclsid
,"<guid-0x%08x>",(int)lpGUID
);
5033 TRACE("(%s,%p,%p)\n",xclsid
,ilplpDD
,pUnkOuter
);
5036 (!memcmp(lpGUID
,&IID_IDirectDraw
,sizeof(IID_IDirectDraw
))) ||
5037 (!memcmp(lpGUID
,&IID_IDirectDraw2
,sizeof(IID_IDirectDraw2
))) ||
5038 (!memcmp(lpGUID
,&IID_IDirectDraw4
,sizeof(IID_IDirectDraw4
)))) {
5039 /* if they didn't request a particular interface, use the best
5041 if (DDRAW_DGA_Available())
5042 lpGUID
= &DGA_DirectDraw_GUID
;
5044 lpGUID
= &XLIB_DirectDraw_GUID
;
5047 wc
.style
= CS_GLOBALCLASS
;
5048 wc
.lpfnWndProc
= Xlib_DDWndProc
;
5050 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
5051 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
5053 /* We can be a child of the desktop since we're really important */
5055 This code is not useful since hInstance is forced to 0 afterward
5056 pParentWindow = WIN_GetDesktop();
5057 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5063 wc
.hCursor
= (HCURSOR
)IDC_ARROWA
;
5064 wc
.hbrBackground
= NULL_BRUSH
;
5065 wc
.lpszMenuName
= 0;
5066 wc
.lpszClassName
= "WINE_DirectDraw";
5067 RegisterClassA(&wc
);
5069 if (!memcmp(lpGUID
, &DGA_DirectDraw_GUID
, sizeof(GUID
)))
5070 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
5071 else if (!memcmp(lpGUID
, &XLIB_DirectDraw_GUID
, sizeof(GUID
)))
5072 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
5077 (*ilplpDD
)->d
.winclass
= RegisterClassA(&wc
);
5081 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
5082 return DDERR_INVALIDDIRECTDRAWGUID
;
5085 /*******************************************************************************
5086 * DirectDraw ClassFactory
5088 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5093 /* IUnknown fields */
5094 ICOM_VTABLE(IClassFactory
)* lpvtbl
;
5096 } IClassFactoryImpl
;
5098 static HRESULT WINAPI
5099 DDCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
) {
5100 ICOM_THIS(IClassFactoryImpl
,iface
);
5104 WINE_StringFromCLSID(riid
,buf
);
5106 sprintf(buf
,"<guid-0x%04x>",LOWORD(riid
));
5107 FIXME("(%p)->(%s,%p),stub!\n",This
,buf
,ppobj
);
5108 return E_NOINTERFACE
;
5112 DDCF_AddRef(LPCLASSFACTORY iface
) {
5113 ICOM_THIS(IClassFactoryImpl
,iface
);
5114 return ++(This
->ref
);
5117 static ULONG WINAPI
DDCF_Release(LPCLASSFACTORY iface
) {
5118 ICOM_THIS(IClassFactoryImpl
,iface
);
5119 /* static class, won't be freed */
5120 return --(This
->ref
);
5123 static HRESULT WINAPI
DDCF_CreateInstance(
5124 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
5126 ICOM_THIS(IClassFactoryImpl
,iface
);
5129 WINE_StringFromCLSID(riid
,buf
);
5130 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,buf
,ppobj
);
5131 if ((!memcmp(riid
,&IID_IDirectDraw
,sizeof(IID_IDirectDraw
))) ||
5132 (!memcmp(riid
,&IID_IDirectDraw2
,sizeof(IID_IDirectDraw2
))) ||
5133 (!memcmp(riid
,&IID_IDirectDraw4
,sizeof(IID_IDirectDraw4
)))) {
5134 /* FIXME: reuse already created DirectDraw if present? */
5135 return DirectDrawCreate((LPGUID
) riid
,(LPDIRECTDRAW
*)ppobj
,pOuter
);
5137 return E_NOINTERFACE
;
5140 static HRESULT WINAPI
DDCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
5141 ICOM_THIS(IClassFactoryImpl
,iface
);
5142 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
5146 static ICOM_VTABLE(IClassFactory
) DDCF_Vtbl
=
5148 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5149 DDCF_QueryInterface
,
5152 DDCF_CreateInstance
,
5155 static IClassFactoryImpl DDRAW_CF
= {&DDCF_Vtbl
, 1 };
5157 /*******************************************************************************
5158 * DllGetClassObject [DDRAW.13]
5159 * Retrieves class object from a DLL object
5162 * Docs say returns STDAPI
5165 * rclsid [I] CLSID for the class object
5166 * riid [I] Reference to identifier of interface for class object
5167 * ppv [O] Address of variable to receive interface pointer for riid
5171 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5174 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
,REFIID riid
,LPVOID
*ppv
)
5176 char buf
[80],xbuf
[80];
5179 WINE_StringFromCLSID(rclsid
,xbuf
);
5181 sprintf(xbuf
,"<guid-0x%04x>",LOWORD(rclsid
));
5183 WINE_StringFromCLSID(riid
,buf
);
5185 sprintf(buf
,"<guid-0x%04x>",LOWORD(riid
));
5186 WINE_StringFromCLSID(riid
,xbuf
);
5187 TRACE("(%p,%p,%p)\n", xbuf
, buf
, ppv
);
5188 if (!memcmp(riid
,&IID_IClassFactory
,sizeof(IID_IClassFactory
))) {
5189 *ppv
= (LPVOID
)&DDRAW_CF
;
5190 IClassFactory_AddRef((IClassFactory
*)*ppv
);
5193 FIXME("(%p,%p,%p): no interface found.\n", xbuf
, buf
, ppv
);
5194 return E_NOINTERFACE
;
5198 /*******************************************************************************
5199 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5205 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5207 FIXME("(void): stub\n");
5211 #else /* !defined(X_DISPLAY_MISSING) */
5214 #include "winerror.h"
5219 typedef void *LPUNKNOWN
;
5220 typedef void *LPDIRECTDRAW
;
5221 typedef void *LPDIRECTDRAWCLIPPER
;
5222 typedef void *LPDDENUMCALLBACKA
;
5223 typedef void *LPDDENUMCALLBACKEXA
;
5224 typedef void *LPDDENUMCALLBACKEXW
;
5225 typedef void *LPDDENUMCALLBACKW
;
5227 HRESULT WINAPI
DSoundHelp(DWORD x
, DWORD y
, DWORD z
)
5232 HRESULT WINAPI
DirectDrawCreate(
5233 LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
)
5238 HRESULT WINAPI
DirectDrawCreateClipper(
5239 DWORD dwFlags
, LPDIRECTDRAWCLIPPER
*lplpDDClipper
, LPUNKNOWN pUnkOuter
)
5244 HRESULT WINAPI
DirectDrawEnumerateA(
5245 LPDDENUMCALLBACKA lpCallback
, LPVOID lpContext
)
5250 HRESULT WINAPI
DirectDrawEnumerateExA(
5251 LPDDENUMCALLBACKEXA lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5256 HRESULT WINAPI
DirectDrawEnumerateExW(
5257 LPDDENUMCALLBACKEXW lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5262 HRESULT WINAPI
DirectDrawEnumerateW(
5263 LPDDENUMCALLBACKW lpCallback
, LPVOID lpContext
)
5268 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
5270 return E_NOINTERFACE
;
5273 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5278 #endif /* !defined(X_DISPLAY_MISSING) */