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 int compl = This
->s
.ddraw
->e
.xlib
.xshm_compl
;
714 X11DRV_EVENT_WaitShmCompletion( compl );
715 This
->s
.ddraw
->e
.xlib
.xshm_compl
= X11DRV_EVENT_PrepareShmCompletion( This
->s
.ddraw
->d
.drawable
);
716 TSXShmPutImage(display
,
717 This
->s
.ddraw
->d
.drawable
,
718 DefaultGCOfScreen(X11DRV_GetXScreen()),
721 This
->t
.xlib
.image
->width
,
722 This
->t
.xlib
.image
->height
,
727 TSXPutImage( display
,
728 This
->s
.ddraw
->d
.drawable
,
729 DefaultGCOfScreen(X11DRV_GetXScreen()),
732 This
->t
.xlib
.image
->width
,
733 This
->t
.xlib
.image
->height
);
736 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Unlock(
737 LPDIRECTDRAWSURFACE4 iface
,LPVOID surface
)
739 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
740 TRACE("(%p)->Unlock(%p)\n",This
,surface
);
742 if (!This
->s
.ddraw
->d
.paintable
)
745 /* Only redraw the screen when unlocking the buffer that is on screen */
746 if (This
->t
.xlib
.image
&& (SDDSCAPS(This
) & DDSCAPS_VISIBLE
)) {
747 Xlib_copy_surface_on_screen(This
);
749 if (This
->s
.palette
&& This
->s
.palette
->cm
)
750 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
755 static IDirectDrawSurface4Impl
* _common_find_flipto(
756 IDirectDrawSurface4Impl
* This
,IDirectDrawSurface4Impl
* flipto
759 struct _surface_chain
*chain
= This
->s
.chain
;
761 /* if there was no override flipto, look for current backbuffer */
763 /* walk the flip chain looking for backbuffer */
764 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
765 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
)
767 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_BACKBUFFER
)
768 flipto
= chain
->surfaces
[i
];
770 /* sanity checks ... */
773 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
774 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FRONTBUFFER
)
776 if (i
==chain
->nrofsurfaces
) {
777 /* we do not have a frontbuffer either */
778 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
779 if (SDDSCAPS(chain
->surfaces
[i
]) & DDSCAPS_FLIP
) {
780 SDDSCAPS(chain
->surfaces
[i
])|=DDSCAPS_FRONTBUFFER
;
783 for (j
=i
+1;j
<i
+chain
->nrofsurfaces
+1;j
++) {
784 int k
= j
% chain
->nrofsurfaces
;
785 if (SDDSCAPS(chain
->surfaces
[k
]) & DDSCAPS_FLIP
) {
786 SDDSCAPS(chain
->surfaces
[k
])|=DDSCAPS_BACKBUFFER
;
787 flipto
= chain
->surfaces
[k
];
796 TRACE("flipping to %p\n",flipto
);
801 #ifdef HAVE_LIBXXF86DGA
802 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_Flip(
803 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
805 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
806 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
810 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
811 iflipto
= _common_find_flipto(This
,iflipto
);
814 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,iflipto
->t
.dga
.fb_height
);
815 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
816 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),iflipto
->s
.palette
->cm
);
817 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
820 /* We need to switch the lowlevel surfaces, for DGA this is: */
822 /* The height within the framebuffer */
823 xheight
= This
->t
.dga
.fb_height
;
824 This
->t
.dga
.fb_height
= iflipto
->t
.dga
.fb_height
;
825 iflipto
->t
.dga
.fb_height
= xheight
;
827 /* And the assciated surface pointer */
828 surf
= This
->s
.surface_desc
.u1
.lpSurface
;
829 This
->s
.surface_desc
.u1
.lpSurface
= iflipto
->s
.surface_desc
.u1
.lpSurface
;
830 iflipto
->s
.surface_desc
.u1
.lpSurface
= surf
;
834 #endif /* defined(HAVE_LIBXXF86DGA) */
836 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_Flip(
837 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
839 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
842 IDirectDrawSurface4Impl
* iflipto
=(IDirectDrawSurface4Impl
*)flipto
;
844 TRACE("(%p)->Flip(%p,%08lx)\n",This
,iflipto
,dwFlags
);
845 iflipto
= _common_find_flipto(This
,iflipto
);
847 #if defined(HAVE_MESAGL) && 0 /* does not work */
848 if (This
->s
.d3d_device
|| (iflipto
&& iflipto
->s
.d3d_device
)) {
849 TRACE(" - OpenGL flip\n");
851 glXSwapBuffers(display
, This
->s
.ddraw
->d
.drawable
);
856 #endif /* defined(HAVE_MESAGL) */
858 if (!This
->s
.ddraw
->d
.paintable
)
861 /* We need to switch the lowlevel surfaces, for xlib this is: */
862 /* The surface pointer */
863 surf
= This
->s
.surface_desc
.u1
.lpSurface
;
864 This
->s
.surface_desc
.u1
.lpSurface
= iflipto
->s
.surface_desc
.u1
.lpSurface
;
865 iflipto
->s
.surface_desc
.u1
.lpSurface
= surf
;
866 /* the associated ximage */
867 image
= This
->t
.xlib
.image
;
868 This
->t
.xlib
.image
= iflipto
->t
.xlib
.image
;
869 iflipto
->t
.xlib
.image
= image
;
871 Xlib_copy_surface_on_screen(This
);
873 if (iflipto
->s
.palette
&& iflipto
->s
.palette
->cm
)
874 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,iflipto
->s
.palette
->cm
);
878 /* The IDirectDrawSurface4::SetPalette method attaches the specified
879 * DirectDrawPalette object to a surface. The surface uses this palette for all
880 * subsequent operations. The palette change takes place immediately.
882 static HRESULT WINAPI
Xlib_IDirectDrawSurface4Impl_SetPalette(
883 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
885 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
886 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
888 TRACE("(%p)->(%p)\n",This
,ipal
);
891 if( This
->s
.palette
!= NULL
)
892 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
893 This
->s
.palette
= ipal
;
898 if( !(ipal
->cm
) && (This
->s
.ddraw
->d
.screen_pixelformat
.u
.dwRGBBitCount
<=8))
900 ipal
->cm
= TSXCreateColormap(display
,This
->s
.ddraw
->d
.drawable
,
901 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
903 if (!Options
.managed
)
904 TSXInstallColormap(display
,ipal
->cm
);
906 for (i
=0;i
<256;i
++) {
909 xc
.red
= ipal
->palents
[i
].peRed
<<8;
910 xc
.blue
= ipal
->palents
[i
].peBlue
<<8;
911 xc
.green
= ipal
->palents
[i
].peGreen
<<8;
912 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
914 TSXStoreColor(display
,ipal
->cm
,&xc
);
916 TSXInstallColormap(display
,ipal
->cm
);
919 /* According to spec, we are only supposed to
920 * AddRef if this is not the same palette.
922 if( This
->s
.palette
!= ipal
)
925 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
926 if( This
->s
.palette
!= NULL
)
927 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
928 This
->s
.palette
= ipal
;
929 /* Perform the refresh */
930 TSXSetWindowColormap(display
,This
->s
.ddraw
->d
.drawable
,This
->s
.palette
->cm
);
935 #ifdef HAVE_LIBXXF86DGA
936 static HRESULT WINAPI
DGA_IDirectDrawSurface4Impl_SetPalette(
937 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWPALETTE pal
939 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
940 IDirectDrawPaletteImpl
* ipal
=(IDirectDrawPaletteImpl
*)pal
;
941 TRACE("(%p)->(%p)\n",This
,ipal
);
943 /* According to spec, we are only supposed to
944 * AddRef if this is not the same palette.
946 if( This
->s
.palette
!= ipal
)
949 IDirectDrawPalette_AddRef( (IDirectDrawPalette
*)ipal
);
950 if( This
->s
.palette
!= NULL
)
951 IDirectDrawPalette_Release( (IDirectDrawPalette
*)This
->s
.palette
);
952 This
->s
.palette
= ipal
;
953 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->s
.palette
->cm
);
957 #endif /* defined(HAVE_LIBXXF86DGA) */
959 static HRESULT
_Blt_ColorFill(LPBYTE buf
, int width
, int height
, int bpp
, LONG lPitch
, DWORD color
)
966 #define COLORFILL_ROW(type) { \
967 type *d = (type *) buf; \
968 for (x = 0; x < width; x++) \
969 d[x] = (type) color; \
974 case 1: COLORFILL_ROW(BYTE
)
975 case 2: COLORFILL_ROW(WORD
)
976 case 4: COLORFILL_ROW(DWORD
)
978 FIXME("Color fill not implemented for bpp %d!\n", bpp
*8);
979 return DDERR_UNSUPPORTED
;
984 /* Now copy first row */
986 for (y
= 1; y
< height
; y
++) {
988 memcpy(buf
, first
, width
* bpp
);
994 static HRESULT WINAPI
IDirectDrawSurface4Impl_Blt(
995 LPDIRECTDRAWSURFACE4 iface
,LPRECT rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
997 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
999 DDSURFACEDESC ddesc
,sdesc
;
1000 HRESULT ret
= DD_OK
;
1001 int bpp
, srcheight
, srcwidth
, dstheight
, dstwidth
, width
;
1005 TRACE("(%p)->(%p,%p,%p,%08lx,%p)\n", This
,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
1007 if (src
) IDirectDrawSurface4_Lock(src
, NULL
, &sdesc
, 0, 0);
1008 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,0,0);
1010 if (TRACE_ON(ddraw
)) {
1011 if (rdst
) TRACE("\tdestrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
1012 if (rsrc
) TRACE("\tsrcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1014 _dump_DDBLT(dwFlags
);
1015 if (dwFlags
& DDBLT_DDFX
) {
1016 TRACE("\tblitfx: ");
1017 _dump_DDBLTFX(lpbltfx
->dwDDFX
);
1022 if ((rdst
->top
< 0) ||
1024 (rdst
->bottom
< 0) ||
1025 (rdst
->right
< 0)) {
1026 ERR(" Negative values in LPRECT !!!\n");
1029 memcpy(&xdst
,rdst
,sizeof(xdst
));
1032 xdst
.bottom
= ddesc
.dwHeight
;
1034 xdst
.right
= ddesc
.dwWidth
;
1038 if ((rsrc
->top
< 0) ||
1040 (rsrc
->bottom
< 0) ||
1041 (rsrc
->right
< 0)) {
1042 ERR(" Negative values in LPRECT !!!\n");
1045 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
1049 xsrc
.bottom
= sdesc
.dwHeight
;
1051 xsrc
.right
= sdesc
.dwWidth
;
1053 memset(&xsrc
,0,sizeof(xsrc
));
1057 bpp
= GET_BPP(ddesc
);
1058 srcheight
= xsrc
.bottom
- xsrc
.top
;
1059 srcwidth
= xsrc
.right
- xsrc
.left
;
1060 dstheight
= xdst
.bottom
- xdst
.top
;
1061 dstwidth
= xdst
.right
- xdst
.left
;
1062 width
= (xdst
.right
- xdst
.left
) * bpp
;
1063 dbuf
= (BYTE
*) ddesc
.u1
.lpSurface
+ (xdst
.top
* ddesc
.lPitch
) + (xdst
.left
* bpp
);
1065 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
1067 /* First, all the 'source-less' blits */
1068 if (dwFlags
& DDBLT_COLORFILL
) {
1069 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
,
1070 ddesc
.lPitch
, lpbltfx
->u4
.dwFillColor
);
1071 dwFlags
&= ~DDBLT_COLORFILL
;
1074 if (dwFlags
& DDBLT_DEPTHFILL
) {
1078 /* Clears the screen */
1079 TRACE(" Filling depth buffer with %ld\n", lpbltfx
->u4
.dwFillDepth
);
1080 glClearDepth(lpbltfx
->u4
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
1081 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
1082 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
1083 glClear(GL_DEPTH_BUFFER_BIT
);
1086 dwFlags
&= ~(DDBLT_DEPTHFILL
);
1087 #endif /* defined(HAVE_MESAGL) */
1090 if (dwFlags
& DDBLT_ROP
) {
1091 /* Catch some degenerate cases here */
1092 switch(lpbltfx
->dwROP
) {
1094 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, 0);
1096 case 0xAA0029: /* No-op */
1099 ret
= _Blt_ColorFill(dbuf
, dstwidth
, dstheight
, bpp
, ddesc
.lPitch
, ~0);
1102 FIXME("Unsupported raster op: %08lx Pattern: %p\n", lpbltfx
->dwROP
, lpbltfx
->u4
.lpDDSPattern
);
1105 dwFlags
&= ~DDBLT_ROP
;
1108 if (dwFlags
& DDBLT_DDROPS
) {
1109 FIXME("\tDdraw Raster Ops: %08lx Pattern: %p\n", lpbltfx
->dwDDROP
, lpbltfx
->u4
.lpDDSPattern
);
1112 /* Now the 'with source' blits */
1115 int sx
, xinc
, sy
, yinc
;
1117 sbase
= (BYTE
*) sdesc
.u1
.lpSurface
+ (xsrc
.top
* sdesc
.lPitch
) + xsrc
.left
* bpp
;
1118 xinc
= (srcwidth
<< 16) / dstwidth
;
1119 yinc
= (srcheight
<< 16) / dstheight
;
1123 /* No effects, we can cheat here */
1124 if (dstwidth
== srcwidth
) {
1125 if (dstheight
== srcheight
) {
1126 /* No stretching in either direction. This needs to be as fast as possible */
1128 for (y
= 0; y
< dstheight
; y
++) {
1129 memcpy(dbuf
, sbuf
, width
);
1130 sbuf
+= sdesc
.lPitch
;
1131 dbuf
+= ddesc
.lPitch
;
1134 /* Stretching in Y direction only */
1135 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1136 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1137 memcpy(dbuf
, sbuf
, width
);
1138 dbuf
+= ddesc
.lPitch
;
1142 /* Stretching in X direction */
1144 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1145 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1147 if ((sy
>> 16) == (last_sy
>> 16)) {
1148 /* Same as last row - copy already stretched row */
1149 memcpy(dbuf
, dbuf
- ddesc
.lPitch
, width
);
1152 #define STRETCH_ROW(type) { \
1153 type *s = (type *) sbuf, *d = (type *) dbuf; \
1154 for (x = sx = 0; x < dstwidth; x++, sx += xinc) \
1155 d[x] = s[sx >> 16]; \
1159 case 1: STRETCH_ROW(BYTE
)
1160 case 2: STRETCH_ROW(WORD
)
1161 case 4: STRETCH_ROW(DWORD
)
1163 FIXME("Stretched blit not implemented for bpp %d!\n", bpp
*8);
1164 ret
= DDERR_UNSUPPORTED
;
1172 dbuf
+= ddesc
.lPitch
;
1175 } else if (dwFlags
& (DDBLT_KEYSRC
| DDBLT_KEYDEST
)) {
1176 DWORD keylow
, keyhigh
;
1178 if (dwFlags
& DDBLT_KEYSRC
) {
1179 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1180 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1182 /* I'm not sure if this is correct */
1183 FIXME("DDBLT_KEYDEST not fully supported yet.\n");
1184 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1185 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1189 for (y
= sy
= 0; y
< dstheight
; y
++, sy
+= yinc
) {
1190 sbuf
= sbase
+ (sy
>> 16) * sdesc
.lPitch
;
1192 #define COPYROW_COLORKEY(type) { \
1193 type *s = (type *) sbuf, *d = (type *) dbuf, tmp; \
1194 for (x = sx = 0; x < dstwidth; x++, sx += xinc) { \
1195 tmp = s[sx >> 16]; \
1196 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1201 case 1: COPYROW_COLORKEY(BYTE
)
1202 case 2: COPYROW_COLORKEY(WORD
)
1203 case 4: COPYROW_COLORKEY(DWORD
)
1205 FIXME("%s color-keyed blit not implemented for bpp %d!\n",
1206 (dwFlags
& DDBLT_KEYSRC
) ? "Source" : "Destination", bpp
*8);
1207 ret
= DDERR_UNSUPPORTED
;
1210 dbuf
+= ddesc
.lPitch
;
1213 #undef COPYROW_COLORKEY
1215 dwFlags
&= ~(DDBLT_KEYSRC
| DDBLT_KEYDEST
);
1222 if (dwFlags
&& FIXME_ON(ddraw
)) {
1223 FIXME("\tUnsupported flags: ");
1224 _dump_DDBLT(dwFlags
);
1228 IDirectDrawSurface4_Unlock(iface
,ddesc
.u1
.lpSurface
);
1229 if (src
) IDirectDrawSurface4_Unlock(src
,sdesc
.u1
.lpSurface
);
1234 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltFast(
1235 LPDIRECTDRAWSURFACE4 iface
,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD trans
1237 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1238 int bpp
, w
, h
, x
, y
;
1239 DDSURFACEDESC ddesc
,sdesc
;
1240 HRESULT ret
= DD_OK
;
1244 if (TRACE_ON(ddraw
)) {
1245 FIXME("(%p)->(%ld,%ld,%p,%p,%08lx)\n",
1246 This
,dstx
,dsty
,src
,rsrc
,trans
1249 if (FIXME_ON(ddraw
))
1250 _dump_DDBLTFAST(trans
);
1251 FIXME(" srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
1253 /* We need to lock the surfaces, or we won't get refreshes when done. */
1254 IDirectDrawSurface4_Lock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
1255 IDirectDrawSurface4_Lock(iface
,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
1257 bpp
= GET_BPP(This
->s
.surface_desc
);
1258 sbuf
= (BYTE
*) sdesc
.u1
.lpSurface
+ (rsrc
->top
* sdesc
.lPitch
) + rsrc
->left
* bpp
;
1259 dbuf
= (BYTE
*) ddesc
.u1
.lpSurface
+ (dsty
* ddesc
.lPitch
) + dstx
* bpp
;
1262 h
=rsrc
->bottom
-rsrc
->top
;
1263 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
1264 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
1267 w
=rsrc
->right
-rsrc
->left
;
1268 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
1269 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
1272 if (trans
& (DDBLTFAST_SRCCOLORKEY
| DDBLTFAST_DESTCOLORKEY
)) {
1273 DWORD keylow
, keyhigh
;
1274 if (trans
& DDBLTFAST_SRCCOLORKEY
) {
1275 keylow
= sdesc
.ddckCKSrcBlt
.dwColorSpaceLowValue
;
1276 keyhigh
= sdesc
.ddckCKSrcBlt
.dwColorSpaceHighValue
;
1278 /* I'm not sure if this is correct */
1279 FIXME("DDBLTFAST_DESTCOLORKEY not fully supported yet.\n");
1280 keylow
= ddesc
.ddckCKDestBlt
.dwColorSpaceLowValue
;
1281 keyhigh
= ddesc
.ddckCKDestBlt
.dwColorSpaceHighValue
;
1284 #define COPYBOX_COLORKEY(type) { \
1285 type *d = (type *)dbuf, *s = (type *)sbuf, tmp; \
1286 s = (type *) ((BYTE *) sdesc.u1.lpSurface + (rsrc->top * sdesc.lPitch) + rsrc->left * bpp); \
1287 d = (type *) ((BYTE *) ddesc.u1.lpSurface + (dsty * ddesc.lPitch) + dstx * bpp); \
1288 for (y = 0; y < h; y++) { \
1289 for (x = 0; x < w; x++) { \
1291 if (tmp < keylow || tmp > keyhigh) d[x] = tmp; \
1293 (LPBYTE)s += sdesc.lPitch; \
1294 (LPBYTE)d += ddesc.lPitch; \
1300 case 1: COPYBOX_COLORKEY(BYTE
)
1301 case 2: COPYBOX_COLORKEY(WORD
)
1302 case 4: COPYBOX_COLORKEY(DWORD
)
1304 FIXME("Source color key blitting not supported for bpp %d\n", bpp
*8);
1305 ret
= DDERR_UNSUPPORTED
;
1309 #undef COPYBOX_COLORKEY
1312 int width
= w
* bpp
;
1314 for (y
= 0; y
< h
; y
++) {
1315 memcpy(dbuf
, sbuf
, width
);
1316 sbuf
+= sdesc
.lPitch
;
1317 dbuf
+= ddesc
.lPitch
;
1323 IDirectDrawSurface4_Unlock(iface
,ddesc
.u1
.lpSurface
);
1324 IDirectDrawSurface4_Unlock(src
,sdesc
.u1
.lpSurface
);
1328 static HRESULT WINAPI
IDirectDrawSurface4Impl_BltBatch(
1329 LPDIRECTDRAWSURFACE4 iface
,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
1331 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1332 FIXME("(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
1338 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetCaps(
1339 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS caps
1341 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1342 TRACE("(%p)->GetCaps(%p)\n",This
,caps
);
1343 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
1347 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetSurfaceDesc(
1348 LPDIRECTDRAWSURFACE4 iface
,LPDDSURFACEDESC ddsd
1350 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1351 TRACE("(%p)->GetSurfaceDesc(%p)\n", This
,ddsd
);
1353 /* Simply copy the surface description stored in the object */
1354 *ddsd
= This
->s
.surface_desc
;
1356 if (TRACE_ON(ddraw
)) { _dump_surface_desc(ddsd
); }
1361 static ULONG WINAPI
IDirectDrawSurface4Impl_AddRef(LPDIRECTDRAWSURFACE4 iface
) {
1362 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1363 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
1364 return ++(This
->ref
);
1367 #ifdef HAVE_LIBXXF86DGA
1368 static ULONG WINAPI
DGA_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1369 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1371 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1376 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1377 /* clear out of surface list */
1378 if (This
->t
.dga
.fb_height
== -1)
1379 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1381 This
->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(This
->t
.dga
.fb_height
/This
->s
.ddraw
->e
.dga
.fb_height
));
1383 /* Free the DIBSection (if any) */
1384 if (This
->s
.hdc
!= 0) {
1385 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1386 DeleteDC(This
->s
.hdc
);
1387 DeleteObject(This
->s
.DIBsection
);
1390 HeapFree(GetProcessHeap(),0,This
);
1393 #endif /* defined(HAVE_LIBXXF86DGA) */
1395 static ULONG WINAPI
Xlib_IDirectDrawSurface4Impl_Release(LPDIRECTDRAWSURFACE4 iface
) {
1396 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1398 TRACE( "(%p)->() decrementing from %lu.\n", This
, This
->ref
);
1403 IDirectDraw2_Release((IDirectDraw2
*)This
->s
.ddraw
);
1405 if (This
->t
.xlib
.image
!= NULL
) {
1406 if (This
->s
.ddraw
->d
.pixel_convert
!= NULL
) {
1407 /* In pixel conversion mode, there are 2 buffers to release. */
1408 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1410 #ifdef HAVE_LIBXXSHM
1411 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1412 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1413 TSXDestroyImage(This
->t
.xlib
.image
);
1414 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1417 HeapFree(GetProcessHeap(),0,This
->t
.xlib
.image
->data
);
1418 This
->t
.xlib
.image
->data
= NULL
;
1419 TSXDestroyImage(This
->t
.xlib
.image
);
1420 #ifdef HAVE_LIBXXSHM
1424 This
->t
.xlib
.image
->data
= NULL
;
1426 #ifdef HAVE_LIBXXSHM
1427 if (This
->s
.ddraw
->e
.xlib
.xshm_active
) {
1428 TSXShmDetach(display
, &(This
->t
.xlib
.shminfo
));
1429 TSXDestroyImage(This
->t
.xlib
.image
);
1430 shmdt(This
->t
.xlib
.shminfo
.shmaddr
);
1433 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1434 TSXDestroyImage(This
->t
.xlib
.image
);
1435 #ifdef HAVE_LIBXXSHM
1439 This
->t
.xlib
.image
= 0;
1441 HeapFree(GetProcessHeap(),0,This
->s
.surface_desc
.u1
.lpSurface
);
1444 if (This
->s
.palette
)
1445 IDirectDrawPalette_Release((IDirectDrawPalette
*)This
->s
.palette
);
1447 /* Free the DIBSection (if any) */
1448 if (This
->s
.hdc
!= 0) {
1449 SelectObject(This
->s
.hdc
, This
->s
.holdbitmap
);
1450 DeleteDC(This
->s
.hdc
);
1451 DeleteObject(This
->s
.DIBsection
);
1454 HeapFree(GetProcessHeap(),0,This
);
1458 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetAttachedSurface(
1459 LPDIRECTDRAWSURFACE4 iface
,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1461 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1462 int i
,found
= 0,xstart
;
1463 struct _surface_chain
*chain
;
1465 TRACE("(%p)->GetAttachedSurface(%p,%p)\n", This
, lpddsd
, lpdsf
);
1466 if (TRACE_ON(ddraw
)) {
1467 TRACE(" caps ");_dump_DDSCAPS((void *) &(lpddsd
->dwCaps
));
1469 chain
= This
->s
.chain
;
1471 return DDERR_NOTFOUND
;
1473 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1474 if (chain
->surfaces
[i
] == This
)
1478 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1479 if ((SDDSCAPS(chain
->surfaces
[(xstart
+i
)%chain
->nrofsurfaces
])&lpddsd
->dwCaps
) == lpddsd
->dwCaps
) {
1481 if (found
) /* may not find the same caps twice, (doc) */
1482 return DDERR_INVALIDPARAMS
;/*FIXME: correct? */
1484 found
= (i
+1)+xstart
;
1488 return DDERR_NOTFOUND
;
1489 *lpdsf
= (LPDIRECTDRAWSURFACE4
)chain
->surfaces
[found
-1-xstart
];
1490 /* FIXME: AddRef? */
1491 TRACE("found %p\n",*lpdsf
);
1495 static HRESULT WINAPI
IDirectDrawSurface4Impl_Initialize(
1496 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1498 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1499 TRACE("(%p)->(%p, %p)\n",This
,ddraw
,lpdsfd
);
1501 return DDERR_ALREADYINITIALIZED
;
1504 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPixelFormat(
1505 LPDIRECTDRAWSURFACE4 iface
,LPDDPIXELFORMAT pf
1507 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1508 TRACE("(%p)->(%p)\n",This
,pf
);
1510 *pf
= This
->s
.surface_desc
.ddpfPixelFormat
;
1511 if (TRACE_ON(ddraw
)) { _dump_pixelformat(pf
); DPRINTF("\n"); }
1515 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetBltStatus(LPDIRECTDRAWSURFACE4 iface
,DWORD dwFlags
) {
1516 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1517 FIXME("(%p)->(0x%08lx),stub!\n",This
,dwFlags
);
1521 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetOverlayPosition(
1522 LPDIRECTDRAWSURFACE4 iface
,LPLONG x1
,LPLONG x2
1524 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1525 FIXME("(%p)->(%p,%p),stub!\n",This
,x1
,x2
);
1529 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetClipper(
1530 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWCLIPPER clipper
1532 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1533 FIXME("(%p)->(%p),stub!\n",This
,clipper
);
1537 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddAttachedSurface(
1538 LPDIRECTDRAWSURFACE4 iface
,LPDIRECTDRAWSURFACE4 surf
1540 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1541 IDirectDrawSurface4Impl
*isurf
= (IDirectDrawSurface4Impl
*)surf
;
1543 struct _surface_chain
*chain
;
1545 IDirectDrawSurface4_AddRef(iface
);
1547 FIXME("(%p)->(%p)\n",This
,surf
);
1548 chain
= This
->s
.chain
;
1551 for (i
=0;i
<chain
->nrofsurfaces
;i
++)
1552 if (chain
->surfaces
[i
] == isurf
)
1553 FIXME("attaching already attached surface %p to %p!\n",iface
,isurf
);
1555 chain
= HeapAlloc(GetProcessHeap(),0,sizeof(*chain
));
1556 chain
->nrofsurfaces
= 1;
1557 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1558 chain
->surfaces
[0] = This
;
1559 This
->s
.chain
= chain
;
1562 if (chain
->surfaces
)
1563 chain
->surfaces
= HeapReAlloc(
1567 sizeof(chain
->surfaces
[0])*(chain
->nrofsurfaces
+1)
1570 chain
->surfaces
= HeapAlloc(GetProcessHeap(),0,sizeof(chain
->surfaces
[0]));
1571 isurf
->s
.chain
= chain
;
1572 chain
->surfaces
[chain
->nrofsurfaces
++] = isurf
;
1576 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDC(LPDIRECTDRAWSURFACE4 iface
,HDC
* lphdc
) {
1577 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1582 FIXME("(%p)->GetDC(%p)\n",This
,lphdc
);
1584 /* Creates a DIB Section of the same size / format as the surface */
1585 IDirectDrawSurface4_Lock(iface
,NULL
,&desc
,0,0);
1587 if (This
->s
.hdc
== 0) {
1588 switch (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
) {
1591 #if 0 /* This should be filled if Wine's DIBSection did understand BI_BITFIELDS */
1592 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
) + 3 * sizeof(DWORD
));
1597 b_info
= (BITMAPINFO
*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BITMAPINFOHEADER
));
1601 b_info
= (BITMAPINFO
*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
,
1602 sizeof(BITMAPINFOHEADER
) + sizeof(RGBQUAD
) * (2 << desc
.ddpfPixelFormat
.u
.dwRGBBitCount
));
1606 b_info
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
1607 b_info
->bmiHeader
.biWidth
= desc
.dwWidth
;
1608 b_info
->bmiHeader
.biHeight
= desc
.dwHeight
;
1609 b_info
->bmiHeader
.biPlanes
= 1;
1610 b_info
->bmiHeader
.biBitCount
= desc
.ddpfPixelFormat
.u
.dwRGBBitCount
;
1612 if ((desc
.ddpfPixelFormat
.u
.dwRGBBitCount
!= 16) &&
1613 (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
!= 32))
1615 b_info
->bmiHeader
.biCompression
= BI_RGB
;
1618 b_info
->bmiHeader
.biCompression
= BI_BITFIELDS
;
1620 b_info
->bmiHeader
.biSizeImage
= (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
/ 8) * desc
.dwWidth
* desc
.dwHeight
;
1621 b_info
->bmiHeader
.biXPelsPerMeter
= 0;
1622 b_info
->bmiHeader
.biYPelsPerMeter
= 0;
1623 b_info
->bmiHeader
.biClrUsed
= 0;
1624 b_info
->bmiHeader
.biClrImportant
= 0;
1626 switch (desc
.ddpfPixelFormat
.u
.dwRGBBitCount
) {
1631 DWORD
*masks
= (DWORD
*) &(b_info
->bmiColors
);
1634 masks
[0] = desc
.ddpfPixelFormat
.u1
.dwRBitMask
;
1635 masks
[1] = desc
.ddpfPixelFormat
.u2
.dwGBitMask
;
1636 masks
[2] = desc
.ddpfPixelFormat
.u3
.dwBBitMask
;
1642 usage
= DIB_RGB_COLORS
;
1648 /* Fill the palette */
1649 usage
= DIB_RGB_COLORS
;
1651 if (This
->s
.palette
== NULL
) {
1652 ERR("Bad palette !!!\n");
1654 RGBQUAD
*rgb
= (RGBQUAD
*) &(b_info
->bmiColors
);
1655 PALETTEENTRY
*pent
= (PALETTEENTRY
*)&(This
->s
.palette
->palents
);
1657 for (i
=0;i
<(1<<desc
.ddpfPixelFormat
.u
.dwRGBBitCount
);i
++) {
1658 rgb
[i
].rgbBlue
= pent
[i
].peBlue
;
1659 rgb
[i
].rgbRed
= pent
[i
].peRed
;
1660 rgb
[i
].rgbGreen
= pent
[i
].peGreen
;
1666 This
->s
.DIBsection
= CreateDIBSection(BeginPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
),
1669 &(This
->s
.bitmap_data
),
1673 EndPaint(This
->s
.ddraw
->d
.mainWindow
,&This
->s
.ddraw
->d
.ps
);
1674 TRACE("DIBSection at : %p\n", This
->s
.bitmap_data
);
1676 /* b_info is not useful anymore */
1677 HeapFree(GetProcessHeap(), 0, b_info
);
1680 This
->s
.hdc
= CreateCompatibleDC(0);
1681 This
->s
.holdbitmap
= SelectObject(This
->s
.hdc
, This
->s
.DIBsection
);
1684 /* Copy our surface in the DIB section */
1685 if ((GET_BPP(desc
) * desc
.dwWidth
) == desc
.lPitch
)
1686 memcpy(This
->s
.bitmap_data
,desc
.u1
.lpSurface
,desc
.lPitch
*desc
.dwHeight
);
1689 FIXME("This case has to be done :/\n");
1691 TRACE("HDC : %08lx\n", (DWORD
) This
->s
.hdc
);
1692 *lphdc
= This
->s
.hdc
;
1697 static HRESULT WINAPI
IDirectDrawSurface4Impl_ReleaseDC(LPDIRECTDRAWSURFACE4 iface
,HDC hdc
) {
1698 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1700 FIXME("(%p)->(0x%08lx),stub!\n",This
,(long)hdc
);
1701 TRACE( "Copying DIBSection at : %p\n", This
->s
.bitmap_data
);
1702 /* Copy the DIB section to our surface */
1703 if ((GET_BPP(This
->s
.surface_desc
) * This
->s
.surface_desc
.dwWidth
) == This
->s
.surface_desc
.lPitch
) {
1704 memcpy(This
->s
.surface_desc
.u1
.lpSurface
, This
->s
.bitmap_data
, This
->s
.surface_desc
.lPitch
* This
->s
.surface_desc
.dwHeight
);
1707 FIXME("This case has to be done :/\n");
1709 /* Unlock the surface */
1710 IDirectDrawSurface4_Unlock(iface
,This
->s
.surface_desc
.u1
.lpSurface
);
1714 static HRESULT WINAPI
IDirectDrawSurface4Impl_QueryInterface(LPDIRECTDRAWSURFACE4 iface
,REFIID refiid
,LPVOID
*obj
) {
1715 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1718 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1719 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
1721 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1722 * the same interface. And IUnknown does that too of course.
1724 if ( IsEqualGUID( &IID_IDirectDrawSurface4
, refiid
) ||
1725 IsEqualGUID( &IID_IDirectDrawSurface3
, refiid
) ||
1726 IsEqualGUID( &IID_IDirectDrawSurface2
, refiid
) ||
1727 IsEqualGUID( &IID_IDirectDrawSurface
, refiid
) ||
1728 IsEqualGUID( &IID_IUnknown
, refiid
)
1731 IDirectDrawSurface4_AddRef(iface
);
1733 TRACE(" Creating IDirectDrawSurface interface (%p)\n", *obj
);
1736 else if ( IsEqualGUID( &IID_IDirect3DTexture2
, refiid
) )
1738 /* Texture interface */
1739 *obj
= d3dtexture2_create(This
);
1740 IDirectDrawSurface4_AddRef(iface
);
1741 TRACE(" Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1744 else if ( IsEqualGUID( &IID_IDirect3DTexture
, refiid
) )
1746 /* Texture interface */
1747 *obj
= d3dtexture_create(This
);
1748 IDirectDrawSurface4_AddRef(iface
);
1750 TRACE(" Creating IDirect3DTexture interface (%p)\n", *obj
);
1754 else if (is_OpenGL_dx3(refiid
, (IDirectDrawSurfaceImpl
*)This
, (IDirect3DDeviceImpl
**) obj
)) {
1755 /* It is the OpenGL Direct3D Device */
1756 IDirectDrawSurface4_AddRef(iface
);
1757 TRACE(" Creating IDirect3DDevice interface (%p)\n", *obj
);
1761 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
1762 return OLE_E_ENUM_NOMORE
;
1765 static HRESULT WINAPI
IDirectDrawSurface4Impl_IsLost(LPDIRECTDRAWSURFACE4 iface
) {
1766 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1767 TRACE("(%p)->(), stub!\n",This
);
1768 return DD_OK
; /* hmm */
1771 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4 iface
,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1772 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1774 struct _surface_chain
*chain
= This
->s
.chain
;
1776 TRACE("(%p)->(%p,%p)\n",This
,context
,esfcb
);
1777 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1778 TRACE( "Enumerating attached surface (%p)\n", chain
->surfaces
[i
]);
1779 if (esfcb((LPDIRECTDRAWSURFACE
) chain
->surfaces
[i
], &(chain
->surfaces
[i
]->s
.surface_desc
), context
) == DDENUMRET_CANCEL
)
1780 return DD_OK
; /* FIXME: return value correct? */
1785 static HRESULT WINAPI
IDirectDrawSurface4Impl_Restore(LPDIRECTDRAWSURFACE4 iface
) {
1786 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1787 FIXME("(%p)->(),stub!\n",This
);
1791 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetColorKey(
1792 LPDIRECTDRAWSURFACE4 iface
, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1794 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1795 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,ckey
);
1796 if (TRACE_ON(ddraw
)) {
1797 _dump_colorkeyflag(dwFlags
);
1799 _dump_DDCOLORKEY((void *) ckey
);
1803 /* If this surface was loaded as a texture, call also the texture
1804 SetColorKey callback */
1805 if (This
->s
.texture
) {
1806 This
->s
.SetColorKey_cb(This
->s
.texture
, dwFlags
, ckey
);
1809 if( dwFlags
& DDCKEY_SRCBLT
)
1811 dwFlags
&= ~DDCKEY_SRCBLT
;
1812 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1813 memcpy( &(This
->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1816 if( dwFlags
& DDCKEY_DESTBLT
)
1818 dwFlags
&= ~DDCKEY_DESTBLT
;
1819 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1820 memcpy( &(This
->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1823 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1825 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1826 This
->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1827 memcpy( &(This
->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1830 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1832 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1833 This
->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1834 memcpy( &(This
->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1839 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
1846 static HRESULT WINAPI
IDirectDrawSurface4Impl_AddOverlayDirtyRect(
1847 LPDIRECTDRAWSURFACE4 iface
,
1850 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1851 FIXME("(%p)->(%p),stub!\n",This
,lpRect
);
1856 static HRESULT WINAPI
IDirectDrawSurface4Impl_DeleteAttachedSurface(
1857 LPDIRECTDRAWSURFACE4 iface
,
1859 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
1861 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1863 struct _surface_chain
*chain
;
1865 TRACE("(%p)->(0x%08lx,%p)\n",This
,dwFlags
,lpDDSAttachedSurface
);
1866 chain
= This
->s
.chain
;
1867 for (i
=0;i
<chain
->nrofsurfaces
;i
++) {
1868 if ((IDirectDrawSurface4Impl
*)lpDDSAttachedSurface
==chain
->surfaces
[i
]){
1869 IDirectDrawSurface4_Release(lpDDSAttachedSurface
);
1871 chain
->surfaces
[i
]->s
.chain
= NULL
;
1872 memcpy( chain
->surfaces
+i
,
1873 chain
->surfaces
+(i
+1),
1874 (chain
->nrofsurfaces
-i
-1)*sizeof(chain
->surfaces
[i
])
1876 chain
->surfaces
= HeapReAlloc(
1880 sizeof(chain
->surfaces
[i
])*(chain
->nrofsurfaces
-1)
1882 chain
->nrofsurfaces
--;
1889 static HRESULT WINAPI
IDirectDrawSurface4Impl_EnumOverlayZOrders(
1890 LPDIRECTDRAWSURFACE4 iface
,
1893 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1895 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1896 FIXME("(%p)->(0x%08lx,%p,%p),stub!\n", This
,dwFlags
,
1897 lpContext
, lpfnCallback
);
1902 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetClipper(
1903 LPDIRECTDRAWSURFACE4 iface
,
1904 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1906 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1907 FIXME("(%p)->(%p),stub!\n", This
, lplpDDClipper
);
1912 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetColorKey(
1913 LPDIRECTDRAWSURFACE4 iface
,
1915 LPDDCOLORKEY lpDDColorKey
)
1917 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1918 TRACE("(%p)->(0x%08lx,%p)\n", This
, dwFlags
, lpDDColorKey
);
1920 if( dwFlags
& DDCKEY_SRCBLT
) {
1921 dwFlags
&= ~DDCKEY_SRCBLT
;
1922 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
1925 if( dwFlags
& DDCKEY_DESTBLT
)
1927 dwFlags
&= ~DDCKEY_DESTBLT
;
1928 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
1931 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1933 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1934 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
1937 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1939 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1940 memcpy( lpDDColorKey
, &(This
->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
1945 FIXME("unhandled dwFlags: 0x%08lx\n", dwFlags
);
1951 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetFlipStatus(
1952 LPDIRECTDRAWSURFACE4 iface
,
1955 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1956 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
1961 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPalette(
1962 LPDIRECTDRAWSURFACE4 iface
,
1963 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1965 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1966 FIXME("(%p)->(%p),stub!\n", This
, lplpDDPalette
);
1971 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetOverlayPosition(
1972 LPDIRECTDRAWSURFACE4 iface
,
1976 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1977 FIXME("(%p)->(%ld,%ld),stub!\n", This
, lX
, lY
);
1982 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlay(
1983 LPDIRECTDRAWSURFACE4 iface
,
1985 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
1988 LPDDOVERLAYFX lpDDOverlayFx
)
1990 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
1991 FIXME("(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", This
,
1992 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1997 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayDisplay(
1998 LPDIRECTDRAWSURFACE4 iface
,
2001 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2002 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2007 static HRESULT WINAPI
IDirectDrawSurface4Impl_UpdateOverlayZOrder(
2008 LPDIRECTDRAWSURFACE4 iface
,
2010 LPDIRECTDRAWSURFACE4 lpDDSReference
)
2012 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2013 FIXME("(%p)->(0x%08lx,%p),stub!\n", This
, dwFlags
, lpDDSReference
);
2018 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetDDInterface(
2019 LPDIRECTDRAWSURFACE4 iface
,
2022 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2023 FIXME("(%p)->(%p),stub!\n", This
, lplpDD
);
2025 /* Not sure about that... */
2026 *lplpDD
= (void *) This
->s
.ddraw
;
2031 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageLock(
2032 LPDIRECTDRAWSURFACE4 iface
,
2035 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2036 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2041 static HRESULT WINAPI
IDirectDrawSurface4Impl_PageUnlock(
2042 LPDIRECTDRAWSURFACE4 iface
,
2045 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2046 FIXME("(%p)->(0x%08lx),stub!\n", This
, dwFlags
);
2051 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetSurfaceDesc(
2052 LPDIRECTDRAWSURFACE4 iface
,
2053 LPDDSURFACEDESC lpDDSD
,
2056 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2057 FIXME("(%p)->(%p,0x%08lx),stub!\n", This
, lpDDSD
, dwFlags
);
2062 static HRESULT WINAPI
IDirectDrawSurface4Impl_SetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2067 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2068 FIXME("(%p)->(%p,%p,%ld,%08lx\n", This
, guidTag
, lpData
, cbSize
, dwFlags
);
2073 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetPrivateData(LPDIRECTDRAWSURFACE4 iface
,
2076 LPDWORD lpcbBufferSize
) {
2077 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2078 FIXME("(%p)->(%p,%p,%p)\n", This
, guidTag
, lpBuffer
, lpcbBufferSize
);
2083 static HRESULT WINAPI
IDirectDrawSurface4Impl_FreePrivateData(LPDIRECTDRAWSURFACE4 iface
,
2085 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2086 FIXME("(%p)->(%p)\n", This
, guidTag
);
2091 static HRESULT WINAPI
IDirectDrawSurface4Impl_GetUniquenessValue(LPDIRECTDRAWSURFACE4 iface
,
2093 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2094 FIXME("(%p)->(%p)\n", This
, lpValue
);
2099 static HRESULT WINAPI
IDirectDrawSurface4Impl_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4 iface
) {
2100 ICOM_THIS(IDirectDrawSurface4Impl
,iface
);
2101 FIXME("(%p)\n", This
);
2106 #ifdef HAVE_LIBXXF86DGA
2107 static ICOM_VTABLE(IDirectDrawSurface4
) dga_dds4vt
=
2109 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2110 IDirectDrawSurface4Impl_QueryInterface
,
2111 IDirectDrawSurface4Impl_AddRef
,
2112 DGA_IDirectDrawSurface4Impl_Release
,
2113 IDirectDrawSurface4Impl_AddAttachedSurface
,
2114 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2115 IDirectDrawSurface4Impl_Blt
,
2116 IDirectDrawSurface4Impl_BltBatch
,
2117 IDirectDrawSurface4Impl_BltFast
,
2118 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2119 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2120 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2121 DGA_IDirectDrawSurface4Impl_Flip
,
2122 IDirectDrawSurface4Impl_GetAttachedSurface
,
2123 IDirectDrawSurface4Impl_GetBltStatus
,
2124 IDirectDrawSurface4Impl_GetCaps
,
2125 IDirectDrawSurface4Impl_GetClipper
,
2126 IDirectDrawSurface4Impl_GetColorKey
,
2127 IDirectDrawSurface4Impl_GetDC
,
2128 IDirectDrawSurface4Impl_GetFlipStatus
,
2129 IDirectDrawSurface4Impl_GetOverlayPosition
,
2130 IDirectDrawSurface4Impl_GetPalette
,
2131 IDirectDrawSurface4Impl_GetPixelFormat
,
2132 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2133 IDirectDrawSurface4Impl_Initialize
,
2134 IDirectDrawSurface4Impl_IsLost
,
2135 IDirectDrawSurface4Impl_Lock
,
2136 IDirectDrawSurface4Impl_ReleaseDC
,
2137 IDirectDrawSurface4Impl_Restore
,
2138 IDirectDrawSurface4Impl_SetClipper
,
2139 IDirectDrawSurface4Impl_SetColorKey
,
2140 IDirectDrawSurface4Impl_SetOverlayPosition
,
2141 DGA_IDirectDrawSurface4Impl_SetPalette
,
2142 DGA_IDirectDrawSurface4Impl_Unlock
,
2143 IDirectDrawSurface4Impl_UpdateOverlay
,
2144 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2145 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2146 IDirectDrawSurface4Impl_GetDDInterface
,
2147 IDirectDrawSurface4Impl_PageLock
,
2148 IDirectDrawSurface4Impl_PageUnlock
,
2149 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2150 IDirectDrawSurface4Impl_SetPrivateData
,
2151 IDirectDrawSurface4Impl_GetPrivateData
,
2152 IDirectDrawSurface4Impl_FreePrivateData
,
2153 IDirectDrawSurface4Impl_GetUniquenessValue
,
2154 IDirectDrawSurface4Impl_ChangeUniquenessValue
2156 #endif /* defined(HAVE_LIBXXF86DGA) */
2158 static ICOM_VTABLE(IDirectDrawSurface4
) xlib_dds4vt
=
2160 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2161 IDirectDrawSurface4Impl_QueryInterface
,
2162 IDirectDrawSurface4Impl_AddRef
,
2163 Xlib_IDirectDrawSurface4Impl_Release
,
2164 IDirectDrawSurface4Impl_AddAttachedSurface
,
2165 IDirectDrawSurface4Impl_AddOverlayDirtyRect
,
2166 IDirectDrawSurface4Impl_Blt
,
2167 IDirectDrawSurface4Impl_BltBatch
,
2168 IDirectDrawSurface4Impl_BltFast
,
2169 IDirectDrawSurface4Impl_DeleteAttachedSurface
,
2170 IDirectDrawSurface4Impl_EnumAttachedSurfaces
,
2171 IDirectDrawSurface4Impl_EnumOverlayZOrders
,
2172 Xlib_IDirectDrawSurface4Impl_Flip
,
2173 IDirectDrawSurface4Impl_GetAttachedSurface
,
2174 IDirectDrawSurface4Impl_GetBltStatus
,
2175 IDirectDrawSurface4Impl_GetCaps
,
2176 IDirectDrawSurface4Impl_GetClipper
,
2177 IDirectDrawSurface4Impl_GetColorKey
,
2178 IDirectDrawSurface4Impl_GetDC
,
2179 IDirectDrawSurface4Impl_GetFlipStatus
,
2180 IDirectDrawSurface4Impl_GetOverlayPosition
,
2181 IDirectDrawSurface4Impl_GetPalette
,
2182 IDirectDrawSurface4Impl_GetPixelFormat
,
2183 IDirectDrawSurface4Impl_GetSurfaceDesc
,
2184 IDirectDrawSurface4Impl_Initialize
,
2185 IDirectDrawSurface4Impl_IsLost
,
2186 IDirectDrawSurface4Impl_Lock
,
2187 IDirectDrawSurface4Impl_ReleaseDC
,
2188 IDirectDrawSurface4Impl_Restore
,
2189 IDirectDrawSurface4Impl_SetClipper
,
2190 IDirectDrawSurface4Impl_SetColorKey
,
2191 IDirectDrawSurface4Impl_SetOverlayPosition
,
2192 Xlib_IDirectDrawSurface4Impl_SetPalette
,
2193 Xlib_IDirectDrawSurface4Impl_Unlock
,
2194 IDirectDrawSurface4Impl_UpdateOverlay
,
2195 IDirectDrawSurface4Impl_UpdateOverlayDisplay
,
2196 IDirectDrawSurface4Impl_UpdateOverlayZOrder
,
2197 IDirectDrawSurface4Impl_GetDDInterface
,
2198 IDirectDrawSurface4Impl_PageLock
,
2199 IDirectDrawSurface4Impl_PageUnlock
,
2200 IDirectDrawSurface4Impl_SetSurfaceDesc
,
2201 IDirectDrawSurface4Impl_SetPrivateData
,
2202 IDirectDrawSurface4Impl_GetPrivateData
,
2203 IDirectDrawSurface4Impl_FreePrivateData
,
2204 IDirectDrawSurface4Impl_GetUniquenessValue
,
2205 IDirectDrawSurface4Impl_ChangeUniquenessValue
2208 /******************************************************************************
2209 * DirectDrawCreateClipper (DDRAW.7)
2211 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
2212 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
2213 LPUNKNOWN pUnkOuter
)
2215 IDirectDrawClipperImpl
** ilplpDDClipper
=(IDirectDrawClipperImpl
**)lplpDDClipper
;
2216 TRACE("(%08lx,%p,%p)\n", dwFlags
, ilplpDDClipper
, pUnkOuter
);
2218 *ilplpDDClipper
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
2219 ICOM_VTBL(*ilplpDDClipper
) = &ddclipvt
;
2220 (*ilplpDDClipper
)->ref
= 1;
2225 /******************************************************************************
2226 * IDirectDrawClipper
2228 static HRESULT WINAPI
IDirectDrawClipperImpl_SetHwnd(
2229 LPDIRECTDRAWCLIPPER iface
,DWORD x
,HWND hwnd
2231 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2232 FIXME("(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",This
,x
,(DWORD
)hwnd
);
2236 static ULONG WINAPI
IDirectDrawClipperImpl_Release(LPDIRECTDRAWCLIPPER iface
) {
2237 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2238 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2243 HeapFree(GetProcessHeap(),0,This
);
2247 static HRESULT WINAPI
IDirectDrawClipperImpl_GetClipList(
2248 LPDIRECTDRAWCLIPPER iface
,LPRECT rects
,LPRGNDATA lprgn
,LPDWORD hmm
2250 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2251 FIXME("(%p,%p,%p,%p),stub!\n",This
,rects
,lprgn
,hmm
);
2256 static HRESULT WINAPI
IDirectDrawClipperImpl_SetClipList(
2257 LPDIRECTDRAWCLIPPER iface
,LPRGNDATA lprgn
,DWORD hmm
2259 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2260 FIXME("(%p,%p,%ld),stub!\n",This
,lprgn
,hmm
);
2264 static HRESULT WINAPI
IDirectDrawClipperImpl_QueryInterface(
2265 LPDIRECTDRAWCLIPPER iface
,
2269 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2270 FIXME("(%p)->(%p,%p),stub!\n",This
,riid
,ppvObj
);
2271 return OLE_E_ENUM_NOMORE
;
2274 static ULONG WINAPI
IDirectDrawClipperImpl_AddRef( LPDIRECTDRAWCLIPPER iface
)
2276 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2277 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2278 return ++(This
->ref
);
2281 static HRESULT WINAPI
IDirectDrawClipperImpl_GetHWnd(
2282 LPDIRECTDRAWCLIPPER iface
,
2285 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2286 FIXME("(%p)->(%p),stub!\n",This
,HWndPtr
);
2290 static HRESULT WINAPI
IDirectDrawClipperImpl_Initialize(
2291 LPDIRECTDRAWCLIPPER iface
,
2295 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2296 FIXME("(%p)->(%p,0x%08lx),stub!\n",This
,lpDD
,dwFlags
);
2300 static HRESULT WINAPI
IDirectDrawClipperImpl_IsClipListChanged(
2301 LPDIRECTDRAWCLIPPER iface
,
2304 ICOM_THIS(IDirectDrawClipperImpl
,iface
);
2305 FIXME("(%p)->(%p),stub!\n",This
,lpbChanged
);
2309 static ICOM_VTABLE(IDirectDrawClipper
) ddclipvt
=
2311 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2312 IDirectDrawClipperImpl_QueryInterface
,
2313 IDirectDrawClipperImpl_AddRef
,
2314 IDirectDrawClipperImpl_Release
,
2315 IDirectDrawClipperImpl_GetClipList
,
2316 IDirectDrawClipperImpl_GetHWnd
,
2317 IDirectDrawClipperImpl_Initialize
,
2318 IDirectDrawClipperImpl_IsClipListChanged
,
2319 IDirectDrawClipperImpl_SetClipList
,
2320 IDirectDrawClipperImpl_SetHwnd
2324 /******************************************************************************
2325 * IDirectDrawPalette
2327 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetEntries(
2328 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2330 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2333 TRACE("(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
2334 This
,x
,start
,count
,palent
);
2336 /* No palette created and not in depth-convertion mode -> BUG ! */
2337 if ((This
->cm
== None
) &&
2338 (This
->ddraw
->d
.palette_convert
== NULL
))
2340 FIXME("app tried to read colormap for non-palettized mode\n");
2341 return DDERR_GENERIC
;
2343 for (i
=0;i
<count
;i
++) {
2344 palent
[i
].peRed
= This
->palents
[start
+i
].peRed
;
2345 palent
[i
].peBlue
= This
->palents
[start
+i
].peBlue
;
2346 palent
[i
].peGreen
= This
->palents
[start
+i
].peGreen
;
2347 palent
[i
].peFlags
= This
->palents
[start
+i
].peFlags
;
2353 static HRESULT WINAPI
Xlib_IDirectDrawPaletteImpl_SetEntries(
2354 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2356 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2360 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2361 This
,x
,start
,count
,palent
2363 for (i
=0;i
<count
;i
++) {
2364 xc
.red
= palent
[i
].peRed
<<8;
2365 xc
.blue
= palent
[i
].peBlue
<<8;
2366 xc
.green
= palent
[i
].peGreen
<<8;
2367 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2371 TSXStoreColor(display
,This
->cm
,&xc
);
2373 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2374 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2375 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2376 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2379 /* Now, if we are in 'depth conversion mode', update the screen palette */
2380 /* FIXME: we need to update the image or we won't get palette fading. */
2381 if (This
->ddraw
->d
.palette_convert
!= NULL
)
2382 This
->ddraw
->d
.palette_convert(palent
, This
->screen_palents
, start
, count
);
2387 #ifdef HAVE_LIBXXF86DGA
2388 static HRESULT WINAPI
DGA_IDirectDrawPaletteImpl_SetEntries(
2389 LPDIRECTDRAWPALETTE iface
,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
2391 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2396 TRACE("(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
2397 This
,x
,start
,count
,palent
2399 if (!This
->cm
) /* should not happen */ {
2400 FIXME("app tried to set colormap in non-palettized mode\n");
2401 return DDERR_GENERIC
;
2403 /* FIXME: free colorcells instead of freeing whole map */
2405 This
->cm
= TSXCopyColormapAndFree(display
,This
->cm
);
2406 TSXFreeColormap(display
,cm
);
2408 for (i
=0;i
<count
;i
++) {
2409 xc
.red
= palent
[i
].peRed
<<8;
2410 xc
.blue
= palent
[i
].peBlue
<<8;
2411 xc
.green
= palent
[i
].peGreen
<<8;
2412 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2415 TSXStoreColor(display
,This
->cm
,&xc
);
2417 This
->palents
[start
+i
].peRed
= palent
[i
].peRed
;
2418 This
->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
2419 This
->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
2420 This
->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
2422 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),This
->cm
);
2425 #endif /* defined(HAVE_LIBXXF86DGA) */
2427 static ULONG WINAPI
IDirectDrawPaletteImpl_Release(LPDIRECTDRAWPALETTE iface
) {
2428 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2429 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2430 if (!--(This
->ref
)) {
2432 TSXFreeColormap(display
,This
->cm
);
2435 HeapFree(GetProcessHeap(),0,This
);
2441 static ULONG WINAPI
IDirectDrawPaletteImpl_AddRef(LPDIRECTDRAWPALETTE iface
) {
2442 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2444 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2445 return ++(This
->ref
);
2448 static HRESULT WINAPI
IDirectDrawPaletteImpl_Initialize(
2449 LPDIRECTDRAWPALETTE iface
,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
2451 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2452 TRACE("(%p)->(%p,%ld,%p)\n", This
, ddraw
, x
, palent
);
2454 return DDERR_ALREADYINITIALIZED
;
2457 static HRESULT WINAPI
IDirectDrawPaletteImpl_GetCaps(
2458 LPDIRECTDRAWPALETTE iface
, LPDWORD lpdwCaps
)
2460 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2461 FIXME("(%p)->(%p) stub.\n", This
, lpdwCaps
);
2465 static HRESULT WINAPI
IDirectDrawPaletteImpl_QueryInterface(
2466 LPDIRECTDRAWPALETTE iface
,REFIID refiid
,LPVOID
*obj
)
2468 ICOM_THIS(IDirectDrawPaletteImpl
,iface
);
2471 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2472 FIXME("(%p)->(%s,%p) stub.\n",This
,xrefiid
,obj
);
2477 #ifdef HAVE_LIBXXF86DGA
2478 static ICOM_VTABLE(IDirectDrawPalette
) dga_ddpalvt
=
2480 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2481 IDirectDrawPaletteImpl_QueryInterface
,
2482 IDirectDrawPaletteImpl_AddRef
,
2483 IDirectDrawPaletteImpl_Release
,
2484 IDirectDrawPaletteImpl_GetCaps
,
2485 IDirectDrawPaletteImpl_GetEntries
,
2486 IDirectDrawPaletteImpl_Initialize
,
2487 DGA_IDirectDrawPaletteImpl_SetEntries
2489 #endif /* defined(HAVE_LIBXXF86DGA) */
2491 static ICOM_VTABLE(IDirectDrawPalette
) xlib_ddpalvt
=
2493 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2494 IDirectDrawPaletteImpl_QueryInterface
,
2495 IDirectDrawPaletteImpl_AddRef
,
2496 IDirectDrawPaletteImpl_Release
,
2497 IDirectDrawPaletteImpl_GetCaps
,
2498 IDirectDrawPaletteImpl_GetEntries
,
2499 IDirectDrawPaletteImpl_Initialize
,
2500 Xlib_IDirectDrawPaletteImpl_SetEntries
2503 /*******************************************************************************
2506 static HRESULT WINAPI
IDirect3DImpl_QueryInterface(
2507 LPDIRECT3D iface
,REFIID refiid
,LPVOID
*obj
2509 ICOM_THIS(IDirect3DImpl
,iface
);
2510 /* FIXME: Not sure if this is correct */
2513 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2514 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
2515 if ( ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) ||
2516 ( IsEqualGUID (&IID_IDirectDraw2
, refiid
) ) ||
2517 ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) ) {
2519 IDirect3D_AddRef(iface
);
2521 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2525 if ( ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) ||
2526 ( IsEqualGUID( &IID_IUnknown
, refiid
) ) ) {
2528 IDirect3D_AddRef(iface
);
2530 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2534 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
2535 IDirect3D2Impl
* d3d
;
2537 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2539 d3d
->ddraw
= This
->ddraw
;
2540 IDirect3D_AddRef(iface
);
2541 ICOM_VTBL(d3d
) = &d3d2vt
;
2544 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2548 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
2549 return OLE_E_ENUM_NOMORE
;
2552 static ULONG WINAPI
IDirect3DImpl_AddRef(LPDIRECT3D iface
) {
2553 ICOM_THIS(IDirect3DImpl
,iface
);
2554 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2556 return ++(This
->ref
);
2559 static ULONG WINAPI
IDirect3DImpl_Release(LPDIRECT3D iface
)
2561 ICOM_THIS(IDirect3DImpl
,iface
);
2562 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2564 if (!--(This
->ref
)) {
2565 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2566 HeapFree(GetProcessHeap(),0,This
);
2572 static HRESULT WINAPI
IDirect3DImpl_Initialize(
2573 LPDIRECT3D iface
, REFIID refiid
)
2575 ICOM_THIS(IDirect3DImpl
,iface
);
2576 /* FIXME: Not sure if this is correct */
2579 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2580 FIXME("(%p)->(%s):stub.\n",This
,xrefiid
);
2582 return DDERR_ALREADYINITIALIZED
;
2585 static HRESULT WINAPI
IDirect3DImpl_EnumDevices(LPDIRECT3D iface
,
2586 LPD3DENUMDEVICESCALLBACK cb
,
2588 ICOM_THIS(IDirect3DImpl
,iface
);
2589 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2591 /* Call functions defined in d3ddevices.c */
2592 if (!d3d_OpenGL_dx3(cb
, context
))
2598 static HRESULT WINAPI
IDirect3DImpl_CreateLight(LPDIRECT3D iface
,
2599 LPDIRECT3DLIGHT
*lplight
,
2602 ICOM_THIS(IDirect3DImpl
,iface
);
2603 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2605 /* Call the creation function that is located in d3dlight.c */
2606 *lplight
= d3dlight_create_dx3(This
);
2611 static HRESULT WINAPI
IDirect3DImpl_CreateMaterial(LPDIRECT3D iface
,
2612 LPDIRECT3DMATERIAL
*lpmaterial
,
2615 ICOM_THIS(IDirect3DImpl
,iface
);
2616 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2618 /* Call the creation function that is located in d3dviewport.c */
2619 *lpmaterial
= d3dmaterial_create(This
);
2624 static HRESULT WINAPI
IDirect3DImpl_CreateViewport(LPDIRECT3D iface
,
2625 LPDIRECT3DVIEWPORT
*lpviewport
,
2628 ICOM_THIS(IDirect3DImpl
,iface
);
2629 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
2631 /* Call the creation function that is located in d3dviewport.c */
2632 *lpviewport
= d3dviewport_create(This
);
2637 static HRESULT WINAPI
IDirect3DImpl_FindDevice(LPDIRECT3D iface
,
2638 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2639 LPD3DFINDDEVICERESULT lpfinddevrst
)
2641 ICOM_THIS(IDirect3DImpl
,iface
);
2642 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
2647 static ICOM_VTABLE(IDirect3D
) d3dvt
=
2649 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2650 IDirect3DImpl_QueryInterface
,
2651 IDirect3DImpl_AddRef
,
2652 IDirect3DImpl_Release
,
2653 IDirect3DImpl_Initialize
,
2654 IDirect3DImpl_EnumDevices
,
2655 IDirect3DImpl_CreateLight
,
2656 IDirect3DImpl_CreateMaterial
,
2657 IDirect3DImpl_CreateViewport
,
2658 IDirect3DImpl_FindDevice
2661 /*******************************************************************************
2664 static HRESULT WINAPI
IDirect3D2Impl_QueryInterface(
2665 LPDIRECT3D2 iface
,REFIID refiid
,LPVOID
*obj
) {
2666 ICOM_THIS(IDirect3D2Impl
,iface
);
2668 /* FIXME: Not sure if this is correct */
2671 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2672 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
2673 if ( ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) ||
2674 ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) ||
2675 ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) ) {
2677 IDirect3D2_AddRef(iface
);
2679 TRACE(" Creating IDirectDrawX interface (%p)\n", *obj
);
2683 if ( ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) ||
2684 ( IsEqualGUID( &IID_IUnknown
, refiid
) ) ) {
2686 IDirect3D2_AddRef(iface
);
2688 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
2692 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
2695 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2697 d3d
->ddraw
= This
->ddraw
;
2698 IDirect3D2_AddRef(iface
);
2699 ICOM_VTBL(d3d
) = &d3dvt
;
2702 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
2706 FIXME("(%p):interface for IID %s NOT found!\n",This
,xrefiid
);
2707 return OLE_E_ENUM_NOMORE
;
2710 static ULONG WINAPI
IDirect3D2Impl_AddRef(LPDIRECT3D2 iface
) {
2711 ICOM_THIS(IDirect3D2Impl
,iface
);
2712 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
2714 return ++(This
->ref
);
2717 static ULONG WINAPI
IDirect3D2Impl_Release(LPDIRECT3D2 iface
) {
2718 ICOM_THIS(IDirect3D2Impl
,iface
);
2719 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
2721 if (!--(This
->ref
)) {
2722 IDirectDraw2_Release((IDirectDraw2
*)This
->ddraw
);
2723 HeapFree(GetProcessHeap(),0,This
);
2729 static HRESULT WINAPI
IDirect3D2Impl_EnumDevices(
2730 LPDIRECT3D2 iface
,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2732 ICOM_THIS(IDirect3D2Impl
,iface
);
2733 FIXME("(%p)->(%p,%p),stub!\n",This
,cb
,context
);
2735 /* Call functions defined in d3ddevices.c */
2736 if (!d3d_OpenGL(cb
, context
))
2742 static HRESULT WINAPI
IDirect3D2Impl_CreateLight(LPDIRECT3D2 iface
,
2743 LPDIRECT3DLIGHT
*lplight
,
2746 ICOM_THIS(IDirect3D2Impl
,iface
);
2747 TRACE("(%p)->(%p,%p): stub\n", This
, lplight
, lpunk
);
2749 /* Call the creation function that is located in d3dlight.c */
2750 *lplight
= d3dlight_create(This
);
2755 static HRESULT WINAPI
IDirect3D2Impl_CreateMaterial(LPDIRECT3D2 iface
,
2756 LPDIRECT3DMATERIAL2
*lpmaterial
,
2759 ICOM_THIS(IDirect3D2Impl
,iface
);
2760 TRACE("(%p)->(%p,%p): stub\n", This
, lpmaterial
, lpunk
);
2762 /* Call the creation function that is located in d3dviewport.c */
2763 *lpmaterial
= d3dmaterial2_create(This
);
2768 static HRESULT WINAPI
IDirect3D2Impl_CreateViewport(LPDIRECT3D2 iface
,
2769 LPDIRECT3DVIEWPORT2
*lpviewport
,
2772 ICOM_THIS(IDirect3D2Impl
,iface
);
2773 TRACE("(%p)->(%p,%p): stub\n", This
, lpviewport
, lpunk
);
2775 /* Call the creation function that is located in d3dviewport.c */
2776 *lpviewport
= d3dviewport2_create(This
);
2781 static HRESULT WINAPI
IDirect3D2Impl_FindDevice(LPDIRECT3D2 iface
,
2782 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2783 LPD3DFINDDEVICERESULT lpfinddevrst
)
2785 ICOM_THIS(IDirect3D2Impl
,iface
);
2786 TRACE("(%p)->(%p,%p): stub\n", This
, lpfinddevsrc
, lpfinddevrst
);
2791 static HRESULT WINAPI
IDirect3D2Impl_CreateDevice(LPDIRECT3D2 iface
,
2793 LPDIRECTDRAWSURFACE surface
,
2794 LPDIRECT3DDEVICE2
*device
)
2796 ICOM_THIS(IDirect3D2Impl
,iface
);
2799 WINE_StringFromCLSID(rguid
,xbuf
);
2800 FIXME("(%p)->(%s,%p,%p): stub\n",This
,xbuf
,surface
,device
);
2802 if (is_OpenGL(rguid
, (IDirectDrawSurfaceImpl
*)surface
, (IDirect3DDevice2Impl
**)device
, This
)) {
2803 IDirect3D2_AddRef(iface
);
2807 return DDERR_INVALIDPARAMS
;
2810 static ICOM_VTABLE(IDirect3D2
) d3d2vt
=
2812 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
2813 IDirect3D2Impl_QueryInterface
,
2814 IDirect3D2Impl_AddRef
,
2815 IDirect3D2Impl_Release
,
2816 IDirect3D2Impl_EnumDevices
,
2817 IDirect3D2Impl_CreateLight
,
2818 IDirect3D2Impl_CreateMaterial
,
2819 IDirect3D2Impl_CreateViewport
,
2820 IDirect3D2Impl_FindDevice
,
2821 IDirect3D2Impl_CreateDevice
2824 /*******************************************************************************
2828 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2829 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2831 static INT ddrawXlibThisOffset
= 0;
2833 static HRESULT
common_off_screen_CreateSurface(IDirectDraw2Impl
* This
,
2834 IDirectDrawSurfaceImpl
* lpdsf
)
2838 /* The surface was already allocated when entering in this function */
2839 TRACE("using system memory for a surface (%p) \n", lpdsf
);
2841 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
2842 /* This is a Z Buffer */
2843 TRACE("Creating Z-Buffer of %ld bit depth\n", lpdsf
->s
.surface_desc
.u
.dwZBufferBitDepth
);
2844 bpp
= lpdsf
->s
.surface_desc
.u
.dwZBufferBitDepth
/ 8;
2846 /* This is a standard image */
2847 if (!(lpdsf
->s
.surface_desc
.dwFlags
& DDSD_PIXELFORMAT
)) {
2848 /* No pixel format => use DirectDraw's format */
2849 lpdsf
->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
2850 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PIXELFORMAT
;
2853 bpp
= GET_BPP(lpdsf
->s
.surface_desc
);
2856 if (lpdsf
->s
.surface_desc
.dwFlags
& DDSD_LPSURFACE
) {
2857 /* The surface was preallocated : seems that we have nothing to do :-) */
2858 WARN("Creates a surface that is already allocated : assuming this is an application bug !\n");
2861 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_PITCH
|DDSD_LPSURFACE
;
2862 lpdsf
->s
.surface_desc
.u1
.lpSurface
=
2863 (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpdsf
->s
.surface_desc
.dwWidth
* lpdsf
->s
.surface_desc
.dwHeight
* bpp
);
2864 lpdsf
->s
.surface_desc
.lPitch
= lpdsf
->s
.surface_desc
.dwWidth
* bpp
;
2869 #ifdef HAVE_LIBXXF86DGA
2870 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreateSurface(
2871 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2873 ICOM_THIS(IDirectDraw2Impl
,iface
);
2874 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
2875 int i
, fbheight
= This
->e
.dga
.fb_height
;
2877 TRACE("(%p)->(%p,%p,%p)\n",This
,lpddsd
,ilpdsf
,lpunk
);
2878 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
2880 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
2883 sizeof(IDirectDrawSurfaceImpl
)
2885 IDirectDraw2_AddRef(iface
);
2888 ICOM_VTBL(*ilpdsf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&dga_dds4vt
;
2889 (*ilpdsf
)->s
.ddraw
= This
;
2890 (*ilpdsf
)->s
.palette
= NULL
;
2891 (*ilpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
2893 /* Copy the surface description */
2894 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
2896 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2897 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
2898 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2899 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
2901 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
2903 /* Check if this a 'primary surface' or not */
2904 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2905 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2906 /* This is THE primary surface => there is DGA-specific code */
2908 /* First, store the surface description */
2909 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
2911 /* Find a viewport */
2913 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
2915 TRACE("using viewport %d for a primary surface\n",i
);
2916 /* if i == 32 or maximum ... return error */
2917 This
->e
.dga
.vpmask
|=(1<<i
);
2918 lpddsd
->lPitch
= (*ilpdsf
)->s
.surface_desc
.lPitch
=
2919 This
->e
.dga
.fb_width
*PFGET_BPP(This
->d
.directdraw_pixelformat
);
2921 (*ilpdsf
)->s
.surface_desc
.u1
.lpSurface
=
2922 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
2924 (*ilpdsf
)->t
.dga
.fb_height
= i
*fbheight
;
2926 /* Add flags if there were not present */
2927 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
2928 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
2929 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
2930 TRACE("primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",This
->d
.width
,This
->d
.height
,lpddsd
->lPitch
);
2931 /* We put our surface always in video memory */
2932 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2933 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
2934 (*ilpdsf
)->s
.chain
= NULL
;
2936 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2937 IDirectDrawSurface4Impl
* back
;
2940 for (bbc
=lpddsd
->dwBackBufferCount
;bbc
--;) {
2943 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
2946 sizeof(IDirectDrawSurface4Impl
)
2948 IDirectDraw2_AddRef(iface
);
2950 ICOM_VTBL(back
) = (ICOM_VTABLE(IDirectDrawSurface4
)*)&dga_dds4vt
;
2952 if (!(This
->e
.dga
.vpmask
& (1<<i
)))
2954 TRACE("using viewport %d for backbuffer %d\n",i
, bbc
);
2955 /* if i == 32 or maximum ... return error */
2956 This
->e
.dga
.vpmask
|=(1<<i
);
2957 back
->t
.dga
.fb_height
= i
*fbheight
;
2958 /* Copy the surface description from the front buffer */
2959 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
2960 /* Change the parameters that are not the same */
2961 back
->s
.surface_desc
.u1
.lpSurface
=
2962 This
->e
.dga
.fb_addr
+ i
*fbheight
*lpddsd
->lPitch
;
2964 back
->s
.ddraw
= This
;
2965 /* Add relevant info to front and back buffers */
2966 /* FIXME: backbuffer/frontbuffer handling broken here, but
2967 * will be fixed up in _Flip().
2969 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
2970 SDDSCAPS(back
) |= DDSCAPS_FLIP
|DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
;
2971 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2972 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
2973 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
2977 /* There is no DGA-specific code here...
2978 Go to the common surface creation function */
2979 return common_off_screen_CreateSurface(This
, *ilpdsf
);
2983 #endif /* defined(HAVE_LIBXXF86DGA) */
2985 #ifdef HAVE_LIBXXSHM
2986 /* Error handlers for Image creation */
2987 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
2992 static XImage
*create_xshmimage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
2994 int (*WineXHandler
)(Display
*, XErrorEvent
*);
2996 img
= TSXShmCreateImage(display
,
2997 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2998 This
->d
.pixmap_depth
,
3001 &(lpdsf
->t
.xlib
.shminfo
),
3002 lpdsf
->s
.surface_desc
.dwWidth
,
3003 lpdsf
->s
.surface_desc
.dwHeight
3007 FIXME("Couldn't create XShm image (due to X11 remote display or failure).\nReverting to standard X images !\n");
3008 This
->e
.xlib
.xshm_active
= 0;
3012 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
3013 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
3014 FIXME("Couldn't create shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3015 This
->e
.xlib
.xshm_active
= 0;
3016 TSXDestroyImage(img
);
3020 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
3022 if (img
->data
== (char *) -1) {
3023 FIXME("Couldn't attach shared memory segment (due to X11 remote display or failure).\nReverting to standard X images !\n");
3024 This
->e
.xlib
.xshm_active
= 0;
3025 TSXDestroyImage(img
);
3026 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3029 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
3031 /* This is where things start to get trickier....
3032 * First, we flush the current X connections to be sure to catch all
3033 * non-XShm related errors
3035 TSXSync(display
, False
);
3036 /* Then we enter in the non-thread safe part of the tests */
3037 EnterCriticalSection( &X11DRV_CritSection
);
3039 /* Reset the error flag, sets our new error handler and try to attach
3043 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
3044 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
3045 XSync(display
, False
);
3047 /* Check the error flag */
3048 if (XShmErrorFlag
) {
3049 /* An error occured */
3053 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
3054 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3055 XSetErrorHandler(WineXHandler
);
3057 FIXME("Couldn't attach shared memory segment to X server (due to X11 remote display or failure).\nReverting to standard X images !\n");
3058 This
->e
.xlib
.xshm_active
= 0;
3060 /* Leave the critical section */
3061 LeaveCriticalSection( &X11DRV_CritSection
);
3064 /* Here, to be REALLY sure, I should do a XShmPutImage to check if
3065 * this works, but it may be a bit overkill....
3067 XSetErrorHandler(WineXHandler
);
3068 LeaveCriticalSection( &X11DRV_CritSection
);
3070 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
3072 if (This
->d
.pixel_convert
!= NULL
) {
3073 lpdsf
->s
.surface_desc
.u1
.lpSurface
= HeapAlloc(
3076 lpdsf
->s
.surface_desc
.dwWidth
*
3077 lpdsf
->s
.surface_desc
.dwHeight
*
3078 PFGET_BPP(This
->d
.directdraw_pixelformat
)
3081 lpdsf
->s
.surface_desc
.u1
.lpSurface
= img
->data
;
3085 #endif /* HAVE_LIBXXSHM */
3087 static XImage
*create_ximage(IDirectDraw2Impl
* This
, IDirectDrawSurface4Impl
* lpdsf
) {
3091 #ifdef HAVE_LIBXXSHM
3092 if (This
->e
.xlib
.xshm_active
)
3093 img
= create_xshmimage(This
, lpdsf
);
3097 /* Allocate surface memory */
3098 lpdsf
->s
.surface_desc
.u1
.lpSurface
= HeapAlloc(
3099 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3100 lpdsf
->s
.surface_desc
.dwWidth
*
3101 lpdsf
->s
.surface_desc
.dwHeight
*
3102 PFGET_BPP(This
->d
.directdraw_pixelformat
)
3105 if (This
->d
.pixel_convert
!= NULL
) {
3106 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
3107 lpdsf
->s
.surface_desc
.dwWidth
*
3108 lpdsf
->s
.surface_desc
.dwHeight
*
3109 PFGET_BPP(This
->d
.screen_pixelformat
)
3112 img_data
= lpdsf
->s
.surface_desc
.u1
.lpSurface
;
3115 /* In this case, create an XImage */
3116 img
= TSXCreateImage(display
,
3117 DefaultVisualOfScreen(X11DRV_GetXScreen()),
3118 This
->d
.pixmap_depth
,
3122 lpdsf
->s
.surface_desc
.dwWidth
,
3123 lpdsf
->s
.surface_desc
.dwHeight
,
3125 lpdsf
->s
.surface_desc
.dwWidth
* PFGET_BPP(This
->d
.screen_pixelformat
)
3127 #ifdef HAVE_LIBXXSHM
3130 if (This
->d
.pixel_convert
!= NULL
)
3131 lpdsf
->s
.surface_desc
.lPitch
= PFGET_BPP(This
->d
.directdraw_pixelformat
) * lpdsf
->s
.surface_desc
.dwWidth
;
3133 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
3137 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreateSurface(
3138 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
3140 ICOM_THIS(IDirectDraw2Impl
,iface
);
3141 IDirectDrawSurfaceImpl
** ilpdsf
=(IDirectDrawSurfaceImpl
**)lpdsf
;
3143 TRACE("(%p)->CreateSurface(%p,%p,%p)\n", This
,lpddsd
,ilpdsf
,lpunk
);
3145 if (TRACE_ON(ddraw
)) { _dump_surface_desc(lpddsd
); }
3147 *ilpdsf
= (IDirectDrawSurfaceImpl
*)HeapAlloc(
3148 GetProcessHeap(),HEAP_ZERO_MEMORY
, sizeof(IDirectDrawSurfaceImpl
)
3151 IDirectDraw2_AddRef(iface
);
3153 (*ilpdsf
)->s
.ddraw
= This
;
3155 ICOM_VTBL(*ilpdsf
) = (ICOM_VTABLE(IDirectDrawSurface
)*)&xlib_dds4vt
;
3156 (*ilpdsf
)->s
.palette
= NULL
;
3157 (*ilpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
3159 /* Copy the surface description */
3160 (*ilpdsf
)->s
.surface_desc
= *lpddsd
;
3162 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
3163 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3164 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
3165 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3166 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
;
3168 /* Check if this a 'primary surface' or not */
3169 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
3170 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
3173 TRACE("using standard XImage for a primary surface (%p)\n", *ilpdsf
);
3174 /* Create the XImage */
3175 img
= create_ximage(This
, (IDirectDrawSurface4Impl
*) *ilpdsf
);
3177 return DDERR_OUTOFMEMORY
;
3178 (*ilpdsf
)->t
.xlib
.image
= img
;
3180 /* Add flags if there were not present */
3181 (*ilpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
3182 (*ilpdsf
)->s
.surface_desc
.dwWidth
= This
->d
.width
;
3183 (*ilpdsf
)->s
.surface_desc
.dwHeight
= This
->d
.height
;
3184 (*ilpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
3185 (*ilpdsf
)->s
.surface_desc
.ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
3187 /* Check for backbuffers */
3188 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
3189 IDirectDrawSurface4Impl
* back
;
3193 for (i
=lpddsd
->dwBackBufferCount
;i
--;) {
3194 back
= (IDirectDrawSurface4Impl
*)HeapAlloc(
3195 GetProcessHeap(),HEAP_ZERO_MEMORY
,
3196 sizeof(IDirectDrawSurface4Impl
)
3199 TRACE("allocated back-buffer (%p)\n", back
);
3201 IDirectDraw2_AddRef(iface
);
3202 back
->s
.ddraw
= This
;
3205 ICOM_VTBL(back
) = (ICOM_VTABLE(IDirectDrawSurface4
)*)&xlib_dds4vt
;
3206 /* Copy the surface description from the front buffer */
3207 back
->s
.surface_desc
= (*ilpdsf
)->s
.surface_desc
;
3209 /* Create the XImage */
3210 img
= create_ximage(This
, back
);
3212 return DDERR_OUTOFMEMORY
;
3213 back
->t
.xlib
.image
= img
;
3215 /* Add relevant info to front and back buffers */
3216 /* FIXME: backbuffer/frontbuffer handling broken here, but
3217 * will be fixed up in _Flip().
3219 SDDSCAPS((*ilpdsf
)) |= DDSCAPS_FRONTBUFFER
;
3220 SDDSCAPS(back
) |= DDSCAPS_BACKBUFFER
|DDSCAPS_VIDEOMEMORY
|DDSCAPS_FLIP
;
3221 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
3222 SDDSCAPS(back
) &= ~DDSCAPS_VISIBLE
;
3223 IDirectDrawSurface4_AddAttachedSurface((LPDIRECTDRAWSURFACE4
)(*ilpdsf
),(LPDIRECTDRAWSURFACE4
)back
);
3227 /* There is no Xlib-specific code here...
3228 Go to the common surface creation function */
3229 return common_off_screen_CreateSurface(This
, *ilpdsf
);
3234 static HRESULT WINAPI
IDirectDraw2Impl_DuplicateSurface(
3235 LPDIRECTDRAW2 iface
,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
3237 ICOM_THIS(IDirectDraw2Impl
,iface
);
3238 FIXME("(%p)->(%p,%p) simply copies\n",This
,src
,dst
);
3239 *dst
= src
; /* FIXME */
3244 * The Xlib Implementation tries to use the passed hwnd as drawing window,
3245 * even when the approbiate bitmasks are not specified.
3247 static HRESULT WINAPI
IDirectDraw2Impl_SetCooperativeLevel(
3248 LPDIRECTDRAW2 iface
,HWND hwnd
,DWORD cooplevel
3250 ICOM_THIS(IDirectDraw2Impl
,iface
);
3257 #define FE(x) { x, #x},
3258 FE(DDSCL_FULLSCREEN)
3259 FE(DDSCL_ALLOWREBOOT)
3260 FE(DDSCL_NOWINDOWCHANGES)
3262 FE(DDSCL_ALLOWMODEX)
3264 FE(DDSCL_SETFOCUSWINDOW)
3265 FE(DDSCL_SETDEVICEWINDOW)
3266 FE(DDSCL_CREATEDEVICEWINDOW)
3271 FIXME("(%p)->(%08lx,%08lx)\n",This
,(DWORD
)hwnd
,cooplevel
);
3272 This
->d
.mainWindow
= hwnd
;
3274 /* This will be overwritten in the case of Full Screen mode.
3275 Windowed games could work with that :-) */
3278 WND
*tmpWnd
= WIN_FindWndPtr(hwnd
);
3279 This
->d
.drawable
= X11DRV_WND_GetXWindow(tmpWnd
);
3280 WIN_ReleaseWndPtr(tmpWnd
);
3282 if( !This
->d
.drawable
) {
3283 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
3284 WIN_ReleaseDesktop();
3286 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
3292 /* Small helper to either use the cooperative window or create a new
3293 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
3295 static void _common_IDirectDrawImpl_SetDisplayMode(IDirectDrawImpl
* This
) {
3298 /* Do not destroy the application supplied cooperative window */
3299 if (This
->d
.window
&& This
->d
.window
!= This
->d
.mainWindow
) {
3300 DestroyWindow(This
->d
.window
);
3303 /* Sanity check cooperative window before assigning it to drawing. */
3304 if ( IsWindow(This
->d
.mainWindow
) &&
3305 IsWindowVisible(This
->d
.mainWindow
)
3307 /* if it does not fit, resize the cooperative window.
3308 * and hope the app likes it
3310 GetWindowRect(This
->d
.mainWindow
,&rect
);
3311 if ((((rect
.right
-rect
.left
) >= This
->d
.width
) &&
3312 ((rect
.bottom
-rect
.top
) >= This
->d
.height
))
3314 This
->d
.window
= This
->d
.mainWindow
;
3315 /*SetWindowPos(This->d.mainWindow,HWND_TOPMOST,0,0,This->d.width,This->d.height,SWP_NOMOVE|SWP_NOOWNERZORDER);*/
3319 /* ... failed, create new one. */
3320 if (!This
->d
.window
) {
3321 This
->d
.window
= CreateWindowExA(
3325 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
3334 /*Store THIS with the window. We'll use it in the window procedure*/
3335 SetWindowLongA(This
->d
.window
,ddrawXlibThisOffset
,(LONG
)This
);
3336 ShowWindow(This
->d
.window
,TRUE
);
3337 UpdateWindow(This
->d
.window
);
3339 SetFocus(This
->d
.window
);
3342 static int _common_depth_to_pixelformat(DWORD depth
,
3343 DDPIXELFORMAT
*pixelformat
,
3344 DDPIXELFORMAT
*screen_pixelformat
,
3347 XPixmapFormatValues
*pf
;
3349 int nvisuals
, npixmap
, i
;
3353 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
3354 pf
= XListPixmapFormats(display
, &npixmap
);
3356 for (i
= 0; i
< npixmap
; i
++) {
3357 if (pf
[i
].depth
== depth
) {
3360 for (j
= 0; j
< nvisuals
; j
++) {
3361 if (vi
[j
].depth
== pf
[i
].depth
) {
3362 pixelformat
->dwSize
= sizeof(*pixelformat
);
3364 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
3365 pixelformat
->u1
.dwRBitMask
= 0;
3366 pixelformat
->u2
.dwGBitMask
= 0;
3367 pixelformat
->u3
.dwBBitMask
= 0;
3369 pixelformat
->dwFlags
= DDPF_RGB
;
3370 pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
3371 pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
3372 pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
3374 pixelformat
->dwFourCC
= 0;
3375 pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3376 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3378 *screen_pixelformat
= *pixelformat
;
3380 if (pix_depth
!= NULL
)
3381 *pix_depth
= vi
[j
].depth
;
3386 goto clean_up_and_exit
;
3390 ERR("No visual corresponding to pixmap format !\n");
3395 /* We try now to find an emulated mode */
3398 for (c
= 0; c
< sizeof(ModeEmulations
) / sizeof(Convert
); c
++) {
3399 if (ModeEmulations
[c
].dest
.depth
== depth
) {
3400 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
3401 for (i
= 0; i
< npixmap
; i
++) {
3402 if ((pf
[i
].depth
== ModeEmulations
[c
].screen
.depth
) &&
3403 (pf
[i
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
3406 for (j
= 0; j
< nvisuals
; j
++) {
3407 if (vi
[j
].depth
== pf
[i
].depth
) {
3408 screen_pixelformat
->dwSize
= sizeof(*screen_pixelformat
);
3409 screen_pixelformat
->dwFlags
= DDPF_RGB
;
3410 screen_pixelformat
->dwFourCC
= 0;
3411 screen_pixelformat
->u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3412 screen_pixelformat
->u1
.dwRBitMask
= vi
[j
].red_mask
;
3413 screen_pixelformat
->u2
.dwGBitMask
= vi
[j
].green_mask
;
3414 screen_pixelformat
->u3
.dwBBitMask
= vi
[j
].blue_mask
;
3415 screen_pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3417 pixelformat
->dwSize
= sizeof(*pixelformat
);
3418 pixelformat
->dwFourCC
= 0;
3420 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
3421 pixelformat
->u
.dwRGBBitCount
= 8;
3422 pixelformat
->u1
.dwRBitMask
= 0;
3423 pixelformat
->u2
.dwGBitMask
= 0;
3424 pixelformat
->u3
.dwBBitMask
= 0;
3426 pixelformat
->dwFlags
= DDPF_RGB
;
3427 pixelformat
->u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
3428 pixelformat
->u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
3429 pixelformat
->u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
3430 pixelformat
->u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
3432 pixelformat
->u4
.dwRGBAlphaBitMask
= 0;
3434 if (pix_depth
!= NULL
)
3435 *pix_depth
= vi
[j
].depth
;
3440 goto clean_up_and_exit
;
3443 ERR("No visual corresponding to pixmap format !\n");
3458 #ifdef HAVE_LIBXXF86DGA
3459 static HRESULT WINAPI
DGA_IDirectDrawImpl_SetDisplayMode(
3460 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
3462 ICOM_THIS(IDirectDrawImpl
,iface
);
3465 TRACE("(%p)->(%ld,%ld,%ld)\n", This
, width
, height
, depth
);
3467 /* We hope getting the asked for depth */
3468 if (_common_depth_to_pixelformat(depth
, &(This
->d
.directdraw_pixelformat
), &(This
->d
.screen_pixelformat
), NULL
) != -1) {
3469 /* I.e. no visual found or emulated */
3470 ERR("(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
3471 return DDERR_UNSUPPORTEDMODE
;
3474 if (This
->d
.width
< width
) {
3475 ERR("SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,This
->d
.width
);
3476 return DDERR_UNSUPPORTEDMODE
;
3478 This
->d
.width
= width
;
3479 This
->d
.height
= height
;
3481 /* adjust fb_height, so we don't overlap */
3482 if (This
->e
.dga
.fb_height
< height
)
3483 This
->e
.dga
.fb_height
= height
;
3484 _common_IDirectDrawImpl_SetDisplayMode(This
);
3486 #ifdef HAVE_LIBXXF86VM
3488 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
3489 XF86VidModeModeLine mod_tmp
;
3490 /* int dotclock_tmp; */
3492 /* save original video mode and set fullscreen if available*/
3493 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
3494 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
3495 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
3496 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
3497 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
3498 orig_mode
->htotal
= mod_tmp
.htotal
;
3499 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
3500 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
3501 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
3502 orig_mode
->vtotal
= mod_tmp
.vtotal
;
3503 orig_mode
->flags
= mod_tmp
.flags
;
3504 orig_mode
->private = mod_tmp
.private;
3506 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
3507 for (i
=0;i
<mode_count
;i
++)
3509 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
3511 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
3512 *vidmode
= *(all_modes
[i
]);
3515 TSXFree(all_modes
[i
]->private);
3517 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
3521 WARN("Fullscreen mode not available!\n");
3525 TRACE("SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
3526 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
3527 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
3528 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
3534 /* FIXME: this function OVERWRITES several signal handlers.
3535 * can we save them? and restore them later? In a way that
3536 * it works for the library too?
3538 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
3539 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
3541 #ifdef RESTORE_SIGNALS
3546 #endif /* defined(HAVE_LIBXXF86DGA) */
3548 /* *************************************
3549 16 / 15 bpp to palettized 8 bpp
3550 ************************************* */
3551 static void pixel_convert_16_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3552 unsigned char *c_src
= (unsigned char *) src
;
3553 unsigned short *c_dst
= (unsigned short *) dst
;
3556 if (palette
!= NULL
) {
3557 const unsigned short * pal
= (unsigned short *) palette
->screen_palents
;
3559 for (y
= height
; y
--; ) {
3560 #if defined(__i386__) && defined(__GNUC__)
3561 /* gcc generates slightly inefficient code for the the copy / lookup,
3562 * it generates one excess memory access (to pal) per pixel. Since
3563 * we know that pal is not modified by the memory write we can
3564 * put it into a register and reduce the number of memory accesses
3565 * from 4 to 3 pp. There are two xor eax,eax to avoid pipeline stalls.
3566 * (This is not guaranteed to be the fastest method.)
3568 __asm__
__volatile__(
3572 " movw (%%edx,%%eax,2),%%ax\n"
3574 " xor %%eax,%%eax\n"
3576 : "=S" (c_src
), "=D" (c_dst
)
3577 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
3578 : "eax", "cc", "memory"
3580 c_src
+=(pitch
-width
);
3582 unsigned char * srclineend
= c_src
+width
;
3583 while (c_src
< srclineend
)
3584 *c_dst
++ = pal
[*c_src
++];
3585 c_src
+=(pitch
-width
);
3589 WARN("No palette set...\n");
3590 memset(dst
, 0, width
* height
* 2);
3593 static void palette_convert_16_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3595 unsigned short *pal
= (unsigned short *) screen_palette
;
3597 for (i
= 0; i
< count
; i
++)
3598 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
3599 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3600 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
3602 static void palette_convert_15_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3604 unsigned short *pal
= (unsigned short *) screen_palette
;
3606 for (i
= 0; i
< count
; i
++)
3607 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 7) |
3608 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
3609 ((((unsigned short) palent
[i
].peGreen
) & 0xF8) << 2));
3612 /* *************************************
3613 24 to palettized 8 bpp
3614 ************************************* */
3615 static void pixel_convert_24_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3616 unsigned char *c_src
= (unsigned char *) src
;
3617 unsigned char *c_dst
= (unsigned char *) dst
;
3620 if (palette
!= NULL
) {
3621 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
3623 for (y
= height
; y
--; ) {
3624 unsigned char * srclineend
= c_src
+width
;
3625 while (c_src
< srclineend
) {
3626 register long pixel
= pal
[*c_src
++];
3628 *c_dst
++ = pixel
>>8;
3629 *c_dst
++ = pixel
>>16;
3631 c_src
+=(pitch
-width
);
3634 WARN("No palette set...\n");
3635 memset(dst
, 0, width
* height
* 4);
3638 /* *************************************
3639 32 bpp to palettized 8 bpp
3640 ************************************* */
3641 static void pixel_convert_32_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3642 unsigned char *c_src
= (unsigned char *) src
;
3643 unsigned int *c_dst
= (unsigned int *) dst
;
3646 if (palette
!= NULL
) {
3647 const unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
3649 for (y
= height
; y
--; ) {
3650 #if defined(__i386__) && defined(__GNUC__)
3651 /* See comment in pixel_convert_16_to_8 */
3652 __asm__
__volatile__(
3656 " movl (%%edx,%%eax,4),%%eax\n"
3658 " xor %%eax,%%eax\n"
3660 : "=S" (c_src
), "=D" (c_dst
)
3661 : "S" (c_src
), "D" (c_dst
) , "c" (width
), "d" (pal
)
3662 : "eax", "cc", "memory"
3664 c_src
+=(pitch
-width
);
3666 unsigned char * srclineend
= c_src
+width
;
3667 while (c_src
< srclineend
)
3668 *c_dst
++ = pal
[*c_src
++];
3669 c_src
+=(pitch
-width
);
3673 WARN("No palette set...\n");
3674 memset(dst
, 0, width
* height
* 4);
3678 static void palette_convert_24_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
3680 unsigned int *pal
= (unsigned int *) screen_palette
;
3682 for (i
= 0; i
< count
; i
++)
3683 pal
[start
+ i
] = ((((unsigned int) palent
[i
].peRed
) << 16) |
3684 (((unsigned int) palent
[i
].peGreen
) << 8) |
3685 ((unsigned int) palent
[i
].peBlue
));
3688 /* *************************************
3690 ************************************* */
3691 static void pixel_convert_32_to_16(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, IDirectDrawPaletteImpl
* palette
) {
3692 unsigned short *c_src
= (unsigned short *) src
;
3693 unsigned int *c_dst
= (unsigned int *) dst
;
3696 for (y
= height
; y
--; ) {
3697 unsigned short * srclineend
= c_src
+width
;
3698 while (c_src
< srclineend
) {
3699 *c_dst
++ = (((*c_src
& 0xF800) << 8) |
3700 ((*c_src
& 0x07E0) << 5) |
3701 ((*c_src
& 0x001F) << 3));
3704 c_src
+=((pitch
/2)-width
);
3709 static HRESULT WINAPI
Xlib_IDirectDrawImpl_SetDisplayMode(
3710 LPDIRECTDRAW iface
,DWORD width
,DWORD height
,DWORD depth
3712 ICOM_THIS(IDirectDrawImpl
,iface
);
3717 TRACE("(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
3718 This
, width
, height
, depth
);
3720 switch ((c
= _common_depth_to_pixelformat(depth
,
3721 &(This
->d
.directdraw_pixelformat
),
3722 &(This
->d
.screen_pixelformat
),
3723 &(This
->d
.pixmap_depth
)))) {
3725 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
3726 MessageBoxA(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
3727 return DDERR_UNSUPPORTEDMODE
;
3731 This
->d
.pixel_convert
= NULL
;
3732 This
->d
.palette_convert
= NULL
;
3736 WARN("Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
3738 /* Set the depth convertion routines */
3739 This
->d
.pixel_convert
= ModeEmulations
[c
].funcs
.pixel_convert
;
3740 This
->d
.palette_convert
= ModeEmulations
[c
].funcs
.palette_convert
;
3743 This
->d
.width
= width
;
3744 This
->d
.height
= height
;
3746 _common_IDirectDrawImpl_SetDisplayMode(This
);
3748 tmpWnd
= WIN_FindWndPtr(This
->d
.window
);
3749 This
->d
.paintable
= 1;
3750 This
->d
.drawable
= ((X11DRV_WND_DATA
*) tmpWnd
->pDriverData
)->window
;
3751 WIN_ReleaseWndPtr(tmpWnd
);
3753 /* We don't have a context for this window. Host off the desktop */
3754 if( !This
->d
.drawable
)
3756 This
->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
3757 WIN_ReleaseDesktop();
3759 TRACE("Setting drawable to %ld\n", This
->d
.drawable
);
3764 #ifdef HAVE_LIBXXF86DGA
3765 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetCaps(
3766 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
3768 ICOM_THIS(IDirectDraw2Impl
,iface
);
3769 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
3770 if (!caps1
&& !caps2
)
3771 return DDERR_INVALIDPARAMS
;
3773 caps1
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
3774 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
3775 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
3778 caps2
->dwVidMemTotal
= This
->e
.dga
.fb_memsize
;
3779 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
3780 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
3784 #endif /* defined(HAVE_LIBXXF86DGA) */
3786 static void fill_caps(LPDDCAPS caps
) {
3787 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3788 Need to be fixed, though.. */
3792 caps
->dwSize
= sizeof(*caps
);
3793 caps
->dwCaps
= DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
| DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
| DDCAPS_NOHARDWARE
;
3794 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NOPAGELOCKREQUIRED
| DDCAPS2_WIDESURFACES
;
3795 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
3797 caps
->dwFXAlphaCaps
= 0;
3798 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
3800 caps
->dwZBufferBitDepths
= DDBD_16
;
3801 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3802 to put textures in video memory.
3803 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3805 caps
->dwVidMemTotal
= 8192 * 1024;
3806 caps
->dwVidMemFree
= 8192 * 1024;
3807 /* These are all the supported capabilities of the surfaces */
3808 caps
->ddsCaps
.dwCaps
= DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
3809 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
3810 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
|
3811 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
;
3813 caps
->dwCaps
|= DDCAPS_3D
| DDCAPS_ZBLTS
;
3814 caps
->dwCaps2
|= DDCAPS2_NO2DDURING3DSCENE
;
3815 caps
->ddsCaps
.dwCaps
|= DDSCAPS_3DDEVICE
| DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
| DDSCAPS_ZBUFFER
;
3819 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetCaps(
3820 LPDIRECTDRAW2 iface
,LPDDCAPS caps1
,LPDDCAPS caps2
3822 ICOM_THIS(IDirectDraw2Impl
,iface
);
3823 TRACE("(%p)->GetCaps(%p,%p)\n",This
,caps1
,caps2
);
3825 /* Put the same caps for the two capabilities */
3832 static HRESULT WINAPI
IDirectDraw2Impl_CreateClipper(
3833 LPDIRECTDRAW2 iface
,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
3835 ICOM_THIS(IDirectDraw2Impl
,iface
);
3836 IDirectDrawClipperImpl
** ilpddclip
=(IDirectDrawClipperImpl
**)lpddclip
;
3837 FIXME("(%p)->(%08lx,%p,%p),stub!\n",
3838 This
,x
,ilpddclip
,lpunk
3840 *ilpddclip
= (IDirectDrawClipperImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipperImpl
));
3841 (*ilpddclip
)->ref
= 1;
3842 ICOM_VTBL(*ilpddclip
) = &ddclipvt
;
3846 static HRESULT WINAPI
common_IDirectDraw2Impl_CreatePalette(
3847 IDirectDraw2Impl
* This
,DWORD dwFlags
,LPPALETTEENTRY palent
,IDirectDrawPaletteImpl
**lpddpal
,LPUNKNOWN lpunk
,int *psize
3851 if (TRACE_ON(ddraw
))
3852 _dump_paletteformat(dwFlags
);
3854 *lpddpal
= (IDirectDrawPaletteImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPaletteImpl
));
3855 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
3856 (*lpddpal
)->ref
= 1;
3857 (*lpddpal
)->ddraw
= (IDirectDrawImpl
*)This
;
3858 (*lpddpal
)->installed
= 0;
3860 if (dwFlags
& DDPCAPS_1BIT
)
3862 else if (dwFlags
& DDPCAPS_2BIT
)
3864 else if (dwFlags
& DDPCAPS_4BIT
)
3866 else if (dwFlags
& DDPCAPS_8BIT
)
3869 ERR("unhandled palette format\n");
3874 /* Now, if we are in 'depth conversion mode', create the screen palette */
3875 if (This
->d
.palette_convert
!= NULL
)
3876 This
->d
.palette_convert(palent
, (*lpddpal
)->screen_palents
, 0, size
);
3878 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
3879 } else if (This
->d
.palette_convert
!= NULL
) {
3880 /* In that case, put all 0xFF */
3881 memset((*lpddpal
)->screen_palents
, 0xFF, 256 * sizeof(int));
3887 #ifdef HAVE_LIBXXF86DGA
3888 static HRESULT WINAPI
DGA_IDirectDraw2Impl_CreatePalette(
3889 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3891 ICOM_THIS(IDirectDraw2Impl
,iface
);
3892 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
3896 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
3897 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
3898 if (res
!= 0) return res
;
3899 ICOM_VTBL(*ilpddpal
) = &dga_ddpalvt
;
3900 if (This
->d
.directdraw_pixelformat
.u
.dwRGBBitCount
<=8) {
3901 (*ilpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
3903 FIXME("why are we doing CreatePalette in hi/truecolor?\n");
3904 (*ilpddpal
)->cm
= 0;
3906 if (((*ilpddpal
)->cm
)&&xsize
) {
3907 for (i
=0;i
<xsize
;i
++) {
3910 xc
.red
= (*ilpddpal
)->palents
[i
].peRed
<<8;
3911 xc
.blue
= (*ilpddpal
)->palents
[i
].peBlue
<<8;
3912 xc
.green
= (*ilpddpal
)->palents
[i
].peGreen
<<8;
3913 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
3915 TSXStoreColor(display
,(*ilpddpal
)->cm
,&xc
);
3920 #endif /* defined(HAVE_LIBXXF86DGA) */
3922 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_CreatePalette(
3923 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3925 ICOM_THIS(IDirectDraw2Impl
,iface
);
3926 IDirectDrawPaletteImpl
** ilpddpal
=(IDirectDrawPaletteImpl
**)lpddpal
;
3930 TRACE("(%p)->(%08lx,%p,%p,%p)\n",This
,dwFlags
,palent
,ilpddpal
,lpunk
);
3931 res
= common_IDirectDraw2Impl_CreatePalette(This
,dwFlags
,palent
,ilpddpal
,lpunk
,&xsize
);
3932 if (res
!= 0) return res
;
3933 ICOM_VTBL(*ilpddpal
) = &xlib_ddpalvt
;
3937 #ifdef HAVE_LIBXXF86DGA
3938 static HRESULT WINAPI
DGA_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
3939 ICOM_THIS(IDirectDraw2Impl
,iface
);
3940 TRACE("(%p)->()\n",This
);
3942 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3943 #ifdef RESTORE_SIGNALS
3948 #endif /* defined(HAVE_LIBXXF86DGA) */
3950 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_RestoreDisplayMode(LPDIRECTDRAW2 iface
) {
3951 ICOM_THIS(IDirectDraw2Impl
,iface
);
3952 TRACE("(%p)->RestoreDisplayMode()\n", This
);
3957 static HRESULT WINAPI
IDirectDraw2Impl_WaitForVerticalBlank(
3958 LPDIRECTDRAW2 iface
,DWORD x
,HANDLE h
3960 ICOM_THIS(IDirectDraw2Impl
,iface
);
3961 TRACE("(%p)->(0x%08lx,0x%08x)\n",This
,x
,h
);
3965 static ULONG WINAPI
IDirectDraw2Impl_AddRef(LPDIRECTDRAW2 iface
) {
3966 ICOM_THIS(IDirectDraw2Impl
,iface
);
3967 TRACE("(%p)->() incrementing from %lu.\n", This
, This
->ref
);
3969 return ++(This
->ref
);
3972 #ifdef HAVE_LIBXXF86DGA
3973 static ULONG WINAPI
DGA_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
3974 ICOM_THIS(IDirectDraw2Impl
,iface
);
3975 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
3977 if (!--(This
->ref
)) {
3978 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3979 if (This
->d
.window
&& (This
->d
.mainWindow
!= This
->d
.window
))
3980 DestroyWindow(This
->d
.window
);
3981 #ifdef HAVE_LIBXXF86VM
3983 TSXF86VidModeSwitchToMode(
3985 DefaultScreen(display
),
3987 if (orig_mode
->privsize
)
3988 TSXFree(orig_mode
->private);
3994 #ifdef RESTORE_SIGNALS
3997 HeapFree(GetProcessHeap(),0,This
);
4002 #endif /* defined(HAVE_LIBXXF86DGA) */
4004 static ULONG WINAPI
Xlib_IDirectDraw2Impl_Release(LPDIRECTDRAW2 iface
) {
4005 ICOM_THIS(IDirectDraw2Impl
,iface
);
4006 TRACE("(%p)->() decrementing from %lu.\n", This
, This
->ref
);
4008 if (!--(This
->ref
)) {
4009 if (This
->d
.window
&& (This
->d
.mainWindow
!= This
->d
.window
))
4010 DestroyWindow(This
->d
.window
);
4011 HeapFree(GetProcessHeap(),0,This
);
4014 /* FIXME: destroy window ... */
4018 #ifdef HAVE_LIBXXF86DGA
4019 static HRESULT WINAPI
DGA_IDirectDraw2Impl_QueryInterface(
4020 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
4022 ICOM_THIS(IDirectDraw2Impl
,iface
);
4025 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
4026 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
4027 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
4029 IDirectDraw2_AddRef(iface
);
4031 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4035 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
4036 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_ddvt
;
4037 IDirectDraw2_AddRef(iface
);
4040 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4044 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
4045 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd2vt
;
4046 IDirectDraw2_AddRef(iface
);
4049 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4053 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
4054 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&dga_dd4vt
;
4055 IDirectDraw2_AddRef(iface
);
4058 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4062 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
4065 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4067 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4068 IDirectDraw2_AddRef(iface
);
4069 ICOM_VTBL(d3d
) = &d3dvt
;
4072 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4076 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
4077 IDirect3D2Impl
* d3d
;
4079 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4081 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4082 IDirectDraw2_AddRef(iface
);
4083 ICOM_VTBL(d3d
) = &d3d2vt
;
4086 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4090 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,xrefiid
);
4091 return OLE_E_ENUM_NOMORE
;
4093 #endif /* defined(HAVE_LIBXXF86DGA) */
4095 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_QueryInterface(
4096 LPDIRECTDRAW2 iface
,REFIID refiid
,LPVOID
*obj
4098 ICOM_THIS(IDirectDraw2Impl
,iface
);
4101 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
4102 TRACE("(%p)->(%s,%p)\n",This
,xrefiid
,obj
);
4103 if ( IsEqualGUID( &IID_IUnknown
, refiid
) ) {
4105 IDirectDraw2_AddRef(iface
);
4107 TRACE(" Creating IUnknown interface (%p)\n", *obj
);
4111 if ( IsEqualGUID( &IID_IDirectDraw
, refiid
) ) {
4112 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_ddvt
;
4113 IDirectDraw2_AddRef(iface
);
4116 TRACE(" Creating IDirectDraw interface (%p)\n", *obj
);
4120 if ( IsEqualGUID( &IID_IDirectDraw2
, refiid
) ) {
4121 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd2vt
;
4122 IDirectDraw2_AddRef(iface
);
4125 TRACE(" Creating IDirectDraw2 interface (%p)\n", *obj
);
4129 if ( IsEqualGUID( &IID_IDirectDraw4
, refiid
) ) {
4130 ICOM_VTBL(This
) = (ICOM_VTABLE(IDirectDraw2
)*)&xlib_dd4vt
;
4131 IDirectDraw2_AddRef(iface
);
4134 TRACE(" Creating IDirectDraw4 interface (%p)\n", *obj
);
4138 if ( IsEqualGUID( &IID_IDirect3D
, refiid
) ) {
4141 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4143 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4144 IDirectDraw2_AddRef(iface
);
4145 ICOM_VTBL(d3d
) = &d3dvt
;
4148 TRACE(" Creating IDirect3D interface (%p)\n", *obj
);
4152 if ( IsEqualGUID( &IID_IDirect3D2
, refiid
) ) {
4153 IDirect3D2Impl
* d3d
;
4155 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
4157 d3d
->ddraw
= (IDirectDrawImpl
*)This
;
4158 IDirectDraw2_AddRef(iface
);
4159 ICOM_VTBL(d3d
) = &d3d2vt
;
4162 TRACE(" Creating IDirect3D2 interface (%p)\n", *obj
);
4166 WARN("(%p):interface for IID %s _NOT_ found!\n",This
,xrefiid
);
4167 return OLE_E_ENUM_NOMORE
;
4170 static HRESULT WINAPI
IDirectDraw2Impl_GetVerticalBlankStatus(
4171 LPDIRECTDRAW2 iface
,BOOL
*status
4173 ICOM_THIS(IDirectDraw2Impl
,iface
);
4174 TRACE("(%p)->(%p)\n",This
,status
);
4179 #ifdef HAVE_LIBXXF86DGA
4180 static HRESULT WINAPI
DGA_IDirectDraw2Impl_EnumDisplayModes(
4181 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4183 ICOM_THIS(IDirectDraw2Impl
,iface
);
4184 DDSURFACEDESC ddsfd
;
4187 } modes
[5] = { /* some of the usual modes */
4194 static int depths
[4] = {8,16,24,32};
4197 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4198 ddsfd
.dwSize
= sizeof(ddsfd
);
4199 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4200 if (dwFlags
& DDEDM_REFRESHRATES
) {
4201 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4202 ddsfd
.u
.dwRefreshRate
= 60;
4205 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
4206 ddsfd
.dwBackBufferCount
= 1;
4207 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4208 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4209 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= depths
[i
];
4210 /* FIXME: those masks would have to be set in depth > 8 */
4212 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4213 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4214 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4215 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4216 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
4217 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
4219 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4221 /* FIXME: We should query those from X itself */
4222 switch (depths
[i
]) {
4224 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0xF800;
4225 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x07E0;
4226 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x001F;
4229 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
4230 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
4231 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
4234 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0x00FF0000;
4235 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0x0000FF00;
4236 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0x000000FF;
4241 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4242 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4243 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4244 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4246 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
4247 ddsfd
.dwWidth
= modes
[j
].w
;
4248 ddsfd
.dwHeight
= modes
[j
].h
;
4249 TRACE(" enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
4250 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4253 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4254 /* modeX is not standard VGA */
4256 ddsfd
.dwHeight
= 200;
4257 ddsfd
.dwWidth
= 320;
4258 TRACE(" enumerating (320x200x%d)\n",depths
[i
]);
4259 if (!modescb(&ddsfd
,context
)) return DD_OK
;
4264 #endif /* defined(HAVE_LIBXXF86DGA) */
4266 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_EnumDisplayModes(
4267 LPDIRECTDRAW2 iface
,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
4269 ICOM_THIS(IDirectDraw2Impl
,iface
);
4271 XPixmapFormatValues
*pf
;
4273 int nvisuals
, npixmap
, i
, emu
;
4274 int has_mode
[] = { 0, 0, 0, 0 };
4275 int has_depth
[] = { 8, 15, 16, 24 };
4276 DDSURFACEDESC ddsfd
;
4279 } modes
[] = { /* some of the usual modes */
4287 DWORD maxWidth
, maxHeight
;
4289 TRACE("(%p)->(0x%08lx,%p,%p,%p)\n",This
,dwFlags
,lpddsfd
,context
,modescb
);
4290 ddsfd
.dwSize
= sizeof(ddsfd
);
4291 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4292 if (dwFlags
& DDEDM_REFRESHRATES
) {
4293 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
4294 ddsfd
.u
.dwRefreshRate
= 60;
4296 maxWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4297 maxHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4299 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
4300 pf
= XListPixmapFormats(display
, &npixmap
);
4304 while ((i
< npixmap
) ||
4311 for (j
= 0; j
< 4; j
++) {
4312 if (has_depth
[j
] == pf
[i
].depth
) {
4323 if (has_mode
[mode_index
] == 0) {
4324 if (mode_index
== 0) {
4327 ddsfd
.ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4328 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4329 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
;
4330 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4331 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
4332 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4333 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4334 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4335 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4337 has_mode
[mode_index
] = 1;
4339 /* All the 'true color' depths (15, 16 and 24)
4340 First, find the corresponding visual to extract the bit masks */
4341 for (j
= 0; j
< nvisuals
; j
++) {
4342 if (vi
[j
].depth
== pf
[i
].depth
) {
4343 ddsfd
.ddsCaps
.dwCaps
= 0;
4344 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4345 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4346 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4347 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
4348 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= vi
[j
].red_mask
;
4349 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= vi
[j
].green_mask
;
4350 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= vi
[j
].blue_mask
;
4351 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4354 has_mode
[mode_index
] = 1;
4360 ERR("Did not find visual corresponding the the pixmap format !\n");
4366 /* Now to emulated modes */
4367 if (has_mode
[emu
] == 0) {
4370 int depth
= has_depth
[emu
];
4372 for (c
= 0; (c
< sizeof(ModeEmulations
) / sizeof(Convert
)) && (send_mode
== 0); c
++) {
4373 if (ModeEmulations
[c
].dest
.depth
== depth
) {
4374 /* Found an emulation function, now tries to find a matching visual / pixel format pair */
4375 for (l
= 0; (l
< npixmap
) && (send_mode
== 0); l
++) {
4376 if ((pf
[l
].depth
== ModeEmulations
[c
].screen
.depth
) &&
4377 (pf
[l
].bits_per_pixel
== ModeEmulations
[c
].screen
.bpp
)) {
4379 for (j
= 0; (j
< nvisuals
) && (send_mode
== 0); j
++) {
4380 if ((vi
[j
].depth
== pf
[l
].depth
) &&
4381 (vi
[j
].red_mask
== ModeEmulations
[c
].screen
.rmask
) &&
4382 (vi
[j
].green_mask
== ModeEmulations
[c
].screen
.gmask
) &&
4383 (vi
[j
].blue_mask
== ModeEmulations
[c
].screen
.bmask
)) {
4384 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
4385 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
4387 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
;
4388 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= 8;
4389 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= 0;
4390 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= 0;
4391 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= 0;
4393 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
4394 ddsfd
.ddpfPixelFormat
.u
.dwRGBBitCount
= ModeEmulations
[c
].dest
.bpp
;
4395 ddsfd
.ddpfPixelFormat
.u1
.dwRBitMask
= ModeEmulations
[c
].dest
.rmask
;
4396 ddsfd
.ddpfPixelFormat
.u2
.dwGBitMask
= ModeEmulations
[c
].dest
.gmask
;
4397 ddsfd
.ddpfPixelFormat
.u3
.dwBBitMask
= ModeEmulations
[c
].dest
.bmask
;
4399 ddsfd
.ddpfPixelFormat
.u4
.dwRGBAlphaBitMask
= 0;
4404 ERR("No visual corresponding to pixmap format !\n");
4418 if (TRACE_ON(ddraw
)) {
4419 TRACE("Enumerating with pixel format : \n");
4420 _dump_pixelformat(&(ddsfd
.ddpfPixelFormat
));
4424 for (mode
= 0; mode
< sizeof(modes
)/sizeof(modes
[0]); mode
++) {
4425 /* Do not enumerate modes we cannot handle anyway */
4426 if ((modes
[mode
].w
> maxWidth
) || (modes
[mode
].h
> maxHeight
))
4429 ddsfd
.dwWidth
= modes
[mode
].w
;
4430 ddsfd
.dwHeight
= modes
[mode
].h
;
4432 /* Now, send the mode description to the application */
4433 TRACE(" - mode %4ld - %4ld\n", ddsfd
.dwWidth
, ddsfd
.dwHeight
);
4434 if (!modescb(&ddsfd
, context
))
4438 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
4439 /* modeX is not standard VGA */
4440 ddsfd
.dwWidth
= 320;
4441 ddsfd
.dwHeight
= 200;
4442 if (!modescb(&ddsfd
, context
))
4455 #ifdef HAVE_LIBXXF86DGA
4456 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetDisplayMode(
4457 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4459 ICOM_THIS(IDirectDraw2Impl
,iface
);
4460 TRACE("(%p)->(%p)\n",This
,lpddsfd
);
4461 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4462 lpddsfd
->dwHeight
= This
->d
.height
;
4463 lpddsfd
->dwWidth
= This
->d
.width
;
4464 lpddsfd
->lPitch
= This
->e
.dga
.fb_width
*PFGET_BPP(This
->d
.directdraw_pixelformat
);
4465 lpddsfd
->dwBackBufferCount
= 1;
4466 lpddsfd
->u
.dwRefreshRate
= 60;
4467 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4468 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4471 #endif /* defined(HAVE_LIBXXF86DGA) */
4473 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetDisplayMode(
4474 LPDIRECTDRAW2 iface
,LPDDSURFACEDESC lpddsfd
4476 ICOM_THIS(IDirectDraw2Impl
,iface
);
4477 TRACE("(%p)->GetDisplayMode(%p)\n",This
,lpddsfd
);
4478 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
4479 lpddsfd
->dwHeight
= This
->d
.height
;
4480 lpddsfd
->dwWidth
= This
->d
.width
;
4481 lpddsfd
->lPitch
= lpddsfd
->dwWidth
* PFGET_BPP(This
->d
.directdraw_pixelformat
);
4482 lpddsfd
->dwBackBufferCount
= 1;
4483 lpddsfd
->u
.dwRefreshRate
= 60;
4484 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
4485 lpddsfd
->ddpfPixelFormat
= This
->d
.directdraw_pixelformat
;
4489 static HRESULT WINAPI
IDirectDraw2Impl_FlipToGDISurface(LPDIRECTDRAW2 iface
) {
4490 ICOM_THIS(IDirectDraw2Impl
,iface
);
4491 TRACE("(%p)->()\n",This
);
4495 static HRESULT WINAPI
IDirectDraw2Impl_GetMonitorFrequency(
4496 LPDIRECTDRAW2 iface
,LPDWORD freq
4498 ICOM_THIS(IDirectDraw2Impl
,iface
);
4499 FIXME("(%p)->(%p) returns 60 Hz always\n",This
,freq
);
4500 *freq
= 60*100; /* 60 Hz */
4504 /* what can we directly decompress? */
4505 static HRESULT WINAPI
IDirectDraw2Impl_GetFourCCCodes(
4506 LPDIRECTDRAW2 iface
,LPDWORD x
,LPDWORD y
4508 ICOM_THIS(IDirectDraw2Impl
,iface
);
4509 FIXME("(%p,%p,%p), stub\n",This
,x
,y
);
4513 static HRESULT WINAPI
IDirectDraw2Impl_EnumSurfaces(
4514 LPDIRECTDRAW2 iface
,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
4516 ICOM_THIS(IDirectDraw2Impl
,iface
);
4517 FIXME("(%p)->(0x%08lx,%p,%p,%p),stub!\n",This
,x
,ddsfd
,context
,ddsfcb
);
4521 static HRESULT WINAPI
IDirectDraw2Impl_Compact(
4522 LPDIRECTDRAW2 iface
)
4524 ICOM_THIS(IDirectDraw2Impl
,iface
);
4525 FIXME("(%p)->()\n", This
);
4530 static HRESULT WINAPI
IDirectDraw2Impl_GetGDISurface(LPDIRECTDRAW2 iface
,
4531 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
4532 ICOM_THIS(IDirectDraw2Impl
,iface
);
4533 FIXME("(%p)->(%p)\n", This
, lplpGDIDDSSurface
);
4538 static HRESULT WINAPI
IDirectDraw2Impl_GetScanLine(LPDIRECTDRAW2 iface
,
4539 LPDWORD lpdwScanLine
) {
4540 ICOM_THIS(IDirectDraw2Impl
,iface
);
4541 FIXME("(%p)->(%p)\n", This
, lpdwScanLine
);
4546 static HRESULT WINAPI
IDirectDraw2Impl_Initialize(LPDIRECTDRAW2 iface
,
4548 ICOM_THIS(IDirectDraw2Impl
,iface
);
4549 FIXME("(%p)->(%p)\n", This
, lpGUID
);
4554 #ifdef HAVE_LIBXXF86DGA
4556 /* Note: Hack so we can reuse the old functions without compiler warnings */
4557 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4558 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
4560 # define XCAST(fun) (void *)
4563 static ICOM_VTABLE(IDirectDraw
) dga_ddvt
=
4565 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4566 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
4567 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4568 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
4569 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4570 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4571 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
4572 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
4573 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4574 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
4575 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4576 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4577 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
4578 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
4579 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4580 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4581 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4582 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4583 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4584 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4585 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4586 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4587 DGA_IDirectDrawImpl_SetDisplayMode
,
4588 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4593 #endif /* defined(HAVE_LIBXXF86DGA) */
4595 /* Note: Hack so we can reuse the old functions without compiler warnings */
4596 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4597 # define XCAST(fun) (typeof(xlib_ddvt.fn##fun))
4599 # define XCAST(fun) (void *)
4602 static ICOM_VTABLE(IDirectDraw
) xlib_ddvt
=
4604 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4605 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
4606 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4607 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
4608 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4609 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4610 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
4611 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
4612 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4613 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4614 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4615 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4616 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
4617 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
4618 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4619 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4620 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4621 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4622 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4623 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4624 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4625 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4626 Xlib_IDirectDrawImpl_SetDisplayMode
,
4627 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4632 /*****************************************************************************
4638 #ifdef HAVE_LIBXXF86DGA
4639 static HRESULT WINAPI
DGA_IDirectDraw2Impl_SetDisplayMode(
4640 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
4642 return DGA_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
4644 #endif /* defined(HAVE_LIBXXF86DGA) */
4646 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_SetDisplayMode(
4647 LPDIRECTDRAW2 iface
,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
4649 return Xlib_IDirectDrawImpl_SetDisplayMode((LPDIRECTDRAW
)iface
,width
,height
,depth
);
4652 #ifdef HAVE_LIBXXF86DGA
4653 static HRESULT WINAPI
DGA_IDirectDraw2Impl_GetAvailableVidMem(
4654 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
4656 ICOM_THIS(IDirectDraw2Impl
,iface
);
4657 TRACE("(%p)->(%p,%p,%p)\n",
4658 This
,ddscaps
,total
,free
4660 if (total
) *total
= This
->e
.dga
.fb_memsize
* 1024;
4661 if (free
) *free
= This
->e
.dga
.fb_memsize
* 1024;
4664 #endif /* defined(HAVE_LIBXXF86DGA) */
4666 static HRESULT WINAPI
Xlib_IDirectDraw2Impl_GetAvailableVidMem(
4667 LPDIRECTDRAW2 iface
,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
4669 ICOM_THIS(IDirectDraw2Impl
,iface
);
4670 TRACE("(%p)->(%p,%p,%p)\n",
4671 This
,ddscaps
,total
,free
4673 if (total
) *total
= 2048 * 1024;
4674 if (free
) *free
= 2048 * 1024;
4678 #ifdef HAVE_LIBXXF86DGA
4679 static ICOM_VTABLE(IDirectDraw2
) dga_dd2vt
=
4681 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4682 DGA_IDirectDraw2Impl_QueryInterface
,
4683 IDirectDraw2Impl_AddRef
,
4684 DGA_IDirectDraw2Impl_Release
,
4685 IDirectDraw2Impl_Compact
,
4686 IDirectDraw2Impl_CreateClipper
,
4687 DGA_IDirectDraw2Impl_CreatePalette
,
4688 DGA_IDirectDraw2Impl_CreateSurface
,
4689 IDirectDraw2Impl_DuplicateSurface
,
4690 DGA_IDirectDraw2Impl_EnumDisplayModes
,
4691 IDirectDraw2Impl_EnumSurfaces
,
4692 IDirectDraw2Impl_FlipToGDISurface
,
4693 DGA_IDirectDraw2Impl_GetCaps
,
4694 DGA_IDirectDraw2Impl_GetDisplayMode
,
4695 IDirectDraw2Impl_GetFourCCCodes
,
4696 IDirectDraw2Impl_GetGDISurface
,
4697 IDirectDraw2Impl_GetMonitorFrequency
,
4698 IDirectDraw2Impl_GetScanLine
,
4699 IDirectDraw2Impl_GetVerticalBlankStatus
,
4700 IDirectDraw2Impl_Initialize
,
4701 DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4702 IDirectDraw2Impl_SetCooperativeLevel
,
4703 DGA_IDirectDraw2Impl_SetDisplayMode
,
4704 IDirectDraw2Impl_WaitForVerticalBlank
,
4705 DGA_IDirectDraw2Impl_GetAvailableVidMem
4707 #endif /* defined(HAVE_LIBXXF86DGA) */
4709 static ICOM_VTABLE(IDirectDraw2
) xlib_dd2vt
=
4711 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4712 Xlib_IDirectDraw2Impl_QueryInterface
,
4713 IDirectDraw2Impl_AddRef
,
4714 Xlib_IDirectDraw2Impl_Release
,
4715 IDirectDraw2Impl_Compact
,
4716 IDirectDraw2Impl_CreateClipper
,
4717 Xlib_IDirectDraw2Impl_CreatePalette
,
4718 Xlib_IDirectDraw2Impl_CreateSurface
,
4719 IDirectDraw2Impl_DuplicateSurface
,
4720 Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4721 IDirectDraw2Impl_EnumSurfaces
,
4722 IDirectDraw2Impl_FlipToGDISurface
,
4723 Xlib_IDirectDraw2Impl_GetCaps
,
4724 Xlib_IDirectDraw2Impl_GetDisplayMode
,
4725 IDirectDraw2Impl_GetFourCCCodes
,
4726 IDirectDraw2Impl_GetGDISurface
,
4727 IDirectDraw2Impl_GetMonitorFrequency
,
4728 IDirectDraw2Impl_GetScanLine
,
4729 IDirectDraw2Impl_GetVerticalBlankStatus
,
4730 IDirectDraw2Impl_Initialize
,
4731 Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4732 IDirectDraw2Impl_SetCooperativeLevel
,
4733 Xlib_IDirectDraw2Impl_SetDisplayMode
,
4734 IDirectDraw2Impl_WaitForVerticalBlank
,
4735 Xlib_IDirectDraw2Impl_GetAvailableVidMem
4738 /*****************************************************************************
4743 static HRESULT WINAPI
IDirectDraw4Impl_GetSurfaceFromDC(LPDIRECTDRAW4 iface
,
4745 LPDIRECTDRAWSURFACE
*lpDDS
) {
4746 ICOM_THIS(IDirectDraw4Impl
,iface
);
4747 FIXME("(%p)->(%08ld,%p)\n", This
, (DWORD
) hdc
, lpDDS
);
4752 static HRESULT WINAPI
IDirectDraw4Impl_RestoreAllSurfaces(LPDIRECTDRAW4 iface
) {
4753 ICOM_THIS(IDirectDraw4Impl
,iface
);
4754 FIXME("(%p)->()\n", This
);
4759 static HRESULT WINAPI
IDirectDraw4Impl_TestCooperativeLevel(LPDIRECTDRAW4 iface
) {
4760 ICOM_THIS(IDirectDraw4Impl
,iface
);
4761 FIXME("(%p)->()\n", This
);
4766 static HRESULT WINAPI
IDirectDraw4Impl_GetDeviceIdentifier(LPDIRECTDRAW4 iface
,
4767 LPDDDEVICEIDENTIFIER lpdddi
,
4769 ICOM_THIS(IDirectDraw4Impl
,iface
);
4770 FIXME("(%p)->(%p,%08lx)\n", This
, lpdddi
, dwFlags
);
4775 #ifdef HAVE_LIBXXF86DGA
4777 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4778 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
4780 # define XCAST(fun) (void*)
4783 static ICOM_VTABLE(IDirectDraw4
) dga_dd4vt
=
4785 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4786 XCAST(QueryInterface
)DGA_IDirectDraw2Impl_QueryInterface
,
4787 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4788 XCAST(Release
)DGA_IDirectDraw2Impl_Release
,
4789 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4790 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4791 XCAST(CreatePalette
)DGA_IDirectDraw2Impl_CreatePalette
,
4792 XCAST(CreateSurface
)DGA_IDirectDraw2Impl_CreateSurface
,
4793 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4794 XCAST(EnumDisplayModes
)DGA_IDirectDraw2Impl_EnumDisplayModes
,
4795 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4796 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4797 XCAST(GetCaps
)DGA_IDirectDraw2Impl_GetCaps
,
4798 XCAST(GetDisplayMode
)DGA_IDirectDraw2Impl_GetDisplayMode
,
4799 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4800 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4801 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4802 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4803 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4804 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4805 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2Impl_RestoreDisplayMode
,
4806 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4807 XCAST(SetDisplayMode
)DGA_IDirectDrawImpl_SetDisplayMode
,
4808 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4809 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2Impl_GetAvailableVidMem
,
4810 IDirectDraw4Impl_GetSurfaceFromDC
,
4811 IDirectDraw4Impl_RestoreAllSurfaces
,
4812 IDirectDraw4Impl_TestCooperativeLevel
,
4813 IDirectDraw4Impl_GetDeviceIdentifier
4818 #endif /* defined(HAVE_LIBXXF86DGA) */
4820 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
4821 # define XCAST(fun) (typeof(xlib_dd4vt.fn##fun))
4823 # define XCAST(fun) (void*)
4826 static ICOM_VTABLE(IDirectDraw4
) xlib_dd4vt
=
4828 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
4829 XCAST(QueryInterface
)Xlib_IDirectDraw2Impl_QueryInterface
,
4830 XCAST(AddRef
)IDirectDraw2Impl_AddRef
,
4831 XCAST(Release
)Xlib_IDirectDraw2Impl_Release
,
4832 XCAST(Compact
)IDirectDraw2Impl_Compact
,
4833 XCAST(CreateClipper
)IDirectDraw2Impl_CreateClipper
,
4834 XCAST(CreatePalette
)Xlib_IDirectDraw2Impl_CreatePalette
,
4835 XCAST(CreateSurface
)Xlib_IDirectDraw2Impl_CreateSurface
,
4836 XCAST(DuplicateSurface
)IDirectDraw2Impl_DuplicateSurface
,
4837 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2Impl_EnumDisplayModes
,
4838 XCAST(EnumSurfaces
)IDirectDraw2Impl_EnumSurfaces
,
4839 XCAST(FlipToGDISurface
)IDirectDraw2Impl_FlipToGDISurface
,
4840 XCAST(GetCaps
)Xlib_IDirectDraw2Impl_GetCaps
,
4841 XCAST(GetDisplayMode
)Xlib_IDirectDraw2Impl_GetDisplayMode
,
4842 XCAST(GetFourCCCodes
)IDirectDraw2Impl_GetFourCCCodes
,
4843 XCAST(GetGDISurface
)IDirectDraw2Impl_GetGDISurface
,
4844 XCAST(GetMonitorFrequency
)IDirectDraw2Impl_GetMonitorFrequency
,
4845 XCAST(GetScanLine
)IDirectDraw2Impl_GetScanLine
,
4846 XCAST(GetVerticalBlankStatus
)IDirectDraw2Impl_GetVerticalBlankStatus
,
4847 XCAST(Initialize
)IDirectDraw2Impl_Initialize
,
4848 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2Impl_RestoreDisplayMode
,
4849 XCAST(SetCooperativeLevel
)IDirectDraw2Impl_SetCooperativeLevel
,
4850 XCAST(SetDisplayMode
)Xlib_IDirectDrawImpl_SetDisplayMode
,
4851 XCAST(WaitForVerticalBlank
)IDirectDraw2Impl_WaitForVerticalBlank
,
4852 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2Impl_GetAvailableVidMem
,
4853 IDirectDraw4Impl_GetSurfaceFromDC
,
4854 IDirectDraw4Impl_RestoreAllSurfaces
,
4855 IDirectDraw4Impl_TestCooperativeLevel
,
4856 IDirectDraw4Impl_GetDeviceIdentifier
4861 /******************************************************************************
4865 static LRESULT WINAPI
Xlib_DDWndProc(HWND hwnd
,UINT msg
,WPARAM wParam
,LPARAM lParam
)
4868 IDirectDrawImpl
* ddraw
= NULL
;
4871 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
4873 SetLastError( ERROR_SUCCESS
);
4874 ddraw
= (IDirectDrawImpl
*)GetWindowLongA( hwnd
, ddrawXlibThisOffset
);
4876 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
4879 ERR("Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
4884 /* Perform any special direct draw functions */
4886 ddraw
->d
.paintable
= 1;
4888 /* Now let the application deal with the rest of this */
4889 if( ddraw
->d
.mainWindow
)
4892 /* Don't think that we actually need to call this but...
4893 might as well be on the safe side of things... */
4895 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
4896 it should be the procedures of our fake window that gets called
4897 instead of those of the window provided by the application.
4898 And with this patch, mouse clicks work with Monkey Island III
4900 ret
= DefWindowProcA( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
4904 WND
*tmpWnd
=WIN_FindWndPtr(ddraw
->d
.mainWindow
);
4905 /* We didn't handle the message - give it to the application */
4906 if (ddraw
&& ddraw
->d
.mainWindow
&& tmpWnd
)
4908 ret
= CallWindowProcA(tmpWnd
->winproc
,
4909 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
4911 WIN_ReleaseWndPtr(tmpWnd
);
4916 ret
= DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
4922 ret
= DefWindowProcA(hwnd
,msg
,wParam
,lParam
);
4928 static HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4929 #ifdef HAVE_LIBXXF86DGA
4930 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
4931 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
4936 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4937 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
4941 MESSAGE("Must be able to access /dev/mem to use XF86DGA!\n");
4942 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
4943 return E_UNEXPECTED
;
4945 if (!DDRAW_DGA_Available()) {
4946 TRACE("No XF86DGA detected.\n");
4947 return DDERR_GENERIC
;
4949 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
4950 ICOM_VTBL(*ilplpDD
) = &dga_ddvt
;
4951 (*ilplpDD
)->ref
= 1;
4952 TSXF86DGAQueryVersion(display
,&major
,&minor
);
4953 TRACE("XF86DGA is version %d.%d\n",major
,minor
);
4954 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
4955 if (!(flags
& XF86DGADirectPresent
))
4956 MESSAGE("direct video is NOT PRESENT.\n");
4957 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
4958 (*ilplpDD
)->e
.dga
.fb_width
= width
;
4959 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
4960 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
4961 (*ilplpDD
)->e
.dga
.fb_height
= height
;
4962 TRACE("video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4963 addr
,width
,banksize
,memsize
4965 TRACE("viewport height: %d\n",height
);
4967 /* Get the screen dimensions as seen by Wine.
4968 In that case, it may be better to ignore the -desktop mode and return the
4969 real screen size => print a warning */
4970 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4971 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4972 if (((*ilplpDD
)->d
.height
!= height
) ||
4973 ((*ilplpDD
)->d
.width
!= width
))
4974 WARN("You seem to be runnin in -desktop mode. This may prove dangerous in DGA mode...\n");
4975 (*ilplpDD
)->e
.dga
.fb_addr
= addr
;
4976 (*ilplpDD
)->e
.dga
.fb_memsize
= memsize
;
4977 (*ilplpDD
)->e
.dga
.fb_banksize
= banksize
;
4978 (*ilplpDD
)->e
.dga
.vpmask
= 0;
4980 /* just assume the default depth is the DGA depth too */
4981 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
4982 _common_depth_to_pixelformat(depth
, &((*ilplpDD
)->d
.directdraw_pixelformat
), &((*ilplpDD
)->d
.screen_pixelformat
), NULL
);
4983 #ifdef RESTORE_SIGNALS
4988 #else /* defined(HAVE_LIBXXF86DGA) */
4989 return DDERR_INVALIDDIRECTDRAWGUID
;
4990 #endif /* defined(HAVE_LIBXXF86DGA) */
4994 DDRAW_XSHM_Available(void)
4996 #ifdef HAVE_LIBXXSHM
4997 if (TSXShmQueryExtension(display
))
5002 if ((TSXShmQueryVersion(display
, &major
, &minor
, &shpix
)) &&
5003 (Options
.noXSHM
!= 1))
5015 static HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
5016 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
5019 *ilplpDD
= (IDirectDrawImpl
*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawImpl
));
5020 ICOM_VTBL(*ilplpDD
) = &xlib_ddvt
;
5021 (*ilplpDD
)->ref
= 1;
5022 (*ilplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
5024 /* At DirectDraw creation, the depth is the default depth */
5025 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
5026 _common_depth_to_pixelformat(depth
,
5027 &((*ilplpDD
)->d
.directdraw_pixelformat
),
5028 &((*ilplpDD
)->d
.screen_pixelformat
),
5029 &((*ilplpDD
)->d
.pixmap_depth
));
5030 (*ilplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
5031 (*ilplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
5033 #ifdef HAVE_LIBXXSHM
5034 /* Test if XShm is available. */
5035 if (((*ilplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available())) {
5036 (*ilplpDD
)->e
.xlib
.xshm_compl
= 0;
5037 TRACE("Using XShm extension.\n");
5044 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
5045 IDirectDrawImpl
** ilplpDD
=(IDirectDrawImpl
**)lplpDD
;
5048 /* WND* pParentWindow; */
5052 WINE_StringFromCLSID(lpGUID
,xclsid
);
5054 sprintf(xclsid
,"<guid-0x%08x>",(int)lpGUID
);
5058 TRACE("(%s,%p,%p)\n",xclsid
,ilplpDD
,pUnkOuter
);
5061 ( IsEqualGUID( &IID_IDirectDraw
, lpGUID
) ) ||
5062 ( IsEqualGUID( &IID_IDirectDraw2
, lpGUID
) ) ||
5063 ( IsEqualGUID( &IID_IDirectDraw4
, lpGUID
) ) ) {
5064 /* if they didn't request a particular interface, use the best
5066 if (DDRAW_DGA_Available())
5067 lpGUID
= &DGA_DirectDraw_GUID
;
5069 lpGUID
= &XLIB_DirectDraw_GUID
;
5072 wc
.style
= CS_GLOBALCLASS
;
5073 wc
.lpfnWndProc
= Xlib_DDWndProc
;
5075 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
5076 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
5078 /* We can be a child of the desktop since we're really important */
5080 This code is not useful since hInstance is forced to 0 afterward
5081 pParentWindow = WIN_GetDesktop();
5082 wc.hInstance = pParentWindow ? pParentWindow->hwndSelf : 0;
5088 wc
.hCursor
= (HCURSOR
)IDC_ARROWA
;
5089 wc
.hbrBackground
= NULL_BRUSH
;
5090 wc
.lpszMenuName
= 0;
5091 wc
.lpszClassName
= "WINE_DirectDraw";
5092 RegisterClassA(&wc
);
5094 if ( IsEqualGUID( &DGA_DirectDraw_GUID
, lpGUID
) ) {
5095 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
5097 else if ( IsEqualGUID( &XLIB_DirectDraw_GUID
, &XLIB_DirectDraw_GUID
) ) {
5098 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
5105 (*ilplpDD
)->d
.winclass
= RegisterClassA(&wc
);
5109 ERR("DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
5110 return DDERR_INVALIDDIRECTDRAWGUID
;
5113 /*******************************************************************************
5114 * DirectDraw ClassFactory
5116 * Heavily inspired (well, can you say completely copied :-) ) from DirectSound
5121 /* IUnknown fields */
5122 ICOM_VFIELD(IClassFactory
);
5124 } IClassFactoryImpl
;
5126 static HRESULT WINAPI
5127 DDCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
) {
5128 ICOM_THIS(IClassFactoryImpl
,iface
);
5132 WINE_StringFromCLSID(riid
,buf
);
5134 sprintf(buf
,"<guid-0x%04x>",LOWORD(riid
));
5135 FIXME("(%p)->(%s,%p),stub!\n",This
,buf
,ppobj
);
5136 return E_NOINTERFACE
;
5140 DDCF_AddRef(LPCLASSFACTORY iface
) {
5141 ICOM_THIS(IClassFactoryImpl
,iface
);
5142 return ++(This
->ref
);
5145 static ULONG WINAPI
DDCF_Release(LPCLASSFACTORY iface
) {
5146 ICOM_THIS(IClassFactoryImpl
,iface
);
5147 /* static class, won't be freed */
5148 return --(This
->ref
);
5151 static HRESULT WINAPI
DDCF_CreateInstance(
5152 LPCLASSFACTORY iface
,LPUNKNOWN pOuter
,REFIID riid
,LPVOID
*ppobj
5154 ICOM_THIS(IClassFactoryImpl
,iface
);
5157 WINE_StringFromCLSID(riid
,buf
);
5158 TRACE("(%p)->(%p,%s,%p)\n",This
,pOuter
,buf
,ppobj
);
5159 if ( ( IsEqualGUID( &IID_IDirectDraw
, riid
) ) ||
5160 ( IsEqualGUID( &IID_IDirectDraw2
, riid
) ) ||
5161 ( IsEqualGUID( &IID_IDirectDraw4
, riid
) ) ) {
5162 /* FIXME: reuse already created DirectDraw if present? */
5163 return DirectDrawCreate((LPGUID
) riid
,(LPDIRECTDRAW
*)ppobj
,pOuter
);
5165 return CLASS_E_CLASSNOTAVAILABLE
;
5168 static HRESULT WINAPI
DDCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
5169 ICOM_THIS(IClassFactoryImpl
,iface
);
5170 FIXME("(%p)->(%d),stub!\n",This
,dolock
);
5174 static ICOM_VTABLE(IClassFactory
) DDCF_Vtbl
=
5176 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
5177 DDCF_QueryInterface
,
5180 DDCF_CreateInstance
,
5183 static IClassFactoryImpl DDRAW_CF
= {&DDCF_Vtbl
, 1 };
5185 /*******************************************************************************
5186 * DllGetClassObject [DDRAW.13]
5187 * Retrieves class object from a DLL object
5190 * Docs say returns STDAPI
5193 * rclsid [I] CLSID for the class object
5194 * riid [I] Reference to identifier of interface for class object
5195 * ppv [O] Address of variable to receive interface pointer for riid
5199 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
5202 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
,REFIID riid
,LPVOID
*ppv
)
5204 char buf
[80],xbuf
[80];
5207 WINE_StringFromCLSID(rclsid
,xbuf
);
5209 sprintf(xbuf
,"<guid-0x%04x>",LOWORD(rclsid
));
5211 WINE_StringFromCLSID(riid
,buf
);
5213 sprintf(buf
,"<guid-0x%04x>",LOWORD(riid
));
5214 WINE_StringFromCLSID(riid
,xbuf
);
5215 TRACE("(%p,%p,%p)\n", xbuf
, buf
, ppv
);
5216 if ( IsEqualCLSID( &IID_IClassFactory
, riid
) ) {
5217 *ppv
= (LPVOID
)&DDRAW_CF
;
5218 IClassFactory_AddRef((IClassFactory
*)*ppv
);
5221 FIXME("(%p,%p,%p): no interface found.\n", xbuf
, buf
, ppv
);
5222 return CLASS_E_CLASSNOTAVAILABLE
;
5226 /*******************************************************************************
5227 * DllCanUnloadNow [DDRAW.12] Determines whether the DLL is in use.
5233 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5235 FIXME("(void): stub\n");
5239 #else /* !defined(X_DISPLAY_MISSING) */
5242 #include "winerror.h"
5247 typedef void *LPUNKNOWN
;
5248 typedef void *LPDIRECTDRAW
;
5249 typedef void *LPDIRECTDRAWCLIPPER
;
5250 typedef void *LPDDENUMCALLBACKA
;
5251 typedef void *LPDDENUMCALLBACKEXA
;
5252 typedef void *LPDDENUMCALLBACKEXW
;
5253 typedef void *LPDDENUMCALLBACKW
;
5255 HRESULT WINAPI
DSoundHelp(DWORD x
, DWORD y
, DWORD z
)
5260 HRESULT WINAPI
DirectDrawCreate(
5261 LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
)
5266 HRESULT WINAPI
DirectDrawCreateClipper(
5267 DWORD dwFlags
, LPDIRECTDRAWCLIPPER
*lplpDDClipper
, LPUNKNOWN pUnkOuter
)
5272 HRESULT WINAPI
DirectDrawEnumerateA(
5273 LPDDENUMCALLBACKA lpCallback
, LPVOID lpContext
)
5278 HRESULT WINAPI
DirectDrawEnumerateExA(
5279 LPDDENUMCALLBACKEXA lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5284 HRESULT WINAPI
DirectDrawEnumerateExW(
5285 LPDDENUMCALLBACKEXW lpCallback
, LPVOID lpContext
, DWORD dwFlags
)
5290 HRESULT WINAPI
DirectDrawEnumerateW(
5291 LPDDENUMCALLBACKW lpCallback
, LPVOID lpContext
)
5296 DWORD WINAPI
DDRAW_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
5298 return CLASS_E_CLASSNOTAVAILABLE
;
5301 DWORD WINAPI
DDRAW_DllCanUnloadNow(void)
5306 #endif /* !defined(X_DISPLAY_MISSING) */