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>
26 # ifdef HAVE_SYS_IPC_H
29 # ifdef HAVE_SYS_SHM_H
33 #endif /* defined(HAVE_LIBXXSHM) */
35 #ifdef HAVE_LIBXXF86DGA
36 #include "ts_xf86dga.h"
37 #endif /* defined(HAVE_LIBXXF86DGA) */
39 #ifdef HAVE_LIBXXF86VM
40 #include "ts_xf86vmode.h"
41 #endif /* defined(HAVE_LIBXXF86VM) */
47 #ifdef HAVE_SYS_SIGNAL_H
48 # include <sys/signal.h>
59 #include "wine/exception.h"
62 #include "debugtools.h"
68 /* This for all the enumeration and creation of D3D-related objects */
69 #include "ddraw_private.h"
70 #include "d3d_private.h"
72 DEFAULT_DEBUG_CHANNEL(ddraw
)
74 /* Restore signal handlers overwritten by XF86DGA
76 #define RESTORE_SIGNALS
78 /* Get DDSCAPS of surface (shortcutmacro) */
79 #define SDDSCAPS(iface) ((iface)->s.surface_desc.ddsCaps.dwCaps)
81 /* Get the number of bytes per pixel for a given surface */
82 #define PFGET_BPP(pf) (pf.dwFlags&DDPF_PALETTEINDEXED8?1:(pf.u.dwRGBBitCount/8))
84 #define GET_BPP(desc) PFGET_BPP(desc.ddpfPixelFormat)
86 /* Where do these GUIDs come from? mkuuid.
87 * They exist solely to distinguish between the targets Wine support,
88 * and should be different than any other GUIDs in existence.
90 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
94 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
97 static GUID XLIB_DirectDraw_GUID
= { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
101 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
104 #ifdef HAVE_LIBXXF86DGA
105 static struct ICOM_VTABLE(IDirectDrawSurface4
) dga_dds4vt
;
106 static struct ICOM_VTABLE(IDirectDraw
) dga_ddvt
;
107 static struct ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
;
108 static struct ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
;
109 static struct ICOM_VTABLE(IDirectDrawPalette
) dga_ddpalvt
;
110 #endif /* defined(HAVE_LIBXXF86DGA) */
112 static struct ICOM_VTABLE(IDirectDrawSurface4
) xlib_dds4vt
;
113 static struct ICOM_VTABLE(IDirectDraw
) xlib_ddvt
;
114 static struct ICOM_VTABLE(IDirectDraw2
) xlib_dd2vt
;
115 static struct ICOM_VTABLE(IDirectDraw4
) xlib_dd4vt
;
116 static struct ICOM_VTABLE(IDirectDrawPalette
) xlib_ddpalvt
;
118 static struct ICOM_VTABLE(IDirectDrawClipper
) ddclipvt
;
119 static struct ICOM_VTABLE(IDirect3D
) d3dvt
;
120 static struct ICOM_VTABLE(IDirect3D2
) d3d2vt
;
122 /* This is for mode-emulation */
124 static void pixel_convert_16_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
125 static void palette_convert_16_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) ;
126 static void palette_convert_15_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) ;
127 static void pixel_convert_24_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
128 static void pixel_convert_32_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
129 static void palette_convert_24_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) ;
130 static void pixel_convert_32_to_16(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) ;
134 unsigned short depth
;
141 void (*pixel_convert
)(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
);
142 void (*palette_convert
)(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
);
146 ConvertMode screen
, dest
;
150 static Convert ModeEmulations
[] = {
151 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_32_to_8
, palette_convert_24_to_8
} },
152 { { 32, 24, 0x00FF0000, 0x0000FF00, 0x000000FF }, { 16, 16, 0xF800, 0x07E0, 0x001F }, { pixel_convert_32_to_16
, NULL
} },
153 { { 24, 24, 0xFF0000, 0x00FF00, 0x0000FF }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_24_to_8
, palette_convert_24_to_8
} },
154 { { 16, 16, 0xF800, 0x07E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8
, palette_convert_16_to_8
} },
155 { { 16, 15, 0x7C00, 0x03E0, 0x001F }, { 8, 8, 0x00, 0x00, 0x00 }, { pixel_convert_16_to_8
, palette_convert_15_to_8
} },
158 #ifdef HAVE_LIBXXF86VM
159 static XF86VidModeModeInfo
*orig_mode
= NULL
;
163 static int XShmErrorFlag
= 0;
167 DDRAW_DGA_Available(void)
169 #ifdef HAVE_LIBXXF86DGA
170 int evbase
, evret
, fd
;
175 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
176 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
177 /* others. --stephenc */
178 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
181 return (fd
!= -1) && TSXF86DGAQueryExtension(display
,&evbase
,&evret
);
182 #else /* defined(HAVE_LIBXXF86DGA) */
184 #endif /* defined(HAVE_LIBXXF86DGA) */
187 /**********************************************************************/
192 } DirectDrawEnumerateProcData
;
194 /***********************************************************************
195 * DirectDrawEnumerateExA (DDRAW.*)
197 HRESULT WINAPI
DirectDrawEnumerateExA(
198 LPDDENUMCALLBACKEXA lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
200 TRACE("(%p,%p, %08lx)\n", lpCallback
, lpContext
, dwFlags
);
202 if (TRACE_ON(ddraw
)) {
203 DPRINTF(" Flags : ");
204 if (dwFlags
& DDENUM_ATTACHEDSECONDARYDEVICES
)
205 DPRINTF("DDENUM_ATTACHEDSECONDARYDEVICES ");
206 if (dwFlags
& DDENUM_DETACHEDSECONDARYDEVICES
)
207 DPRINTF("DDENUM_DETACHEDSECONDARYDEVICES ");
208 if (dwFlags
& DDENUM_NONDISPLAYDEVICES
)
209 DPRINTF("DDENUM_NONDISPLAYDEVICES ");
213 if (dwFlags
== DDENUM_NONDISPLAYDEVICES
) {
214 /* For the moment, Wine does not support any 3D only accelerators */
218 if (DDRAW_DGA_Available()) {
219 TRACE("Enumerating DGA interface\n");
220 if (!lpCallback(&DGA_DirectDraw_GUID
, "WINE with XFree86 DGA", "display", lpContext
, 0))
224 TRACE("Enumerating Xlib interface\n");
225 if (!lpCallback(&XLIB_DirectDraw_GUID
, "WINE with Xlib", "display", lpContext
, 0))
228 TRACE("Enumerating Default interface\n");
229 if (!lpCallback(NULL
,"WINE (default)", "display", lpContext
, 0))
235 /***********************************************************************
236 * DirectDrawEnumerateExW (DDRAW.*)
239 static BOOL CALLBACK
DirectDrawEnumerateExProcW(
240 GUID
*lpGUID
, LPSTR lpDriverDescription
, LPSTR lpDriverName
,
241 LPVOID lpContext
, HMONITOR hm
)
243 DirectDrawEnumerateProcData
*pEPD
=
244 (DirectDrawEnumerateProcData
*) lpContext
;
245 LPWSTR lpDriverDescriptionW
=
246 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverDescription
);
247 LPWSTR lpDriverNameW
=
248 HEAP_strdupAtoW(GetProcessHeap(), 0, lpDriverName
);
250 BOOL bResult
= (*(LPDDENUMCALLBACKEXW
*) pEPD
->lpCallback
)(
251 lpGUID
, lpDriverDescriptionW
, lpDriverNameW
, pEPD
->lpContext
, hm
);
253 HeapFree(GetProcessHeap(), 0, lpDriverDescriptionW
);
254 HeapFree(GetProcessHeap(), 0, lpDriverNameW
);
259 /**********************************************************************/
261 HRESULT WINAPI
DirectDrawEnumerateExW(
262 LPDDENUMCALLBACKEXW lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
264 DirectDrawEnumerateProcData epd
;
265 epd
.lpCallback
= (LPVOID
) lpCallback
;
266 epd
.lpContext
= lpContext
;
268 return DirectDrawEnumerateExA(DirectDrawEnumerateExProcW
,
272 /***********************************************************************
273 * DirectDrawEnumerateA (DDRAW.*)
276 static BOOL CALLBACK
DirectDrawEnumerateProcA(
277 GUID
*lpGUID
, LPSTR lpDriverDescription
, LPSTR lpDriverName
,
278 LPVOID lpContext
, HMONITOR hm
)
280 DirectDrawEnumerateProcData
*pEPD
=
281 (DirectDrawEnumerateProcData
*) lpContext
;
283 return ((LPDDENUMCALLBACKA
) pEPD
->lpCallback
)(
284 lpGUID
, lpDriverDescription
, lpDriverName
, pEPD
->lpContext
);
287 /**********************************************************************/
289 HRESULT WINAPI
DirectDrawEnumerateA(
290 LPDDENUMCALLBACKA lpCallback
, LPVOID lpContext
)
292 DirectDrawEnumerateProcData epd
;
293 epd
.lpCallback
= (LPVOID
) lpCallback
;
294 epd
.lpContext
= lpContext
;
296 return DirectDrawEnumerateExA(DirectDrawEnumerateProcA
,
300 /***********************************************************************
301 * DirectDrawEnumerateW (DDRAW.*)
304 static BOOL WINAPI
DirectDrawEnumerateProcW(
305 GUID
*lpGUID
, LPWSTR lpDriverDescription
, LPWSTR lpDriverName
,
306 LPVOID lpContext
, HMONITOR hm
)
308 DirectDrawEnumerateProcData
*pEPD
=
309 (DirectDrawEnumerateProcData
*) lpContext
;
311 return ((LPDDENUMCALLBACKW
) pEPD
->lpCallback
)(
312 lpGUID
, lpDriverDescription
, lpDriverName
,
316 /**********************************************************************/
318 HRESULT WINAPI
DirectDrawEnumerateW(
319 LPDDENUMCALLBACKW lpCallback
, LPVOID lpContext
)
321 DirectDrawEnumerateProcData epd
;
322 epd
.lpCallback
= (LPVOID
) lpCallback
;
323 epd
.lpContext
= lpContext
;
325 return DirectDrawEnumerateExW(DirectDrawEnumerateProcW
,
329 /***********************************************************************
330 * DSoundHelp (DDRAW.?)
333 /* What is this doing here? */
335 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
336 FIXME("(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
340 /******************************************************************************
341 * internal helper functions
343 static void _dump_DDBLTFX(DWORD flagmask
) {
349 #define FE(x) { x, #x},
350 FE(DDBLTFX_ARITHSTRETCHY
)
351 FE(DDBLTFX_MIRRORLEFTRIGHT
)
352 FE(DDBLTFX_MIRRORUPDOWN
)
353 FE(DDBLTFX_NOTEARING
)
354 FE(DDBLTFX_ROTATE180
)
355 FE(DDBLTFX_ROTATE270
)
357 FE(DDBLTFX_ZBUFFERRANGE
)
358 FE(DDBLTFX_ZBUFFERBASEDEST
)
361 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
362 if (flags
[i
].mask
& flagmask
) {
363 DPRINTF("%s ",flags
[i
].name
);
370 static void _dump_DDBLTFAST(DWORD flagmask
) {
376 #define FE(x) { x, #x},
377 FE(DDBLTFAST_NOCOLORKEY
)
378 FE(DDBLTFAST_SRCCOLORKEY
)
379 FE(DDBLTFAST_DESTCOLORKEY
)
383 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
384 if (flags
[i
].mask
& flagmask
)
385 DPRINTF("%s ",flags
[i
].name
);
389 static void _dump_DDBLT(DWORD flagmask
) {
395 #define FE(x) { x, #x},
397 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
398 FE(DDBLT_ALPHADESTNEG
)
399 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
400 FE(DDBLT_ALPHAEDGEBLEND
)
402 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
403 FE(DDBLT_ALPHASRCNEG
)
404 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
410 FE(DDBLT_KEYDESTOVERRIDE
)
412 FE(DDBLT_KEYSRCOVERRIDE
)
414 FE(DDBLT_ROTATIONANGLE
)
416 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
417 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
418 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
419 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
424 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
425 if (flags
[i
].mask
& flagmask
)
426 DPRINTF("%s ",flags
[i
].name
);
430 static void _dump_DDSCAPS(void *in
) {
436 #define FE(x) { x, #x},
437 FE(DDSCAPS_RESERVED1
)
439 FE(DDSCAPS_BACKBUFFER
)
442 FE(DDSCAPS_FRONTBUFFER
)
443 FE(DDSCAPS_OFFSCREENPLAIN
)
446 FE(DDSCAPS_PRIMARYSURFACE
)
447 FE(DDSCAPS_PRIMARYSURFACELEFT
)
448 FE(DDSCAPS_SYSTEMMEMORY
)
451 FE(DDSCAPS_VIDEOMEMORY
)
453 FE(DDSCAPS_WRITEONLY
)
456 FE(DDSCAPS_LIVEVIDEO
)
460 FE(DDSCAPS_RESERVED2
)
461 FE(DDSCAPS_ALLOCONLOAD
)
462 FE(DDSCAPS_VIDEOPORT
)
463 FE(DDSCAPS_LOCALVIDMEM
)
464 FE(DDSCAPS_NONLOCALVIDMEM
)
465 FE(DDSCAPS_STANDARDVGAMODE
)
466 FE(DDSCAPS_OPTIMIZED
)
469 DWORD flagmask
= *((DWORD
*) in
);
470 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
471 if (flags
[i
].mask
& flagmask
)
472 DPRINTF("%s ",flags
[i
].name
);
475 static void _dump_pixelformat_flag(DWORD flagmask
) {
481 #define FE(x) { x, #x},
485 FE(DDPF_PALETTEINDEXED4
)
486 FE(DDPF_PALETTEINDEXEDTO8
)
487 FE(DDPF_PALETTEINDEXED8
)
493 FE(DDPF_PALETTEINDEXED1
)
494 FE(DDPF_PALETTEINDEXED2
)
498 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
499 if (flags
[i
].mask
& flagmask
)
500 DPRINTF("%s ",flags
[i
].name
);
503 static void _dump_paletteformat(DWORD dwFlags
) {
509 #define FE(x) { x, #x},
511 FE(DDPCAPS_8BITENTRIES
)
513 FE(DDPCAPS_INITIALIZE
)
514 FE(DDPCAPS_PRIMARYSURFACE
)
515 FE(DDPCAPS_PRIMARYSURFACELEFT
)
523 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
524 if (flags
[i
].mask
& dwFlags
)
525 DPRINTF("%s ",flags
[i
].name
);
529 static void _dump_pixelformat(void *in
) {
530 LPDDPIXELFORMAT pf
= (LPDDPIXELFORMAT
) in
;
534 _dump_pixelformat_flag(pf
->dwFlags
);
535 if (pf
->dwFlags
& DDPF_FOURCC
) {
536 DPRINTF(", dwFourCC : %ld", pf
->dwFourCC
);
538 if (pf
->dwFlags
& DDPF_RGB
) {
539 DPRINTF(", RGB bits: %ld, ", pf
->u
.dwRGBBitCount
);
540 switch (pf
->u
.dwRGBBitCount
) {
557 ERR("Unexpected bit depth !\n");
560 DPRINTF(" R "); DPRINTF(cmd
, pf
->u1
.dwRBitMask
);
561 DPRINTF(" G "); DPRINTF(cmd
, pf
->u2
.dwGBitMask
);
562 DPRINTF(" B "); DPRINTF(cmd
, pf
->u3
.dwBBitMask
);
563 if (pf
->dwFlags
& DDPF_ALPHAPIXELS
) {
564 DPRINTF(" A "); DPRINTF(cmd
, pf
->u4
.dwRGBAlphaBitMask
);
566 if (pf
->dwFlags
& DDPF_ZPIXELS
) {
567 DPRINTF(" Z "); DPRINTF(cmd
, pf
->u4
.dwRGBZBitMask
);
570 if (pf
->dwFlags
& DDPF_ZBUFFER
) {
571 DPRINTF(", Z bits : %ld", pf
->u
.dwZBufferBitDepth
);
573 if (pf
->dwFlags
& DDPF_ALPHA
) {
574 DPRINTF(", Alpha bits : %ld", pf
->u
.dwAlphaBitDepth
);
579 static void _dump_colorkeyflag(DWORD ck
) {
585 #define FE(x) { x, #x},
586 FE(DDCKEY_COLORSPACE
)
588 FE(DDCKEY_DESTOVERLAY
)
590 FE(DDCKEY_SRCOVERLAY
)
593 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
594 if (flags
[i
].mask
& ck
)
595 DPRINTF("%s ",flags
[i
].name
);
598 static void _dump_DWORD(void *in
) {
599 DPRINTF("%ld", *((DWORD
*) in
));
601 static void _dump_PTR(void *in
) {
602 DPRINTF("%p", *((void **) in
));
604 static void _dump_DDCOLORKEY(void *in
) {
605 DDCOLORKEY
*ddck
= (DDCOLORKEY
*) in
;
607 DPRINTF(" Low : %ld - High : %ld", ddck
->dwColorSpaceLowValue
, ddck
->dwColorSpaceHighValue
);
610 static void _dump_surface_desc(DDSURFACEDESC
*lpddsd
) {
615 void (*func
)(void *);
617 } flags
[16], *fe
= flags
;
618 #define FE(x,f,e) do { fe->mask = x; fe->name = #x; fe->func = f; fe->elt = (void *) &(lpddsd->e); fe++; } while(0)
619 FE(DDSD_CAPS
, _dump_DDSCAPS
, ddsCaps
);
620 FE(DDSD_HEIGHT
, _dump_DWORD
, dwHeight
);
621 FE(DDSD_WIDTH
, _dump_DWORD
, dwWidth
);
622 FE(DDSD_PITCH
, _dump_DWORD
, lPitch
);
623 FE(DDSD_BACKBUFFERCOUNT
, _dump_DWORD
, dwBackBufferCount
);
624 FE(DDSD_ZBUFFERBITDEPTH
, _dump_DWORD
, u
.dwZBufferBitDepth
);
625 FE(DDSD_ALPHABITDEPTH
, _dump_DWORD
, dwAlphaBitDepth
);
626 FE(DDSD_PIXELFORMAT
, _dump_pixelformat
, ddpfPixelFormat
);
627 FE(DDSD_CKDESTOVERLAY
, _dump_DDCOLORKEY
, ddckCKDestOverlay
);
628 FE(DDSD_CKDESTBLT
, _dump_DDCOLORKEY
, ddckCKDestBlt
);
629 FE(DDSD_CKSRCOVERLAY
, _dump_DDCOLORKEY
, ddckCKSrcOverlay
);
630 FE(DDSD_CKSRCBLT
, _dump_DDCOLORKEY
, ddckCKSrcBlt
);
631 FE(DDSD_MIPMAPCOUNT
, _dump_DWORD
, u
.dwMipMapCount
);
632 FE(DDSD_REFRESHRATE
, _dump_DWORD
, u
.dwRefreshRate
);
633 FE(DDSD_LINEARSIZE
, _dump_DWORD
, u1
.dwLinearSize
);
634 FE(DDSD_LPSURFACE
, _dump_PTR
, u1
.lpSurface
);
637 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
638 if (flags
[i
].mask
& lpddsd
->dwFlags
) {
639 DPRINTF(" - %s : ",flags
[i
].name
);
640 flags
[i
].func(flags
[i
].elt
);
646 /******************************************************************************
647 * IDirectDrawSurface methods
649 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
650 * DDS and DDS2 use those functions. (Function calls did not change (except
651 * using different DirectDrawSurfaceX version), just added flags and functions)
654 static HRESULT WINAPI
IDirectDrawSurface4Impl_Lock(
655 LPDIRECTDRAWSURFACE4 iface
,LPRECT lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE hnd
657 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
658 TRACE("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
659 This
,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
660 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
661 WARN("(%p)->Lock(%p,%p,%08lx,%08lx)\n",
662 This
,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
664 /* First, copy the Surface description */
665 *lpddsd
= This
->s
.surface_desc
;
666 TRACE("locked surface: height=%ld, width=%ld, pitch=%ld\n",
667 lpddsd
->dwHeight
,lpddsd
->dwWidth
,lpddsd
->lPitch
);
669 /* If asked only for a part, change the surface pointer */
671 TRACE(" lprect: %dx%d-%dx%d\n",
672 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
674 if ((lprect
->top
< 0) ||
675 (lprect
->left
< 0) ||
676 (lprect
->bottom
< 0) ||
677 (lprect
->right
< 0)) {
678 ERR(" Negative values in LPRECT !!!\n");
679 return DDERR_INVALIDPARAMS
;
682 lpddsd
->u1
.lpSurface
= (LPVOID
) ((char *) This
->s
.surface_desc
.u1
.lpSurface
+
683 (lprect
->top
*This
->s
.surface_desc
.lPitch
) +
684 lprect
->left
*GET_BPP(This
->s
.surface_desc
));
686 assert(This
->s
.surface_desc
.u1
.lpSurface
);
691 #ifdef HAVE_LIBXXF86DGA
692 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_Unlock(
693 LPDIRECTDRAWSURFACE4 iface
,LPVOID surface
695 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
696 TRACE("(%p)->Unlock(%p)\n",This
,surface
);
699 #endif /* defined(HAVE_LIBXXF86DGA) */
701 static void Xlib_copy_surface_on_screen(IDirectDrawSurface4Impl
* This
) {
702 if (This
->s
.ddraw
->d
.pixel_convert
!= NULL
)
703 This
->s
.ddraw
->d
.pixel_convert(This
->s
.surface_desc
.u1
.lpSurface
,
704 This
->t
.xlib
.image
->data
,
705 This
->s
.surface_desc
.dwWidth
,
706 This
->s
.surface_desc
.dwHeight
,
707 This
->s
.surface_desc
.lPitch
,
711 if (This
->s
.ddraw
->e
.xlib
.xshm_active
)
712 TSXShmPutImage(display
,
713 This
->s
.ddraw
->d
.drawable
,
714 DefaultGCOfScreen(X11DRV_GetXScreen()),
717 This
->t
.xlib
.image
->width
,
718 This
->t
.xlib
.image
->height
,
722 TSXPutImage( display
,
723 This
->s
.ddraw
->d
.drawable
,
724 DefaultGCOfScreen(X11DRV_GetXScreen()),
727 This
->t
.xlib
.image
->width
,
728 This
->t
.xlib
.image
->height
);
731 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Unlock(
732 LPDIRECTDRAWSURFACE4 iface
,LPVOID surface
)
734 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
735 TRACE("(%p)->Unlock(%p)\n",This
,surface
);
737 if (!This
->s
.ddraw
->d
.paintable
)
740 /* Only redraw the screen when unlocking the buffer that is on screen */
741 if (This
->t
.xlib
.image
&& (SDDSCAPS(This
) & DDSCAPS_VISIBLE
)) {
742 Xlib_copy_surface_on_screen(This
);
744 if (This
->s
.palette
&& This
->s
.palette
->cm
)
745 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
750 static IDirectDrawSurface4Impl
* _common_find_flipto(
751 IDirectDrawSurface4Impl
* This
,IDirectDrawSurface4Impl
* flipto
754 struct _surface_chain
*chain
= This
->s
.chain
;
756 /* if there was no override flipto, look for current backbuffer */
758 /* walk the flip chain looking for backbuffer */
759 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
760 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
)
762 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_BACKBUFFER
)
763 flipto
= chain
->surfaces
[i
];
765 /* sanity checks ... */
768 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
769 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FRONTBUFFER
)
771 if (i
==chain
->nrofsurfaces
) {
772 /* we do not have a frontbuffer either */
773 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
774 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
) {
775 SDDSCAPS(chain
->surfaces
[i
])|=DDSCAPS_FRONTBUFFER
;
778 for (j
=i
+1;j
<i
+chain
->nrofsurfaces
+1;j
++) {
779 int k
= j
% chain
->nrofsurfaces
;
780 if (SDDSCAPS(chain
->surfaces
[k
]) & DDSCAPS_FLIP
) {
781 SDDSCAPS(chain
->surfaces
[k
])|=DDSCAPS_BACKBUFFER
;
782 flipto
= chain
->surfaces
[k
];
791 TRACE("flipping to %p\n",flipto
);
796 #ifdef HAVE_LIBXXF86DGA
797 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_Flip(
798 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
800 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
801 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
805 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
806 iflipto
= _common_find_flipto(This
,iflipto
);
809 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,iflipto
->t
.dga
.fb_height
);
810 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
811 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),iflipto
->s
.palette
->cm
);
812 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
815 /* We need to switch the lowlevel surfaces, for DGA this is: */
817 /* The height within the framebuffer */
818 xheight
= This
->t
.dga
.fb_height
;
819 This
->t
.dga
.fb_height
= iflipto
->t
.dga
.fb_height
;
820 iflipto
->t
.dga
.fb_height
= xheight
;
822 /* And the assciated surface pointer */
823 surf
= This
->s
.surface_desc
.u1
.lpSurface
;
824 This
->s
.surface_desc
.u1
.lpSurface
= iflipto
->s
.surface_desc
.u1
.lpSurface
;
825 iflipto
->s
.surface_desc
.u1
.lpSurface
= surf
;
829 #endif /* defined(HAVE_LIBXXF86DGA) */
831 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Flip(
832 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
834 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
837 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
839 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
840 iflipto
= _common_find_flipto(This
,iflipto
);
842 #if defined(HAVE_MESAGL) && 0 /* does not work */
843 if (This
->s
.d3d_device
|| (iflipto
&& iflipto
->s
.d3d_device
)) {
844 TRACE(" - OpenGL flip\n");
846 glXSwapBuffers(display
, This
->s
.ddraw
->d
.drawable
);
851 #endif /* defined(HAVE_MESAGL) */
853 if (!This
->s
.ddraw
->d
.paintable
)
856 /* We need to switch the lowlevel surfaces, for xlib this is: */
857 /* The surface pointer */
858 surf
= This
->s
.surface_desc
.u1
.lpSurface
;
859 This
->s
.surface_desc
.u1
.lpSurface
= iflipto
->s
.surface_desc
.u1
.lpSurface
;
860 iflipto
->s
.surface_desc
.u1
.lpSurface
= surf
;
861 /* the associated ximage */
862 image
= This
->t
.xlib
.image
;
863 This
->t
.xlib
.image
= iflipto
->t
.xlib
.image
;
864 iflipto
->t
.xlib
.image
= image
;
866 Xlib_copy_surface_on_screen(This
);
868 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
869 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,iflipto
->s
.palette
->cm
);
873 /* The IDirectDrawSurface4::SetPalette method attaches the specified
874 * DirectDrawPalette object to a surface. The surface uses this palette for all
875 * subsequent operations. The palette change takes place immediately.
877 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_SetPalette(
878 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
880 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
881 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
883 TRACE("(%p)->(%p)\n",This
,ipal
);
886 if( This
->s
.palette
!= NULL
)
887 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
888 This
->s
.palette
= ipal
;
893 if( !(ipal
->cm
) && (This
->s
.ddraw
->d
.screen_pixelformat
.u
.dwRGBBitCount
<=8))
895 ipal
->cm
= TSXCreateColormap(display
,This
->s
.ddraw
->d
.drawable
,
896 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
898 if (!Options
.managed
)
899 TSXInstallColormap(display
,ipal
->cm
);
901 for (i
=0;i
<256;i
++) {
904 xc
.red
= ipal
->palents
[i
].peRed
<<8;
905 xc
.blue
= ipal
->palents
[i
].peBlue
<<8;
906 xc
.green
= ipal
->palents
[i
].peGreen
<<8;
907 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
909 TSXStoreColor(display
,ipal
->cm
,&xc
);
911 TSXInstallColormap(display
,ipal
->cm
);
914 /* According to spec, we are only supposed to
915 * AddRef if this is not the same palette.
917 if( This
->s
.palette
!= ipal
)
920 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
921 if( This
->s
.palette
!= NULL
)
922 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
923 This
->s
.palette
= ipal
;
924 /* Perform the refresh */
925 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
930 #ifdef HAVE_LIBXXF86DGA
931 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_SetPalette(
932 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
934 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
935 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
936 TRACE("(%p)->(%p)\n",This
,ipal
);
938 /* According to spec, we are only supposed to
939 * AddRef if this is not the same palette.
941 if( This
->s
.palette
!= ipal
)
944 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
945 if( This
->s
.palette
!= NULL
)
946 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
947 This
->s
.palette
= ipal
;
948 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->s
.palette
->cm
);
952 #endif /* defined(HAVE_LIBXXF86DGA) */
954 static HRESULT
_Blt_ColorFill(LPBYTE buf
, int width
, int height
, int bpp
, LONG lPitch
, DWORD color
)
961 #define COLORFILL_ROW(type) { \
962 type *d = (type *) buf; \
963 for (x = 0; x < width; x++) \
964 d[x] = (type) color; \
969 case 1: COLORFILL_ROW(BYTE
)
970 case 2: COLORFILL_ROW(WORD
)
971 case 4: COLORFILL_ROW(DWORD
)
973 FIXME("Color fill not implemented for bpp %d!\n", bpp
*8);
974 return DDERR_UNSUPPORTED
;
979 /* Now copy first row */
981 for (y
= 1; y
< height
; y
++) {
983 memcpy(buf
, first
, width
* bpp
);
989 static HRESULT WINAPI
IDirectDrawSurface4Impl_Blt(
990 LPDIRECTDRAWSURFACE4 iface
,LPRECT rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
992 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
994 DDSURFACEDESC ddesc
,sdesc
;
996 int bpp
, srcheight
, srcwidth
, dstheight
, dstwidth
, width
;
1000 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This
,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
1002 if (src
) IDirectDrawSurface4_Lock(src
, NULL
, &sdesc
, 0, 0);
1003 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,0,0);
1005 if (TRACE_ON(ddraw
)) {
1006 if (rdst
) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
1007 if (rsrc
) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1009 _dump_DDBLT(dwFlags
);
1010 if (dwFlags
& DDBLT_DDFX
) {
1011 TRACE("\tblitfx: ");
1012 _dump_DDBLTFX(lpbltfx
->dwDDFX
);
1017 memcpy(&xdst
,rdst
,sizeof(xdst
));
1020 xdst
.bottom
= ddesc
.dwHeight
;
1022 xdst
.right
= ddesc
.dwWidth
;
1026 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
1030 xsrc
.bottom
= sdesc
.dwHeight
;
1032 xsrc
.right
= sdesc
.dwWidth
;
1034 memset(&xsrc
,0,sizeof(xsrc
));
1038 bpp
= GET_BPP(ddesc
);
1039 srcheight
= xsrc
.bottom
- xsrc
.top
;
1040 srcwidth
= xsrc
.right
- xsrc
.left
;
1041 dstheight
= xdst
.bottom
- xdst
.top
;
1042 dstwidth
= xdst
.right
- xdst
.left
;
1043 width
= (xdst
.right
- xdst
.left
) * bpp
;
1044 dbuf
= (BYTE
*) ddesc
.u1
.lpSurface
+ (xdst
.top
* ddesc
.lPitch
) + (xdst
.left
* bpp
);
1046 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
1048 /* First, all the 'source-less' blits */
1049 if (dwFlags
& DDBLT_COLORFILL
) {
1050 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
,
1051 ddesc
.lPitch
, lpbltfx
->u4
.dwFillColor
);
1052 dwFlags
&= ~DDBLT_COLORFILL
;
1055 if (dwFlags
& DDBLT_DEPTHFILL
) {
1059 /* Clears the screen */
1060 TRACE(" Filling depth buffer with %ld\n", lpbltfx
->u4
.dwFillDepth
);
1061 glClearDepth(lpbltfx
->u4
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
1062 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
1063 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
1064 glClear(GL_DEPTH_BUFFER_BIT
);
1067 dwFlags
&= ~(DDBLT_DEPTHFILL
);
1068 #endif /* defined(HAVE_MESAGL) */
1071 if (dwFlags
& DDBLT_ROP
) {
1072 /* Catch some degenerate cases here */
1073 switch(lpbltfx
->dwROP
) {
1075 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, 0);
1077 case 0xAA0029: /* No-op */
1080 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, ~0);
1083 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx
->dwROP
, lpbltfx
->u4
.lpDDSPattern
);
1086 dwFlags
&= ~DDBLT_ROP
;
1089 if (dwFlags
& DDBLT_DDROPS
) {
1090 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx
->dwDDROP
, lpbltfx
->u4
.lpDDSPattern
);
1093 /* Now the 'with source' blits */
1096 int sx
, xinc
, sy
, yinc
;
1098 sbase
= (BYTE
*) sdesc
.u1
.lpSurface
+ (xsrc
.top
* sdesc
.lPitch
) + xsrc
.left
* bpp
;
1099 xinc
= (srcwidth
<< 16) / dstwidth
;
1100 yinc
= (srcheight
<< 16) / dstheight
;
1104 /* No effects, we can cheat here */
1105 if (dstwidth
== srcwidth
) {
1106 if (dstheight
== srcheight
) {
1107 /* No stretching in either direction. This needs to be as fast as possible */
1109 for (y
= 0; y
< dstheight
; y
++) {
1110 memcpy(dbuf
, sbuf
, width
);
1111 sbuf
+= sdesc
.lPitch
;
1112 dbuf
+= ddesc
.lPitch
;
1115 /* Stretching in Y direction only */
1116 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1117 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1118 memcpy(dbuf
, sbuf
, width
);
1119 dbuf
+= ddesc
.lPitch
;
1123 /* Stretching in X direction */
1125 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1126 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1128 if ((sy
>> 16) == (last_sy
>> 16)) {
1129 /* Same as last row - copy already stretched row */
1130 memcpy(dbuf
, dbuf
- ddesc
.lPitch
, width
);
1133 #define STRETCH_ROW(type) { \
1134 type *s = (type *) sbuf, *d = (type *) dbuf; \
1135 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1136 d[x] = s[sx >> 16]; \
1140 case 1: STRETCH_ROW(BYTE
)
1141 case 2: STRETCH_ROW(WORD
)
1142 case 4: STRETCH_ROW(DWORD
)
1144 FIXME("Stretched blit not implemented for bpp %d!\n", bpp
*8);
1145 ret
= DDERR_UNSUPPORTED
;
1153 dbuf
+= ddesc
.lPitch
;
1156 } else if (dwFlags
& (DDBLT_KEYSRC
| DDBLT_KEYDEST
)) {
1157 DWORD keylow
, keyhigh
;
1159 if (dwFlags
& DDBLT_KEYSRC
) {
1160 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1161 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1163 /* I'm not sure if this is correct */
1164 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1165 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1166 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1170 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1171 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1173 #define COPYROW_COLORKEY(type) { \
1174 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1175 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1176 tmp = s[sx >> 16]; \
1177 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1182 case 1: COPYROW_COLORKEY(BYTE
)
1183 case 2: COPYROW_COLORKEY(WORD
)
1184 case 4: COPYROW_COLORKEY(DWORD
)
1186 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1187 (dwFlags
& DDBLT_KEYSRC
) ? "Source" : "Destination", bpp
*8);
1188 ret
= DDERR_UNSUPPORTED
;
1191 dbuf
+= ddesc
.lPitch
;
1194 #undef COPYROW_COLORKEY
1196 dwFlags
&= ~(DDBLT_KEYSRC
| DDBLT_KEYDEST
);
1203 if (dwFlags
&& FIXME_ON(ddraw
)) {
1204 FIXME("\tUnsupported flags: ");
1205 _dump_DDBLT(dwFlags
);
1208 IDirectDrawSurface4_Unlock(iface
,ddesc
.u1
.lpSurface
);
1209 if (src
) IDirectDrawSurface4_Unlock(src
,sdesc
.u1
.lpSurface
);
1214 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltFast(
1215 LPDIRECTDRAWSURFACE4 iface
,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD trans
1217 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1218 int bpp
, w
, h
, x
, y
;
1219 DDSURFACEDESC ddesc
,sdesc
;
1220 HRESULT ret
= DD_OK
;
1224 if (TRACE_ON(ddraw
)) {
1225 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1226 This
,dstx
,dsty
,src
,rsrc
,trans
1229 if (FIXME_ON(ddraw
))
1230 _dump_DDBLTFAST(trans
);
1231 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1233 /* We need to lock the surfaces, or we won't get refreshes when done. */
1234 IDirectDrawSurface4_Lock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
1235 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
1237 bpp
= GET_BPP(This
->s
.surface_desc
);
1238 sbuf
= (BYTE
*) sdesc
.u1
.lpSurface
+ (rsrc
->top
* sdesc
.lPitch
) + rsrc
->left
* bpp
;
1239 dbuf
= (BYTE
*) ddesc
.u1
.lpSurface
+ (dsty
* ddesc
.lPitch
) + dstx
* bpp
;
1242 h
=rsrc
->bottom
-rsrc
->top
;
1243 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
1244 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
1247 w
=rsrc
->right
-rsrc
->left
;
1248 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
1249 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
1252 if (trans
& (DDBLTFAST_SRCCOLORKEY
| DDBLTFAST_DESTCOLORKEY
)) {
1253 DWORD keylow
, keyhigh
;
1254 if (trans
& DDBLTFAST_SRCCOLORKEY
) {
1255 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1256 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1258 /* I'm not sure if this is correct */
1259 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1260 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1261 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1264 #define COPYBOX_COLORKEY(type) { \
1265 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1266 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1267 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1268 for (y = 0; y < h; y++) { \
1269 for (x = 0; x < w; x++) { \
1271 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1273 (LPBYTE)s += sdesc.lPitch; \
1274 (LPBYTE)d += ddesc.lPitch; \
1280 case 1: COPYBOX_COLORKEY(BYTE
)
1281 case 2: COPYBOX_COLORKEY(WORD
)
1282 case 4: COPYBOX_COLORKEY(DWORD
)
1284 FIXME("Source color key blitting not supported for bpp %d\n", bpp
*8);
1285 ret
= DDERR_UNSUPPORTED
;
1289 #undef COPYBOX_COLORKEY
1292 int width
= w
* bpp
;
1294 for (y
= 0; y
< h
; y
++) {
1295 memcpy(dbuf
, sbuf
, width
);
1296 sbuf
+= sdesc
.lPitch
;
1297 dbuf
+= ddesc
.lPitch
;
1303 IDirectDrawSurface4_Unlock(iface
,ddesc
.u1
.lpSurface
);
1304 IDirectDrawSurface4_Unlock(src
,sdesc
.u1
.lpSurface
);
1308 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltBatch(
1309 LPDIRECTDRAWSURFACE4 iface
,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
1311 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1312 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1318 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetCaps(
1319 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS caps
1321 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1322 TRACE("(%p)->GetCaps(%p)\n",This
,caps
);
1323 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
1327 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetSurfaceDesc(
1328 LPDIRECTDRAWSURFACE4 iface
,LPDDSURFACEDESC ddsd
1330 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1331 TRACE("(%p)->GetSurfaceDesc(%p)\n", This
,ddsd
);
1333 /* Simply copy the surface description stored in the object */
1334 *ddsd
= This
->s
.surface_desc
;
1336 if (TRACE_ON(ddraw
)) { _dump_surface_desc(ddsd
); }
1341 static ULONG WINAPI
IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface
) {
1342 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1343 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
1344 return ++(This
->ref
);
1347 #ifdef HAVE_LIBXXF86DGA
1348 static ULONG WINAPI
DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1349 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1351 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1356 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1357 /* clear out of surface list */
1358 if (This
->t
.dga
.fb_height
== -1)
1359 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1361 This
->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(This
->t
.dga
.fb_height
/This
->s
.ddraw
->e
.dga
.fb_height
));
1363 /* Free the DIBSection (if any) */
1364 if (This
->s
.hdc
!= 0) {
1365 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1366 DeleteDC(This
->s
.hdc
);
1367 DeleteObject(This
->s
.DIBsection
);
1370 HeapFree(GetProcessHeap(),0,This
);
1373 #endif /* defined(HAVE_LIBXXF86DGA) */
1375 static ULONG WINAPI
Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1376 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1378 TRACE( "(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1383 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1385 if (This
->t
.xlib
.image
!= NULL
) {
1386 if (This
->s
.ddraw
->d
.pixel_convert
!= NULL
) {
1387 /* In pixel conversion mode, there are 2 buffers to release. */
1388 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1390 #ifdef HAVE_LIBXXSHM
1391 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1392 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1393 TSXDestroyImage(This
->t
.xlib
.image
);
1394 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1397 HeapFree(GetProcessHeap(),0,This
->t
.xlib
.image
->data
);
1398 This
->t
.xlib
.image
->data
= NULL
;
1399 TSXDestroyImage(This
->t
.xlib
.image
);
1400 #ifdef HAVE_LIBXXSHM
1404 This
->t
.xlib
.image
->data
= NULL
;
1406 #ifdef HAVE_LIBXXSHM
1407 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1408 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1409 TSXDestroyImage(This
->t
.xlib
.image
);
1410 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1413 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1414 TSXDestroyImage(This
->t
.xlib
.image
);
1415 #ifdef HAVE_LIBXXSHM
1419 This
->t
.xlib
.image
= 0;
1421 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1424 if (This
->s
.palette
)
1425 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
1427 /* Free the DIBSection (if any) */
1428 if (This
->s
.hdc
!= 0) {
1429 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1430 DeleteDC(This
->s
.hdc
);
1431 DeleteObject(This
->s
.DIBsection
);
1434 HeapFree(GetProcessHeap(),0,This
);
1438 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetAttachedSurface(
1439 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1441 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1442 int i
,found
= 0,xstart
;
1443 struct _surface_chain
*chain
;
1445 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This
, lpddsd
, lpdsf
);
1446 if (TRACE_ON(ddraw
)) {
1447 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd
->dwCaps
));
1449 chain
= This
->s
.chain
;
1451 return DDERR_NOTFOUND
;
1453 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1454 if (chain
->surfaces
[i
] == This
)
1458 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1459 if ((SDDSCAPS(chain
->surfaces
[(xstart
+i
)%chain
->nrofsurfaces
])&lpddsd
->dwCaps
) == lpddsd
->dwCaps
) {
1461 if (found
) /* may not find the same caps twice, (doc) */
1462 return DDERR_INVALIDPARAMS
;/*FIXME: correct? */
1464 found
= (i
+1)+xstart
;
1468 return DDERR_NOTFOUND
;
1469 *lpdsf
= (LPDIRECTDRAWSURFACE4
)chain
->surfaces
[found
-1-xstart
];
1470 /* FIXME: AddRef? */
1471 TRACE("found %p\n",*lpdsf
);
1475 static HRESULT WINAPI
IDirectDrawSurface4Impl_Initialize(
1476 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1478 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1479 TRACE("(%p)->(%p, %p)\n",This
,ddraw
,lpdsfd
);
1481 return DDERR_ALREADYINITIALIZED
;
1484 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPixelFormat(
1485 LPDIRECTDRAWSURFACE4 iface
,LPDDPIXELFORMAT pf
1487 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1488 TRACE("(%p)->(%p)\n",This
,pf
);
1490 *pf
= This
->s
.surface_desc
.ddpfPixelFormat
;
1491 if (TRACE_ON(ddraw
)) { _dump_pixelformat(pf
); DPRINTF("\n"); }
1495 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface
,DWORD dwFlags
) {
1496 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1497 FIXME("(%p)->(0x%08lx),stub!\n",This
,dwFlags
);
1501 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetOverlayPosition(
1502 LPDIRECTDRAWSURFACE4 iface
,LPLONG x1
,LPLONG x2
1504 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1505 FIXME("(%p)->(%p,%p),stub!\n",This
,x1
,x2
);
1509 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetClipper(
1510 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWCLIPPER clipper
1512 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1513 FIXME("(%p)->(%p),stub!\n",This
,clipper
);
1517 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddAttachedSurface(
1518 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 surf
1520 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1521 IDirectDrawSurface4Impl
*isurf
= (IDirectDrawSurface4Impl
*)surf
;
1523 struct _surface_chain
*chain
;
1525 IDirectDrawSurface4_AddRef(iface
);
1527 FIXME("(%p)->(%p)\n",This
,surf
);
1528 chain
= This
->s
.chain
;
1531 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1532 if (chain
->surfaces
[i
] == isurf
)
1533 FIXME("attaching already attached surface %p to %p!\n",iface
,isurf
);
1535 chain
= HeapAlloc(GetProcessHeap(),0,sizeof(*chain
));
1536 chain
->nrofsurfaces
= 1;
1537 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1538 chain
->surfaces
[0] = This
;
1539 This
->s
.chain
= chain
;
1542 if (chain
->surfaces
)
1543 chain
->surfaces
= HeapReAlloc(
1547 sizeof(chain
->surfaces
[0])*(chain
->nrofsurfaces
+1)
1550 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1551 isurf
->s
.chain
= chain
;
1552 chain
->surfaces
[chain
->nrofsurfaces
++] = isurf
;
1556 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface
,HDC
* lphdc
) {
1557 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1562 FIXME("(%p)->GetDC(%p)\n",This
,lphdc
);
1564 /* Creates a DIB Section of the same size / format as the surface */
1565 IDirectDrawSurface4_Lock(iface
,NULL
,&desc
,0,0);
1567 if (This
->s
.hdc
== 0) {
1568 switch (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
) {
1571 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1572 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 3 * sizeof(DWORD
));
1577 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
));
1581 b_info
= (BITMAPINFO
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1582 sizeof(BITMAPINFOHEADER
) + sizeof(RGBQUAD
) * (2 << desc
.ddpfPixelFormat
.u
.dwRGBBitCount
));
1586 b_info
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
1587 b_info
->bmiHeader
.biWidth
= desc
.dwWidth
;
1588 b_info
->bmiHeader
.biHeight
= desc
.dwHeight
;
1589 b_info
->bmiHeader
.biPlanes
= 1;
1590 b_info
->bmiHeader
.biBitCount
= desc
.ddpfPixelFormat
.u
.dwRGBBitCount
;
1592 if ((desc
.ddpfPixelFormat
.u
.dwRGBBitCount
!= 16) &&
1593 (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
!= 32))
1595 b_info
->bmiHeader
.biCompression
= BI_RGB
;
1598 b_info
->bmiHeader
.biCompression
= BI_BITFIELDS
;
1600 b_info
->bmiHeader
.biSizeImage
= (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
/ 8) * desc
.dwWidth
* desc
.dwHeight
;
1601 b_info
->bmiHeader
.biXPelsPerMeter
= 0;
1602 b_info
->bmiHeader
.biYPelsPerMeter
= 0;
1603 b_info
->bmiHeader
.biClrUsed
= 0;
1604 b_info
->bmiHeader
.biClrImportant
= 0;
1606 switch (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
) {
1611 DWORD
*masks
= (DWORD
*) &(b_info
->bmiColors
);
1614 masks
[0] = desc
.ddpfPixelFormat
.u1
.dwRBitMask
;
1615 masks
[1] = desc
.ddpfPixelFormat
.u2
.dwGBitMask
;
1616 masks
[2] = desc
.ddpfPixelFormat
.u3
.dwBBitMask
;
1622 usage
= DIB_RGB_COLORS
;
1628 /* Fill the palette */
1629 usage
= DIB_RGB_COLORS
;
1631 if (This
->s
.palette
== NULL
) {
1632 ERR("Bad palette !!!\n");
1634 RGBQUAD
*rgb
= (RGBQUAD
*) &(b_info
->bmiColors
);
1635 PALETTEENTRY
*pent
= (PALETTEENTRY
*)&(This
->s
.palette
->palents
);
1637 for (i
=0;i
<(1<<desc
.ddpfPixelFormat
.u
.dwRGBBitCount
);i
++) {
1638 rgb
[i
].rgbBlue
= pent
[i
].peBlue
;
1639 rgb
[i
].rgbRed
= pent
[i
].peRed
;
1640 rgb
[i
].rgbGreen
= pent
[i
].peGreen
;
1646 This
->s
.DIBsection
= CreateDIBSection(BeginPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
),
1649 &(This
->s
.bitmap_data
),
1653 EndPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
);
1654 TRACE("DIBSection at : %p\n", This
->s
.bitmap_data
);
1656 /* b_info is not useful anymore */
1657 HeapFree(GetProcessHeap(), 0, b_info
);
1660 This
->s
.hdc
= CreateCompatibleDC(0);
1661 This
->s
.holdbitmap
= SelectObject(This
->s
.hdc
, This
->s
.DIBsection
);
1664 /* Copy our surface in the DIB section */
1665 if ((GET_BPP(desc
) * desc
.dwWidth
) == desc
.lPitch
)
1666 memcpy(This
->s
.bitmap_data
,desc
.u1
.lpSurface
,desc
.lPitch
*desc
.dwHeight
);
1669 FIXME("This case has to be done :/\n");
1671 TRACE("HDC : %08lx\n", (DWORD
) This
->s
.hdc
);
1672 *lphdc
= This
->s
.hdc
;
1677 static HRESULT WINAPI
IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface
,HDC hdc
) {
1678 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1680 FIXME("(%p)->(0x%08lx),stub!\n",This
,(long)hdc
);
1681 TRACE( "Copying DIBSection at : %p\n", This
->s
.bitmap_data
);
1682 /* Copy the DIB section to our surface */
1683 if ((GET_BPP(This
->s
.surface_desc
) * This
->s
.surface_desc
.dwWidth
) == This
->s
.surface_desc
.lPitch
) {
1684 memcpy(This
->s
.surface_desc
.u1
.lpSurface
, This
->s
.bitmap_data
, This
->s
.surface_desc
.lPitch
* This
->s
.surface_desc
.dwHeight
);
1687 FIXME("This case has to be done :/\n");
1689 /* Unlock the surface */
1690 IDirectDrawSurface4_Unlock(iface
,This
->s
.surface_desc
.u1
.lpSurface
);
1694 static HRESULT WINAPI
IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface
,REFIID refiid
,LPVOID
*obj
) {
1695 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1698 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1699 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
1701 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1702 * the same interface. And IUnknown does that too of course.
1704 if ( IsEqualGUID( &IID_IDirectDrawSurface4
, refiid
) ||
1705 IsEqualGUID( &IID_IDirectDrawSurface3
, refiid
) ||
1706 IsEqualGUID( &IID_IDirectDrawSurface2
, refiid
) ||
1707 IsEqualGUID( &IID_IDirectDrawSurface
, refiid
) ||
1708 IsEqualGUID( &IID_IUnknown
, refiid
)
1711 IDirectDrawSurface4_AddRef(iface
);
1713 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj
);
1716 else if ( IsEqualGUID( &IID_IDirect3DTexture2
, refiid
) )
1718 /* Texture interface */
1719 *obj
= d3dtexture2_create(This
);
1720 IDirectDrawSurface4_AddRef(iface
);
1721 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1724 else if ( IsEqualGUID( &IID_IDirect3DTexture
, refiid
) )
1726 /* Texture interface */
1727 *obj
= d3dtexture_create(This
);
1728 IDirectDrawSurface4_AddRef(iface
);
1730 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj
);
1734 else if (is_OpenGL_dx3(refiid
, (IDirectDrawSurfaceImpl
*)This
, (IDirect3DDeviceImpl
**) obj
)) {
1735 /* It is the OpenGL Direct3D Device */
1736 IDirectDrawSurface4_AddRef(iface
);
1737 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj
);
1741 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
1742 return OLE_E_ENUM_NOMORE
;
1745 static HRESULT WINAPI
IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface
) {
1746 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1747 TRACE("(%p)->(), stub!\n",This
);
1748 return DD_OK
; /* hmm */
1751 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface
,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1752 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1754 struct _surface_chain
*chain
= This
->s
.chain
;
1756 TRACE("(%p)->(%p,%p)\n",This
,context
,esfcb
);
1757 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1758 TRACE( "Enumerating attached surface (%p)\n", chain
->surfaces
[i
]);
1759 if (esfcb((LPDIRECTDRAWSURFACE
) chain
->surfaces
[i
], &(chain
->surfaces
[i
]->s
.surface_desc
), context
) == DDENUMRET_CANCEL
)
1760 return DD_OK
; /* FIXME: return value correct? */
1765 static HRESULT WINAPI
IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface
) {
1766 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1767 FIXME("(%p)->(),stub!\n",This
);
1771 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetColorKey(
1772 LPDIRECTDRAWSURFACE4 iface
, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1774 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1775 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,ckey
);
1776 if (TRACE_ON(ddraw
)) {
1777 _dump_colorkeyflag(dwFlags
);
1779 _dump_DDCOLORKEY((void *) ckey
);
1783 /* If this surface was loaded as a texture, call also the texture
1784 SetColorKey callback */
1785 if (This
->s
.texture
) {
1786 This
->s
.SetColorKey_cb(This
->s
.texture
, dwFlags
, ckey
);
1789 if( dwFlags
& DDCKEY_SRCBLT
)
1791 dwFlags
&= ~DDCKEY_SRCBLT
;
1792 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1793 memcpy( &(This
->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1796 if( dwFlags
& DDCKEY_DESTBLT
)
1798 dwFlags
&= ~DDCKEY_DESTBLT
;
1799 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1800 memcpy( &(This
->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1803 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1805 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1806 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1807 memcpy( &(This
->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1810 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1812 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1813 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1814 memcpy( &(This
->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1819 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
1826 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1827 LPDIRECTDRAWSURFACE4 iface
,
1830 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1831 FIXME("(%p)->(%p),stub!\n",This
,lpRect
);
1836 static HRESULT WINAPI
IDirectDrawSurface4Impl_DeleteAttachedSurface(
1837 LPDIRECTDRAWSURFACE4 iface
,
1839 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
1841 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1843 struct _surface_chain
*chain
;
1845 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,lpDDSAttachedSurface
);
1846 chain
= This
->s
.chain
;
1847 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1848 if ((IDirectDrawSurface4Impl
*)lpDDSAttachedSurface
==chain
->surfaces
[i
]){
1849 IDirectDrawSurface4_Release(lpDDSAttachedSurface
);
1851 chain
->surfaces
[i
]->s
.chain
= NULL
;
1852 memcpy( chain
->surfaces
+i
,
1853 chain
->surfaces
+(i
+1),
1854 (chain
->nrofsurfaces
-i
-1)*sizeof(chain
->surfaces
[i
])
1856 chain
->surfaces
= HeapReAlloc(
1860 sizeof(chain
->surfaces
[i
])*(chain
->nrofsurfaces
-1)
1862 chain
->nrofsurfaces
--;
1869 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumOverlayZOrders(
1870 LPDIRECTDRAWSURFACE4 iface
,
1873 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1875 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1876 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This
,dwFlags
,
1877 lpContext
, lpfnCallback
);
1882 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetClipper(
1883 LPDIRECTDRAWSURFACE4 iface
,
1884 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1886 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1887 FIXME("(%p)->(%p),stub!\n", This
, lplpDDClipper
);
1892 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetColorKey(
1893 LPDIRECTDRAWSURFACE4 iface
,
1895 LPDDCOLORKEY lpDDColorKey
)
1897 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1898 TRACE("(%p)->(0x%08lx,%p)\n", This
, dwFlags
, lpDDColorKey
);
1900 if( dwFlags
& DDCKEY_SRCBLT
) {
1901 dwFlags
&= ~DDCKEY_SRCBLT
;
1902 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
1905 if( dwFlags
& DDCKEY_DESTBLT
)
1907 dwFlags
&= ~DDCKEY_DESTBLT
;
1908 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
1911 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1913 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1914 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
1917 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1919 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1920 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
1925 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
1931 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetFlipStatus(
1932 LPDIRECTDRAWSURFACE4 iface
,
1935 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1936 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
1941 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPalette(
1942 LPDIRECTDRAWSURFACE4 iface
,
1943 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1945 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1946 FIXME("(%p)->(%p),stub!\n", This
, lplpDDPalette
);
1951 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetOverlayPosition(
1952 LPDIRECTDRAWSURFACE4 iface
,
1956 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1957 FIXME("(%p)->(%ld,%ld),stub!\n", This
, lX
, lY
);
1962 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlay(
1963 LPDIRECTDRAWSURFACE4 iface
,
1965 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
1968 LPDDOVERLAYFX lpDDOverlayFx
)
1970 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1971 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This
,
1972 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1977 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1978 LPDIRECTDRAWSURFACE4 iface
,
1981 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1982 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
1987 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayZOrder(
1988 LPDIRECTDRAWSURFACE4 iface
,
1990 LPDIRECTDRAWSURFACE4 lpDDSReference
)
1992 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1993 FIXME("(%p)->(0x%08lx,%p),stub!\n", This
, dwFlags
, lpDDSReference
);
1998 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDDInterface(
1999 LPDIRECTDRAWSURFACE4 iface
,
2002 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2003 FIXME("(%p)->(%p),stub!\n", This
, lplpDD
);
2005 /* Not sure about that... */
2006 *lplpDD
= (void *) This
->s
.ddraw
;
2011 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageLock(
2012 LPDIRECTDRAWSURFACE4 iface
,
2015 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2016 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2021 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageUnlock(
2022 LPDIRECTDRAWSURFACE4 iface
,
2025 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2026 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2031 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetSurfaceDesc(
2032 LPDIRECTDRAWSURFACE4 iface
,
2033 LPDDSURFACEDESC lpDDSD
,
2036 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2037 FIXME("(%p)->(%p,0x%08lx),stub!\n", This
, lpDDSD
, dwFlags
);
2042 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2047 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2048 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This
, guidTag
, lpData
, cbSize
, dwFlags
);
2053 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2056 LPDWORD lpcbBufferSize
) {
2057 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2058 FIXME("(%p)->(%p,%p,%p)\n", This
, guidTag
, lpBuffer
, lpcbBufferSize
);
2063 static HRESULT WINAPI
IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface
,
2065 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2066 FIXME("(%p)->(%p)\n", This
, guidTag
);
2071 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface
,
2073 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2074 FIXME("(%p)->(%p)\n", This
, lpValue
);
2079 static HRESULT WINAPI
IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface
) {
2080 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2081 FIXME("(%p)\n", This
);
2086 #ifdef HAVE_LIBXXF86DGA
2087 static ICOM_VTABLE(IDirectDrawSurface4
) dga_dds4vt
=
2089 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2090 IDirectDrawSurface4Impl_QueryInterface
,
2091 IDirectDrawSurface4Impl_AddRef
,
2092 DGA_IDirectDrawSurface4Impl_Release
,
2093 IDirectDrawSurface4Impl_AddAttachedSurface
,
2094 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2095 IDirectDrawSurface4Impl_Blt
,
2096 IDirectDrawSurface4Impl_BltBatch
,
2097 IDirectDrawSurface4Impl_BltFast
,
2098 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2099 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2100 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2101 DGA_IDirectDrawSurface4Impl_Flip
,
2102 IDirectDrawSurface4Impl_GetAttachedSurface
,
2103 IDirectDrawSurface4Impl_GetBltStatus
,
2104 IDirectDrawSurface4Impl_GetCaps
,
2105 IDirectDrawSurface4Impl_GetClipper
,
2106 IDirectDrawSurface4Impl_GetColorKey
,
2107 IDirectDrawSurface4Impl_GetDC
,
2108 IDirectDrawSurface4Impl_GetFlipStatus
,
2109 IDirectDrawSurface4Impl_GetOverlayPosition
,
2110 IDirectDrawSurface4Impl_GetPalette
,
2111 IDirectDrawSurface4Impl_GetPixelFormat
,
2112 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2113 IDirectDrawSurface4Impl_Initialize
,
2114 IDirectDrawSurface4Impl_IsLost
,
2115 IDirectDrawSurface4Impl_Lock
,
2116 IDirectDrawSurface4Impl_ReleaseDC
,
2117 IDirectDrawSurface4Impl_Restore
,
2118 IDirectDrawSurface4Impl_SetClipper
,
2119 IDirectDrawSurface4Impl_SetColorKey
,
2120 IDirectDrawSurface4Impl_SetOverlayPosition
,
2121 DGA_IDirectDrawSurface4Impl_SetPalette
,
2122 DGA_IDirectDrawSurface4Impl_Unlock
,
2123 IDirectDrawSurface4Impl_UpdateOverlay
,
2124 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2125 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2126 IDirectDrawSurface4Impl_GetDDInterface
,
2127 IDirectDrawSurface4Impl_PageLock
,
2128 IDirectDrawSurface4Impl_PageUnlock
,
2129 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2130 IDirectDrawSurface4Impl_SetPrivateData
,
2131 IDirectDrawSurface4Impl_GetPrivateData
,
2132 IDirectDrawSurface4Impl_FreePrivateData
,
2133 IDirectDrawSurface4Impl_GetUniquenessValue
,
2134 IDirectDrawSurface4Impl_ChangeUniquenessValue
2136 #endif /* defined(HAVE_LIBXXF86DGA) */
2138 static ICOM_VTABLE(IDirectDrawSurface4
) xlib_dds4vt
=
2140 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2141 IDirectDrawSurface4Impl_QueryInterface
,
2142 IDirectDrawSurface4Impl_AddRef
,
2143 Xlib_IDirectDrawSurface4Impl_Release
,
2144 IDirectDrawSurface4Impl_AddAttachedSurface
,
2145 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2146 IDirectDrawSurface4Impl_Blt
,
2147 IDirectDrawSurface4Impl_BltBatch
,
2148 IDirectDrawSurface4Impl_BltFast
,
2149 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2150 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2151 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2152 Xlib_IDirectDrawSurface4Impl_Flip
,
2153 IDirectDrawSurface4Impl_GetAttachedSurface
,
2154 IDirectDrawSurface4Impl_GetBltStatus
,
2155 IDirectDrawSurface4Impl_GetCaps
,
2156 IDirectDrawSurface4Impl_GetClipper
,
2157 IDirectDrawSurface4Impl_GetColorKey
,
2158 IDirectDrawSurface4Impl_GetDC
,
2159 IDirectDrawSurface4Impl_GetFlipStatus
,
2160 IDirectDrawSurface4Impl_GetOverlayPosition
,
2161 IDirectDrawSurface4Impl_GetPalette
,
2162 IDirectDrawSurface4Impl_GetPixelFormat
,
2163 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2164 IDirectDrawSurface4Impl_Initialize
,
2165 IDirectDrawSurface4Impl_IsLost
,
2166 IDirectDrawSurface4Impl_Lock
,
2167 IDirectDrawSurface4Impl_ReleaseDC
,
2168 IDirectDrawSurface4Impl_Restore
,
2169 IDirectDrawSurface4Impl_SetClipper
,
2170 IDirectDrawSurface4Impl_SetColorKey
,
2171 IDirectDrawSurface4Impl_SetOverlayPosition
,
2172 Xlib_IDirectDrawSurface4Impl_SetPalette
,
2173 Xlib_IDirectDrawSurface4Impl_Unlock
,
2174 IDirectDrawSurface4Impl_UpdateOverlay
,
2175 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2176 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2177 IDirectDrawSurface4Impl_GetDDInterface
,
2178 IDirectDrawSurface4Impl_PageLock
,
2179 IDirectDrawSurface4Impl_PageUnlock
,
2180 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2181 IDirectDrawSurface4Impl_SetPrivateData
,
2182 IDirectDrawSurface4Impl_GetPrivateData
,
2183 IDirectDrawSurface4Impl_FreePrivateData
,
2184 IDirectDrawSurface4Impl_GetUniquenessValue
,
2185 IDirectDrawSurface4Impl_ChangeUniquenessValue
2188 /******************************************************************************
2189 * DirectDrawCreateClipper (DDRAW.7)
2191 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
2192 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
2193 LPUNKNOWN pUnkOuter
)
2195 IDirectDrawClipperImpl
** ilplpDDClipper
=(IDirectDrawClipperImpl
**)lplpDDClipper
;
2196 TRACE("(%08lx,%p,%p)\n", dwFlags
, ilplpDDClipper
, pUnkOuter
);
2198 *ilplpDDClipper
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
2199 ICOM_VTBL(*ilplpDDClipper
) = &ddclipvt
;
2200 (*ilplpDDClipper
)->ref
= 1;
2205 /******************************************************************************
2206 * IDirectDrawClipper
2208 static HRESULT WINAPI
IDirectDrawClipperImpl_SetHwnd(
2209 LPDIRECTDRAWCLIPPER iface
,DWORD x
,HWND hwnd
2211 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2212 FIXME("(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This
,x
,(DWORD
)hwnd
);
2216 static ULONG WINAPI
IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface
) {
2217 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2218 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2223 HeapFree(GetProcessHeap(),0,This
);
2227 static HRESULT WINAPI
IDirectDrawClipperImpl_GetClipList(
2228 LPDIRECTDRAWCLIPPER iface
,LPRECT rects
,LPRGNDATA lprgn
,LPDWORD hmm
2230 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2231 FIXME("(%p,%p,%p,%p),stub!\n",This
,rects
,lprgn
,hmm
);
2236 static HRESULT WINAPI
IDirectDrawClipperImpl_SetClipList(
2237 LPDIRECTDRAWCLIPPER iface
,LPRGNDATA lprgn
,DWORD hmm
2239 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2240 FIXME("(%p,%p,%ld),stub!\n",This
,lprgn
,hmm
);
2244 static HRESULT WINAPI
IDirectDrawClipperImpl_QueryInterface(
2245 LPDIRECTDRAWCLIPPER iface
,
2249 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2250 FIXME("(%p)->(%p,%p),stub!\n",This
,riid
,ppvObj
);
2251 return OLE_E_ENUM_NOMORE
;
2254 static ULONG WINAPI
IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface
)
2256 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2257 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2258 return ++(This
->ref
);
2261 static HRESULT WINAPI
IDirectDrawClipperImpl_GetHWnd(
2262 LPDIRECTDRAWCLIPPER iface
,
2265 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2266 FIXME("(%p)->(%p),stub!\n",This
,HWndPtr
);
2270 static HRESULT WINAPI
IDirectDrawClipperImpl_Initialize(
2271 LPDIRECTDRAWCLIPPER iface
,
2275 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2276 FIXME("(%p)->(%p,0x%08lx),stub!\n",This
,lpDD
,dwFlags
);
2280 static HRESULT WINAPI
IDirectDrawClipperImpl_IsClipListChanged(
2281 LPDIRECTDRAWCLIPPER iface
,
2284 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2285 FIXME("(%p)->(%p),stub!\n",This
,lpbChanged
);
2289 static ICOM_VTABLE(IDirectDrawClipper
) ddclipvt
=
2291 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2292 IDirectDrawClipperImpl_QueryInterface
,
2293 IDirectDrawClipperImpl_AddRef
,
2294 IDirectDrawClipperImpl_Release
,
2295 IDirectDrawClipperImpl_GetClipList
,
2296 IDirectDrawClipperImpl_GetHWnd
,
2297 IDirectDrawClipperImpl_Initialize
,
2298 IDirectDrawClipperImpl_IsClipListChanged
,
2299 IDirectDrawClipperImpl_SetClipList
,
2300 IDirectDrawClipperImpl_SetHwnd
2304 /******************************************************************************
2305 * IDirectDrawPalette
2307 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetEntries(
2308 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2310 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2313 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2314 This
,x
,start
,count
,palent
);
2316 /* No palette created and not in depth-convertion mode -> BUG ! */
2317 if ((This
->cm
== None
) &&
2318 (This
->ddraw
->d
.palette_convert
== NULL
))
2320 FIXME("app tried to read colormap for non-palettized mode\n");
2321 return DDERR_GENERIC
;
2323 for (i
=0;i
<count
;i
++) {
2324 palent
[i
].peRed
= This
->palents
[start
+i
].peRed
;
2325 palent
[i
].peBlue
= This
->palents
[start
+i
].peBlue
;
2326 palent
[i
].peGreen
= This
->palents
[start
+i
].peGreen
;
2327 palent
[i
].peFlags
= This
->palents
[start
+i
].peFlags
;
2333 static HRESULT WINAPI
Xlib_IDirectDrawPaletteImpl_SetEntries(
2334 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2336 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2340 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2341 This
,x
,start
,count
,palent
2343 for (i
=0;i
<count
;i
++) {
2344 xc
.red
= palent
[i
].peRed
<<8;
2345 xc
.blue
= palent
[i
].peBlue
<<8;
2346 xc
.green
= palent
[i
].peGreen
<<8;
2347 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2351 TSXStoreColor(display
,This
->cm
,&xc
);
2353 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2354 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2355 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2356 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2359 /* Now, if we are in 'depth conversion mode', update the screen palette */
2360 /* FIXME: we need to update the image or we won't get palette fading. */
2361 if (This
->ddraw
->d
.palette_convert
!= NULL
)
2362 This
->ddraw
->d
.palette_convert(palent
, This
->screen_palents
, start
, count
);
2367 #ifdef HAVE_LIBXXF86DGA
2368 static HRESULT WINAPI
DGA_IDirectDrawPaletteImpl_SetEntries(
2369 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2371 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2376 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2377 This
,x
,start
,count
,palent
2379 if (!This
->cm
) /* should not happen */ {
2380 FIXME("app tried to set colormap in non-palettized mode\n");
2381 return DDERR_GENERIC
;
2383 /* FIXME: free colorcells instead of freeing whole map */
2385 This
->cm
= TSXCopyColormapAndFree(display
,This
->cm
);
2386 TSXFreeColormap(display
,cm
);
2388 for (i
=0;i
<count
;i
++) {
2389 xc
.red
= palent
[i
].peRed
<<8;
2390 xc
.blue
= palent
[i
].peBlue
<<8;
2391 xc
.green
= palent
[i
].peGreen
<<8;
2392 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2395 TSXStoreColor(display
,This
->cm
,&xc
);
2397 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2398 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2399 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2400 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2402 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->cm
);
2405 #endif /* defined(HAVE_LIBXXF86DGA) */
2407 static ULONG WINAPI
IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface
) {
2408 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2409 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2410 if (!--(This
->ref
)) {
2412 TSXFreeColormap(display
,This
->cm
);
2415 HeapFree(GetProcessHeap(),0,This
);
2421 static ULONG WINAPI
IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface
) {
2422 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2424 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2425 return ++(This
->ref
);
2428 static HRESULT WINAPI
IDirectDrawPaletteImpl_Initialize(
2429 LPDIRECTDRAWPALETTE iface
,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
2431 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2432 TRACE("(%p)->(%p,%ld,%p)\n", This
, ddraw
, x
, palent
);
2434 return DDERR_ALREADYINITIALIZED
;
2437 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetCaps(
2438 LPDIRECTDRAWPALETTE iface
, LPDWORD lpdwCaps
)
2440 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2441 FIXME("(%p)->(%p) stub.\n", This
, lpdwCaps
);
2445 static HRESULT WINAPI
IDirectDrawPaletteImpl_QueryInterface(
2446 LPDIRECTDRAWPALETTE iface
,REFIID refiid
,LPVOID
*obj
)
2448 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2451 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2452 FIXME("(%p)->(%s,%p) stub.\n",This
,xrefiid
,obj
);
2457 #ifdef HAVE_LIBXXF86DGA
2458 static ICOM_VTABLE(IDirectDrawPalette
) dga_ddpalvt
=
2460 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2461 IDirectDrawPaletteImpl_QueryInterface
,
2462 IDirectDrawPaletteImpl_AddRef
,
2463 IDirectDrawPaletteImpl_Release
,
2464 IDirectDrawPaletteImpl_GetCaps
,
2465 IDirectDrawPaletteImpl_GetEntries
,
2466 IDirectDrawPaletteImpl_Initialize
,
2467 DGA_IDirectDrawPaletteImpl_SetEntries
2469 #endif /* defined(HAVE_LIBXXF86DGA) */
2471 static ICOM_VTABLE(IDirectDrawPalette
) xlib_ddpalvt
=
2473 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2474 IDirectDrawPaletteImpl_QueryInterface
,
2475 IDirectDrawPaletteImpl_AddRef
,
2476 IDirectDrawPaletteImpl_Release
,
2477 IDirectDrawPaletteImpl_GetCaps
,
2478 IDirectDrawPaletteImpl_GetEntries
,
2479 IDirectDrawPaletteImpl_Initialize
,
2480 Xlib_IDirectDrawPaletteImpl_SetEntries
2483 /*******************************************************************************
2486 static HRESULT WINAPI
IDirect3DImpl_QueryInterface(
2487 LPDIRECT3D iface
,REFIID refiid
,LPVOID
*obj
2489 ICOM_THIS(IDirect3DImpl
,iface
);
2490 /* FIXME: Not sure if this is correct */
2493 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2494 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
2495 if ( ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) ||
2496 ( IsEqualGUID (&IID_IDirectDraw2
, refiid
) ) ||
2497 ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) ) {
2499 IDirect3D_AddRef(iface
);
2501 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2505 if ( ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) ||
2506 ( IsEqualGUID( &IID_IUnknown
, refiid
) ) ) {
2508 IDirect3D_AddRef(iface
);
2510 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2514 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
2515 IDirect3D2Impl
* d3d
;
2517 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2519 d3d
->ddraw
= This
->ddraw
;
2520 IDirect3D_AddRef(iface
);
2521 ICOM_VTBL(d3d
) = &d3d2vt
;
2524 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2528 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
2529 return OLE_E_ENUM_NOMORE
;
2532 static ULONG WINAPI
IDirect3DImpl_AddRef(LPDIRECT3D iface
) {
2533 ICOM_THIS(IDirect3DImpl
,iface
);
2534 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2536 return ++(This
->ref
);
2539 static ULONG WINAPI
IDirect3DImpl_Release(LPDIRECT3D iface
)
2541 ICOM_THIS(IDirect3DImpl
,iface
);
2542 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2544 if (!--(This
->ref
)) {
2545 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2546 HeapFree(GetProcessHeap(),0,This
);
2552 static HRESULT WINAPI
IDirect3DImpl_Initialize(
2553 LPDIRECT3D iface
, REFIID refiid
)
2555 ICOM_THIS(IDirect3DImpl
,iface
);
2556 /* FIXME: Not sure if this is correct */
2559 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2560 FIXME("(%p)->(%s):stub.\n",This
,xrefiid
);
2562 return DDERR_ALREADYINITIALIZED
;
2565 static HRESULT WINAPI
IDirect3DImpl_EnumDevices(LPDIRECT3D iface
,
2566 LPD3DENUMDEVICESCALLBACK cb
,
2568 ICOM_THIS(IDirect3DImpl
,iface
);
2569 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2571 /* Call functions defined in d3ddevices.c */
2572 if (!d3d_OpenGL_dx3(cb
, context
))
2578 static HRESULT WINAPI
IDirect3DImpl_CreateLight(LPDIRECT3D iface
,
2579 LPDIRECT3DLIGHT
*lplight
,
2582 ICOM_THIS(IDirect3DImpl
,iface
);
2583 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2585 /* Call the creation function that is located in d3dlight.c */
2586 *lplight
= d3dlight_create_dx3(This
);
2591 static HRESULT WINAPI
IDirect3DImpl_CreateMaterial(LPDIRECT3D iface
,
2592 LPDIRECT3DMATERIAL
*lpmaterial
,
2595 ICOM_THIS(IDirect3DImpl
,iface
);
2596 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2598 /* Call the creation function that is located in d3dviewport.c */
2599 *lpmaterial
= d3dmaterial_create(This
);
2604 static HRESULT WINAPI
IDirect3DImpl_CreateViewport(LPDIRECT3D iface
,
2605 LPDIRECT3DVIEWPORT
*lpviewport
,
2608 ICOM_THIS(IDirect3DImpl
,iface
);
2609 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
2611 /* Call the creation function that is located in d3dviewport.c */
2612 *lpviewport
= d3dviewport_create(This
);
2617 static HRESULT WINAPI
IDirect3DImpl_FindDevice(LPDIRECT3D iface
,
2618 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2619 LPD3DFINDDEVICERESULT lpfinddevrst
)
2621 ICOM_THIS(IDirect3DImpl
,iface
);
2622 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
2627 static ICOM_VTABLE(IDirect3D
) d3dvt
=
2629 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2630 IDirect3DImpl_QueryInterface
,
2631 IDirect3DImpl_AddRef
,
2632 IDirect3DImpl_Release
,
2633 IDirect3DImpl_Initialize
,
2634 IDirect3DImpl_EnumDevices
,
2635 IDirect3DImpl_CreateLight
,
2636 IDirect3DImpl_CreateMaterial
,
2637 IDirect3DImpl_CreateViewport
,
2638 IDirect3DImpl_FindDevice
2641 /*******************************************************************************
2644 static HRESULT WINAPI
IDirect3D2Impl_QueryInterface(
2645 LPDIRECT3D2 iface
,REFIID refiid
,LPVOID
*obj
) {
2646 ICOM_THIS(IDirect3D2Impl
,iface
);
2648 /* FIXME: Not sure if this is correct */
2651 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2652 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
2653 if ( ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) ||
2654 ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) ||
2655 ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) ) {
2657 IDirect3D2_AddRef(iface
);
2659 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2663 if ( ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) ||
2664 ( IsEqualGUID( &IID_IUnknown
, refiid
) ) ) {
2666 IDirect3D2_AddRef(iface
);
2668 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2672 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
2675 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2677 d3d
->ddraw
= This
->ddraw
;
2678 IDirect3D2_AddRef(iface
);
2679 ICOM_VTBL(d3d
) = &d3dvt
;
2682 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2686 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
2687 return OLE_E_ENUM_NOMORE
;
2690 static ULONG WINAPI
IDirect3D2Impl_AddRef(LPDIRECT3D2 iface
) {
2691 ICOM_THIS(IDirect3D2Impl
,iface
);
2692 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2694 return ++(This
->ref
);
2697 static ULONG WINAPI
IDirect3D2Impl_Release(LPDIRECT3D2 iface
) {
2698 ICOM_THIS(IDirect3D2Impl
,iface
);
2699 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2701 if (!--(This
->ref
)) {
2702 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2703 HeapFree(GetProcessHeap(),0,This
);
2709 static HRESULT WINAPI
IDirect3D2Impl_EnumDevices(
2710 LPDIRECT3D2 iface
,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2712 ICOM_THIS(IDirect3D2Impl
,iface
);
2713 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2715 /* Call functions defined in d3ddevices.c */
2716 if (!d3d_OpenGL(cb
, context
))
2722 static HRESULT WINAPI
IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface
,
2723 LPDIRECT3DLIGHT
*lplight
,
2726 ICOM_THIS(IDirect3D2Impl
,iface
);
2727 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2729 /* Call the creation function that is located in d3dlight.c */
2730 *lplight
= d3dlight_create(This
);
2735 static HRESULT WINAPI
IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface
,
2736 LPDIRECT3DMATERIAL2
*lpmaterial
,
2739 ICOM_THIS(IDirect3D2Impl
,iface
);
2740 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2742 /* Call the creation function that is located in d3dviewport.c */
2743 *lpmaterial
= d3dmaterial2_create(This
);
2748 static HRESULT WINAPI
IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface
,
2749 LPDIRECT3DVIEWPORT2
*lpviewport
,
2752 ICOM_THIS(IDirect3D2Impl
,iface
);
2753 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
2755 /* Call the creation function that is located in d3dviewport.c */
2756 *lpviewport
= d3dviewport2_create(This
);
2761 static HRESULT WINAPI
IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface
,
2762 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2763 LPD3DFINDDEVICERESULT lpfinddevrst
)
2765 ICOM_THIS(IDirect3D2Impl
,iface
);
2766 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
2771 static HRESULT WINAPI
IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface
,
2773 LPDIRECTDRAWSURFACE surface
,
2774 LPDIRECT3DDEVICE2
*device
)
2776 ICOM_THIS(IDirect3D2Impl
,iface
);
2779 WINE_StringFromCLSID(rguid
,xbuf
);
2780 FIXME("(%p)->(%s,%p,%p): stub\n",This
,xbuf
,surface
,device
);
2782 if (is_OpenGL(rguid
, (IDirectDrawSurfaceImpl
*)surface
, (IDirect3DDevice2Impl
**)device
, This
)) {
2783 IDirect3D2_AddRef(iface
);
2787 return DDERR_INVALIDPARAMS
;
2790 static ICOM_VTABLE(IDirect3D2
) d3d2vt
=
2792 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2793 IDirect3D2Impl_QueryInterface
,
2794 IDirect3D2Impl_AddRef
,
2795 IDirect3D2Impl_Release
,
2796 IDirect3D2Impl_EnumDevices
,
2797 IDirect3D2Impl_CreateLight
,
2798 IDirect3D2Impl_CreateMaterial
,
2799 IDirect3D2Impl_CreateViewport
,
2800 IDirect3D2Impl_FindDevice
,
2801 IDirect3D2Impl_CreateDevice
2804 /*******************************************************************************
2808 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2809 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2811 static INT ddrawXlibThisOffset
= 0;
2813 static HRESULT
common_off_screen_CreateSurface(IDirectDraw2Impl
* This
,
2814 IDirectDrawSurfaceImpl
* lpdsf
)
2818 /* The surface was already allocated when entering in this function */
2819 TRACE("using system memory for a surface (%p) \n", lpdsf
);
2821 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
2822 /* This is a Z Buffer */
2823 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf
->s
.surface_desc
.u
.dwZBufferBitDepth
);
2824 bpp
= lpdsf
->s
.surface_desc
.u
.dwZBufferBitDepth
/ 8;
2826 /* This is a standard image */
2827 if (!(lpdsf
->s
.surface_desc
.dwFlags
& DDSD_PIXELFORMAT
)) {
2828 /* No pixel format => use DirectDraw's format */
2829 lpdsf
->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
2830 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
2833 bpp
= GET_BPP(lpdsf
->s
.surface_desc
);
2836 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_LPSURFACE
) {
2837 /* The surface was preallocated : seems that we have nothing to do :-) */
2838 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
2841 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PITCH
|DDSD_LPSURFACE
;
2842 lpdsf
->s
.surface_desc
.u1
.lpSurface
=
2843 (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpdsf
->s
.surface_desc
.dwWidth
* lpdsf
->s
.surface_desc
.dwHeight
* bpp
);
2844 lpdsf
->s
.surface_desc
.lPitch
= lpdsf
->s
.surface_desc
.dwWidth
* bpp
;
2849 #ifdef HAVE_LIBXXF86DGA
2850 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreateSurface(
2851 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2853 ICOM_THIS(IDirectDraw2Impl
,iface
);
2854 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
2855 int i
, fbheight
= This
->e
.dga
.fb_height
;
2857 TRACE("(%p)->(%p,%p,%p)\n",This
,lpddsd
,ilpdsf
,lpunk
);
2858 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
2860 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
2863 sizeof(IDirectDrawSurfaceImpl
)
2865 IDirectDraw2_AddRef(iface
);
2868 ICOM_VTBL(*ilpdsf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&dga_dds4vt
;
2869 (*ilpdsf
)->s
.ddraw
= This
;
2870 (*ilpdsf
)->s
.palette
= NULL
;
2871 (*ilpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
2873 /* Copy the surface description */
2874 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
2876 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2877 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
2878 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2879 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
2881 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
2883 /* Check if this a 'primary surface' or not */
2884 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2885 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2886 /* This is THE primary surface => there is DGA-specific code */
2888 /* First, store the surface description */
2889 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
2891 /* Find a viewport */
2893 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
2895 TRACE("using viewport %d for a primary surface\n",i
);
2896 /* if i == 32 or maximum ... return error */
2897 This
->e
.dga
.vpmask
|=(1<<i
);
2898 lpddsd
->lPitch
= (*ilpdsf
)->s
.surface_desc
.lPitch
=
2899 This
->e
.dga
.fb_width
*PFGET_BPP(This
->d
.directdraw_pixelformat
);
2901 (*ilpdsf
)->s
.surface_desc
.u1
.lpSurface
=
2902 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
2904 (*ilpdsf
)->t
.dga
.fb_height
= i
*fbheight
;
2906 /* Add flags if there were not present */
2907 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
2908 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
2909 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
2910 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This
->d
.width
,This
->d
.height
,lpddsd
->lPitch
);
2911 /* We put our surface always in video memory */
2912 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2913 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
2914 (*ilpdsf
)->s
.chain
= NULL
;
2916 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2917 IDirectDrawSurface4Impl
* back
;
2920 for (bbc
=lpddsd
->dwBackBufferCount
;bbc
--;) {
2923 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
2926 sizeof(IDirectDrawSurface4Impl
)
2928 IDirectDraw2_AddRef(iface
);
2930 ICOM_VTBL(back
) = (ICOM_VTABLE(IDirectDrawSurface4
)*)&dga_dds4vt
;
2932 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
2934 TRACE("using viewport %d for backbuffer %d\n",i
, bbc
);
2935 /* if i == 32 or maximum ... return error */
2936 This
->e
.dga
.vpmask
|=(1<<i
);
2937 back
->t
.dga
.fb_height
= i
*fbheight
;
2938 /* Copy the surface description from the front buffer */
2939 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
2940 /* Change the parameters that are not the same */
2941 back
->s
.surface_desc
.u1
.lpSurface
=
2942 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
2944 back
->s
.ddraw
= This
;
2945 /* Add relevant info to front and back buffers */
2946 /* FIXME: backbuffer/frontbuffer handling broken here, but
2947 * will be fixed up in _Flip().
2949 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
2950 SDDSCAPS(back
) |= DDSCAPS_FLIP
|DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
;
2951 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2952 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
2953 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
2957 /* There is no DGA-specific code here...
2958 Go to the common surface creation function */
2959 return common_off_screen_CreateSurface(This
, *ilpdsf
);
2963 #endif /* defined(HAVE_LIBXXF86DGA) */
2965 #ifdef HAVE_LIBXXSHM
2966 /* Error handlers for Image creation */
2967 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
2972 static XImage
*create_xshmimage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
2974 int (*WineXHandler
)(Display
*, XErrorEvent
*);
2976 img
= TSXShmCreateImage(display
,
2977 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2978 This
->d
.pixmap_depth
,
2981 &(lpdsf
->t
.xlib
.shminfo
),
2982 lpdsf
->s
.surface_desc
.dwWidth
,
2983 lpdsf
->s
.surface_desc
.dwHeight
2987 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
2988 This
->e
.xlib
.xshm_active
= 0;
2992 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
2993 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
2994 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
2995 This
->e
.xlib
.xshm_active
= 0;
2996 TSXDestroyImage(img
);
3000 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
3002 if (img
->data
== (char *) -1) {
3003 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3004 This
->e
.xlib
.xshm_active
= 0;
3005 TSXDestroyImage(img
);
3006 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3009 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
3011 /* This is where things start to get trickier....
3012 * First, we flush the current X connections to be sure to catch all
3013 * non-XShm related errors
3015 TSXSync(display
, False
);
3016 /* Then we enter in the non-thread safe part of the tests */
3017 EnterCriticalSection( &X11DRV_CritSection
);
3019 /* Reset the error flag, sets our new error handler and try to attach
3023 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3024 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
3025 XSync(display
, False
);
3027 /* Check the error flag */
3028 if (XShmErrorFlag
) {
3029 /* An error occured */
3033 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
3034 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3035 XSetErrorHandler(WineXHandler
);
3037 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3038 This
->e
.xlib
.xshm_active
= 0;
3040 /* Leave the critical section */
3041 LeaveCriticalSection( &X11DRV_CritSection
);
3044 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3045 * this works, but it may be a bit overkill....
3047 XSetErrorHandler(WineXHandler
);
3048 LeaveCriticalSection( &X11DRV_CritSection
);
3050 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3052 if (This
->d
.pixel_convert
!= NULL
) {
3053 lpdsf
->s
.surface_desc
.u1
.lpSurface
= HeapAlloc(
3056 lpdsf
->s
.surface_desc
.dwWidth
*
3057 lpdsf
->s
.surface_desc
.dwHeight
*
3058 PFGET_BPP(This
->d
.directdraw_pixelformat
)
3061 lpdsf
->s
.surface_desc
.u1
.lpSurface
= img
->data
;
3065 #endif /* HAVE_LIBXXSHM */
3067 static XImage
*create_ximage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
3071 #ifdef HAVE_LIBXXSHM
3072 if (This
->e
.xlib
.xshm_active
)
3073 img
= create_xshmimage(This
, lpdsf
);
3077 /* Allocate surface memory */
3078 lpdsf
->s
.surface_desc
.u1
.lpSurface
= HeapAlloc(
3079 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3080 lpdsf
->s
.surface_desc
.dwWidth
*
3081 lpdsf
->s
.surface_desc
.dwHeight
*
3082 PFGET_BPP(This
->d
.directdraw_pixelformat
)
3085 if (This
->d
.pixel_convert
!= NULL
) {
3086 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
3087 lpdsf
->s
.surface_desc
.dwWidth
*
3088 lpdsf
->s
.surface_desc
.dwHeight
*
3089 PFGET_BPP(This
->d
.screen_pixelformat
)
3092 img_data
= lpdsf
->s
.surface_desc
.u1
.lpSurface
;
3095 /* In this case, create an XImage */
3096 img
= TSXCreateImage(display
,
3097 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3098 This
->d
.pixmap_depth
,
3102 lpdsf
->s
.surface_desc
.dwWidth
,
3103 lpdsf
->s
.surface_desc
.dwHeight
,
3105 lpdsf
->s
.surface_desc
.dwWidth
* PFGET_BPP(This
->d
.screen_pixelformat
)
3107 #ifdef HAVE_LIBXXSHM
3110 if (This
->d
.pixel_convert
!= NULL
)
3111 lpdsf
->s
.surface_desc
.lPitch
= PFGET_BPP(This
->d
.directdraw_pixelformat
) * lpdsf
->s
.surface_desc
.dwWidth
;
3113 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
3117 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreateSurface(
3118 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
3120 ICOM_THIS(IDirectDraw2Impl
,iface
);
3121 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
3123 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This
,lpddsd
,ilpdsf
,lpunk
);
3125 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
3127 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
3128 GetProcessHeap(),HEAP_ZERO_MEMORY
, sizeof(IDirectDrawSurfaceImpl
)
3131 IDirectDraw2_AddRef(iface
);
3133 (*ilpdsf
)->s
.ddraw
= This
;
3135 ICOM_VTBL(*ilpdsf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&xlib_dds4vt
;
3136 (*ilpdsf
)->s
.palette
= NULL
;
3137 (*ilpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
3139 /* Copy the surface description */
3140 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
3142 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
3143 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3144 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
3145 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3146 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
3148 /* Check if this a 'primary surface' or not */
3149 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
3150 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
3153 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf
);
3154 /* Create the XImage */
3155 img
= create_ximage(This
, (IDirectDrawSurface4Impl
*) *ilpdsf
);
3157 return DDERR_OUTOFMEMORY
;
3158 (*ilpdsf
)->t
.xlib
.image
= img
;
3160 /* Add flags if there were not present */
3161 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
3162 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3163 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3164 (*ilpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
3165 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
3167 /* Check for backbuffers */
3168 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
3169 IDirectDrawSurface4Impl
* back
;
3173 for (i
=lpddsd
->dwBackBufferCount
;i
--;) {
3174 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
3175 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3176 sizeof(IDirectDrawSurface4Impl
)
3179 TRACE("allocated back-buffer (%p)\n", back
);
3181 IDirectDraw2_AddRef(iface
);
3182 back
->s
.ddraw
= This
;
3185 ICOM_VTBL(back
) = (ICOM_VTABLE(IDirectDrawSurface4
)*)&xlib_dds4vt
;
3186 /* Copy the surface description from the front buffer */
3187 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
3189 /* Create the XImage */
3190 img
= create_ximage(This
, back
);
3192 return DDERR_OUTOFMEMORY
;
3193 back
->t
.xlib
.image
= img
;
3195 /* Add relevant info to front and back buffers */
3196 /* FIXME: backbuffer/frontbuffer handling broken here, but
3197 * will be fixed up in _Flip().
3199 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
3200 SDDSCAPS(back
) |= DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
|DDSCAPS_FLIP
;
3201 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
3202 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
3203 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
3207 /* There is no Xlib-specific code here...
3208 Go to the common surface creation function */
3209 return common_off_screen_CreateSurface(This
, *ilpdsf
);
3214 static HRESULT WINAPI
IDirectDraw2Impl_DuplicateSurface(
3215 LPDIRECTDRAW2 iface
,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
3217 ICOM_THIS(IDirectDraw2Impl
,iface
);
3218 FIXME("(%p)->(%p,%p) simply copies\n",This
,src
,dst
);
3219 *dst
= src
; /* FIXME */
3224 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3225 * even when the approbiate bitmasks are not specified.
3227 static HRESULT WINAPI
IDirectDraw2Impl_SetCooperativeLevel(
3228 LPDIRECTDRAW2 iface
,HWND hwnd
,DWORD cooplevel
3230 ICOM_THIS(IDirectDraw2Impl
,iface
);
3237 #define FE(x) { x, #x},
3238 FE(DDSCL_FULLSCREEN)
3239 FE(DDSCL_ALLOWREBOOT)
3240 FE(DDSCL_NOWINDOWCHANGES)
3242 FE(DDSCL_ALLOWMODEX)
3244 FE(DDSCL_SETFOCUSWINDOW)
3245 FE(DDSCL_SETDEVICEWINDOW)
3246 FE(DDSCL_CREATEDEVICEWINDOW)
3251 FIXME("(%p)->(%08lx,%08lx)\n",This
,(DWORD
)hwnd
,cooplevel
);
3252 This
->d
.mainWindow
= hwnd
;
3254 /* This will be overwritten in the case of Full Screen mode.
3255 Windowed games could work with that :-) */
3258 WND
*tmpWnd
= WIN_FindWndPtr(hwnd
);
3259 This
->d
.drawable
= X11DRV_WND_GetXWindow(tmpWnd
);
3260 WIN_ReleaseWndPtr(tmpWnd
);
3262 if( !This
->d
.drawable
) {
3263 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
3264 WIN_ReleaseDesktop();
3266 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
3272 /* Small helper to either use the cooperative window or create a new
3273 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3275 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl
* This
) {
3278 /* Do not destroy the application supplied cooperative window */
3279 if (This
->d
.window
&& This
->d
.window
!= This
->d
.mainWindow
) {
3280 DestroyWindow(This
->d
.window
);
3283 /* Sanity check cooperative window before assigning it to drawing. */
3284 if ( IsWindow(This
->d
.mainWindow
) &&
3285 IsWindowVisible(This
->d
.mainWindow
)
3287 /* if it does not fit, resize the cooperative window.
3288 * and hope the app likes it
3290 GetWindowRect(This
->d
.mainWindow
,&rect
);
3291 if ((((rect
.right
-rect
.left
) >= This
->d
.width
) &&
3292 ((rect
.bottom
-rect
.top
) >= This
->d
.height
))
3294 This
->d
.window
= This
->d
.mainWindow
;
3295 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3299 /* ... failed, create new one. */
3300 if (!This
->d
.window
) {
3301 This
->d
.window
= CreateWindowExA(
3305 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
3314 /*Store THIS with the window. We'll use it in the window procedure*/
3315 SetWindowLongA(This
->d
.window
,ddrawXlibThisOffset
,(LONG
)This
);
3316 ShowWindow(This
->d
.window
,TRUE
);
3317 UpdateWindow(This
->d
.window
);
3319 SetFocus(This
->d
.window
);
3322 static int _common_depth_to_pixelformat(DWORD depth
,
3323 DDPIXELFORMAT
*pixelformat
,
3324 DDPIXELFORMAT
*screen_pixelformat
,
3327 XPixmapFormatValues
*pf
;
3329 int nvisuals
, npixmap
, i
;
3333 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
3334 pf
= XListPixmapFormats(display
, &npixmap
);
3336 for (i
= 0; i
< npixmap
; i
++) {
3337 if (pf
[i
].depth
== depth
) {
3340 for (j
= 0; j
< nvisuals
; j
++) {
3341 if (vi
[j
].depth
== pf
[i
].depth
) {
3342 pixelformat
->dwSize
= sizeof(*pixelformat
);
3344 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
3345 pixelformat
->u1
.dwRBitMask
= 0;
3346 pixelformat
->u2
.dwGBitMask
= 0;
3347 pixelformat
->u3
.dwBBitMask
= 0;
3349 pixelformat
->dwFlags
= DDPF_RGB
;
3350 pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
3351 pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
3352 pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
3354 pixelformat
->dwFourCC
= 0;
3355 pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3356 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3358 *screen_pixelformat
= *pixelformat
;
3360 if (pix_depth
!= NULL
)
3361 *pix_depth
= vi
[j
].depth
;
3366 goto clean_up_and_exit
;
3370 ERR("No visual corresponding to pixmap format !\n");
3375 /* We try now to find an emulated mode */
3378 for (c
= 0; c
< sizeof(ModeEmulations
) / sizeof(Convert
); c
++) {
3379 if (ModeEmulations
[c
].dest
.depth
== depth
) {
3380 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3381 for (i
= 0; i
< npixmap
; i
++) {
3382 if ((pf
[i
].depth
== ModeEmulations
[c
].screen
.depth
) &&
3383 (pf
[i
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
3386 for (j
= 0; j
< nvisuals
; j
++) {
3387 if (vi
[j
].depth
== pf
[i
].depth
) {
3388 screen_pixelformat
->dwSize
= sizeof(*screen_pixelformat
);
3389 screen_pixelformat
->dwFlags
= DDPF_RGB
;
3390 screen_pixelformat
->dwFourCC
= 0;
3391 screen_pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3392 screen_pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
3393 screen_pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
3394 screen_pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
3395 screen_pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3397 pixelformat
->dwSize
= sizeof(*pixelformat
);
3398 pixelformat
->dwFourCC
= 0;
3400 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
3401 pixelformat
->u
.dwRGBBitCount
= 8;
3402 pixelformat
->u1
.dwRBitMask
= 0;
3403 pixelformat
->u2
.dwGBitMask
= 0;
3404 pixelformat
->u3
.dwBBitMask
= 0;
3406 pixelformat
->dwFlags
= DDPF_RGB
;
3407 pixelformat
->u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
3408 pixelformat
->u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
3409 pixelformat
->u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
3410 pixelformat
->u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
3412 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3414 if (pix_depth
!= NULL
)
3415 *pix_depth
= vi
[j
].depth
;
3420 goto clean_up_and_exit
;
3423 ERR("No visual corresponding to pixmap format !\n");
3438 #ifdef HAVE_LIBXXF86DGA
3439 static HRESULT WINAPI
DGA_IDirectDrawImpl_SetDisplayMode(
3440 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
3442 ICOM_THIS(IDirectDrawImpl
,iface
);
3445 TRACE("(%p)->(%ld,%ld,%ld)\n", This
, width
, height
, depth
);
3447 /* We hope getting the asked for depth */
3448 if (_common_depth_to_pixelformat(depth
, &(This
->d
.directdraw_pixelformat
), &(This
->d
.screen_pixelformat
), NULL
) != -1) {
3449 /* I.e. no visual found or emulated */
3450 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
3451 return DDERR_UNSUPPORTEDMODE
;
3454 if (This
->d
.width
< width
) {
3455 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,This
->d
.width
);
3456 return DDERR_UNSUPPORTEDMODE
;
3458 This
->d
.width
= width
;
3459 This
->d
.height
= height
;
3461 /* adjust fb_height, so we don't overlap */
3462 if (This
->e
.dga
.fb_height
< height
)
3463 This
->e
.dga
.fb_height
= height
;
3464 _common_IDirectDrawImpl_SetDisplayMode(This
);
3466 #ifdef HAVE_LIBXXF86VM
3468 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
3469 XF86VidModeModeLine mod_tmp
;
3470 /* int dotclock_tmp; */
3472 /* save original video mode and set fullscreen if available*/
3473 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
3474 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
3475 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
3476 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
3477 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
3478 orig_mode
->htotal
= mod_tmp
.htotal
;
3479 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
3480 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
3481 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
3482 orig_mode
->vtotal
= mod_tmp
.vtotal
;
3483 orig_mode
->flags
= mod_tmp
.flags
;
3484 orig_mode
->private = mod_tmp
.private;
3486 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
3487 for (i
=0;i
<mode_count
;i
++)
3489 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
3491 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
3492 *vidmode
= *(all_modes
[i
]);
3495 TSXFree(all_modes
[i
]->private);
3497 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
3501 WARN("Fullscreen mode not available!\n");
3505 TRACE("SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
3506 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
3507 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3508 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
3514 /* FIXME: this function OVERWRITES several signal handlers.
3515 * can we save them? and restore them later? In a way that
3516 * it works for the library too?
3518 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
3519 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
3521 #ifdef RESTORE_SIGNALS
3526 #endif /* defined(HAVE_LIBXXF86DGA) */
3528 /* *************************************
3529 16 / 15 bpp to palettized 8 bpp
3530 ************************************* */
3531 static void pixel_convert_16_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3532 unsigned char *c_src
= (unsigned char *) src
;
3533 unsigned short *c_dst
= (unsigned short *) dst
;
3536 if (palette
!= NULL
) {
3537 const unsigned short * pal
= (unsigned short *) palette
->screen_palents
;
3539 for (y
= height
; y
--; ) {
3540 #if defined(__i386__) && defined(__GNUC__)
3541 /* gcc generates slightly inefficient code for the the copy / lookup,
3542 * it generates one excess memory access (to pal) per pixel. Since
3543 * we know that pal is not modified by the memory write we can
3544 * put it into a register and reduce the number of memory accesses
3545 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3546 * (This is not guaranteed to be the fastest method.)
3548 __asm__
__volatile__(
3552 " movw (%%edx,%%eax,2),%%ax\n"
3554 " xor %%eax,%%eax\n"
3556 : "=S" (c_src
), "=D" (c_dst
)
3557 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
3558 : "eax", "cc", "memory"
3560 c_src
+=(pitch
-width
);
3562 unsigned char * srclineend
= c_src
+width
;
3563 while (c_src
< srclineend
)
3564 *c_dst
++ = pal
[*c_src
++];
3565 c_src
+=(pitch
-width
);
3569 WARN("No palette set...\n");
3570 memset(dst
, 0, width
* height
* 2);
3573 static void palette_convert_16_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3575 unsigned short *pal
= (unsigned short *) screen_palette
;
3577 for (i
= 0; i
< count
; i
++)
3578 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
3579 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3580 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
3582 static void palette_convert_15_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3584 unsigned short *pal
= (unsigned short *) screen_palette
;
3586 for (i
= 0; i
< count
; i
++)
3587 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 7) |
3588 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3589 ((((unsigned short) palent
[i
].peGreen
) & 0xF8) << 2));
3592 /* *************************************
3593 24 to palettized 8 bpp
3594 ************************************* */
3595 static void pixel_convert_24_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3596 unsigned char *c_src
= (unsigned char *) src
;
3597 unsigned char *c_dst
= (unsigned char *) dst
;
3600 if (palette
!= NULL
) {
3601 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
3603 for (y
= height
; y
--; ) {
3604 unsigned char * srclineend
= c_src
+width
;
3605 while (c_src
< srclineend
) {
3606 register long pixel
= pal
[*c_src
++];
3608 *c_dst
++ = pixel
>>8;
3609 *c_dst
++ = pixel
>>16;
3611 c_src
+=(pitch
-width
);
3614 WARN("No palette set...\n");
3615 memset(dst
, 0, width
* height
* 4);
3618 /* *************************************
3619 32 bpp to palettized 8 bpp
3620 ************************************* */
3621 static void pixel_convert_32_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3622 unsigned char *c_src
= (unsigned char *) src
;
3623 unsigned int *c_dst
= (unsigned int *) dst
;
3626 if (palette
!= NULL
) {
3627 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
3629 for (y
= height
; y
--; ) {
3630 #if defined(__i386__) && defined(__GNUC__)
3631 /* See comment in pixel_convert_16_to_8 */
3632 __asm__
__volatile__(
3636 " movl (%%edx,%%eax,4),%%eax\n"
3638 " xor %%eax,%%eax\n"
3640 : "=S" (c_src
), "=D" (c_dst
)
3641 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
3642 : "eax", "cc", "memory"
3644 c_src
+=(pitch
-width
);
3646 unsigned char * srclineend
= c_src
+width
;
3647 while (c_src
< srclineend
)
3648 *c_dst
++ = pal
[*c_src
++];
3649 c_src
+=(pitch
-width
);
3653 WARN("No palette set...\n");
3654 memset(dst
, 0, width
* height
* 4);
3658 static void palette_convert_24_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3660 unsigned int *pal
= (unsigned int *) screen_palette
;
3662 for (i
= 0; i
< count
; i
++)
3663 pal
[start
+ i
] = ((((unsigned int) palent
[i
].peRed
) << 16) |
3664 (((unsigned int) palent
[i
].peGreen
) << 8) |
3665 ((unsigned int) palent
[i
].peBlue
));
3668 /* *************************************
3670 ************************************* */
3671 static void pixel_convert_32_to_16(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3672 unsigned short *c_src
= (unsigned short *) src
;
3673 unsigned int *c_dst
= (unsigned int *) dst
;
3676 for (y
= height
; y
--; ) {
3677 unsigned short * srclineend
= c_src
+width
;
3678 while (c_src
< srclineend
) {
3679 *c_dst
++ = (((*c_src
& 0xF800) << 8) |
3680 ((*c_src
& 0x07E0) << 5) |
3681 ((*c_src
& 0x001F) << 3));
3684 c_src
+=((pitch
/2)-width
);
3689 static HRESULT WINAPI
Xlib_IDirectDrawImpl_SetDisplayMode(
3690 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
3692 ICOM_THIS(IDirectDrawImpl
,iface
);
3697 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3698 This
, width
, height
, depth
);
3700 switch ((c
= _common_depth_to_pixelformat(depth
,
3701 &(This
->d
.directdraw_pixelformat
),
3702 &(This
->d
.screen_pixelformat
),
3703 &(This
->d
.pixmap_depth
)))) {
3705 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
3706 MessageBoxA(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
3707 return DDERR_UNSUPPORTEDMODE
;
3711 This
->d
.pixel_convert
= NULL
;
3712 This
->d
.palette_convert
= NULL
;
3716 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
3718 /* Set the depth convertion routines */
3719 This
->d
.pixel_convert
= ModeEmulations
[c
].funcs
.pixel_convert
;
3720 This
->d
.palette_convert
= ModeEmulations
[c
].funcs
.palette_convert
;
3723 This
->d
.width
= width
;
3724 This
->d
.height
= height
;
3726 _common_IDirectDrawImpl_SetDisplayMode(This
);
3728 tmpWnd
= WIN_FindWndPtr(This
->d
.window
);
3729 This
->d
.paintable
= 1;
3730 This
->d
.drawable
= ((X11DRV_WND_DATA
*) tmpWnd
->pDriverData
)->window
;
3731 WIN_ReleaseWndPtr(tmpWnd
);
3733 /* We don't have a context for this window. Host off the desktop */
3734 if( !This
->d
.drawable
)
3736 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
3737 WIN_ReleaseDesktop();
3739 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
3744 #ifdef HAVE_LIBXXF86DGA
3745 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetCaps(
3746 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
3748 ICOM_THIS(IDirectDraw2Impl
,iface
);
3749 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
3750 if (!caps1
&& !caps2
)
3751 return DDERR_INVALIDPARAMS
;
3753 caps1
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
3754 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
3755 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
3758 caps2
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
3759 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
3760 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
3764 #endif /* defined(HAVE_LIBXXF86DGA) */
3766 static void fill_caps(LPDDCAPS caps
) {
3767 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3768 Need to be fixed, though.. */
3772 caps
->dwSize
= sizeof(*caps
);
3773 caps
->dwCaps
= DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
| DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
| DDCAPS_NOHARDWARE
;
3774 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NOPAGELOCKREQUIRED
| DDCAPS2_WIDESURFACES
;
3775 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
3777 caps
->dwFXAlphaCaps
= 0;
3778 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
3780 caps
->dwZBufferBitDepths
= DDBD_16
;
3781 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3782 to put textures in video memory.
3783 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3785 caps
->dwVidMemTotal
= 8192 * 1024;
3786 caps
->dwVidMemFree
= 8192 * 1024;
3787 /* These are all the supported capabilities of the surfaces */
3788 caps
->ddsCaps
.dwCaps
= DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
3789 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
3790 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
|
3791 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
;
3793 caps
->dwCaps
|= DDCAPS_3D
| DDCAPS_ZBLTS
;
3794 caps
->dwCaps2
|= DDCAPS2_NO2DDURING3DSCENE
;
3795 caps
->ddsCaps
.dwCaps
|= DDSCAPS_3DDEVICE
| DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
| DDSCAPS_ZBUFFER
;
3799 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetCaps(
3800 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
3802 ICOM_THIS(IDirectDraw2Impl
,iface
);
3803 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
3805 /* Put the same caps for the two capabilities */
3812 static HRESULT WINAPI
IDirectDraw2Impl_CreateClipper(
3813 LPDIRECTDRAW2 iface
,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
3815 ICOM_THIS(IDirectDraw2Impl
,iface
);
3816 IDirectDrawClipperImpl
** ilpddclip
=(IDirectDrawClipperImpl
**)lpddclip
;
3817 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
3818 This
,x
,ilpddclip
,lpunk
3820 *ilpddclip
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
3821 (*ilpddclip
)->ref
= 1;
3822 ICOM_VTBL(*ilpddclip
) = &ddclipvt
;
3826 static HRESULT WINAPI
common_IDirectDraw2Impl_CreatePalette(
3827 IDirectDraw2Impl
* This
,DWORD dwFlags
,LPPALETTEENTRY palent
,IDirectDrawPaletteImpl
**lpddpal
,LPUNKNOWN lpunk
,int *psize
3831 if (TRACE_ON(ddraw
))
3832 _dump_paletteformat(dwFlags
);
3834 *lpddpal
= (IDirectDrawPaletteImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPaletteImpl
));
3835 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
3836 (*lpddpal
)->ref
= 1;
3837 (*lpddpal
)->ddraw
= (IDirectDrawImpl
*)This
;
3838 (*lpddpal
)->installed
= 0;
3840 if (dwFlags
& DDPCAPS_1BIT
)
3842 else if (dwFlags
& DDPCAPS_2BIT
)
3844 else if (dwFlags
& DDPCAPS_4BIT
)
3846 else if (dwFlags
& DDPCAPS_8BIT
)
3849 ERR("unhandled palette format\n");
3854 /* Now, if we are in 'depth conversion mode', create the screen palette */
3855 if (This
->d
.palette_convert
!= NULL
)
3856 This
->d
.palette_convert(palent
, (*lpddpal
)->screen_palents
, 0, size
);
3858 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
3859 } else if (This
->d
.palette_convert
!= NULL
) {
3860 /* In that case, put all 0xFF */
3861 memset((*lpddpal
)->screen_palents
, 0xFF, 256 * sizeof(int));
3867 #ifdef HAVE_LIBXXF86DGA
3868 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreatePalette(
3869 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3871 ICOM_THIS(IDirectDraw2Impl
,iface
);
3872 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
3876 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
3877 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
3878 if (res
!= 0) return res
;
3879 ICOM_VTBL(*ilpddpal
) = &dga_ddpalvt
;
3880 if (This
->d
.directdraw_pixelformat
.u
.dwRGBBitCount
<=8) {
3881 (*ilpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
3883 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
3884 (*ilpddpal
)->cm
= 0;
3886 if (((*ilpddpal
)->cm
)&&xsize
) {
3887 for (i
=0;i
<xsize
;i
++) {
3890 xc
.red
= (*ilpddpal
)->palents
[i
].peRed
<<8;
3891 xc
.blue
= (*ilpddpal
)->palents
[i
].peBlue
<<8;
3892 xc
.green
= (*ilpddpal
)->palents
[i
].peGreen
<<8;
3893 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
3895 TSXStoreColor(display
,(*ilpddpal
)->cm
,&xc
);
3900 #endif /* defined(HAVE_LIBXXF86DGA) */
3902 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreatePalette(
3903 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3905 ICOM_THIS(IDirectDraw2Impl
,iface
);
3906 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
3910 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
3911 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
3912 if (res
!= 0) return res
;
3913 ICOM_VTBL(*ilpddpal
) = &xlib_ddpalvt
;
3917 #ifdef HAVE_LIBXXF86DGA
3918 static HRESULT WINAPI
DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
3919 ICOM_THIS(IDirectDraw2Impl
,iface
);
3920 TRACE("(%p)->()\n",This
);
3922 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3923 #ifdef RESTORE_SIGNALS
3928 #endif /* defined(HAVE_LIBXXF86DGA) */
3930 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
3931 ICOM_THIS(IDirectDraw2Impl
,iface
);
3932 TRACE("(%p)->RestoreDisplayMode()\n", This
);
3937 static HRESULT WINAPI
IDirectDraw2Impl_WaitForVerticalBlank(
3938 LPDIRECTDRAW2 iface
,DWORD x
,HANDLE h
3940 ICOM_THIS(IDirectDraw2Impl
,iface
);
3941 TRACE("(%p)->(0x%08lx,0x%08x)\n",This
,x
,h
);
3945 static ULONG WINAPI
IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface
) {
3946 ICOM_THIS(IDirectDraw2Impl
,iface
);
3947 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
3949 return ++(This
->ref
);
3952 #ifdef HAVE_LIBXXF86DGA
3953 static ULONG WINAPI
DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
3954 ICOM_THIS(IDirectDraw2Impl
,iface
);
3955 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
3957 if (!--(This
->ref
)) {
3958 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3959 if (This
->d
.window
&& (This
->d
.mainWindow
!= This
->d
.window
))
3960 DestroyWindow(This
->d
.window
);
3961 #ifdef HAVE_LIBXXF86VM
3963 TSXF86VidModeSwitchToMode(
3965 DefaultScreen(display
),
3967 if (orig_mode
->privsize
)
3968 TSXFree(orig_mode
->private);
3974 #ifdef RESTORE_SIGNALS
3977 HeapFree(GetProcessHeap(),0,This
);
3982 #endif /* defined(HAVE_LIBXXF86DGA) */
3984 static ULONG WINAPI
Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
3985 ICOM_THIS(IDirectDraw2Impl
,iface
);
3986 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
3988 if (!--(This
->ref
)) {
3989 if (This
->d
.window
&& (This
->d
.mainWindow
!= This
->d
.window
))
3990 DestroyWindow(This
->d
.window
);
3991 HeapFree(GetProcessHeap(),0,This
);
3994 /* FIXME: destroy window ... */
3998 #ifdef HAVE_LIBXXF86DGA
3999 static HRESULT WINAPI
DGA_IDirectDraw2Impl_QueryInterface(
4000 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
4002 ICOM_THIS(IDirectDraw2Impl
,iface
);
4005 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
4006 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
4007 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
4009 IDirectDraw2_AddRef(iface
);
4011 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4015 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
4016 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_ddvt
;
4017 IDirectDraw2_AddRef(iface
);
4020 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4024 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
4025 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd2vt
;
4026 IDirectDraw2_AddRef(iface
);
4029 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4033 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
4034 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd4vt
;
4035 IDirectDraw2_AddRef(iface
);
4038 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4042 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
4045 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4047 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4048 IDirectDraw2_AddRef(iface
);
4049 ICOM_VTBL(d3d
) = &d3dvt
;
4052 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4056 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
4057 IDirect3D2Impl
* d3d
;
4059 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4061 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4062 IDirectDraw2_AddRef(iface
);
4063 ICOM_VTBL(d3d
) = &d3d2vt
;
4066 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4070 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,xrefiid
);
4071 return OLE_E_ENUM_NOMORE
;
4073 #endif /* defined(HAVE_LIBXXF86DGA) */
4075 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_QueryInterface(
4076 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
4078 ICOM_THIS(IDirectDraw2Impl
,iface
);
4081 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
4082 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
4083 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
4085 IDirectDraw2_AddRef(iface
);
4087 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4091 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
4092 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_ddvt
;
4093 IDirectDraw2_AddRef(iface
);
4096 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4100 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
4101 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd2vt
;
4102 IDirectDraw2_AddRef(iface
);
4105 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4109 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
4110 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd4vt
;
4111 IDirectDraw2_AddRef(iface
);
4114 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4118 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
4121 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4123 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4124 IDirectDraw2_AddRef(iface
);
4125 ICOM_VTBL(d3d
) = &d3dvt
;
4128 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4132 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
4133 IDirect3D2Impl
* d3d
;
4135 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4137 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4138 IDirectDraw2_AddRef(iface
);
4139 ICOM_VTBL(d3d
) = &d3d2vt
;
4142 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4146 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,xrefiid
);
4147 return OLE_E_ENUM_NOMORE
;
4150 static HRESULT WINAPI
IDirectDraw2Impl_GetVerticalBlankStatus(
4151 LPDIRECTDRAW2 iface
,BOOL
*status
4153 ICOM_THIS(IDirectDraw2Impl
,iface
);
4154 TRACE("(%p)->(%p)\n",This
,status
);
4159 #ifdef HAVE_LIBXXF86DGA
4160 static HRESULT WINAPI
DGA_IDirectDraw2Impl_EnumDisplayModes(
4161 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4163 ICOM_THIS(IDirectDraw2Impl
,iface
);
4164 DDSURFACEDESC ddsfd
;
4167 } modes
[5] = { /* some of the usual modes */
4174 static int depths
[4] = {8,16,24,32};
4177 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4178 ddsfd
.dwSize
= sizeof(ddsfd
);
4179 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4180 if (dwFlags
& DDEDM_REFRESHRATES
) {
4181 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4182 ddsfd
.u
.dwRefreshRate
= 60;
4185 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
4186 ddsfd
.dwBackBufferCount
= 1;
4187 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4188 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4189 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= depths
[i
];
4190 /* FIXME: those masks would have to be set in depth > 8 */
4192 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4193 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4194 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4195 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4196 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
4197 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
4199 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4201 /* FIXME: We should query those from X itself */
4202 switch (depths
[i
]) {
4204 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0xF800;
4205 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x07E0;
4206 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x001F;
4209 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
4210 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
4211 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
4214 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
4215 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
4216 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
4221 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4222 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4223 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4224 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4226 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
4227 ddsfd
.dwWidth
= modes
[j
].w
;
4228 ddsfd
.dwHeight
= modes
[j
].h
;
4229 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4230 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4233 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4234 /* modeX is not standard VGA */
4236 ddsfd
.dwHeight
= 200;
4237 ddsfd
.dwWidth
= 320;
4238 TRACE(" enumerating (320x200x%d)\n",depths
[i
]);
4239 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4244 #endif /* defined(HAVE_LIBXXF86DGA) */
4246 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_EnumDisplayModes(
4247 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4249 ICOM_THIS(IDirectDraw2Impl
,iface
);
4251 XPixmapFormatValues
*pf
;
4253 int nvisuals
, npixmap
, i
, emu
;
4254 int has_mode
[] = { 0, 0, 0, 0 };
4255 int has_depth
[] = { 8, 15, 16, 24 };
4256 DDSURFACEDESC ddsfd
;
4259 } modes
[] = { /* some of the usual modes */
4267 DWORD maxWidth
, maxHeight
;
4269 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4270 ddsfd
.dwSize
= sizeof(ddsfd
);
4271 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4272 if (dwFlags
& DDEDM_REFRESHRATES
) {
4273 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4274 ddsfd
.u
.dwRefreshRate
= 60;
4276 maxWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4277 maxHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4279 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
4280 pf
= XListPixmapFormats(display
, &npixmap
);
4284 while ((i
< npixmap
) ||
4291 for (j
= 0; j
< 4; j
++) {
4292 if (has_depth
[j
] == pf
[i
].depth
) {
4303 if (has_mode
[mode_index
] == 0) {
4304 if (mode_index
== 0) {
4307 ddsfd
.ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4308 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4309 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
;
4310 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4311 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
4312 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4313 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4314 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4315 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4317 has_mode
[mode_index
] = 1;
4319 /* All the 'true color' depths (15, 16 and 24)
4320 First, find the corresponding visual to extract the bit masks */
4321 for (j
= 0; j
< nvisuals
; j
++) {
4322 if (vi
[j
].depth
== pf
[i
].depth
) {
4323 ddsfd
.ddsCaps
.dwCaps
= 0;
4324 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4325 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4326 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4327 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
4328 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= vi
[j
].red_mask
;
4329 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= vi
[j
].green_mask
;
4330 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= vi
[j
].blue_mask
;
4331 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4334 has_mode
[mode_index
] = 1;
4340 ERR("Did not find visual corresponding the the pixmap format !\n");
4346 /* Now to emulated modes */
4347 if (has_mode
[emu
] == 0) {
4350 int depth
= has_depth
[emu
];
4352 for (c
= 0; (c
< sizeof(ModeEmulations
) / sizeof(Convert
)) && (send_mode
== 0); c
++) {
4353 if (ModeEmulations
[c
].dest
.depth
== depth
) {
4354 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4355 for (l
= 0; (l
< npixmap
) && (send_mode
== 0); l
++) {
4356 if ((pf
[l
].depth
== ModeEmulations
[c
].screen
.depth
) &&
4357 (pf
[l
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
4359 for (j
= 0; (j
< nvisuals
) && (send_mode
== 0); j
++) {
4360 if ((vi
[j
].depth
== pf
[l
].depth
) &&
4361 (vi
[j
].red_mask
== ModeEmulations
[c
].screen
.rmask
) &&
4362 (vi
[j
].green_mask
== ModeEmulations
[c
].screen
.gmask
) &&
4363 (vi
[j
].blue_mask
== ModeEmulations
[c
].screen
.bmask
)) {
4364 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4365 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4367 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
;
4368 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
4369 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4370 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4371 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4373 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4374 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
4375 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
4376 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
4377 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
4379 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4384 ERR("No visual corresponding to pixmap format !\n");
4398 if (TRACE_ON(ddraw
)) {
4399 TRACE("Enumerating with pixel format : \n");
4400 _dump_pixelformat(&(ddsfd
.ddpfPixelFormat
));
4404 for (mode
= 0; mode
< sizeof(modes
)/sizeof(modes
[0]); mode
++) {
4405 /* Do not enumerate modes we cannot handle anyway */
4406 if ((modes
[mode
].w
> maxWidth
) || (modes
[mode
].h
> maxHeight
))
4409 ddsfd
.dwWidth
= modes
[mode
].w
;
4410 ddsfd
.dwHeight
= modes
[mode
].h
;
4412 /* Now, send the mode description to the application */
4413 TRACE(" - mode %4ld - %4ld\n", ddsfd
.dwWidth
, ddsfd
.dwHeight
);
4414 if (!modescb(&ddsfd
, context
))
4418 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4419 /* modeX is not standard VGA */
4420 ddsfd
.dwWidth
= 320;
4421 ddsfd
.dwHeight
= 200;
4422 if (!modescb(&ddsfd
, context
))
4435 #ifdef HAVE_LIBXXF86DGA
4436 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetDisplayMode(
4437 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4439 ICOM_THIS(IDirectDraw2Impl
,iface
);
4440 TRACE("(%p)->(%p)\n",This
,lpddsfd
);
4441 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4442 lpddsfd
->dwHeight
= This
->d
.height
;
4443 lpddsfd
->dwWidth
= This
->d
.width
;
4444 lpddsfd
->lPitch
= This
->e
.dga
.fb_width
*PFGET_BPP(This
->d
.directdraw_pixelformat
);
4445 lpddsfd
->dwBackBufferCount
= 1;
4446 lpddsfd
->u
.dwRefreshRate
= 60;
4447 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4448 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4451 #endif /* defined(HAVE_LIBXXF86DGA) */
4453 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetDisplayMode(
4454 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4456 ICOM_THIS(IDirectDraw2Impl
,iface
);
4457 TRACE("(%p)->GetDisplayMode(%p)\n",This
,lpddsfd
);
4458 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4459 lpddsfd
->dwHeight
= This
->d
.height
;
4460 lpddsfd
->dwWidth
= This
->d
.width
;
4461 lpddsfd
->lPitch
= lpddsfd
->dwWidth
* PFGET_BPP(This
->d
.directdraw_pixelformat
);
4462 lpddsfd
->dwBackBufferCount
= 1;
4463 lpddsfd
->u
.dwRefreshRate
= 60;
4464 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4465 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4469 static HRESULT WINAPI
IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface
) {
4470 ICOM_THIS(IDirectDraw2Impl
,iface
);
4471 TRACE("(%p)->()\n",This
);
4475 static HRESULT WINAPI
IDirectDraw2Impl_GetMonitorFrequency(
4476 LPDIRECTDRAW2 iface
,LPDWORD freq
4478 ICOM_THIS(IDirectDraw2Impl
,iface
);
4479 FIXME("(%p)->(%p) returns 60 Hz always\n",This
,freq
);
4480 *freq
= 60*100; /* 60 Hz */
4484 /* what can we directly decompress? */
4485 static HRESULT WINAPI
IDirectDraw2Impl_GetFourCCCodes(
4486 LPDIRECTDRAW2 iface
,LPDWORD x
,LPDWORD y
4488 ICOM_THIS(IDirectDraw2Impl
,iface
);
4489 FIXME("(%p,%p,%p), stub\n",This
,x
,y
);
4493 static HRESULT WINAPI
IDirectDraw2Impl_EnumSurfaces(
4494 LPDIRECTDRAW2 iface
,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
4496 ICOM_THIS(IDirectDraw2Impl
,iface
);
4497 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This
,x
,ddsfd
,context
,ddsfcb
);
4501 static HRESULT WINAPI
IDirectDraw2Impl_Compact(
4502 LPDIRECTDRAW2 iface
)
4504 ICOM_THIS(IDirectDraw2Impl
,iface
);
4505 FIXME("(%p)->()\n", This
);
4510 static HRESULT WINAPI
IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface
,
4511 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
4512 ICOM_THIS(IDirectDraw2Impl
,iface
);
4513 FIXME("(%p)->(%p)\n", This
, lplpGDIDDSSurface
);
4518 static HRESULT WINAPI
IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface
,
4519 LPDWORD lpdwScanLine
) {
4520 ICOM_THIS(IDirectDraw2Impl
,iface
);
4521 FIXME("(%p)->(%p)\n", This
, lpdwScanLine
);
4526 static HRESULT WINAPI
IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface
,
4528 ICOM_THIS(IDirectDraw2Impl
,iface
);
4529 FIXME("(%p)->(%p)\n", This
, lpGUID
);
4534 #ifdef HAVE_LIBXXF86DGA
4536 /* Note: Hack so we can reuse the old functions without compiler warnings */
4537 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4538 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4540 # define XCAST(fun) (void *)
4543 static ICOM_VTABLE(IDirectDraw
) dga_ddvt
=
4545 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4546 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
4547 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4548 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
4549 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4550 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4551 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
4552 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
4553 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4554 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
4555 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4556 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4557 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
4558 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
4559 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4560 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4561 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4562 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4563 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4564 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4565 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4566 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4567 DGA_IDirectDrawImpl_SetDisplayMode
,
4568 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4573 #endif /* defined(HAVE_LIBXXF86DGA) */
4575 /* Note: Hack so we can reuse the old functions without compiler warnings */
4576 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4577 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4579 # define XCAST(fun) (void *)
4582 static ICOM_VTABLE(IDirectDraw
) xlib_ddvt
=
4584 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4585 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
4586 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4587 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
4588 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4589 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4590 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
4591 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
4592 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4593 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4594 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4595 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4596 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
4597 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
4598 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4599 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4600 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4601 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4602 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4603 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4604 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4605 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4606 Xlib_IDirectDrawImpl_SetDisplayMode
,
4607 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4612 /*****************************************************************************
4618 #ifdef HAVE_LIBXXF86DGA
4619 static HRESULT WINAPI
DGA_IDirectDraw2Impl_SetDisplayMode(
4620 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
4622 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
4624 #endif /* defined(HAVE_LIBXXF86DGA) */
4626 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_SetDisplayMode(
4627 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
4629 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
4632 #ifdef HAVE_LIBXXF86DGA
4633 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetAvailableVidMem(
4634 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
4636 ICOM_THIS(IDirectDraw2Impl
,iface
);
4637 TRACE("(%p)->(%p,%p,%p)\n",
4638 This
,ddscaps
,total
,free
4640 if (total
) *total
= This
->e
.dga
.fb_memsize
* 1024;
4641 if (free
) *free
= This
->e
.dga
.fb_memsize
* 1024;
4644 #endif /* defined(HAVE_LIBXXF86DGA) */
4646 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4647 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
4649 ICOM_THIS(IDirectDraw2Impl
,iface
);
4650 TRACE("(%p)->(%p,%p,%p)\n",
4651 This
,ddscaps
,total
,free
4653 if (total
) *total
= 2048 * 1024;
4654 if (free
) *free
= 2048 * 1024;
4658 #ifdef HAVE_LIBXXF86DGA
4659 static ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
=
4661 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4662 DGA_IDirectDraw2Impl_QueryInterface
,
4663 IDirectDraw2Impl_AddRef
,
4664 DGA_IDirectDraw2Impl_Release
,
4665 IDirectDraw2Impl_Compact
,
4666 IDirectDraw2Impl_CreateClipper
,
4667 DGA_IDirectDraw2Impl_CreatePalette
,
4668 DGA_IDirectDraw2Impl_CreateSurface
,
4669 IDirectDraw2Impl_DuplicateSurface
,
4670 DGA_IDirectDraw2Impl_EnumDisplayModes
,
4671 IDirectDraw2Impl_EnumSurfaces
,
4672 IDirectDraw2Impl_FlipToGDISurface
,
4673 DGA_IDirectDraw2Impl_GetCaps
,
4674 DGA_IDirectDraw2Impl_GetDisplayMode
,
4675 IDirectDraw2Impl_GetFourCCCodes
,
4676 IDirectDraw2Impl_GetGDISurface
,
4677 IDirectDraw2Impl_GetMonitorFrequency
,
4678 IDirectDraw2Impl_GetScanLine
,
4679 IDirectDraw2Impl_GetVerticalBlankStatus
,
4680 IDirectDraw2Impl_Initialize
,
4681 DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4682 IDirectDraw2Impl_SetCooperativeLevel
,
4683 DGA_IDirectDraw2Impl_SetDisplayMode
,
4684 IDirectDraw2Impl_WaitForVerticalBlank
,
4685 DGA_IDirectDraw2Impl_GetAvailableVidMem
4687 #endif /* defined(HAVE_LIBXXF86DGA) */
4689 static ICOM_VTABLE(IDirectDraw2
) xlib_dd2vt
=
4691 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4692 Xlib_IDirectDraw2Impl_QueryInterface
,
4693 IDirectDraw2Impl_AddRef
,
4694 Xlib_IDirectDraw2Impl_Release
,
4695 IDirectDraw2Impl_Compact
,
4696 IDirectDraw2Impl_CreateClipper
,
4697 Xlib_IDirectDraw2Impl_CreatePalette
,
4698 Xlib_IDirectDraw2Impl_CreateSurface
,
4699 IDirectDraw2Impl_DuplicateSurface
,
4700 Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4701 IDirectDraw2Impl_EnumSurfaces
,
4702 IDirectDraw2Impl_FlipToGDISurface
,
4703 Xlib_IDirectDraw2Impl_GetCaps
,
4704 Xlib_IDirectDraw2Impl_GetDisplayMode
,
4705 IDirectDraw2Impl_GetFourCCCodes
,
4706 IDirectDraw2Impl_GetGDISurface
,
4707 IDirectDraw2Impl_GetMonitorFrequency
,
4708 IDirectDraw2Impl_GetScanLine
,
4709 IDirectDraw2Impl_GetVerticalBlankStatus
,
4710 IDirectDraw2Impl_Initialize
,
4711 Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4712 IDirectDraw2Impl_SetCooperativeLevel
,
4713 Xlib_IDirectDraw2Impl_SetDisplayMode
,
4714 IDirectDraw2Impl_WaitForVerticalBlank
,
4715 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4718 /*****************************************************************************
4723 static HRESULT WINAPI
IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface
,
4725 LPDIRECTDRAWSURFACE
*lpDDS
) {
4726 ICOM_THIS(IDirectDraw4Impl
,iface
);
4727 FIXME("(%p)->(%08ld,%p)\n", This
, (DWORD
) hdc
, lpDDS
);
4732 static HRESULT WINAPI
IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface
) {
4733 ICOM_THIS(IDirectDraw4Impl
,iface
);
4734 FIXME("(%p)->()\n", This
);
4739 static HRESULT WINAPI
IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface
) {
4740 ICOM_THIS(IDirectDraw4Impl
,iface
);
4741 FIXME("(%p)->()\n", This
);
4746 static HRESULT WINAPI
IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface
,
4747 LPDDDEVICEIDENTIFIER lpdddi
,
4749 ICOM_THIS(IDirectDraw4Impl
,iface
);
4750 FIXME("(%p)->(%p,%08lx)\n", This
, lpdddi
, dwFlags
);
4755 #ifdef HAVE_LIBXXF86DGA
4757 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4758 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4760 # define XCAST(fun) (void*)
4763 static ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
=
4765 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4766 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
4767 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4768 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
4769 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4770 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4771 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
4772 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
4773 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4774 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
4775 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4776 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4777 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
4778 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
4779 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4780 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4781 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4782 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4783 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4784 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4785 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4786 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4787 XCAST(SetDisplayMode
)DGA_IDirectDrawImpl_SetDisplayMode
,
4788 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4789 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2Impl_GetAvailableVidMem
,
4790 IDirectDraw4Impl_GetSurfaceFromDC
,
4791 IDirectDraw4Impl_RestoreAllSurfaces
,
4792 IDirectDraw4Impl_TestCooperativeLevel
,
4793 IDirectDraw4Impl_GetDeviceIdentifier
4798 #endif /* defined(HAVE_LIBXXF86DGA) */
4800 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4801 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
4803 # define XCAST(fun) (void*)
4806 static ICOM_VTABLE(IDirectDraw4
) xlib_dd4vt
=
4808 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4809 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
4810 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4811 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
4812 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4813 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4814 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
4815 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
4816 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4817 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4818 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4819 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4820 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
4821 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
4822 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4823 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4824 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4825 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4826 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4827 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4828 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4829 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4830 XCAST(SetDisplayMode
)Xlib_IDirectDrawImpl_SetDisplayMode
,
4831 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4832 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2Impl_GetAvailableVidMem
,
4833 IDirectDraw4Impl_GetSurfaceFromDC
,
4834 IDirectDraw4Impl_RestoreAllSurfaces
,
4835 IDirectDraw4Impl_TestCooperativeLevel
,
4836 IDirectDraw4Impl_GetDeviceIdentifier
4841 /******************************************************************************
4845 static LRESULT WINAPI
Xlib_DDWndProc(HWND hwnd
,UINT msg
,WPARAM wParam
,LPARAM lParam
)
4848 IDirectDrawImpl
* ddraw
= NULL
;
4851 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4853 SetLastError( ERROR_SUCCESS
);
4854 ddraw
= (IDirectDrawImpl
*)GetWindowLongA( hwnd
, ddrawXlibThisOffset
);
4856 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
4859 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
4864 /* Perform any special direct draw functions */
4866 ddraw
->d
.paintable
= 1;
4868 /* Now let the application deal with the rest of this */
4869 if( ddraw
->d
.mainWindow
)
4872 /* Don't think that we actually need to call this but...
4873 might as well be on the safe side of things... */
4875 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4876 it should be the procedures of our fake window that gets called
4877 instead of those of the window provided by the application.
4878 And with this patch, mouse clicks work with Monkey Island III
4880 ret
= DefWindowProcA( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
4884 WND
*tmpWnd
=WIN_FindWndPtr(ddraw
->d
.mainWindow
);
4885 /* We didn't handle the message - give it to the application */
4886 if (ddraw
&& ddraw
->d
.mainWindow
&& tmpWnd
)
4888 ret
= CallWindowProcA(tmpWnd
->winproc
,
4889 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
4891 WIN_ReleaseWndPtr(tmpWnd
);
4896 ret
= DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
4902 ret
= DefWindowProcA(hwnd
,msg
,wParam
,lParam
);
4908 static HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4909 #ifdef HAVE_LIBXXF86DGA
4910 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
4911 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
4916 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4917 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
4921 MESSAGE("Must be able to access /dev/mem to use XF86DGA!\n");
4922 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
4923 return E_UNEXPECTED
;
4925 if (!DDRAW_DGA_Available()) {
4926 TRACE("No XF86DGA detected.\n");
4927 return DDERR_GENERIC
;
4929 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
4930 ICOM_VTBL(*ilplpDD
) = &dga_ddvt
;
4931 (*ilplpDD
)->ref
= 1;
4932 TSXF86DGAQueryVersion(display
,&major
,&minor
);
4933 TRACE("XF86DGA is version %d.%d\n",major
,minor
);
4934 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
4935 if (!(flags
& XF86DGADirectPresent
))
4936 MESSAGE("direct video is NOT PRESENT.\n");
4937 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
4938 (*ilplpDD
)->e
.dga
.fb_width
= width
;
4939 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
4940 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
4941 (*ilplpDD
)->e
.dga
.fb_height
= height
;
4942 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4943 addr
,width
,banksize
,memsize
4945 TRACE("viewport height: %d\n",height
);
4947 /* Get the screen dimensions as seen by Wine.
4948 In that case, it may be better to ignore the -desktop mode and return the
4949 real screen size => print a warning */
4950 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4951 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4952 if (((*ilplpDD
)->d
.height
!= height
) ||
4953 ((*ilplpDD
)->d
.width
!= width
))
4954 WARN("You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4955 (*ilplpDD
)->e
.dga
.fb_addr
= addr
;
4956 (*ilplpDD
)->e
.dga
.fb_memsize
= memsize
;
4957 (*ilplpDD
)->e
.dga
.fb_banksize
= banksize
;
4958 (*ilplpDD
)->e
.dga
.vpmask
= 0;
4960 /* just assume the default depth is the DGA depth too */
4961 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
4962 _common_depth_to_pixelformat(depth
, &((*ilplpDD
)->d
.directdraw_pixelformat
), &((*ilplpDD
)->d
.screen_pixelformat
), NULL
);
4963 #ifdef RESTORE_SIGNALS
4968 #else /* defined(HAVE_LIBXXF86DGA) */
4969 return DDERR_INVALIDDIRECTDRAWGUID
;
4970 #endif /* defined(HAVE_LIBXXF86DGA) */
4974 DDRAW_XSHM_Available(void)
4976 #ifdef HAVE_LIBXXSHM
4977 if (TSXShmQueryExtension(display
))
4982 if ((TSXShmQueryVersion(display
, &major
, &minor
, &shpix
)) &&
4983 (Options
.noXSHM
!= 1))
4995 static HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4996 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
4999 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
5000 ICOM_VTBL(*ilplpDD
) = &xlib_ddvt
;
5001 (*ilplpDD
)->ref
= 1;
5002 (*ilplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
5004 /* At DirectDraw creation, the depth is the default depth */
5005 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
5006 _common_depth_to_pixelformat(depth
,
5007 &((*ilplpDD
)->d
.directdraw_pixelformat
),
5008 &((*ilplpDD
)->d
.screen_pixelformat
),
5009 &((*ilplpDD
)->d
.pixmap_depth
));
5010 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
5011 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
5013 #ifdef HAVE_LIBXXSHM
5014 /* Test if XShm is available. */
5015 if (((*ilplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available()))
5016 TRACE("Using XShm extension.\n");
5022 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
5023 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
5026 /* WND* pParentWindow; */
5030 WINE_StringFromCLSID(lpGUID
,xclsid
);
5032 sprintf(xclsid
,"<guid-0x%08x>",(int)lpGUID
);
5036 TRACE("(%s,%p,%p)\n",xclsid
,ilplpDD
,pUnkOuter
);
5039 ( IsEqualGUID( &IID_IDirectDraw
, lpGUID
) ) ||
5040 ( IsEqualGUID( &IID_IDirectDraw2
, lpGUID
) ) ||
5041 ( IsEqualGUID( &IID_IDirectDraw4
, lpGUID
) ) ) {
5042 /* if they didn't request a particular interface, use the best
5044 if (DDRAW_DGA_Available())
5045 lpGUID
= &DGA_DirectDraw_GUID
;
5047 lpGUID
= &XLIB_DirectDraw_GUID
;
5050 wc
.style
= CS_GLOBALCLASS
;
5051 wc
.lpfnWndProc
= Xlib_DDWndProc
;
5053 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
5054 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
5056 /* We can be a child of the desktop since we're really important */
5058 This code is not useful since hInstance is forced to 0 afterward
5059 pParentWindow = WIN_GetDesktop();
5060 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5066 wc
.hCursor
= (HCURSOR
)IDC_ARROWA
;
5067 wc
.hbrBackground
= NULL_BRUSH
;
5068 wc
.lpszMenuName
= 0;
5069 wc
.lpszClassName
= "WINE_DirectDraw";
5070 RegisterClassA(&wc
);
5072 if ( IsEqualGUID( &DGA_DirectDraw_GUID
, lpGUID
) ) {
5073 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
5075 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID
, &XLIB_DirectDraw_GUID
) ) {
5076 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
5083 (*ilplpDD
)->d
.winclass
= RegisterClassA(&wc
);
5087 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
5088 return DDERR_INVALIDDIRECTDRAWGUID
;
5091 /*******************************************************************************
5092 * DirectDraw ClassFactory
5094 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5099 /* IUnknown fields */
5100 ICOM_VFIELD(IClassFactory
);
5102 } IClassFactoryImpl
;
5104 static HRESULT WINAPI
5105 DDCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
) {
5106 ICOM_THIS(IClassFactoryImpl
,iface
);
5110 WINE_StringFromCLSID(riid
,buf
);
5112 sprintf(buf
,"<guid-0x%04x>",LOWORD(riid
));
5113 FIXME("(%p)->(%s,%p),stub!\n",This
,buf
,ppobj
);
5114 return E_NOINTERFACE
;
5118 DDCF_AddRef(LPCLASSFACTORY iface
) {
5119 ICOM_THIS(IClassFactoryImpl
,iface
);
5120 return ++(This
->ref
);
5123 static ULONG WINAPI
DDCF_Release(LPCLASSFACTORY iface
) {
5124 ICOM_THIS(IClassFactoryImpl
,iface
);
5125 /* static class, won't be freed */
5126 return --(This
->ref
);
5129 static HRESULT WINAPI
DDCF_CreateInstance(
5130 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
5132 ICOM_THIS(IClassFactoryImpl
,iface
);
5135 WINE_StringFromCLSID(riid
,buf
);
5136 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,buf
,ppobj
);
5137 if ( ( IsEqualGUID( &IID_IDirectDraw
, riid
) ) ||
5138 ( IsEqualGUID( &IID_IDirectDraw2
, riid
) ) ||
5139 ( IsEqualGUID( &IID_IDirectDraw4
, riid
) ) ) {
5140 /* FIXME: reuse already created DirectDraw if present? */
5141 return DirectDrawCreate((LPGUID
) riid
,(LPDIRECTDRAW
*)ppobj
,pOuter
);
5143 return CLASS_E_CLASSNOTAVAILABLE
;
5146 static HRESULT WINAPI
DDCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
5147 ICOM_THIS(IClassFactoryImpl
,iface
);
5148 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
5152 static ICOM_VTABLE(IClassFactory
) DDCF_Vtbl
=
5154 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5155 DDCF_QueryInterface
,
5158 DDCF_CreateInstance
,
5161 static IClassFactoryImpl DDRAW_CF
= {&DDCF_Vtbl
, 1 };
5163 /*******************************************************************************
5164 * DllGetClassObject [DDRAW.13]
5165 * Retrieves class object from a DLL object
5168 * Docs say returns STDAPI
5171 * rclsid [I] CLSID for the class object
5172 * riid [I] Reference to identifier of interface for class object
5173 * ppv [O] Address of variable to receive interface pointer for riid
5177 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5180 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
,REFIID riid
,LPVOID
*ppv
)
5182 char buf
[80],xbuf
[80];
5185 WINE_StringFromCLSID(rclsid
,xbuf
);
5187 sprintf(xbuf
,"<guid-0x%04x>",LOWORD(rclsid
));
5189 WINE_StringFromCLSID(riid
,buf
);
5191 sprintf(buf
,"<guid-0x%04x>",LOWORD(riid
));
5192 WINE_StringFromCLSID(riid
,xbuf
);
5193 TRACE("(%p,%p,%p)\n", xbuf
, buf
, ppv
);
5194 if ( IsEqualCLSID( &IID_IClassFactory
, riid
) ) {
5195 *ppv
= (LPVOID
)&DDRAW_CF
;
5196 IClassFactory_AddRef((IClassFactory
*)*ppv
);
5199 FIXME("(%p,%p,%p): no interface found.\n", xbuf
, buf
, ppv
);
5200 return CLASS_E_CLASSNOTAVAILABLE
;
5204 /*******************************************************************************
5205 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5211 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5213 FIXME("(void): stub\n");
5217 #else /* !defined(X_DISPLAY_MISSING) */
5220 #include "winerror.h"
5225 typedef void *LPUNKNOWN
;
5226 typedef void *LPDIRECTDRAW
;
5227 typedef void *LPDIRECTDRAWCLIPPER
;
5228 typedef void *LPDDENUMCALLBACKA
;
5229 typedef void *LPDDENUMCALLBACKEXA
;
5230 typedef void *LPDDENUMCALLBACKEXW
;
5231 typedef void *LPDDENUMCALLBACKW
;
5233 HRESULT WINAPI
DSoundHelp(DWORD x
, DWORD y
, DWORD z
)
5238 HRESULT WINAPI
DirectDrawCreate(
5239 LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
)
5244 HRESULT WINAPI
DirectDrawCreateClipper(
5245 DWORD dwFlags
, LPDIRECTDRAWCLIPPER
*lplpDDClipper
, LPUNKNOWN pUnkOuter
)
5250 HRESULT WINAPI
DirectDrawEnumerateA(
5251 LPDDENUMCALLBACKA lpCallback
, LPVOID lpContext
)
5256 HRESULT WINAPI
DirectDrawEnumerateExA(
5257 LPDDENUMCALLBACKEXA lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5262 HRESULT WINAPI
DirectDrawEnumerateExW(
5263 LPDDENUMCALLBACKEXW lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5268 HRESULT WINAPI
DirectDrawEnumerateW(
5269 LPDDENUMCALLBACKW lpCallback
, LPVOID lpContext
)
5274 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
5276 return CLASS_E_CLASSNOTAVAILABLE
;
5279 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5284 #endif /* !defined(X_DISPLAY_MISSING) */