1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 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.
23 #include <sys/types.h>
27 #endif /* defined(HAVE_LIBXXSHM) */
29 #ifdef HAVE_LIBXXF86DGA
30 #include "ts_xf86dga.h"
31 #endif /* defined(HAVE_LIBXXF86DGA) */
33 #ifdef HAVE_LIBXXF86VM
34 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
35 this is a crude hack to get around it */
38 #include "ts_xf86vmode.h"
39 #endif /* defined(HAVE_LIBXXF86VM) */
45 #include <sys/signal.h>
64 /* This for all the enumeration and creation of D3D-related objects */
65 #include "d3d_private.h"
67 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
70 /* Restore signal handlers overwritten by XF86DGA
72 #define RESTORE_SIGNALS
74 /* Where do these GUIDs come from? mkuuid.
75 * They exist solely to distinguish between the targets Wine support,
76 * and should be different than any other GUIDs in existence.
78 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
82 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
85 static GUID XLIB_DirectDraw_GUID
= { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
89 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
92 static struct IDirectDrawSurface4_VTable dga_dds4vt
, xlib_dds4vt
;
93 static struct IDirectDraw_VTable dga_ddvt
, xlib_ddvt
;
94 static struct IDirectDraw2_VTable dga_dd2vt
, xlib_dd2vt
;
95 static struct IDirectDraw4_VTable dga_dd4vt
, xlib_dd4vt
;
96 static struct IDirectDrawClipper_VTable ddclipvt
;
97 static struct IDirectDrawPalette_VTable dga_ddpalvt
, xlib_ddpalvt
;
98 static struct IDirect3D_VTable d3dvt
;
99 static struct IDirect3D2_VTable d3d2vt
;
101 #ifdef HAVE_LIBXXF86VM
102 static XF86VidModeModeInfo
*orig_mode
= NULL
;
106 static int XShmErrorFlag
= 0;
110 DDRAW_DGA_Available(void)
112 #ifdef HAVE_LIBXXF86DGA
113 int evbase
, evret
, fd
;
118 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
119 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
120 /* others. --stephenc */
121 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
124 return (fd
!= -1) && TSXF86DGAQueryExtension(display
,&evbase
,&evret
);
125 #else /* defined(HAVE_LIBXXF86DGA) */
127 #endif /* defined(HAVE_LIBXXF86DGA) */
131 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc
,LPVOID data
) {
132 if (DDRAW_DGA_Available()) {
133 TRACE(ddraw
, "Enumerating DGA interface\n");
134 ddenumproc(&DGA_DirectDraw_GUID
,"WINE with XFree86 DGA","display",data
);
136 TRACE(ddraw
, "Enumerating Xlib interface\n");
137 ddenumproc(&XLIB_DirectDraw_GUID
,"WINE with Xlib","display",data
);
138 TRACE(ddraw
, "Enumerating Default interface\n");
139 ddenumproc(NULL
,"WINE (default)","display",data
);
143 /* What is this doing here? */
145 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
146 FIXME(ddraw
,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
151 /******************************************************************************
152 * internal helper functions
154 static void _dump_DDBLTFX(DWORD flagmask
) {
160 #define FE(x) { x, #x},
161 FE(DDBLTFX_ARITHSTRETCHY
)
162 FE(DDBLTFX_MIRRORLEFTRIGHT
)
163 FE(DDBLTFX_MIRRORUPDOWN
)
164 FE(DDBLTFX_NOTEARING
)
165 FE(DDBLTFX_ROTATE180
)
166 FE(DDBLTFX_ROTATE270
)
168 FE(DDBLTFX_ZBUFFERRANGE
)
169 FE(DDBLTFX_ZBUFFERBASEDEST
)
171 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
172 if (flags
[i
].mask
& flagmask
) {
173 DUMP("%s ",flags
[i
].name
);
180 static void _dump_DDBLTFAST(DWORD flagmask
) {
186 #define FE(x) { x, #x},
187 FE(DDBLTFAST_NOCOLORKEY
)
188 FE(DDBLTFAST_SRCCOLORKEY
)
189 FE(DDBLTFAST_DESTCOLORKEY
)
192 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
193 if (flags
[i
].mask
& flagmask
)
194 DUMP("%s ",flags
[i
].name
);
198 static void _dump_DDBLT(DWORD flagmask
) {
204 #define FE(x) { x, #x},
206 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
207 FE(DDBLT_ALPHADESTNEG
)
208 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
209 FE(DDBLT_ALPHAEDGEBLEND
)
211 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
212 FE(DDBLT_ALPHASRCNEG
)
213 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
219 FE(DDBLT_KEYDESTOVERRIDE
)
221 FE(DDBLT_KEYSRCOVERRIDE
)
223 FE(DDBLT_ROTATIONANGLE
)
225 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
226 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
227 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
228 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
232 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
233 if (flags
[i
].mask
& flagmask
)
234 DUMP("%s ",flags
[i
].name
);
238 static void _dump_DDSCAPS(DWORD flagmask
) {
244 #define FE(x) { x, #x},
245 FE(DDSCAPS_RESERVED1
)
247 FE(DDSCAPS_BACKBUFFER
)
250 FE(DDSCAPS_FRONTBUFFER
)
251 FE(DDSCAPS_OFFSCREENPLAIN
)
254 FE(DDSCAPS_PRIMARYSURFACE
)
255 FE(DDSCAPS_PRIMARYSURFACELEFT
)
256 FE(DDSCAPS_SYSTEMMEMORY
)
259 FE(DDSCAPS_VIDEOMEMORY
)
261 FE(DDSCAPS_WRITEONLY
)
264 FE(DDSCAPS_LIVEVIDEO
)
268 FE(DDSCAPS_RESERVED2
)
269 FE(DDSCAPS_ALLOCONLOAD
)
270 FE(DDSCAPS_VIDEOPORT
)
271 FE(DDSCAPS_LOCALVIDMEM
)
272 FE(DDSCAPS_NONLOCALVIDMEM
)
273 FE(DDSCAPS_STANDARDVGAMODE
)
274 FE(DDSCAPS_OPTIMIZED
)
276 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
277 if (flags
[i
].mask
& flagmask
)
278 DUMP("%s ",flags
[i
].name
);
282 static void _dump_DDSD(DWORD flagmask
) {
292 FE(DDSD_BACKBUFFERCOUNT
)
293 FE(DDSD_ZBUFFERBITDEPTH
)
294 FE(DDSD_ALPHABITDEPTH
)
296 FE(DDSD_CKDESTOVERLAY
)
298 FE(DDSD_CKSRCOVERLAY
)
305 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
306 if (flags
[i
].mask
& flagmask
)
307 DUMP("%s ",flags
[i
].name
);
311 static void _dump_DDCOLORKEY(DWORD flagmask
) {
317 #define FE(x) { x, #x},
321 FE(DDPF_PALETTEINDEXED4
)
322 FE(DDPF_PALETTEINDEXEDTO8
)
323 FE(DDPF_PALETTEINDEXED8
)
329 FE(DDPF_PALETTEINDEXED1
)
330 FE(DDPF_PALETTEINDEXED2
)
333 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
334 if (flags
[i
].mask
& flagmask
)
335 DUMP("%s ",flags
[i
].name
);
339 static void _dump_paletteformat(DWORD dwFlags
) {
345 #define FE(x) { x, #x},
347 FE(DDPCAPS_8BITENTRIES
)
349 FE(DDPCAPS_INITIALIZE
)
350 FE(DDPCAPS_PRIMARYSURFACE
)
351 FE(DDPCAPS_PRIMARYSURFACELEFT
)
358 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
359 if (flags
[i
].mask
& dwFlags
)
360 DUMP("%s ",flags
[i
].name
);
364 static void _dump_pixelformat(LPDDPIXELFORMAT pf
) {
365 DUMP("Size : %ld\n", pf
->dwSize
);
367 _dump_DDCOLORKEY(pf
->dwFlags
);
368 DUMP("dwFourCC : %ld\n", pf
->dwFourCC
);
369 DUMP("RGB bit count : %ld\n", pf
->x
.dwRGBBitCount
);
370 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
371 pf
->y
.dwRBitMask
, pf
->z
.dwGBitMask
, pf
->xx
.dwBBitMask
, pf
->xy
.dwRGBAlphaBitMask
);
374 static int _getpixelformat(LPDIRECTDRAW2 ddraw
,LPDDPIXELFORMAT pf
) {
375 static XVisualInfo
*vi
;
380 vi
= TSXGetVisualInfo(display
,VisualNoMask
,&vt
,&nitems
);
383 pf
->dwSize
= sizeof(DDPIXELFORMAT
);
384 if (ddraw
->d
.depth
==8) {
385 pf
->dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
386 pf
->x
.dwRGBBitCount
= 8;
387 pf
->y
.dwRBitMask
= 0;
388 pf
->z
.dwGBitMask
= 0;
389 pf
->xx
.dwBBitMask
= 0;
390 pf
->xy
.dwRGBAlphaBitMask
= 0;
393 if (ddraw
->d
.depth
==16) {
394 pf
->dwFlags
= DDPF_RGB
;
395 pf
->x
.dwRGBBitCount
= 16;
396 pf
->y
.dwRBitMask
= vi
[0].red_mask
;
397 pf
->z
.dwGBitMask
= vi
[0].green_mask
;
398 pf
->xx
.dwBBitMask
= vi
[0].blue_mask
;
399 pf
->xy
.dwRGBAlphaBitMask
= 0;
402 if (ddraw
->d
.depth
==24) {
403 pf
->dwFlags
= DDPF_RGB
;
404 pf
->x
.dwRGBBitCount
= 24;
405 pf
->y
.dwRBitMask
= vi
[0].red_mask
;
406 pf
->z
.dwGBitMask
= vi
[0].green_mask
;
407 pf
->xx
.dwBBitMask
= vi
[0].blue_mask
;
408 pf
->xy
.dwRGBAlphaBitMask
= 0;
411 FIXME(ddraw
,"_getpixelformat:unknown depth %ld?\n",ddraw
->d
.depth
);
412 return DDERR_GENERIC
;
415 /******************************************************************************
416 * IDirectDrawSurface methods
418 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
419 * DDS and DDS2 use those functions. (Function calls did not change (except
420 * using different DirectDrawSurfaceX version), just added flags and functions)
422 static HRESULT WINAPI
IDirectDrawSurface4_Lock(
423 LPDIRECTDRAWSURFACE4
this,LPRECT32 lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE32 hnd
425 TRACE(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
426 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
427 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
428 WARN(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
429 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
431 /* First, copy the Surface description */
432 *lpddsd
= this->s
.surface_desc
;
433 TRACE(ddraw
,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
434 lpddsd
->dwHeight
,lpddsd
->dwWidth
,lpddsd
->lPitch
);
436 /* If asked only for a part, change the surface pointer */
438 FIXME(ddraw
," lprect: %dx%d-%dx%d\n",
439 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
441 lpddsd
->y
.lpSurface
= this->s
.surface_desc
.y
.lpSurface
+
442 (lprect
->top
*this->s
.surface_desc
.lPitch
) +
443 (lprect
->left
*(this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8));
445 assert(this->s
.surface_desc
.y
.lpSurface
);
450 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Unlock(
451 LPDIRECTDRAWSURFACE4
this,LPVOID surface
453 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
457 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4
this) {
458 if (this->s
.ddraw
->d
.depth
!= this->s
.ddraw
->d
.screen_depth
) {
459 /* Pixel convertion ! */
460 if ((this->s
.ddraw
->d
.depth
== 8) && (this->s
.ddraw
->d
.screen_depth
== 16)) {
461 unsigned char *src
= (unsigned char *) this->s
.surface_desc
.y
.lpSurface
;
462 unsigned short *dst
= (unsigned short *) this->t
.xlib
.image
->data
;
466 if (this->s
.palette
!= NULL
) {
467 pal
= (unsigned short *) this->s
.palette
->screen_palents
;
468 for (y
= 0; y
< this->s
.surface_desc
.dwHeight
; y
++) {
469 for (x
= 0; x
< this->s
.surface_desc
.dwWidth
; x
++) {
470 dst
[x
+ y
* this->s
.surface_desc
.lPitch
] = pal
[src
[x
+ y
* this->s
.surface_desc
.lPitch
]];
474 WARN(ddraw
, "No palette set...\n");
475 memset(dst
, 0, this->s
.surface_desc
.lPitch
* this->s
.surface_desc
.dwHeight
* 2);
478 ERR(ddraw
, "Unsupported pixel convertion...\n");
483 if (this->s
.ddraw
->e
.xlib
.xshm_active
)
484 TSXShmPutImage(display
,
485 this->s
.ddraw
->d
.drawable
,
486 DefaultGCOfScreen(X11DRV_GetXScreen()),
489 this->t
.xlib
.image
->width
,
490 this->t
.xlib
.image
->height
,
494 TSXPutImage( display
,
495 this->s
.ddraw
->d
.drawable
,
496 DefaultGCOfScreen(X11DRV_GetXScreen()),
499 this->t
.xlib
.image
->width
,
500 this->t
.xlib
.image
->height
);
503 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Unlock(
504 LPDIRECTDRAWSURFACE4
this,LPVOID surface
)
506 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
508 if (!this->s
.ddraw
->d
.paintable
)
511 /* Only redraw the screen when unlocking the buffer that is on screen */
512 if ((this->t
.xlib
.image
!= NULL
) &&
513 (this->s
.surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VISIBLE
)) {
514 Xlib_copy_surface_on_screen(this);
516 if (this->s
.palette
&& this->s
.palette
->cm
)
517 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
523 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Flip(
524 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
526 #ifdef HAVE_LIBXXF86DGA
527 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
529 if (this->s
.backbuffer
)
530 flipto
= this->s
.backbuffer
;
534 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,flipto
->t
.dga
.fb_height
);
536 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
537 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),flipto
->s
.palette
->cm
);
539 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
545 tmp
= this->t
.dga
.fb_height
;
546 this->t
.dga
.fb_height
= flipto
->t
.dga
.fb_height
;
547 flipto
->t
.dga
.fb_height
= tmp
;
549 ptmp
= this->s
.surface_desc
.y
.lpSurface
;
550 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
551 flipto
->s
.surface_desc
.y
.lpSurface
= ptmp
;
554 #else /* defined(HAVE_LIBXXF86DGA) */
556 #endif /* defined(HAVE_LIBXXF86DGA) */
559 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Flip(
560 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
562 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
563 if (!this->s
.ddraw
->d
.paintable
)
567 if (this->s
.backbuffer
)
568 flipto
= this->s
.backbuffer
;
573 Xlib_copy_surface_on_screen(this);
575 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
576 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,flipto
->s
.palette
->cm
);
581 tmp
= this->t
.xlib
.image
;
582 this->t
.xlib
.image
= flipto
->t
.xlib
.image
;
583 flipto
->t
.xlib
.image
= tmp
;
584 surf
= this->s
.surface_desc
.y
.lpSurface
;
585 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
586 flipto
->s
.surface_desc
.y
.lpSurface
= surf
;
592 /* The IDirectDrawSurface4::SetPalette method attaches the specified
593 * DirectDrawPalette object to a surface. The surface uses this palette for all
594 * subsequent operations. The palette change takes place immediately.
596 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_SetPalette(
597 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
600 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
603 if( this->s
.palette
!= NULL
)
604 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
605 this->s
.palette
= pal
;
610 if( !(pal
->cm
) && (this->s
.ddraw
->d
.screen_depth
<=8))
612 pal
->cm
= TSXCreateColormap(display
,this->s
.ddraw
->d
.drawable
,
613 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
615 if (!Options
.managed
)
616 TSXInstallColormap(display
,pal
->cm
);
618 for (i
=0;i
<256;i
++) {
621 xc
.red
= pal
->palents
[i
].peRed
<<8;
622 xc
.blue
= pal
->palents
[i
].peBlue
<<8;
623 xc
.green
= pal
->palents
[i
].peGreen
<<8;
624 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
626 TSXStoreColor(display
,pal
->cm
,&xc
);
628 TSXInstallColormap(display
,pal
->cm
);
631 /* According to spec, we are only supposed to
632 * AddRef if this is not the same palette.
634 if( this->s
.palette
!= pal
)
637 pal
->lpvtbl
->fnAddRef( pal
);
638 if( this->s
.palette
!= NULL
)
639 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
640 this->s
.palette
= pal
;
642 /* I think that we need to attach it to all backbuffers...*/
643 if( this->s
.backbuffer
) {
644 if( this->s
.backbuffer
->s
.palette
)
645 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(
646 this->s
.backbuffer
->s
.palette
);
647 this->s
.backbuffer
->s
.palette
= pal
;
649 pal
->lpvtbl
->fnAddRef( pal
);
651 /* Perform the refresh */
652 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
657 static HRESULT WINAPI
DGA_IDirectDrawSurface4_SetPalette(
658 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
660 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
661 #ifdef HAVE_LIBXXF86DGA
662 /* According to spec, we are only supposed to
663 * AddRef if this is not the same palette.
665 if( this->s
.palette
!= pal
)
668 pal
->lpvtbl
->fnAddRef( pal
);
669 if( this->s
.palette
!= NULL
)
670 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
671 this->s
.palette
= pal
;
673 /* I think that we need to attach it to all backbuffers...*/
674 if( this->s
.backbuffer
) {
675 if( this->s
.backbuffer
->s
.palette
)
676 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(this->s
.backbuffer
->s
.palette
);
677 this->s
.backbuffer
->s
.palette
= pal
;
678 if( pal
) pal
->lpvtbl
->fnAddRef( pal
);
680 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->s
.palette
->cm
);
683 #else /* defined(HAVE_LIBXXF86DGA) */
685 #endif /* defined(HAVE_LIBXXF86DGA) */
690 static HRESULT WINAPI
IDirectDrawSurface4_Blt(
691 LPDIRECTDRAWSURFACE4
this,LPRECT32 rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT32 rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
694 DDSURFACEDESC ddesc
,sdesc
;
697 TRACE(ddraw
,"(%p)->(%p,%p,%p,%08lx,%p)\n",
698 this,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
701 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,0,0);
702 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,0,0);
704 if (TRACE_ON(ddraw
)) {
705 if (rdst
) TRACE(ddraw
," destrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
706 if (rsrc
) TRACE(ddraw
," srcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
707 TRACE(ddraw
,"\tflags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
708 if (dwFlags
& DDBLT_DDFX
) {
709 TRACE(ddraw
," blitfx: \n");_dump_DDBLTFX(lpbltfx
->dwDDFX
);
714 memcpy(&xdst
,rdst
,sizeof(xdst
));
717 xdst
.bottom
= ddesc
.dwHeight
;
719 xdst
.right
= ddesc
.dwWidth
;
723 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
727 xsrc
.bottom
= sdesc
.dwHeight
;
729 xsrc
.right
= sdesc
.dwWidth
;
731 memset(&xsrc
,0,sizeof(xsrc
));
735 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
737 /* First, all the 'source-less' blits */
738 if (dwFlags
& DDBLT_COLORFILL
) {
739 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
742 xline
= (LPBYTE
) ddesc
.y
.lpSurface
+ xdst
.top
* ddesc
.lPitch
;
743 for (i
=xdst
.top
;i
<xdst
.bottom
;i
++) {
744 xpixel
= xline
+bpp
*xdst
.left
;
746 for (j
=xdst
.left
;j
<xdst
.right
;j
++) {
747 /* FIXME: this only works on little endian
748 * architectures, where DWORD starts with low
751 memcpy(xpixel
,&(lpbltfx
->b
.dwFillColor
),bpp
);
754 xline
+= ddesc
.lPitch
;
756 dwFlags
&= ~(DDBLT_COLORFILL
);
759 if (dwFlags
& DDBLT_DEPTHFILL
) {
763 /* Clears the screen */
764 TRACE(ddraw
, " Filling depth buffer with %ld\n", lpbltfx
->b
.dwFillDepth
);
765 glClearDepth(lpbltfx
->b
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
766 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
767 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
768 glClear(GL_DEPTH_BUFFER_BIT
);
771 dwFlags
&= ~(DDBLT_DEPTHFILL
);
777 TRACE(ddraw
,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
779 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
783 /* Now the 'with source' blits */
785 /* Standard 'full-surface' blit without special effects */
786 if ( (xsrc
.top
==0) && (xsrc
.bottom
==ddesc
.dwHeight
) &&
787 (xsrc
.left
==0) && (xsrc
.right
==ddesc
.dwWidth
) &&
788 (xdst
.top
==0) && (xdst
.bottom
==ddesc
.dwHeight
) &&
789 (xdst
.left
==0) && (xdst
.right
==ddesc
.dwWidth
) &&
792 memcpy(ddesc
.y
.lpSurface
,
794 ddesc
.dwHeight
* ddesc
.lPitch
);
796 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
797 int srcheight
= xsrc
.bottom
- xsrc
.top
;
798 int srcwidth
= xsrc
.right
- xsrc
.left
;
799 int dstheight
= xdst
.bottom
- xdst
.top
;
800 int dstwidth
= xdst
.right
- xdst
.left
;
801 int width
= (xsrc
.right
- xsrc
.left
) * bpp
;
804 /* Sanity check for rectangle sizes */
805 if ((srcheight
!= dstheight
) || (srcwidth
!= dstwidth
)) {
808 /* I think we should do a Blit with 'stretching' here....
809 Tomb Raider II uses this to display the background during the menu selection
810 when the screen resolution is != than 640x480 */
811 TRACE(ddraw
, "Blt with stretching\n");
813 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
815 /* In this case, we cannot do any anti-aliasing */
816 if(dwFlags
& DDBLT_KEYSRC
) {
817 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
818 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
821 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
822 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
824 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
825 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
827 tmp
= sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
829 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
830 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
831 dbuf
[(y
* ddesc
.lPitch
) + x
] = tmp
;
835 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
836 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
838 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
839 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
841 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
842 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
844 dbuf
[(y
* ddesc
.lPitch
) + x
] = sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
849 FIXME(ddraw
, "Not done yet for depth != 8\n");
852 /* Same size => fast blit */
853 if (dwFlags
& DDBLT_KEYSRC
) {
856 unsigned char tmp
,*psrc
,*pdst
;
859 for (h
= 0; h
< srcheight
; h
++) {
860 psrc
=sdesc
.y
.lpSurface
+
861 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
862 pdst
=ddesc
.y
.lpSurface
+
863 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
864 for(i
=0;i
<srcwidth
;i
++) {
866 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
867 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
871 dwFlags
&=~(DDBLT_KEYSRC
);
875 unsigned short tmp
,*psrc
,*pdst
;
878 for (h
= 0; h
< srcheight
; h
++) {
879 psrc
=sdesc
.y
.lpSurface
+
880 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
881 pdst
=ddesc
.y
.lpSurface
+
882 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
883 for(i
=0;i
<srcwidth
;i
++) {
885 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
886 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
890 dwFlags
&=~(DDBLT_KEYSRC
);
894 FIXME(ddraw
, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
897 /* Non-stretching Blt without color keying */
898 for (h
= 0; h
< srcheight
; h
++) {
899 memcpy(ddesc
.y
.lpSurface
+ ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
* bpp
,
900 sdesc
.y
.lpSurface
+ ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
* bpp
,
907 if (dwFlags
&& FIXME_ON(ddraw
)) {
908 FIXME(ddraw
,"\tUnsupported flags: ");_dump_DDBLT(dwFlags
);
911 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
912 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
917 static HRESULT WINAPI
IDirectDrawSurface4_BltFast(
918 LPDIRECTDRAWSURFACE4
this,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT32 rsrc
,DWORD trans
921 DDSURFACEDESC ddesc
,sdesc
;
923 if (1 || TRACE_ON(ddraw
)) {
924 FIXME(ddraw
,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
925 this,dstx
,dsty
,src
,rsrc
,trans
927 FIXME(ddraw
," trans:");
929 _dump_DDBLTFAST(trans
);
930 FIXME(ddraw
," srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
932 /* We need to lock the surfaces, or we won't get refreshes when done. */
933 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
934 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
935 bpp
= this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
936 h
=rsrc
->bottom
-rsrc
->top
;
937 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
938 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
940 w
=rsrc
->right
-rsrc
->left
;
941 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
942 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
946 memcpy( ddesc
.y
.lpSurface
+(dsty
+i
)*ddesc
.lPitch
+dstx
*bpp
,
947 sdesc
.y
.lpSurface
+(rsrc
->top
+i
)*sdesc
.lPitch
+rsrc
->left
*bpp
,
951 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
952 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
956 static HRESULT WINAPI
IDirectDrawSurface4_BltBatch(
957 LPDIRECTDRAWSURFACE4
this,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
959 FIXME(ddraw
,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
965 static HRESULT WINAPI
IDirectDrawSurface4_GetCaps(
966 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS caps
968 TRACE(ddraw
,"(%p)->GetCaps(%p)\n",this,caps
);
969 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
973 static HRESULT WINAPI
IDirectDrawSurface4_GetSurfaceDesc(
974 LPDIRECTDRAWSURFACE4
this,LPDDSURFACEDESC ddsd
976 TRACE(ddraw
, "(%p)->GetSurfaceDesc(%p)\n",
979 /* Simply copy the surface description stored in the object */
980 *ddsd
= this->s
.surface_desc
;
982 if (TRACE_ON(ddraw
)) {
983 fprintf(stderr
," flags: ");
984 _dump_DDSD(ddsd
->dwFlags
);
985 if (ddsd
->dwFlags
& DDSD_CAPS
) {
986 fprintf(stderr
, " caps: ");
987 _dump_DDSCAPS(ddsd
->ddsCaps
.dwCaps
);
989 fprintf(stderr
,"\n");
995 static ULONG WINAPI
IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4
this) {
996 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
998 return ++(this->ref
);
1001 static ULONG WINAPI
DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
1002 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1004 #ifdef HAVE_LIBXXF86DGA
1005 if (!--(this->ref
)) {
1006 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
1007 /* clear out of surface list */
1008 if (this->t
.dga
.fb_height
== -1) {
1009 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1011 this->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(this->t
.dga
.fb_height
/this->s
.ddraw
->e
.dga
.fb_height
));
1014 /* Free the backbuffer */
1015 if (this->s
.backbuffer
)
1016 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1018 HeapFree(GetProcessHeap(),0,this);
1021 #endif /* defined(HAVE_LIBXXF86DGA) */
1025 static ULONG WINAPI
Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
1026 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1028 if (!--(this->ref
)) {
1029 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
1031 if( this->s
.backbuffer
)
1032 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1034 if (this->t
.xlib
.image
!= NULL
) {
1035 if (this->s
.ddraw
->d
.depth
!= this->s
.ddraw
->d
.screen_depth
) {
1036 /* In pixel conversion mode, there are two buffers to release... */
1037 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1039 #ifdef HAVE_LIBXXSHM
1040 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1041 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1042 TSXDestroyImage(this->t
.xlib
.image
);
1043 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1046 HeapFree(GetProcessHeap(),0,this->t
.xlib
.image
->data
);
1047 this->t
.xlib
.image
->data
= NULL
;
1048 TSXDestroyImage(this->t
.xlib
.image
);
1049 #ifdef HAVE_LIBXXSHM
1054 this->t
.xlib
.image
->data
= NULL
;
1056 #ifdef HAVE_LIBXXSHM
1057 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1058 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1059 TSXDestroyImage(this->t
.xlib
.image
);
1060 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1063 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1064 TSXDestroyImage(this->t
.xlib
.image
);
1065 #ifdef HAVE_LIBXXSHM
1070 this->t
.xlib
.image
= 0;
1072 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1075 if (this->s
.palette
)
1076 this->s
.palette
->lpvtbl
->fnRelease(this->s
.palette
);
1078 HeapFree(GetProcessHeap(),0,this);
1085 static HRESULT WINAPI
IDirectDrawSurface4_GetAttachedSurface(
1086 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1088 TRACE(ddraw
, "(%p)->GetAttachedSurface(%p,%p)\n",
1089 this, lpddsd
, lpdsf
);
1091 if (TRACE_ON(ddraw
)) {
1092 TRACE(ddraw
," caps ");
1093 _dump_DDSCAPS(lpddsd
->dwCaps
);
1096 if (!(lpddsd
->dwCaps
& DDSCAPS_BACKBUFFER
)) {
1097 FIXME(ddraw
,"whoops, can only handle backbuffers for now\n");
1101 /* FIXME: should handle more than one backbuffer */
1102 *lpdsf
= this->s
.backbuffer
;
1104 if( this->s
.backbuffer
)
1105 this->s
.backbuffer
->lpvtbl
->fnAddRef( this->s
.backbuffer
);
1110 static HRESULT WINAPI
IDirectDrawSurface4_Initialize(
1111 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1113 TRACE(ddraw
,"(%p)->(%p, %p)\n",this,ddraw
,lpdsfd
);
1115 return DDERR_ALREADYINITIALIZED
;
1118 static HRESULT WINAPI
IDirectDrawSurface4_GetPixelFormat(
1119 LPDIRECTDRAWSURFACE4
this,LPDDPIXELFORMAT pf
1121 TRACE(ddraw
,"(%p)->(%p)\n",this,pf
);
1123 *pf
= this->s
.surface_desc
.ddpfPixelFormat
;
1128 static HRESULT WINAPI
IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4
this,DWORD dwFlags
) {
1129 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,dwFlags
);
1133 static HRESULT WINAPI
IDirectDrawSurface4_GetOverlayPosition(
1134 LPDIRECTDRAWSURFACE4
this,LPLONG x1
,LPLONG x2
1136 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,x1
,x2
);
1140 static HRESULT WINAPI
IDirectDrawSurface4_SetClipper(
1141 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWCLIPPER clipper
1143 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,clipper
);
1147 static HRESULT WINAPI
IDirectDrawSurface4_AddAttachedSurface(
1148 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 surf
1150 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,surf
);
1152 this->lpvtbl
->fnAddRef(this);
1154 /* This hack will be enough for the moment */
1155 if (this->s
.backbuffer
== NULL
)
1156 this->s
.backbuffer
= surf
;
1160 static HRESULT WINAPI
IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4
this,HDC32
* lphdc
) {
1161 FIXME(ddraw
,"(%p)->GetDC(%p)\n",this,lphdc
);
1162 *lphdc
= BeginPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1166 static HRESULT WINAPI
IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4
this,HDC32 hdc
) {
1170 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,(long)hdc
);
1171 EndPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1173 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1174 I fill it with 'dummy' values to have something on the screen */
1175 this->lpvtbl
->fnLock(this,NULL
,&desc
,0,0);
1176 for (y
= 0; y
< desc
.dwHeight
; y
++) {
1177 for (x
= 0; x
< desc
.dwWidth
; x
++) {
1178 ((unsigned char *) desc
.y
.lpSurface
)[x
+ y
* desc
.dwWidth
] = (unsigned int) this + x
+ y
;
1181 this->lpvtbl
->fnUnlock(this,NULL
);
1187 static HRESULT WINAPI
IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4
this,REFIID refiid
,LPVOID
*obj
) {
1190 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1191 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1193 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1194 * the same interface. And IUnknown does that too of course.
1196 if ( !memcmp(&IID_IDirectDrawSurface4
,refiid
,sizeof(IID
)) ||
1197 !memcmp(&IID_IDirectDrawSurface3
,refiid
,sizeof(IID
)) ||
1198 !memcmp(&IID_IDirectDrawSurface2
,refiid
,sizeof(IID
)) ||
1199 !memcmp(&IID_IDirectDrawSurface
,refiid
,sizeof(IID
)) ||
1200 !memcmp(&IID_IUnknown
,refiid
,sizeof(IID
))
1203 this->lpvtbl
->fnAddRef(this);
1205 TRACE(ddraw
, " Creating IDirectDrawSurface interface (%p)\n", *obj
);
1209 else if (!memcmp(&IID_IDirect3DTexture2
,refiid
,sizeof(IID
)))
1211 /* Texture interface */
1212 *obj
= d3dtexture2_create(this);
1213 this->lpvtbl
->fnAddRef(this);
1215 TRACE(ddraw
, " Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1219 else if (!memcmp(&IID_IDirect3DTexture
,refiid
,sizeof(IID
)))
1221 /* Texture interface */
1222 *obj
= d3dtexture_create(this);
1223 this->lpvtbl
->fnAddRef(this);
1225 TRACE(ddraw
, " Creating IDirect3DTexture interface (%p)\n", *obj
);
1229 else if (is_OpenGL_dx3(refiid
, (LPDIRECTDRAWSURFACE
) this, (LPDIRECT3DDEVICE
*) obj
))
1231 /* It is the OpenGL Direct3D Device */
1232 this->lpvtbl
->fnAddRef(this);
1234 TRACE(ddraw
, " Creating IDirect3DDevice interface (%p)\n", *obj
);
1239 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1240 return OLE_E_ENUM_NOMORE
;
1243 static HRESULT WINAPI
IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4
this) {
1244 TRACE(ddraw
,"(%p)->(), stub!\n",this);
1245 return DD_OK
; /* hmm */
1248 static HRESULT WINAPI
IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4
this,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1249 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,context
,esfcb
);
1253 static HRESULT WINAPI
IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4
this) {
1254 FIXME(ddraw
,"(%p)->(),stub!\n",this);
1258 static HRESULT WINAPI
IDirectDrawSurface4_SetColorKey(
1259 LPDIRECTDRAWSURFACE4
this, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1261 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n",this,dwFlags
,ckey
);
1263 if( dwFlags
& DDCKEY_SRCBLT
)
1265 dwFlags
&= ~DDCKEY_SRCBLT
;
1266 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1267 memcpy( &(this->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1270 if( dwFlags
& DDCKEY_DESTBLT
)
1272 dwFlags
&= ~DDCKEY_DESTBLT
;
1273 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1274 memcpy( &(this->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1277 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1279 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1280 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1281 memcpy( &(this->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1284 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1286 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1287 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1288 memcpy( &(this->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1293 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1300 static HRESULT WINAPI
IDirectDrawSurface4_AddOverlayDirtyRect(
1301 LPDIRECTDRAWSURFACE4
this,
1304 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpRect
);
1309 static HRESULT WINAPI
IDirectDrawSurface4_DeleteAttachedSurface(
1310 LPDIRECTDRAWSURFACE4
this,
1312 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
1314 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags
,lpDDSAttachedSurface
);
1319 static HRESULT WINAPI
IDirectDrawSurface4_EnumOverlayZOrders(
1320 LPDIRECTDRAWSURFACE4
this,
1323 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1325 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags
,
1326 lpContext
, lpfnCallback
);
1331 static HRESULT WINAPI
IDirectDrawSurface4_GetClipper(
1332 LPDIRECTDRAWSURFACE4
this,
1333 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1335 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDClipper
);
1340 static HRESULT WINAPI
IDirectDrawSurface4_GetColorKey(
1341 LPDIRECTDRAWSURFACE4
this,
1343 LPDDCOLORKEY lpDDColorKey
)
1345 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n", this, dwFlags
, lpDDColorKey
);
1347 if( dwFlags
& DDCKEY_SRCBLT
) {
1348 dwFlags
&= ~DDCKEY_SRCBLT
;
1349 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
1352 if( dwFlags
& DDCKEY_DESTBLT
)
1354 dwFlags
&= ~DDCKEY_DESTBLT
;
1355 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
1358 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1360 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1361 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
1364 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1366 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1367 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
1372 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1378 static HRESULT WINAPI
IDirectDrawSurface4_GetFlipStatus(
1379 LPDIRECTDRAWSURFACE4
this,
1382 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1387 static HRESULT WINAPI
IDirectDrawSurface4_GetPalette(
1388 LPDIRECTDRAWSURFACE4
this,
1389 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1391 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDPalette
);
1396 static HRESULT WINAPI
IDirectDrawSurface4_SetOverlayPosition(
1397 LPDIRECTDRAWSURFACE4
this,
1401 FIXME(ddraw
,"(%p)->(%ld,%ld),stub!\n", this, lX
, lY
);
1406 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlay(
1407 LPDIRECTDRAWSURFACE4
this,
1409 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
1410 LPRECT32 lpDestRect
,
1412 LPDDOVERLAYFX lpDDOverlayFx
)
1414 FIXME(ddraw
,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1415 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1420 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayDisplay(
1421 LPDIRECTDRAWSURFACE4
this,
1424 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1429 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayZOrder(
1430 LPDIRECTDRAWSURFACE4
this,
1432 LPDIRECTDRAWSURFACE4 lpDDSReference
)
1434 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags
, lpDDSReference
);
1439 static HRESULT WINAPI
IDirectDrawSurface4_GetDDInterface(
1440 LPDIRECTDRAWSURFACE4
this,
1443 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDD
);
1445 /* Not sure about that... */
1446 *lplpDD
= (void *) this->s
.ddraw
;
1451 static HRESULT WINAPI
IDirectDrawSurface4_PageLock(
1452 LPDIRECTDRAWSURFACE4
this,
1455 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1460 static HRESULT WINAPI
IDirectDrawSurface4_PageUnlock(
1461 LPDIRECTDRAWSURFACE4
this,
1464 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1469 static HRESULT WINAPI
IDirectDrawSurface4_SetSurfaceDesc(
1470 LPDIRECTDRAWSURFACE4
this,
1471 LPDDSURFACEDESC lpDDSD
,
1474 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD
, dwFlags
);
1479 static HRESULT WINAPI
IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4
this,
1484 FIXME(ddraw
, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag
, lpData
, cbSize
, dwFlags
);
1489 static HRESULT WINAPI
IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4
this,
1492 LPDWORD lpcbBufferSize
) {
1493 FIXME(ddraw
, "(%p)->(%p,%p,%p)\n", this, guidTag
, lpBuffer
, lpcbBufferSize
);
1498 static HRESULT WINAPI
IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4
this,
1500 FIXME(ddraw
, "(%p)->(%p)\n", this, guidTag
);
1505 static HRESULT WINAPI
IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4
this,
1507 FIXME(ddraw
, "(%p)->(%p)\n", this, lpValue
);
1512 static HRESULT WINAPI
IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4
this) {
1513 FIXME(ddraw
, "(%p)\n", this);
1518 static struct IDirectDrawSurface4_VTable dga_dds4vt
= {
1519 IDirectDrawSurface4_QueryInterface
,
1520 IDirectDrawSurface4_AddRef
,
1521 DGA_IDirectDrawSurface4_Release
,
1522 IDirectDrawSurface4_AddAttachedSurface
,
1523 IDirectDrawSurface4_AddOverlayDirtyRect
,
1524 IDirectDrawSurface4_Blt
,
1525 IDirectDrawSurface4_BltBatch
,
1526 IDirectDrawSurface4_BltFast
,
1527 IDirectDrawSurface4_DeleteAttachedSurface
,
1528 IDirectDrawSurface4_EnumAttachedSurfaces
,
1529 IDirectDrawSurface4_EnumOverlayZOrders
,
1530 DGA_IDirectDrawSurface4_Flip
,
1531 IDirectDrawSurface4_GetAttachedSurface
,
1532 IDirectDrawSurface4_GetBltStatus
,
1533 IDirectDrawSurface4_GetCaps
,
1534 IDirectDrawSurface4_GetClipper
,
1535 IDirectDrawSurface4_GetColorKey
,
1536 IDirectDrawSurface4_GetDC
,
1537 IDirectDrawSurface4_GetFlipStatus
,
1538 IDirectDrawSurface4_GetOverlayPosition
,
1539 IDirectDrawSurface4_GetPalette
,
1540 IDirectDrawSurface4_GetPixelFormat
,
1541 IDirectDrawSurface4_GetSurfaceDesc
,
1542 IDirectDrawSurface4_Initialize
,
1543 IDirectDrawSurface4_IsLost
,
1544 IDirectDrawSurface4_Lock
,
1545 IDirectDrawSurface4_ReleaseDC
,
1546 IDirectDrawSurface4_Restore
,
1547 IDirectDrawSurface4_SetClipper
,
1548 IDirectDrawSurface4_SetColorKey
,
1549 IDirectDrawSurface4_SetOverlayPosition
,
1550 DGA_IDirectDrawSurface4_SetPalette
,
1551 DGA_IDirectDrawSurface4_Unlock
,
1552 IDirectDrawSurface4_UpdateOverlay
,
1553 IDirectDrawSurface4_UpdateOverlayDisplay
,
1554 IDirectDrawSurface4_UpdateOverlayZOrder
,
1555 IDirectDrawSurface4_GetDDInterface
,
1556 IDirectDrawSurface4_PageLock
,
1557 IDirectDrawSurface4_PageUnlock
,
1558 IDirectDrawSurface4_SetSurfaceDesc
,
1559 IDirectDrawSurface4_SetPrivateData
,
1560 IDirectDrawSurface4_GetPrivateData
,
1561 IDirectDrawSurface4_FreePrivateData
,
1562 IDirectDrawSurface4_GetUniquenessValue
,
1563 IDirectDrawSurface4_ChangeUniquenessValue
1566 static struct IDirectDrawSurface4_VTable xlib_dds4vt
= {
1567 IDirectDrawSurface4_QueryInterface
,
1568 IDirectDrawSurface4_AddRef
,
1569 Xlib_IDirectDrawSurface4_Release
,
1570 IDirectDrawSurface4_AddAttachedSurface
,
1571 IDirectDrawSurface4_AddOverlayDirtyRect
,
1572 IDirectDrawSurface4_Blt
,
1573 IDirectDrawSurface4_BltBatch
,
1574 IDirectDrawSurface4_BltFast
,
1575 IDirectDrawSurface4_DeleteAttachedSurface
,
1576 IDirectDrawSurface4_EnumAttachedSurfaces
,
1577 IDirectDrawSurface4_EnumOverlayZOrders
,
1578 Xlib_IDirectDrawSurface4_Flip
,
1579 IDirectDrawSurface4_GetAttachedSurface
,
1580 IDirectDrawSurface4_GetBltStatus
,
1581 IDirectDrawSurface4_GetCaps
,
1582 IDirectDrawSurface4_GetClipper
,
1583 IDirectDrawSurface4_GetColorKey
,
1584 IDirectDrawSurface4_GetDC
,
1585 IDirectDrawSurface4_GetFlipStatus
,
1586 IDirectDrawSurface4_GetOverlayPosition
,
1587 IDirectDrawSurface4_GetPalette
,
1588 IDirectDrawSurface4_GetPixelFormat
,
1589 IDirectDrawSurface4_GetSurfaceDesc
,
1590 IDirectDrawSurface4_Initialize
,
1591 IDirectDrawSurface4_IsLost
,
1592 IDirectDrawSurface4_Lock
,
1593 IDirectDrawSurface4_ReleaseDC
,
1594 IDirectDrawSurface4_Restore
,
1595 IDirectDrawSurface4_SetClipper
,
1596 IDirectDrawSurface4_SetColorKey
,
1597 IDirectDrawSurface4_SetOverlayPosition
,
1598 Xlib_IDirectDrawSurface4_SetPalette
,
1599 Xlib_IDirectDrawSurface4_Unlock
,
1600 IDirectDrawSurface4_UpdateOverlay
,
1601 IDirectDrawSurface4_UpdateOverlayDisplay
,
1602 IDirectDrawSurface4_UpdateOverlayZOrder
,
1603 IDirectDrawSurface4_GetDDInterface
,
1604 IDirectDrawSurface4_PageLock
,
1605 IDirectDrawSurface4_PageUnlock
,
1606 IDirectDrawSurface4_SetSurfaceDesc
,
1607 IDirectDrawSurface4_SetPrivateData
,
1608 IDirectDrawSurface4_GetPrivateData
,
1609 IDirectDrawSurface4_FreePrivateData
,
1610 IDirectDrawSurface4_GetUniquenessValue
,
1611 IDirectDrawSurface4_ChangeUniquenessValue
1614 /******************************************************************************
1615 * DirectDrawCreateClipper (DDRAW.7)
1617 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
1618 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
1619 LPUNKNOWN pUnkOuter
)
1621 TRACE(ddraw
, "(%08lx,%p,%p)\n", dwFlags
, lplpDDClipper
, pUnkOuter
);
1623 *lplpDDClipper
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
1624 (*lplpDDClipper
)->lpvtbl
= &ddclipvt
;
1625 (*lplpDDClipper
)->ref
= 1;
1630 /******************************************************************************
1631 * IDirectDrawClipper
1633 static HRESULT WINAPI
IDirectDrawClipper_SetHwnd(
1634 LPDIRECTDRAWCLIPPER
this,DWORD x
,HWND32 hwnd
1636 FIXME(ddraw
,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x
,(DWORD
)hwnd
);
1640 static ULONG WINAPI
IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER
this) {
1641 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1646 HeapFree(GetProcessHeap(),0,this);
1650 static HRESULT WINAPI
IDirectDrawClipper_GetClipList(
1651 LPDIRECTDRAWCLIPPER
this,LPRECT32 rects
,LPRGNDATA lprgn
,LPDWORD hmm
1653 FIXME(ddraw
,"(%p,%p,%p,%p),stub!\n",this,rects
,lprgn
,hmm
);
1658 static HRESULT WINAPI
IDirectDrawClipper_SetClipList(
1659 LPDIRECTDRAWCLIPPER
this,LPRGNDATA lprgn
,DWORD hmm
1661 FIXME(ddraw
,"(%p,%p,%ld),stub!\n",this,lprgn
,hmm
);
1665 static HRESULT WINAPI
IDirectDrawClipper_QueryInterface(
1666 LPDIRECTDRAWCLIPPER
this,
1670 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,riid
,ppvObj
);
1671 return OLE_E_ENUM_NOMORE
;
1674 static ULONG WINAPI
IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER
this )
1676 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1677 return ++(this->ref
);
1680 static HRESULT WINAPI
IDirectDrawClipper_GetHWnd(
1681 LPDIRECTDRAWCLIPPER
this,
1684 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,HWndPtr
);
1688 static HRESULT WINAPI
IDirectDrawClipper_Initialize(
1689 LPDIRECTDRAWCLIPPER
this,
1693 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD
,dwFlags
);
1697 static HRESULT WINAPI
IDirectDrawClipper_IsClipListChanged(
1698 LPDIRECTDRAWCLIPPER
this,
1699 BOOL32
* lpbChanged
)
1701 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpbChanged
);
1705 static struct IDirectDrawClipper_VTable ddclipvt
= {
1706 IDirectDrawClipper_QueryInterface
,
1707 IDirectDrawClipper_AddRef
,
1708 IDirectDrawClipper_Release
,
1709 IDirectDrawClipper_GetClipList
,
1710 IDirectDrawClipper_GetHWnd
,
1711 IDirectDrawClipper_Initialize
,
1712 IDirectDrawClipper_IsClipListChanged
,
1713 IDirectDrawClipper_SetClipList
,
1714 IDirectDrawClipper_SetHwnd
1718 /******************************************************************************
1719 * IDirectDrawPalette
1721 static HRESULT WINAPI
IDirectDrawPalette_GetEntries(
1722 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1726 TRACE(ddraw
,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1727 this,x
,start
,count
,palent
);
1729 if (!this->cm
) /* should not happen */ {
1730 FIXME(ddraw
,"app tried to read colormap for non-palettized mode\n");
1731 return DDERR_GENERIC
;
1733 for (i
=0;i
<count
;i
++) {
1734 palent
[i
].peRed
= this->palents
[start
+i
].peRed
;
1735 palent
[i
].peBlue
= this->palents
[start
+i
].peBlue
;
1736 palent
[i
].peGreen
= this->palents
[start
+i
].peGreen
;
1737 palent
[i
].peFlags
= this->palents
[start
+i
].peFlags
;
1743 static HRESULT WINAPI
Xlib_IDirectDrawPalette_SetEntries(
1744 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1749 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1750 this,x
,start
,count
,palent
1752 for (i
=0;i
<count
;i
++) {
1753 xc
.red
= palent
[i
].peRed
<<8;
1754 xc
.blue
= palent
[i
].peBlue
<<8;
1755 xc
.green
= palent
[i
].peGreen
<<8;
1756 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1760 TSXStoreColor(display
,this->cm
,&xc
);
1762 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1763 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1764 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1765 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1768 /* Now, if we are in 'depth conversion mode', update the screen palette */
1769 if (this->ddraw
->d
.depth
!= this->ddraw
->d
.screen_depth
) {
1772 switch (this->ddraw
->d
.screen_depth
) {
1774 unsigned short *screen_palette
= (unsigned short *) this->screen_palents
;
1776 for (i
= 0; i
< count
; i
++) {
1777 screen_palette
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
1778 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
1779 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
1784 ERR(ddraw
, "Memory corruption !\n");
1789 if (!this->cm
) /* should not happen */ {
1794 static HRESULT WINAPI
DGA_IDirectDrawPalette_SetEntries(
1795 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1797 #ifdef HAVE_LIBXXF86DGA
1802 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1803 this,x
,start
,count
,palent
1805 if (!this->cm
) /* should not happen */ {
1806 FIXME(ddraw
,"app tried to set colormap in non-palettized mode\n");
1807 return DDERR_GENERIC
;
1809 /* FIXME: free colorcells instead of freeing whole map */
1811 this->cm
= TSXCopyColormapAndFree(display
,this->cm
);
1812 TSXFreeColormap(display
,cm
);
1814 for (i
=0;i
<count
;i
++) {
1815 xc
.red
= palent
[i
].peRed
<<8;
1816 xc
.blue
= palent
[i
].peBlue
<<8;
1817 xc
.green
= palent
[i
].peGreen
<<8;
1818 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1821 TSXStoreColor(display
,this->cm
,&xc
);
1823 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1824 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1825 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1826 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1828 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->cm
);
1830 #else /* defined(HAVE_LIBXXF86DGA) */
1831 return E_UNEXPECTED
;
1832 #endif /* defined(HAVE_LIBXXF86DGA) */
1835 static ULONG WINAPI
IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE
this) {
1836 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1837 if (!--(this->ref
)) {
1839 TSXFreeColormap(display
,this->cm
);
1842 HeapFree(GetProcessHeap(),0,this);
1848 static ULONG WINAPI
IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE
this) {
1850 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1851 return ++(this->ref
);
1854 static HRESULT WINAPI
IDirectDrawPalette_Initialize(
1855 LPDIRECTDRAWPALETTE
this,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
1857 TRACE(ddraw
,"(%p)->(%p,%ld,%p)\n", this, ddraw
, x
, palent
);
1859 return DDERR_ALREADYINITIALIZED
;
1862 static HRESULT WINAPI
IDirectDrawPalette_GetCaps(
1863 LPDIRECTDRAWPALETTE
this, LPDWORD lpdwCaps
)
1865 FIXME( ddraw
, "(%p)->(%p) stub.\n", this, lpdwCaps
);
1869 static HRESULT WINAPI
IDirectDrawPalette_QueryInterface(
1870 LPDIRECTDRAWPALETTE
this,REFIID refiid
,LPVOID
*obj
)
1874 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1875 FIXME(ddraw
,"(%p)->(%s,%p) stub.\n",this,xrefiid
,obj
);
1880 static struct IDirectDrawPalette_VTable dga_ddpalvt
= {
1881 IDirectDrawPalette_QueryInterface
,
1882 IDirectDrawPalette_AddRef
,
1883 IDirectDrawPalette_Release
,
1884 IDirectDrawPalette_GetCaps
,
1885 IDirectDrawPalette_GetEntries
,
1886 IDirectDrawPalette_Initialize
,
1887 DGA_IDirectDrawPalette_SetEntries
1890 static struct IDirectDrawPalette_VTable xlib_ddpalvt
= {
1891 IDirectDrawPalette_QueryInterface
,
1892 IDirectDrawPalette_AddRef
,
1893 IDirectDrawPalette_Release
,
1894 IDirectDrawPalette_GetCaps
,
1895 IDirectDrawPalette_GetEntries
,
1896 IDirectDrawPalette_Initialize
,
1897 Xlib_IDirectDrawPalette_SetEntries
1900 /*******************************************************************************
1903 static HRESULT WINAPI
IDirect3D_QueryInterface(
1904 LPDIRECT3D
this,REFIID refiid
,LPVOID
*obj
1906 /* FIXME: Not sure if this is correct */
1909 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1910 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1911 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
1913 this->lpvtbl
->fnAddRef(this);
1915 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
1919 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
1922 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1924 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1925 this->lpvtbl
->fnAddRef(this);
1926 d3d
->lpvtbl
= &d3dvt
;
1929 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
1933 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
1936 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1938 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1939 this->lpvtbl
->fnAddRef(this);
1940 d3d
->lpvtbl
= &d3d2vt
;
1943 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
1947 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1948 return OLE_E_ENUM_NOMORE
;
1951 static ULONG WINAPI
IDirect3D_AddRef(LPDIRECT3D
this) {
1952 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1954 return ++(this->ref
);
1957 static ULONG WINAPI
IDirect3D_Release(LPDIRECT3D
this)
1959 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1961 if (!--(this->ref
)) {
1962 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
1963 HeapFree(GetProcessHeap(),0,this);
1969 static HRESULT WINAPI
IDirect3D_Initialize(
1970 LPDIRECT3D
this, REFIID refiid
)
1972 /* FIXME: Not sure if this is correct */
1975 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1976 FIXME(ddraw
,"(%p)->(%s):stub.\n",this,xrefiid
);
1978 return DDERR_ALREADYINITIALIZED
;
1981 static HRESULT WINAPI
IDirect3D_EnumDevices(LPDIRECT3D
this,
1982 LPD3DENUMDEVICESCALLBACK cb
,
1984 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
1986 /* Call functions defined in d3ddevices.c */
1987 if (d3d_OpenGL_dx3(cb
, context
))
1993 static HRESULT WINAPI
IDirect3D_CreateLight(LPDIRECT3D
this,
1994 LPDIRECT3DLIGHT
*lplight
,
1997 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
1999 /* Call the creation function that is located in d3dlight.c */
2000 *lplight
= d3dlight_create_dx3(this);
2005 static HRESULT WINAPI
IDirect3D_CreateMaterial(LPDIRECT3D
this,
2006 LPDIRECT3DMATERIAL
*lpmaterial
,
2009 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
2011 /* Call the creation function that is located in d3dviewport.c */
2012 *lpmaterial
= d3dmaterial_create(this);
2017 static HRESULT WINAPI
IDirect3D_CreateViewport(LPDIRECT3D
this,
2018 LPDIRECT3DVIEWPORT
*lpviewport
,
2021 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
2023 /* Call the creation function that is located in d3dviewport.c */
2024 *lpviewport
= d3dviewport_create(this);
2029 static HRESULT WINAPI
IDirect3D_FindDevice(LPDIRECT3D
this,
2030 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2031 LPD3DFINDDEVICERESULT lpfinddevrst
)
2033 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2038 static struct IDirect3D_VTable d3dvt
= {
2039 IDirect3D_QueryInterface
,
2042 IDirect3D_Initialize
,
2043 IDirect3D_EnumDevices
,
2044 IDirect3D_CreateLight
,
2045 IDirect3D_CreateMaterial
,
2046 IDirect3D_CreateViewport
,
2047 IDirect3D_FindDevice
2050 /*******************************************************************************
2053 static HRESULT WINAPI
IDirect3D2_QueryInterface(
2054 LPDIRECT3D2
this,REFIID refiid
,LPVOID
*obj
) {
2055 /* For the moment, we use the same function as in IDirect3D */
2056 TRACE(ddraw
, "Calling IDirect3D enumerating function.\n");
2058 return IDirect3D_QueryInterface((LPDIRECT3D
) this, refiid
, obj
);
2061 static ULONG WINAPI
IDirect3D2_AddRef(LPDIRECT3D2
this) {
2062 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
2064 return ++(this->ref
);
2067 static ULONG WINAPI
IDirect3D2_Release(LPDIRECT3D2
this) {
2068 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
2070 if (!--(this->ref
)) {
2071 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
2072 HeapFree(GetProcessHeap(),0,this);
2078 static HRESULT WINAPI
IDirect3D2_EnumDevices(
2079 LPDIRECT3D2
this,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2081 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
2083 /* Call functions defined in d3ddevices.c */
2084 if (d3d_OpenGL(cb
, context
))
2090 static HRESULT WINAPI
IDirect3D2_CreateLight(LPDIRECT3D2
this,
2091 LPDIRECT3DLIGHT
*lplight
,
2094 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
2096 /* Call the creation function that is located in d3dlight.c */
2097 *lplight
= d3dlight_create(this);
2102 static HRESULT WINAPI
IDirect3D2_CreateMaterial(LPDIRECT3D2
this,
2103 LPDIRECT3DMATERIAL2
*lpmaterial
,
2106 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
2108 /* Call the creation function that is located in d3dviewport.c */
2109 *lpmaterial
= d3dmaterial2_create(this);
2114 static HRESULT WINAPI
IDirect3D2_CreateViewport(LPDIRECT3D2
this,
2115 LPDIRECT3DVIEWPORT2
*lpviewport
,
2118 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
2120 /* Call the creation function that is located in d3dviewport.c */
2121 *lpviewport
= d3dviewport2_create(this);
2126 static HRESULT WINAPI
IDirect3D2_FindDevice(LPDIRECT3D2
this,
2127 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2128 LPD3DFINDDEVICERESULT lpfinddevrst
)
2130 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2135 static HRESULT WINAPI
IDirect3D2_CreateDevice(LPDIRECT3D2
this,
2137 LPDIRECTDRAWSURFACE surface
,
2138 LPDIRECT3DDEVICE2
*device
)
2142 WINE_StringFromCLSID(rguid
,xbuf
);
2143 FIXME(ddraw
,"(%p)->(%s,%p,%p): stub\n",this,xbuf
,surface
,device
);
2145 if (is_OpenGL(rguid
, surface
, device
, this)) {
2146 this->lpvtbl
->fnAddRef(this);
2150 return DDERR_INVALIDPARAMS
;
2153 static struct IDirect3D2_VTable d3d2vt
= {
2154 IDirect3D2_QueryInterface
,
2157 IDirect3D2_EnumDevices
,
2158 IDirect3D2_CreateLight
,
2159 IDirect3D2_CreateMaterial
,
2160 IDirect3D2_CreateViewport
,
2161 IDirect3D2_FindDevice
,
2162 IDirect3D2_CreateDevice
2165 /*******************************************************************************
2169 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2170 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2172 static INT32 ddrawXlibThisOffset
= 0;
2174 static HRESULT
common_off_screen_CreateSurface(LPDIRECTDRAW2
this,
2175 LPDDSURFACEDESC lpddsd
,
2176 LPDIRECTDRAWSURFACE lpdsf
)
2180 /* The surface was already allocated when entering in this function */
2181 TRACE(ddraw
,"using system memory for a surface (%p)\n", lpdsf
);
2183 if (lpddsd
->dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
2184 /* This is a Z Buffer */
2185 TRACE(ddraw
, "Creating Z-Buffer of %ld bit depth\n", lpddsd
->x
.dwZBufferBitDepth
);
2186 bpp
= lpddsd
->x
.dwZBufferBitDepth
/ 8;
2188 /* This is a standard image */
2189 if (!(lpddsd
->dwFlags
& DDSD_PIXELFORMAT
)) {
2190 /* No pixel format => use DirectDraw's format */
2191 _getpixelformat(this,&(lpddsd
->ddpfPixelFormat
));
2192 lpddsd
->dwFlags
|= DDSD_PIXELFORMAT
;
2194 /* To check what the program wants */
2195 if (TRACE_ON(ddraw
)) {
2196 _dump_pixelformat(&(lpddsd
->ddpfPixelFormat
));
2200 if (lpddsd
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) {
2203 bpp
= lpddsd
->ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
2207 /* Copy the surface description */
2208 lpdsf
->s
.surface_desc
= *lpddsd
;
2210 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2211 lpdsf
->s
.surface_desc
.y
.lpSurface
= (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpddsd
->dwWidth
* lpddsd
->dwHeight
* bpp
);
2212 lpdsf
->s
.surface_desc
.lPitch
= lpddsd
->dwWidth
* bpp
;
2217 static HRESULT WINAPI
DGA_IDirectDraw2_CreateSurface(
2218 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2220 #ifdef HAVE_LIBXXF86DGA
2223 TRACE(ddraw
, "(%p)->(%p,%p,%p)\n",this,lpddsd
,lpdsf
,lpunk
);
2224 if (TRACE_ON(ddraw
)) {
2225 DUMP("[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2226 _dump_DDSD(lpddsd
->dwFlags
);
2227 fprintf(stderr
,"caps ");
2228 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2229 fprintf(stderr
,"]\n");
2232 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2233 this->lpvtbl
->fnAddRef(this);
2236 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&dga_dds4vt
;
2237 (*lpdsf
)->s
.ddraw
= this;
2238 (*lpdsf
)->s
.palette
= NULL
;
2239 (*lpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
2241 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2242 lpddsd
->dwWidth
= this->d
.width
;
2243 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2244 lpddsd
->dwHeight
= this->d
.height
;
2246 /* Check if this a 'primary surface' or not */
2247 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2248 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2250 /* This is THE primary surface => there is DGA-specific code */
2251 /* First, store the surface description */
2252 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2254 /* Find a viewport */
2256 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2258 TRACE(ddraw
,"using viewport %d for a primary surface\n",i
);
2259 /* if i == 32 or maximum ... return error */
2260 this->e
.dga
.vpmask
|=(1<<i
);
2261 (*lpdsf
)->s
.surface_desc
.y
.lpSurface
=
2262 this->e
.dga
.fb_addr
+((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
2263 (*lpdsf
)->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2264 (*lpdsf
)->s
.surface_desc
.lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
2265 lpddsd
->lPitch
= (*lpdsf
)->s
.surface_desc
.lPitch
;
2267 /* Add flags if there were not present */
2268 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2269 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2270 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2271 TRACE(ddraw
,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d
.width
,this->d
.height
,lpddsd
->lPitch
);
2272 /* We put our surface always in video memory */
2273 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2274 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
2275 (*lpdsf
)->s
.backbuffer
= NULL
;
2277 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2278 LPDIRECTDRAWSURFACE4 back
;
2280 if (lpddsd
->dwBackBufferCount
>1)
2281 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2283 (*lpdsf
)->s
.backbuffer
= back
=
2284 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2285 this->lpvtbl
->fnAddRef(this);
2287 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&dga_dds4vt
;
2289 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2291 TRACE(ddraw
,"using viewport %d for backbuffer\n",i
);
2292 /* if i == 32 or maximum ... return error */
2293 this->e
.dga
.vpmask
|=(1<<i
);
2294 back
->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2296 /* Copy the surface description from the front buffer */
2297 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2298 /* Change the parameters that are not the same */
2299 back
->s
.surface_desc
.y
.lpSurface
= this->e
.dga
.fb_addr
+
2300 ((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
2301 back
->s
.ddraw
= this;
2302 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2305 /* Add relevant info to front and back buffers */
2306 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2307 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2308 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2309 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2310 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2313 /* There is no DGA-specific code here...
2314 Go to the common surface creation function */
2315 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2319 #else /* defined(HAVE_LIBXXF86DGA) */
2320 return E_UNEXPECTED
;
2321 #endif /* defined(HAVE_LIBXXF86DGA) */
2324 #ifdef HAVE_LIBXXSHM
2325 /* Error handlers for Image creation */
2326 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
2331 static XImage
*create_xshmimage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2333 int (*WineXHandler
)(Display
*, XErrorEvent
*);
2335 img
= TSXShmCreateImage(display
,
2336 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2337 this->d
.screen_depth
,
2340 &(lpdsf
->t
.xlib
.shminfo
),
2341 lpdsf
->s
.surface_desc
.dwWidth
,
2342 lpdsf
->s
.surface_desc
.dwHeight
);
2345 ERR(ddraw
, "Error creating XShm image. Reverting to standard X images !\n");
2346 this->e
.xlib
.xshm_active
= 0;
2350 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
2351 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
2352 ERR(ddraw
, "Error creating shared memory segment. Reverting to standard X images !\n");
2353 this->e
.xlib
.xshm_active
= 0;
2354 TSXDestroyImage(img
);
2358 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
2360 if (img
->data
== (char *) -1) {
2361 ERR(ddraw
, "Error attaching shared memory segment. Reverting to standard X images !\n");
2362 this->e
.xlib
.xshm_active
= 0;
2363 TSXDestroyImage(img
);
2364 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2367 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
2369 /* This is where things start to get trickier....
2370 First, we flush the current X connections to be sure to catch all non-XShm related
2372 TSXSync(display
, False
);
2373 /* Then we enter in the non-thread safe part of the tests */
2374 EnterCriticalSection( &X11DRV_CritSection
);
2376 /* Reset the error flag, sets our new error handler and try to attach the surface */
2378 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
2379 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
2380 XSync(display
, False
);
2382 /* Check the error flag */
2383 if (XShmErrorFlag
) {
2384 /* An error occured */
2388 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
2389 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2390 XSetErrorHandler(WineXHandler
);
2392 ERR(ddraw
, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2393 this->e
.xlib
.xshm_active
= 0;
2395 /* Leave the critical section */
2396 LeaveCriticalSection( &X11DRV_CritSection
);
2401 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2402 but it may be a bit overkill.... */
2403 XSetErrorHandler(WineXHandler
);
2404 LeaveCriticalSection( &X11DRV_CritSection
);
2406 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2408 if (this->d
.depth
!= this->d
.screen_depth
) {
2409 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2410 lpdsf
->s
.surface_desc
.dwWidth
*
2411 lpdsf
->s
.surface_desc
.dwHeight
*
2412 (this->d
.depth
/ 8));
2414 lpdsf
->s
.surface_desc
.y
.lpSurface
= img
->data
;
2419 #endif /* HAVE_LIBXXSHM */
2421 static XImage
*create_ximage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2425 #ifdef HAVE_LIBXXSHM
2426 if (this->e
.xlib
.xshm_active
) {
2427 img
= create_xshmimage(this, lpdsf
);
2432 /* Allocate surface memory */
2433 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2434 lpdsf
->s
.surface_desc
.dwWidth
*
2435 lpdsf
->s
.surface_desc
.dwHeight
*
2436 (this->d
.depth
/ 8));
2438 if (this->d
.depth
!= this->d
.screen_depth
) {
2439 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2440 lpdsf
->s
.surface_desc
.dwWidth
*
2441 lpdsf
->s
.surface_desc
.dwHeight
*
2442 (this->d
.screen_depth
/ 8));
2444 img_data
= lpdsf
->s
.surface_desc
.y
.lpSurface
;
2447 /* In this case, create an XImage */
2449 TSXCreateImage(display
,
2450 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2451 this->d
.screen_depth
,
2455 lpdsf
->s
.surface_desc
.dwWidth
,
2456 lpdsf
->s
.surface_desc
.dwHeight
,
2458 lpdsf
->s
.surface_desc
.dwWidth
* (this->d
.screen_depth
/ 8)
2461 #ifdef HAVE_LIBXXSHM
2464 if (this->d
.depth
!= this->d
.screen_depth
) {
2465 lpdsf
->s
.surface_desc
.lPitch
= (this->d
.depth
/ 8) * lpdsf
->s
.surface_desc
.dwWidth
;
2467 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
2473 static HRESULT WINAPI
Xlib_IDirectDraw2_CreateSurface(
2474 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2476 TRACE(ddraw
, "(%p)->CreateSurface(%p,%p,%p)\n",
2477 this,lpddsd
,lpdsf
,lpunk
);
2479 if (TRACE_ON(ddraw
)) {
2480 fprintf(stderr
,"[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2481 _dump_DDSD(lpddsd
->dwFlags
);
2482 fprintf(stderr
,"caps ");
2483 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2484 fprintf(stderr
,"]\n");
2487 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2489 this->lpvtbl
->fnAddRef(this);
2490 (*lpdsf
)->s
.ddraw
= this;
2492 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&xlib_dds4vt
;
2493 (*lpdsf
)->s
.palette
= NULL
;
2494 (*lpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
2496 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2497 lpddsd
->dwWidth
= this->d
.width
;
2498 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2499 lpddsd
->dwHeight
= this->d
.height
;
2501 /* Check if this a 'primary surface' or not */
2502 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2503 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2506 TRACE(ddraw
,"using standard XImage for a primary surface (%p)\n", *lpdsf
);
2508 /* First, store the surface description */
2509 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2511 /* Create the XImage */
2512 img
= create_ximage(this, (LPDIRECTDRAWSURFACE4
) *lpdsf
);
2514 return DDERR_OUTOFMEMORY
;
2515 (*lpdsf
)->t
.xlib
.image
= img
;
2517 /* Add flags if there were not present */
2518 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2519 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2520 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2521 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2522 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
2523 (*lpdsf
)->s
.backbuffer
= NULL
;
2525 /* Check for backbuffers */
2526 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2527 LPDIRECTDRAWSURFACE4 back
;
2530 if (lpddsd
->dwBackBufferCount
>1)
2531 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2533 (*lpdsf
)->s
.backbuffer
= back
=
2534 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2536 TRACE(ddraw
,"allocated back-buffer (%p)\n", back
);
2538 this->lpvtbl
->fnAddRef(this);
2539 back
->s
.ddraw
= this;
2542 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&xlib_dds4vt
;
2543 /* Copy the surface description from the front buffer */
2544 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2546 /* Create the XImage */
2547 img
= create_ximage(this, back
);
2549 return DDERR_OUTOFMEMORY
;
2550 back
->t
.xlib
.image
= img
;
2552 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2555 /* Add relevant info to front and back buffers */
2556 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2557 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2558 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2559 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2560 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2563 /* There is no Xlib-specific code here...
2564 Go to the common surface creation function */
2565 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2571 static HRESULT WINAPI
IDirectDraw2_DuplicateSurface(
2572 LPDIRECTDRAW2
this,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
2574 FIXME(ddraw
,"(%p)->(%p,%p) simply copies\n",this,src
,dst
);
2575 *dst
= src
; /* FIXME */
2580 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2581 * even when the approbiate bitmasks are not specified.
2583 static HRESULT WINAPI
IDirectDraw2_SetCooperativeLevel(
2584 LPDIRECTDRAW2
this,HWND32 hwnd
,DWORD cooplevel
2591 FE(DDSCL_FULLSCREEN
)
2592 FE(DDSCL_ALLOWREBOOT
)
2593 FE(DDSCL_NOWINDOWCHANGES
)
2595 FE(DDSCL_ALLOWMODEX
)
2597 FE(DDSCL_SETFOCUSWINDOW
)
2598 FE(DDSCL_SETDEVICEWINDOW
)
2599 FE(DDSCL_CREATEDEVICEWINDOW
)
2602 FIXME(ddraw
,"(%p)->(%08lx,%08lx)\n",this,(DWORD
)hwnd
,cooplevel
);
2603 if(TRACE_ON(ddraw
)){
2604 dbg_decl_str(ddraw
, 512);
2605 for (i
=0;i
<sizeof(flagmap
)/sizeof(flagmap
[0]);i
++)
2606 if (flagmap
[i
].mask
& cooplevel
)
2607 dsprintf(ddraw
, "%s ", flagmap
[i
].name
);
2608 TRACE(ddraw
," cooperative level %s\n", dbg_str(ddraw
));
2610 this->d
.mainWindow
= hwnd
;
2612 /* This will be overwritten in the case of Full Screen mode.
2613 Windowed games could work with that :-) */
2615 this->d
.drawable
= X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd
));
2620 /* Small helper to either use the cooperative window or create a new
2621 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2623 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW
this) {
2626 /* Do not destroy the application supplied cooperative window */
2627 if (this->d
.window
&& this->d
.window
!= this->d
.mainWindow
) {
2628 DestroyWindow32(this->d
.window
);
2631 /* Sanity check cooperative window before assigning it to drawing. */
2632 if ( IsWindow32(this->d
.mainWindow
) &&
2633 IsWindowVisible32(this->d
.mainWindow
)
2635 GetWindowRect32(this->d
.mainWindow
,&rect
);
2636 if (((rect
.right
-rect
.left
) >= this->d
.width
) &&
2637 ((rect
.bottom
-rect
.top
) >= this->d
.height
)
2639 this->d
.window
= this->d
.mainWindow
;
2641 /* ... failed, create new one. */
2642 if (!this->d
.window
) {
2643 this->d
.window
= CreateWindowEx32A(
2647 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
2656 /*Store THIS with the window. We'll use it in the window procedure*/
2657 SetWindowLong32A(this->d
.window
,ddrawXlibThisOffset
,(LONG
)this);
2658 ShowWindow32(this->d
.window
,TRUE
);
2659 UpdateWindow32(this->d
.window
);
2661 SetFocus32(this->d
.window
);
2664 static HRESULT WINAPI
DGA_IDirectDraw_SetDisplayMode(
2665 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2667 #ifdef HAVE_LIBXXF86DGA
2668 int i
,*depths
,depcount
,mode_count
;
2670 TRACE(ddraw
, "(%p)->(%ld,%ld,%ld)\n", this, width
, height
, depth
);
2672 /* We hope getting the asked for depth */
2673 this->d
.screen_depth
= depth
;
2675 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
2677 for (i
=0;i
<depcount
;i
++)
2678 if (depths
[i
]==depth
)
2681 if (i
==depcount
) {/* not found */
2682 ERR(ddraw
,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
2683 return DDERR_UNSUPPORTEDMODE
;
2685 if (this->d
.width
< width
) {
2686 ERR(ddraw
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,this->d
.width
);
2687 return DDERR_UNSUPPORTEDMODE
;
2689 this->d
.width
= width
;
2690 this->d
.height
= height
;
2691 this->d
.depth
= depth
;
2693 /* adjust fb_height, so we don't overlap */
2694 if (this->e
.dga
.fb_height
< height
)
2695 this->e
.dga
.fb_height
= height
;
2696 _common_IDirectDraw_SetDisplayMode(this);
2698 #ifdef HAVE_LIBXXF86VM
2700 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
2701 XF86VidModeModeLine mod_tmp
;
2702 /* int dotclock_tmp; */
2704 /* save original video mode and set fullscreen if available*/
2705 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
2706 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
2707 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
2708 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
2709 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
2710 orig_mode
->htotal
= mod_tmp
.htotal
;
2711 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
2712 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
2713 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
2714 orig_mode
->vtotal
= mod_tmp
.vtotal
;
2715 orig_mode
->flags
= mod_tmp
.flags
;
2716 orig_mode
->private = mod_tmp
.private;
2718 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
2719 for (i
=0;i
<mode_count
;i
++)
2721 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
2723 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
2724 *vidmode
= *(all_modes
[i
]);
2727 TSXFree(all_modes
[i
]->private);
2729 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
2733 WARN(ddraw
, "Fullscreen mode not available!\n");
2737 TRACE(ddraw
,"SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
2738 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
2739 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2740 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
2746 /* FIXME: this function OVERWRITES several signal handlers.
2747 * can we save them? and restore them later? In a way that
2748 * it works for the library too?
2750 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
2752 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,this->e
.dga
.fb_height
);
2754 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
2757 #ifdef RESTORE_SIGNALS
2758 SIGNAL_InitHandlers();
2761 #else /* defined(HAVE_LIBXXF86DGA) */
2762 return E_UNEXPECTED
;
2763 #endif /* defined(HAVE_LIBXXF86DGA) */
2766 static HRESULT WINAPI
Xlib_IDirectDraw_SetDisplayMode(
2767 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2769 int i
,*depths
,depcount
;
2772 TRACE(ddraw
, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2773 this, width
, height
, depth
);
2775 /* We hope getting the asked for depth */
2776 this->d
.screen_depth
= depth
;
2778 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
2780 for (i
=0;i
<depcount
;i
++)
2781 if (depths
[i
]==depth
)
2783 if (i
==depcount
) {/* not found */
2784 for (i
=0;i
<depcount
;i
++)
2789 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
2790 MessageBox32A(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
2792 return DDERR_UNSUPPORTEDMODE
;
2794 WARN(ddraw
, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
2795 this->d
.screen_depth
= 16;
2800 this->d
.width
= width
;
2801 this->d
.height
= height
;
2802 this->d
.depth
= depth
;
2804 _common_IDirectDraw_SetDisplayMode(this);
2806 this->d
.paintable
= 1;
2807 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_FindWndPtr(this->d
.window
)->pDriverData
)->window
;
2808 /* We don't have a context for this window. Host off the desktop */
2809 if( !this->d
.drawable
)
2810 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
2814 static HRESULT WINAPI
DGA_IDirectDraw2_GetCaps(
2815 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2817 #ifdef HAVE_LIBXXF86DGA
2818 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2819 caps1
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2820 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2821 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2823 caps2
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2824 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2825 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2828 #else /* defined(HAVE_LIBXXF86DGA) */
2829 return E_UNEXPECTED
;
2830 #endif /* defined(HAVE_LIBXXF86DGA) */
2833 static void fill_caps(LPDDCAPS caps
) {
2834 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2835 Need to be fixed, though.. */
2839 caps
->dwSize
= sizeof(*caps
);
2840 caps
->dwCaps
= DDCAPS_3D
| DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
|
2841 DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
| DDCAPS_ZBLTS
;
2842 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NO2DDURING3DSCENE
| DDCAPS2_NOPAGELOCKREQUIRED
|
2843 DDCAPS2_WIDESURFACES
;
2844 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
2846 caps
->dwFXAlphaCaps
= 0;
2847 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
2849 caps
->dwZBufferBitDepths
= DDBD_16
;
2850 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2851 to put textures in video memory.
2852 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2854 caps
->dwVidMemTotal
= 8192 * 1024;
2855 caps
->dwVidMemFree
= 8192 * 1024;
2856 /* These are all the supported capabilities of the surfaces */
2857 caps
->ddsCaps
.dwCaps
= DDSCAPS_3DDEVICE
| DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
2858 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_MIPMAP
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
2859 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
|
2860 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
| DDSCAPS_ZBUFFER
;
2863 static HRESULT WINAPI
Xlib_IDirectDraw2_GetCaps(
2864 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2866 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2868 /* Put the same caps for the two capabilities */
2875 static HRESULT WINAPI
IDirectDraw2_CreateClipper(
2876 LPDIRECTDRAW2
this,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
2878 FIXME(ddraw
,"(%p)->(%08lx,%p,%p),stub!\n",
2879 this,x
,lpddclip
,lpunk
2881 *lpddclip
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
2882 (*lpddclip
)->ref
= 1;
2883 (*lpddclip
)->lpvtbl
= &ddclipvt
;
2887 static HRESULT WINAPI
common_IDirectDraw2_CreatePalette(
2888 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
,int *psize
2892 if (TRACE_ON(ddraw
))
2893 _dump_paletteformat(dwFlags
);
2895 *lpddpal
= (LPDIRECTDRAWPALETTE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPalette
));
2896 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
2897 (*lpddpal
)->ref
= 1;
2898 (*lpddpal
)->ddraw
= (LPDIRECTDRAW
)this;
2899 (*lpddpal
)->installed
= 0;
2901 if (dwFlags
& DDPCAPS_1BIT
)
2903 else if (dwFlags
& DDPCAPS_2BIT
)
2905 else if (dwFlags
& DDPCAPS_4BIT
)
2907 else if (dwFlags
& DDPCAPS_8BIT
)
2910 ERR(ddraw
, "unhandled palette format\n");
2915 /* Now, if we are in 'depth conversion mode', create the screen palette */
2916 if (this->d
.depth
!= this->d
.screen_depth
) {
2919 switch (this->d
.screen_depth
) {
2921 unsigned short *screen_palette
= (unsigned short *) (*lpddpal
)->screen_palents
;
2923 for (i
= 0; i
< size
; i
++) {
2924 screen_palette
[i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
2925 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
2926 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
2931 ERR(ddraw
, "Memory corruption ! (depth=%ld, screen_depth=%ld)\n",this->d
.depth
,this->d
.screen_depth
);
2936 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
2937 } else if (this->d
.depth
!= this->d
.screen_depth
) {
2940 switch (this->d
.screen_depth
) {
2942 unsigned short *screen_palette
= (unsigned short *) (*lpddpal
)->screen_palents
;
2944 for (i
= 0; i
< size
; i
++) {
2945 screen_palette
[i
] = 0xFFFF;
2950 ERR(ddraw
, "Memory corruption !\n");
2958 static HRESULT WINAPI
DGA_IDirectDraw2_CreatePalette(
2959 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2964 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
2965 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
2966 if (res
!= 0) return res
;
2967 (*lpddpal
)->lpvtbl
= &dga_ddpalvt
;
2968 if (this->d
.depth
<=8) {
2969 (*lpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
2971 FIXME(ddraw
,"why are we doing CreatePalette in hi/truecolor?\n");
2974 if (((*lpddpal
)->cm
)&&xsize
) {
2975 for (i
=0;i
<xsize
;i
++) {
2978 xc
.red
= (*lpddpal
)->palents
[i
].peRed
<<8;
2979 xc
.blue
= (*lpddpal
)->palents
[i
].peBlue
<<8;
2980 xc
.green
= (*lpddpal
)->palents
[i
].peGreen
<<8;
2981 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2983 TSXStoreColor(display
,(*lpddpal
)->cm
,&xc
);
2989 static HRESULT WINAPI
Xlib_IDirectDraw2_CreatePalette(
2990 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2995 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
2996 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
2997 if (res
!= 0) return res
;
2998 (*lpddpal
)->lpvtbl
= &xlib_ddpalvt
;
3002 static HRESULT WINAPI
DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3003 #ifdef HAVE_LIBXXF86DGA
3004 TRACE(ddraw
, "(%p)->()\n",this);
3006 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3007 #ifdef RESTORE_SIGNALS
3008 SIGNAL_InitHandlers();
3011 #else /* defined(HAVE_LIBXXF86DGA) */
3012 return E_UNEXPECTED
;
3016 static HRESULT WINAPI
Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3017 TRACE(ddraw
, "(%p)->RestoreDisplayMode()\n", this);
3022 static HRESULT WINAPI
IDirectDraw2_WaitForVerticalBlank(
3023 LPDIRECTDRAW2
this,DWORD x
,HANDLE32 h
3025 TRACE(ddraw
,"(%p)->(0x%08lx,0x%08x)\n",this,x
,h
);
3029 static ULONG WINAPI
IDirectDraw2_AddRef(LPDIRECTDRAW2
this) {
3030 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
3032 return ++(this->ref
);
3035 static ULONG WINAPI
DGA_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3036 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3038 #ifdef HAVE_LIBXXF86DGA
3039 if (!--(this->ref
)) {
3040 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3041 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3042 DestroyWindow32(this->d
.window
);
3043 #ifdef HAVE_LIBXXF86VM
3045 TSXF86VidModeSwitchToMode(
3047 DefaultScreen(display
),
3049 if (orig_mode
->privsize
)
3050 TSXFree(orig_mode
->private);
3056 #ifdef RESTORE_SIGNALS
3057 SIGNAL_InitHandlers();
3059 HeapFree(GetProcessHeap(),0,this);
3062 #endif /* defined(HAVE_LIBXXF86DGA) */
3066 static ULONG WINAPI
Xlib_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3067 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3069 if (!--(this->ref
)) {
3070 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3071 DestroyWindow32(this->d
.window
);
3072 HeapFree(GetProcessHeap(),0,this);
3075 /* FIXME: destroy window ... */
3079 static HRESULT WINAPI
DGA_IDirectDraw2_QueryInterface(
3080 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3084 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3085 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3086 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3088 this->lpvtbl
->fnAddRef(this);
3090 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3094 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3095 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_ddvt
;
3096 this->lpvtbl
->fnAddRef(this);
3099 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3103 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3104 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd2vt
;
3105 this->lpvtbl
->fnAddRef(this);
3108 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3112 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3113 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd4vt
;
3114 this->lpvtbl
->fnAddRef(this);
3117 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3121 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3124 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3126 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3127 this->lpvtbl
->fnAddRef(this);
3128 d3d
->lpvtbl
= &d3dvt
;
3131 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3135 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
3138 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3140 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3141 this->lpvtbl
->fnAddRef(this);
3142 d3d
->lpvtbl
= &d3d2vt
;
3145 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3149 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3150 return OLE_E_ENUM_NOMORE
;
3153 static HRESULT WINAPI
Xlib_IDirectDraw2_QueryInterface(
3154 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3158 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3159 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3160 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3162 this->lpvtbl
->fnAddRef(this);
3164 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3168 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3169 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_ddvt
;
3170 this->lpvtbl
->fnAddRef(this);
3173 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3177 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3178 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd2vt
;
3179 this->lpvtbl
->fnAddRef(this);
3182 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3186 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3187 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd4vt
;
3188 this->lpvtbl
->fnAddRef(this);
3191 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3195 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3198 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3200 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3201 this->lpvtbl
->fnAddRef(this);
3202 d3d
->lpvtbl
= &d3dvt
;
3205 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3209 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
3212 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3214 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3215 this->lpvtbl
->fnAddRef(this);
3216 d3d
->lpvtbl
= &d3d2vt
;
3219 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3223 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3224 return OLE_E_ENUM_NOMORE
;
3227 static HRESULT WINAPI
IDirectDraw2_GetVerticalBlankStatus(
3228 LPDIRECTDRAW2
this,BOOL32
*status
3230 TRACE(ddraw
,"(%p)->(%p)\n",this,status
);
3235 static HRESULT WINAPI
IDirectDraw2_EnumDisplayModes(
3236 LPDIRECTDRAW2
this,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
3238 DDSURFACEDESC ddsfd
;
3241 } modes
[5] = { /* some of the usual modes */
3248 static int depths
[4] = {8,16,24,32};
3251 TRACE(ddraw
,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags
,lpddsfd
,context
,modescb
);
3252 ddsfd
.dwSize
= sizeof(ddsfd
);
3253 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3254 if (dwFlags
& DDEDM_REFRESHRATES
) {
3255 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
3256 ddsfd
.x
.dwRefreshRate
= 60;
3259 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
3260 ddsfd
.dwBackBufferCount
= 1;
3261 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
3262 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
3263 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= depths
[i
];
3264 /* FIXME: those masks would have to be set in depth > 8 */
3266 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
3267 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
3268 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
3269 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3270 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
3271 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
3273 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3275 /* FIXME: We should query those from X itself */
3276 switch (depths
[i
]) {
3278 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0xF800;
3279 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x07E0;
3280 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x001F;
3283 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3284 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3285 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3288 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3289 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3290 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3295 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3296 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3297 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3298 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3300 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
3301 ddsfd
.dwWidth
= modes
[j
].w
;
3302 ddsfd
.dwHeight
= modes
[j
].h
;
3303 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3304 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3307 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
3308 /* modeX is not standard VGA */
3310 ddsfd
.dwHeight
= 200;
3311 ddsfd
.dwWidth
= 320;
3312 TRACE(ddraw
," enumerating (320x200x%d)\n",depths
[i
]);
3313 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3319 static HRESULT WINAPI
DGA_IDirectDraw2_GetDisplayMode(
3320 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3322 #ifdef HAVE_LIBXXF86DGA
3323 TRACE(ddraw
,"(%p)->(%p)\n",this,lpddsfd
);
3324 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3325 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3326 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3327 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
3328 lpddsfd
->dwBackBufferCount
= 1;
3329 lpddsfd
->x
.dwRefreshRate
= 60;
3330 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3331 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
3333 #else /* defined(HAVE_LIBXXF86DGA) */
3334 return E_UNEXPECTED
;
3335 #endif /* defined(HAVE_LIBXXF86DGA) */
3338 static HRESULT WINAPI
Xlib_IDirectDraw2_GetDisplayMode(
3339 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3341 TRACE(ddraw
,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd
);
3342 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3343 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3344 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3345 /* POOLE FIXME: Xlib */
3346 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
3347 /* END FIXME: Xlib */
3348 lpddsfd
->dwBackBufferCount
= 1;
3349 lpddsfd
->x
.dwRefreshRate
= 60;
3350 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3351 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
3355 static HRESULT WINAPI
IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2
this) {
3356 TRACE(ddraw
,"(%p)->()\n",this);
3360 static HRESULT WINAPI
IDirectDraw2_GetMonitorFrequency(
3361 LPDIRECTDRAW2
this,LPDWORD freq
3363 FIXME(ddraw
,"(%p)->(%p) returns 60 Hz always\n",this,freq
);
3364 *freq
= 60*100; /* 60 Hz */
3368 /* what can we directly decompress? */
3369 static HRESULT WINAPI
IDirectDraw2_GetFourCCCodes(
3370 LPDIRECTDRAW2
this,LPDWORD x
,LPDWORD y
3372 FIXME(ddraw
,"(%p,%p,%p), stub\n",this,x
,y
);
3376 static HRESULT WINAPI
IDirectDraw2_EnumSurfaces(
3377 LPDIRECTDRAW2
this,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
3379 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x
,ddsfd
,context
,ddsfcb
);
3383 static HRESULT WINAPI
IDirectDraw2_Compact(
3384 LPDIRECTDRAW2
this )
3386 FIXME(ddraw
,"(%p)->()\n", this );
3391 static HRESULT WINAPI
IDirectDraw2_GetGDISurface(LPDIRECTDRAW2
this,
3392 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
3393 FIXME(ddraw
,"(%p)->(%p)\n", this, lplpGDIDDSSurface
);
3398 static HRESULT WINAPI
IDirectDraw2_GetScanLine(LPDIRECTDRAW2
this,
3399 LPDWORD lpdwScanLine
) {
3400 FIXME(ddraw
,"(%p)->(%p)\n", this, lpdwScanLine
);
3405 static HRESULT WINAPI
IDirectDraw2_Initialize(LPDIRECTDRAW2
this,
3407 FIXME(ddraw
,"(%p)->(%p)\n", this, lpGUID
);
3412 /* Note: Hack so we can reuse the old functions without compiler warnings */
3414 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3416 # define XCAST(fun) (void*)
3419 static struct IDirectDraw_VTable dga_ddvt
= {
3420 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3421 XCAST(AddRef
)IDirectDraw2_AddRef
,
3422 XCAST(Release
)DGA_IDirectDraw2_Release
,
3423 XCAST(Compact
)IDirectDraw2_Compact
,
3424 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3425 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3426 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3427 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3428 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3429 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3430 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3431 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3432 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3433 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3434 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3435 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3436 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3437 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3438 XCAST(Initialize
)IDirectDraw2_Initialize
,
3439 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3440 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3441 DGA_IDirectDraw_SetDisplayMode
,
3442 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3445 static struct IDirectDraw_VTable xlib_ddvt
= {
3446 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3447 XCAST(AddRef
)IDirectDraw2_AddRef
,
3448 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3449 XCAST(Compact
)IDirectDraw2_Compact
,
3450 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3451 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3452 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3453 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3454 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3455 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3456 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3457 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3458 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3459 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3460 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3461 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3462 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3463 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3464 XCAST(Initialize
)IDirectDraw2_Initialize
,
3465 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3466 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3467 Xlib_IDirectDraw_SetDisplayMode
,
3468 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3473 /*****************************************************************************
3479 static HRESULT WINAPI
DGA_IDirectDraw2_SetDisplayMode(
3480 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3482 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3485 static HRESULT WINAPI
Xlib_IDirectDraw2_SetDisplayMode(
3486 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3488 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3491 static HRESULT WINAPI
DGA_IDirectDraw2_GetAvailableVidMem(
3492 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3494 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3495 this,ddscaps
,total
,free
3497 if (total
) *total
= this->e
.dga
.fb_memsize
* 1024;
3498 if (free
) *free
= this->e
.dga
.fb_memsize
* 1024;
3502 static HRESULT WINAPI
Xlib_IDirectDraw2_GetAvailableVidMem(
3503 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3505 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3506 this,ddscaps
,total
,free
3508 if (total
) *total
= 2048 * 1024;
3509 if (free
) *free
= 2048 * 1024;
3513 static IDirectDraw2_VTable dga_dd2vt
= {
3514 DGA_IDirectDraw2_QueryInterface
,
3515 IDirectDraw2_AddRef
,
3516 DGA_IDirectDraw2_Release
,
3517 IDirectDraw2_Compact
,
3518 IDirectDraw2_CreateClipper
,
3519 DGA_IDirectDraw2_CreatePalette
,
3520 DGA_IDirectDraw2_CreateSurface
,
3521 IDirectDraw2_DuplicateSurface
,
3522 IDirectDraw2_EnumDisplayModes
,
3523 IDirectDraw2_EnumSurfaces
,
3524 IDirectDraw2_FlipToGDISurface
,
3525 DGA_IDirectDraw2_GetCaps
,
3526 DGA_IDirectDraw2_GetDisplayMode
,
3527 IDirectDraw2_GetFourCCCodes
,
3528 IDirectDraw2_GetGDISurface
,
3529 IDirectDraw2_GetMonitorFrequency
,
3530 IDirectDraw2_GetScanLine
,
3531 IDirectDraw2_GetVerticalBlankStatus
,
3532 IDirectDraw2_Initialize
,
3533 DGA_IDirectDraw2_RestoreDisplayMode
,
3534 IDirectDraw2_SetCooperativeLevel
,
3535 DGA_IDirectDraw2_SetDisplayMode
,
3536 IDirectDraw2_WaitForVerticalBlank
,
3537 DGA_IDirectDraw2_GetAvailableVidMem
3540 static struct IDirectDraw2_VTable xlib_dd2vt
= {
3541 Xlib_IDirectDraw2_QueryInterface
,
3542 IDirectDraw2_AddRef
,
3543 Xlib_IDirectDraw2_Release
,
3544 IDirectDraw2_Compact
,
3545 IDirectDraw2_CreateClipper
,
3546 Xlib_IDirectDraw2_CreatePalette
,
3547 Xlib_IDirectDraw2_CreateSurface
,
3548 IDirectDraw2_DuplicateSurface
,
3549 IDirectDraw2_EnumDisplayModes
,
3550 IDirectDraw2_EnumSurfaces
,
3551 IDirectDraw2_FlipToGDISurface
,
3552 Xlib_IDirectDraw2_GetCaps
,
3553 Xlib_IDirectDraw2_GetDisplayMode
,
3554 IDirectDraw2_GetFourCCCodes
,
3555 IDirectDraw2_GetGDISurface
,
3556 IDirectDraw2_GetMonitorFrequency
,
3557 IDirectDraw2_GetScanLine
,
3558 IDirectDraw2_GetVerticalBlankStatus
,
3559 IDirectDraw2_Initialize
,
3560 Xlib_IDirectDraw2_RestoreDisplayMode
,
3561 IDirectDraw2_SetCooperativeLevel
,
3562 Xlib_IDirectDraw2_SetDisplayMode
,
3563 IDirectDraw2_WaitForVerticalBlank
,
3564 Xlib_IDirectDraw2_GetAvailableVidMem
3567 /*****************************************************************************
3572 static HRESULT WINAPI
IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4
this,
3574 LPDIRECTDRAWSURFACE
*lpDDS
) {
3575 FIXME(ddraw
, "(%p)->(%08ld,%p)\n", this, (DWORD
) hdc
, lpDDS
);
3580 static HRESULT WINAPI
IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4
this) {
3581 FIXME(ddraw
, "(%p)->()\n", this);
3586 static HRESULT WINAPI
IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4
this) {
3587 FIXME(ddraw
, "(%p)->()\n", this);
3592 static HRESULT WINAPI
IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4
this,
3593 LPDDDEVICEIDENTIFIER lpdddi
,
3595 FIXME(ddraw
, "(%p)->(%p,%08lx)\n", this, lpdddi
, dwFlags
);
3601 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3603 # define XCAST(fun) (void*)
3607 static struct IDirectDraw4_VTable dga_dd4vt
= {
3608 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3609 XCAST(AddRef
)IDirectDraw2_AddRef
,
3610 XCAST(Release
)DGA_IDirectDraw2_Release
,
3611 XCAST(Compact
)IDirectDraw2_Compact
,
3612 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3613 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3614 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3615 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3616 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3617 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3618 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3619 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3620 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3621 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3622 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3623 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3624 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3625 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3626 XCAST(Initialize
)IDirectDraw2_Initialize
,
3627 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3628 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3629 XCAST(SetDisplayMode
)DGA_IDirectDraw_SetDisplayMode
,
3630 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3631 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2_GetAvailableVidMem
,
3632 IDirectDraw4_GetSurfaceFromDC
,
3633 IDirectDraw4_RestoreAllSurfaces
,
3634 IDirectDraw4_TestCooperativeLevel
,
3635 IDirectDraw4_GetDeviceIdentifier
3638 static struct IDirectDraw4_VTable xlib_dd4vt
= {
3639 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3640 XCAST(AddRef
)IDirectDraw2_AddRef
,
3641 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3642 XCAST(Compact
)IDirectDraw2_Compact
,
3643 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3644 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3645 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3646 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3647 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3648 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3649 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3650 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3651 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3652 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3653 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3654 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3655 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3656 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3657 XCAST(Initialize
)IDirectDraw2_Initialize
,
3658 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3659 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3660 XCAST(SetDisplayMode
)Xlib_IDirectDraw_SetDisplayMode
,
3661 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3662 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2_GetAvailableVidMem
,
3663 IDirectDraw4_GetSurfaceFromDC
,
3664 IDirectDraw4_RestoreAllSurfaces
,
3665 IDirectDraw4_TestCooperativeLevel
,
3666 IDirectDraw4_GetDeviceIdentifier
3671 /******************************************************************************
3675 LRESULT WINAPI
Xlib_DDWndProc(HWND32 hwnd
,UINT32 msg
,WPARAM32 wParam
,LPARAM lParam
)
3678 LPDIRECTDRAW ddraw
= NULL
;
3681 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3683 SetLastError( ERROR_SUCCESS
);
3684 ddraw
= (LPDIRECTDRAW
)GetWindowLong32A( hwnd
, ddrawXlibThisOffset
);
3686 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
3689 ERR( ddraw
, "Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
3694 /* Perform any special direct draw functions */
3696 ddraw
->d
.paintable
= 1;
3698 /* Now let the application deal with the rest of this */
3699 if( ddraw
->d
.mainWindow
)
3702 /* Don't think that we actually need to call this but...
3703 might as well be on the safe side of things... */
3705 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3706 it should be the procedures of our fake window that gets called
3707 instead of those of the window provided by the application.
3708 And with this patch, mouse clicks work with Monkey Island III
3710 ret
= DefWindowProc32A( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3714 /* We didn't handle the message - give it to the application */
3715 if (ddraw
&& ddraw
->d
.mainWindow
&& WIN_FindWndPtr(ddraw
->d
.mainWindow
)) {
3716 ret
= CallWindowProc32A( WIN_FindWndPtr( ddraw
->d
.mainWindow
)->winproc
,
3717 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3722 ret
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
3728 ret
= DefWindowProc32A(hwnd
,msg
,wParam
,lParam
);
3734 HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3735 #ifdef HAVE_LIBXXF86DGA
3736 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
3740 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3741 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
3745 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3746 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
3747 return E_UNEXPECTED
;
3749 if (!DDRAW_DGA_Available()) {
3750 TRACE(ddraw
,"No XF86DGA detected.\n");
3751 return DDERR_GENERIC
;
3753 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
3754 (*lplpDD
)->lpvtbl
= &dga_ddvt
;
3756 TSXF86DGAQueryVersion(display
,&major
,&minor
);
3757 TRACE(ddraw
,"XF86DGA is version %d.%d\n",major
,minor
);
3758 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
3759 if (!(flags
& XF86DGADirectPresent
))
3760 MSG("direct video is NOT PRESENT.\n");
3761 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
3762 TRACE(ddraw
,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3763 addr
,width
,banksize
,memsize
3765 (*lplpDD
)->e
.dga
.fb_width
= width
;
3766 (*lplpDD
)->d
.width
= width
;
3767 (*lplpDD
)->e
.dga
.fb_addr
= addr
;
3768 (*lplpDD
)->e
.dga
.fb_memsize
= memsize
;
3769 (*lplpDD
)->e
.dga
.fb_banksize
= banksize
;
3771 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
3772 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
3773 (*lplpDD
)->e
.dga
.fb_height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3775 (*lplpDD
)->e
.dga
.vpmask
= 1;
3777 (*lplpDD
)->e
.dga
.vpmask
= 0;
3780 /* just assume the default depth is the DGA depth too */
3781 (*lplpDD
)->d
.screen_depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3782 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3783 #ifdef RESTORE_SIGNALS
3784 SIGNAL_InitHandlers();
3788 #else /* defined(HAVE_LIBXXF86DGA) */
3789 return DDERR_INVALIDDIRECTDRAWGUID
;
3790 #endif /* defined(HAVE_LIBXXF86DGA) */
3794 DDRAW_XSHM_Available(void)
3796 #ifdef HAVE_LIBXXSHM
3797 if (TSXShmQueryExtension(display
))
3802 if (TSXShmQueryVersion(display
, &major
, &minor
, &shpix
))
3814 HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3816 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
3817 (*lplpDD
)->lpvtbl
= &xlib_ddvt
;
3819 (*lplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
3821 /* At DirectDraw creation, the depth is the default depth */
3822 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3823 (*lplpDD
)->d
.screen_depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3824 (*lplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3825 (*lplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3827 #ifdef HAVE_LIBXXSHM
3828 /* Test if XShm is available. */
3829 if (((*lplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available()))
3830 TRACE(ddraw
, "Using XShm extension.\n");
3836 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3843 WINE_StringFromCLSID(lpGUID
,xclsid
);
3845 sprintf(xclsid
,"<guid-0x%08x>",(int)lpGUID
);
3849 TRACE(ddraw
,"(%s,%p,%p)\n",xclsid
,lplpDD
,pUnkOuter
);
3852 /* if they didn't request a particular interface, use the best
3854 if (DDRAW_DGA_Available())
3855 lpGUID
= &DGA_DirectDraw_GUID
;
3857 lpGUID
= &XLIB_DirectDraw_GUID
;
3860 wc
.style
= CS_GLOBALCLASS
;
3861 wc
.lpfnWndProc
= Xlib_DDWndProc
;
3863 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
3864 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
3866 /* We can be a child of the desktop since we're really important */
3867 pParentWindow
= WIN_GetDesktop();
3868 wc
.hInstance
= pParentWindow
? pParentWindow
->hwndSelf
: 0;
3872 wc
.hCursor
= (HCURSOR32
)IDC_ARROW32A
;
3873 wc
.hbrBackground
= NULL_BRUSH
;
3874 wc
.lpszMenuName
= 0;
3875 wc
.lpszClassName
= "WINE_DirectDraw";
3876 RegisterClass32A(&wc
);
3878 if (!memcmp(lpGUID
, &DGA_DirectDraw_GUID
, sizeof(GUID
)))
3879 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
3880 else if (!memcmp(lpGUID
, &XLIB_DirectDraw_GUID
, sizeof(GUID
)))
3881 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
3886 (*lplpDD
)->d
.winclass
= RegisterClass32A(&wc
);
3890 fprintf(stderr
,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
3891 return DDERR_INVALIDDIRECTDRAWGUID
;