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>
67 /* This for all the enumeration and creation of D3D-related objects */
68 #include "d3d_private.h"
70 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
73 /* Restore signal handlers overwritten by XF86DGA
75 #define RESTORE_SIGNALS
77 /* Where do these GUIDs come from? mkuuid.
78 * They exist solely to distinguish between the targets Wine support,
79 * and should be different than any other GUIDs in existence.
81 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
85 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
88 static GUID XLIB_DirectDraw_GUID
= { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
92 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
95 static struct IDirectDrawSurface4_VTable dga_dds4vt
, xlib_dds4vt
;
96 static struct IDirectDraw_VTable dga_ddvt
, xlib_ddvt
;
97 static struct IDirectDraw2_VTable dga_dd2vt
, xlib_dd2vt
;
98 static struct IDirectDraw4_VTable dga_dd4vt
, xlib_dd4vt
;
99 static struct IDirectDrawClipper_VTable ddclipvt
;
100 static struct IDirectDrawPalette_VTable dga_ddpalvt
, xlib_ddpalvt
;
101 static struct IDirect3D_VTable d3dvt
;
102 static struct IDirect3D2_VTable d3d2vt
;
104 #ifdef HAVE_LIBXXF86VM
105 static XF86VidModeModeInfo
*orig_mode
= NULL
;
109 static int XShmErrorFlag
= 0;
113 DDRAW_DGA_Available(void)
115 #ifdef HAVE_LIBXXF86DGA
116 int evbase
, evret
, fd
;
121 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
122 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
123 /* others. --stephenc */
124 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
127 return (fd
!= -1) && TSXF86DGAQueryExtension(display
,&evbase
,&evret
);
128 #else /* defined(HAVE_LIBXXF86DGA) */
130 #endif /* defined(HAVE_LIBXXF86DGA) */
134 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc
,LPVOID data
) {
135 if (DDRAW_DGA_Available()) {
136 TRACE(ddraw
, "Enumerating DGA interface\n");
137 ddenumproc(&DGA_DirectDraw_GUID
,"WINE with XFree86 DGA","display",data
);
139 TRACE(ddraw
, "Enumerating Xlib interface\n");
140 ddenumproc(&XLIB_DirectDraw_GUID
,"WINE with Xlib","display",data
);
141 TRACE(ddraw
, "Enumerating Default interface\n");
142 ddenumproc(NULL
,"WINE (default)","display",data
);
146 /* What is this doing here? */
148 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
149 FIXME(ddraw
,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
154 /******************************************************************************
155 * internal helper functions
157 static void _dump_DDBLTFX(DWORD flagmask
) {
163 #define FE(x) { x, #x},
164 FE(DDBLTFX_ARITHSTRETCHY
)
165 FE(DDBLTFX_MIRRORLEFTRIGHT
)
166 FE(DDBLTFX_MIRRORUPDOWN
)
167 FE(DDBLTFX_NOTEARING
)
168 FE(DDBLTFX_ROTATE180
)
169 FE(DDBLTFX_ROTATE270
)
171 FE(DDBLTFX_ZBUFFERRANGE
)
172 FE(DDBLTFX_ZBUFFERBASEDEST
)
174 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
175 if (flags
[i
].mask
& flagmask
) {
176 DUMP("%s ",flags
[i
].name
);
183 static void _dump_DDBLTFAST(DWORD flagmask
) {
189 #define FE(x) { x, #x},
190 FE(DDBLTFAST_NOCOLORKEY
)
191 FE(DDBLTFAST_SRCCOLORKEY
)
192 FE(DDBLTFAST_DESTCOLORKEY
)
195 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
196 if (flags
[i
].mask
& flagmask
)
197 DUMP("%s ",flags
[i
].name
);
201 static void _dump_DDBLT(DWORD flagmask
) {
207 #define FE(x) { x, #x},
209 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
210 FE(DDBLT_ALPHADESTNEG
)
211 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
212 FE(DDBLT_ALPHAEDGEBLEND
)
214 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
215 FE(DDBLT_ALPHASRCNEG
)
216 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
222 FE(DDBLT_KEYDESTOVERRIDE
)
224 FE(DDBLT_KEYSRCOVERRIDE
)
226 FE(DDBLT_ROTATIONANGLE
)
228 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
229 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
230 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
231 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
235 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
236 if (flags
[i
].mask
& flagmask
)
237 DUMP("%s ",flags
[i
].name
);
241 static void _dump_DDSCAPS(DWORD flagmask
) {
247 #define FE(x) { x, #x},
248 FE(DDSCAPS_RESERVED1
)
250 FE(DDSCAPS_BACKBUFFER
)
253 FE(DDSCAPS_FRONTBUFFER
)
254 FE(DDSCAPS_OFFSCREENPLAIN
)
257 FE(DDSCAPS_PRIMARYSURFACE
)
258 FE(DDSCAPS_PRIMARYSURFACELEFT
)
259 FE(DDSCAPS_SYSTEMMEMORY
)
262 FE(DDSCAPS_VIDEOMEMORY
)
264 FE(DDSCAPS_WRITEONLY
)
267 FE(DDSCAPS_LIVEVIDEO
)
271 FE(DDSCAPS_RESERVED2
)
272 FE(DDSCAPS_ALLOCONLOAD
)
273 FE(DDSCAPS_VIDEOPORT
)
274 FE(DDSCAPS_LOCALVIDMEM
)
275 FE(DDSCAPS_NONLOCALVIDMEM
)
276 FE(DDSCAPS_STANDARDVGAMODE
)
277 FE(DDSCAPS_OPTIMIZED
)
279 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
280 if (flags
[i
].mask
& flagmask
)
281 DUMP("%s ",flags
[i
].name
);
285 static void _dump_DDSD(DWORD flagmask
) {
295 FE(DDSD_BACKBUFFERCOUNT
)
296 FE(DDSD_ZBUFFERBITDEPTH
)
297 FE(DDSD_ALPHABITDEPTH
)
299 FE(DDSD_CKDESTOVERLAY
)
301 FE(DDSD_CKSRCOVERLAY
)
308 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
309 if (flags
[i
].mask
& flagmask
)
310 DUMP("%s ",flags
[i
].name
);
314 static void _dump_DDCOLORKEY(DWORD flagmask
) {
320 #define FE(x) { x, #x},
324 FE(DDPF_PALETTEINDEXED4
)
325 FE(DDPF_PALETTEINDEXEDTO8
)
326 FE(DDPF_PALETTEINDEXED8
)
332 FE(DDPF_PALETTEINDEXED1
)
333 FE(DDPF_PALETTEINDEXED2
)
336 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
337 if (flags
[i
].mask
& flagmask
)
338 DUMP("%s ",flags
[i
].name
);
342 static void _dump_paletteformat(DWORD dwFlags
) {
348 #define FE(x) { x, #x},
350 FE(DDPCAPS_8BITENTRIES
)
352 FE(DDPCAPS_INITIALIZE
)
353 FE(DDPCAPS_PRIMARYSURFACE
)
354 FE(DDPCAPS_PRIMARYSURFACELEFT
)
361 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
362 if (flags
[i
].mask
& dwFlags
)
363 DUMP("%s ",flags
[i
].name
);
367 static void _dump_pixelformat(LPDDPIXELFORMAT pf
) {
368 DUMP("Size : %ld\n", pf
->dwSize
);
370 _dump_DDCOLORKEY(pf
->dwFlags
);
371 DUMP("dwFourCC : %ld\n", pf
->dwFourCC
);
372 DUMP("RGB bit count : %ld\n", pf
->x
.dwRGBBitCount
);
373 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
374 pf
->y
.dwRBitMask
, pf
->z
.dwGBitMask
, pf
->xx
.dwBBitMask
, pf
->xy
.dwRGBAlphaBitMask
);
377 static int _getpixelformat(LPDIRECTDRAW2 ddraw
,LPDDPIXELFORMAT pf
) {
378 static XVisualInfo
*vi
;
383 vi
= TSXGetVisualInfo(display
,VisualNoMask
,&vt
,&nitems
);
386 pf
->dwSize
= sizeof(DDPIXELFORMAT
);
387 if (ddraw
->d
.depth
==8) {
388 pf
->dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
389 pf
->x
.dwRGBBitCount
= 8;
390 pf
->y
.dwRBitMask
= 0;
391 pf
->z
.dwGBitMask
= 0;
392 pf
->xx
.dwBBitMask
= 0;
393 pf
->xy
.dwRGBAlphaBitMask
= 0;
396 if (ddraw
->d
.depth
==16) {
397 pf
->dwFlags
= DDPF_RGB
;
398 pf
->x
.dwRGBBitCount
= 16;
399 pf
->y
.dwRBitMask
= vi
[0].red_mask
;
400 pf
->z
.dwGBitMask
= vi
[0].green_mask
;
401 pf
->xx
.dwBBitMask
= vi
[0].blue_mask
;
402 pf
->xy
.dwRGBAlphaBitMask
= 0;
405 if (ddraw
->d
.depth
==24) {
406 pf
->dwFlags
= DDPF_RGB
;
407 pf
->x
.dwRGBBitCount
= 24;
408 pf
->y
.dwRBitMask
= vi
[0].red_mask
;
409 pf
->z
.dwGBitMask
= vi
[0].green_mask
;
410 pf
->xx
.dwBBitMask
= vi
[0].blue_mask
;
411 pf
->xy
.dwRGBAlphaBitMask
= 0;
414 FIXME(ddraw
,"_getpixelformat:unknown depth %ld?\n",ddraw
->d
.depth
);
415 return DDERR_GENERIC
;
418 /******************************************************************************
419 * IDirectDrawSurface methods
421 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
422 * DDS and DDS2 use those functions. (Function calls did not change (except
423 * using different DirectDrawSurfaceX version), just added flags and functions)
425 static HRESULT WINAPI
IDirectDrawSurface4_Lock(
426 LPDIRECTDRAWSURFACE4
this,LPRECT32 lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE32 hnd
428 TRACE(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
429 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
430 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
431 WARN(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
432 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
434 /* First, copy the Surface description */
435 *lpddsd
= this->s
.surface_desc
;
436 TRACE(ddraw
,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
437 lpddsd
->dwHeight
,lpddsd
->dwWidth
,lpddsd
->lPitch
);
439 /* If asked only for a part, change the surface pointer */
441 FIXME(ddraw
," lprect: %dx%d-%dx%d\n",
442 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
444 lpddsd
->y
.lpSurface
= this->s
.surface_desc
.y
.lpSurface
+
445 (lprect
->top
*this->s
.surface_desc
.lPitch
) +
446 (lprect
->left
*(this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8));
448 assert(this->s
.surface_desc
.y
.lpSurface
);
453 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Unlock(
454 LPDIRECTDRAWSURFACE4
this,LPVOID surface
456 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
460 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4
this) {
461 if (this->s
.ddraw
->d
.depth
!= this->s
.ddraw
->d
.screen_depth
) {
462 /* Pixel convertion ! */
463 if ((this->s
.ddraw
->d
.depth
== 8) && (this->s
.ddraw
->d
.screen_depth
== 16)) {
464 unsigned char *src
= (unsigned char *) this->s
.surface_desc
.y
.lpSurface
;
465 unsigned short *dst
= (unsigned short *) this->t
.xlib
.image
->data
;
469 if (this->s
.palette
!= NULL
) {
470 pal
= (unsigned short *) this->s
.palette
->screen_palents
;
471 for (y
= 0; y
< this->s
.surface_desc
.dwHeight
; y
++) {
472 for (x
= 0; x
< this->s
.surface_desc
.dwWidth
; x
++) {
473 dst
[x
+ y
* this->s
.surface_desc
.lPitch
] = pal
[src
[x
+ y
* this->s
.surface_desc
.lPitch
]];
477 WARN(ddraw
, "No palette set...\n");
478 memset(dst
, 0, this->s
.surface_desc
.lPitch
* this->s
.surface_desc
.dwHeight
* 2);
481 ERR(ddraw
, "Unsupported pixel convertion...\n");
486 if (this->s
.ddraw
->e
.xlib
.xshm_active
)
487 TSXShmPutImage(display
,
488 this->s
.ddraw
->d
.drawable
,
489 DefaultGCOfScreen(X11DRV_GetXScreen()),
492 this->t
.xlib
.image
->width
,
493 this->t
.xlib
.image
->height
,
497 TSXPutImage( display
,
498 this->s
.ddraw
->d
.drawable
,
499 DefaultGCOfScreen(X11DRV_GetXScreen()),
502 this->t
.xlib
.image
->width
,
503 this->t
.xlib
.image
->height
);
506 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Unlock(
507 LPDIRECTDRAWSURFACE4
this,LPVOID surface
)
509 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
511 if (!this->s
.ddraw
->d
.paintable
)
514 /* Only redraw the screen when unlocking the buffer that is on screen */
515 if ((this->t
.xlib
.image
!= NULL
) &&
516 (this->s
.surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VISIBLE
)) {
517 Xlib_copy_surface_on_screen(this);
519 if (this->s
.palette
&& this->s
.palette
->cm
)
520 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
526 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Flip(
527 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
529 #ifdef HAVE_LIBXXF86DGA
530 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
532 if (this->s
.backbuffer
)
533 flipto
= this->s
.backbuffer
;
537 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,flipto
->t
.dga
.fb_height
);
539 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
540 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),flipto
->s
.palette
->cm
);
542 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
548 tmp
= this->t
.dga
.fb_height
;
549 this->t
.dga
.fb_height
= flipto
->t
.dga
.fb_height
;
550 flipto
->t
.dga
.fb_height
= tmp
;
552 ptmp
= this->s
.surface_desc
.y
.lpSurface
;
553 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
554 flipto
->s
.surface_desc
.y
.lpSurface
= ptmp
;
557 #else /* defined(HAVE_LIBXXF86DGA) */
559 #endif /* defined(HAVE_LIBXXF86DGA) */
562 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Flip(
563 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
565 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
566 if (!this->s
.ddraw
->d
.paintable
)
570 if (this->s
.backbuffer
)
571 flipto
= this->s
.backbuffer
;
576 Xlib_copy_surface_on_screen(this);
578 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
579 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,flipto
->s
.palette
->cm
);
584 tmp
= this->t
.xlib
.image
;
585 this->t
.xlib
.image
= flipto
->t
.xlib
.image
;
586 flipto
->t
.xlib
.image
= tmp
;
587 surf
= this->s
.surface_desc
.y
.lpSurface
;
588 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
589 flipto
->s
.surface_desc
.y
.lpSurface
= surf
;
595 /* The IDirectDrawSurface4::SetPalette method attaches the specified
596 * DirectDrawPalette object to a surface. The surface uses this palette for all
597 * subsequent operations. The palette change takes place immediately.
599 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_SetPalette(
600 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
603 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
606 if( this->s
.palette
!= NULL
)
607 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
608 this->s
.palette
= pal
;
613 if( !(pal
->cm
) && (this->s
.ddraw
->d
.screen_depth
<=8))
615 pal
->cm
= TSXCreateColormap(display
,this->s
.ddraw
->d
.drawable
,
616 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
618 if (!Options
.managed
)
619 TSXInstallColormap(display
,pal
->cm
);
621 for (i
=0;i
<256;i
++) {
624 xc
.red
= pal
->palents
[i
].peRed
<<8;
625 xc
.blue
= pal
->palents
[i
].peBlue
<<8;
626 xc
.green
= pal
->palents
[i
].peGreen
<<8;
627 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
629 TSXStoreColor(display
,pal
->cm
,&xc
);
631 TSXInstallColormap(display
,pal
->cm
);
634 /* According to spec, we are only supposed to
635 * AddRef if this is not the same palette.
637 if( this->s
.palette
!= pal
)
640 pal
->lpvtbl
->fnAddRef( pal
);
641 if( this->s
.palette
!= NULL
)
642 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
643 this->s
.palette
= pal
;
645 /* I think that we need to attach it to all backbuffers...*/
646 if( this->s
.backbuffer
) {
647 if( this->s
.backbuffer
->s
.palette
)
648 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(
649 this->s
.backbuffer
->s
.palette
);
650 this->s
.backbuffer
->s
.palette
= pal
;
652 pal
->lpvtbl
->fnAddRef( pal
);
654 /* Perform the refresh */
655 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
660 static HRESULT WINAPI
DGA_IDirectDrawSurface4_SetPalette(
661 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
663 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
664 #ifdef HAVE_LIBXXF86DGA
665 /* According to spec, we are only supposed to
666 * AddRef if this is not the same palette.
668 if( this->s
.palette
!= pal
)
671 pal
->lpvtbl
->fnAddRef( pal
);
672 if( this->s
.palette
!= NULL
)
673 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
674 this->s
.palette
= pal
;
676 /* I think that we need to attach it to all backbuffers...*/
677 if( this->s
.backbuffer
) {
678 if( this->s
.backbuffer
->s
.palette
)
679 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(this->s
.backbuffer
->s
.palette
);
680 this->s
.backbuffer
->s
.palette
= pal
;
681 if( pal
) pal
->lpvtbl
->fnAddRef( pal
);
683 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->s
.palette
->cm
);
686 #else /* defined(HAVE_LIBXXF86DGA) */
688 #endif /* defined(HAVE_LIBXXF86DGA) */
693 static HRESULT WINAPI
IDirectDrawSurface4_Blt(
694 LPDIRECTDRAWSURFACE4
this,LPRECT32 rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT32 rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
697 DDSURFACEDESC ddesc
,sdesc
;
700 TRACE(ddraw
,"(%p)->(%p,%p,%p,%08lx,%p)\n",
701 this,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
704 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,0,0);
705 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,0,0);
707 if (TRACE_ON(ddraw
)) {
708 if (rdst
) TRACE(ddraw
," destrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
709 if (rsrc
) TRACE(ddraw
," srcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
710 TRACE(ddraw
,"\tflags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
711 if (dwFlags
& DDBLT_DDFX
) {
712 TRACE(ddraw
," blitfx: \n");_dump_DDBLTFX(lpbltfx
->dwDDFX
);
717 memcpy(&xdst
,rdst
,sizeof(xdst
));
720 xdst
.bottom
= ddesc
.dwHeight
;
722 xdst
.right
= ddesc
.dwWidth
;
726 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
730 xsrc
.bottom
= sdesc
.dwHeight
;
732 xsrc
.right
= sdesc
.dwWidth
;
734 memset(&xsrc
,0,sizeof(xsrc
));
738 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
740 /* First, all the 'source-less' blits */
741 if (dwFlags
& DDBLT_COLORFILL
) {
742 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
745 xline
= (LPBYTE
) ddesc
.y
.lpSurface
+ xdst
.top
* ddesc
.lPitch
;
746 for (i
=xdst
.top
;i
<xdst
.bottom
;i
++) {
747 xpixel
= xline
+bpp
*xdst
.left
;
749 for (j
=xdst
.left
;j
<xdst
.right
;j
++) {
750 /* FIXME: this only works on little endian
751 * architectures, where DWORD starts with low
754 memcpy(xpixel
,&(lpbltfx
->b
.dwFillColor
),bpp
);
757 xline
+= ddesc
.lPitch
;
759 dwFlags
&= ~(DDBLT_COLORFILL
);
762 if (dwFlags
& DDBLT_DEPTHFILL
) {
766 /* Clears the screen */
767 TRACE(ddraw
, " Filling depth buffer with %ld\n", lpbltfx
->b
.dwFillDepth
);
768 glClearDepth(lpbltfx
->b
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
769 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
770 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
771 glClear(GL_DEPTH_BUFFER_BIT
);
774 dwFlags
&= ~(DDBLT_DEPTHFILL
);
780 TRACE(ddraw
,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
782 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
786 /* Now the 'with source' blits */
788 /* Standard 'full-surface' blit without special effects */
789 if ( (xsrc
.top
==0) && (xsrc
.bottom
==ddesc
.dwHeight
) &&
790 (xsrc
.left
==0) && (xsrc
.right
==ddesc
.dwWidth
) &&
791 (xdst
.top
==0) && (xdst
.bottom
==ddesc
.dwHeight
) &&
792 (xdst
.left
==0) && (xdst
.right
==ddesc
.dwWidth
) &&
795 memcpy(ddesc
.y
.lpSurface
,
797 ddesc
.dwHeight
* ddesc
.lPitch
);
799 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
800 int srcheight
= xsrc
.bottom
- xsrc
.top
;
801 int srcwidth
= xsrc
.right
- xsrc
.left
;
802 int dstheight
= xdst
.bottom
- xdst
.top
;
803 int dstwidth
= xdst
.right
- xdst
.left
;
804 int width
= (xsrc
.right
- xsrc
.left
) * bpp
;
807 /* Sanity check for rectangle sizes */
808 if ((srcheight
!= dstheight
) || (srcwidth
!= dstwidth
)) {
811 /* I think we should do a Blit with 'stretching' here....
812 Tomb Raider II uses this to display the background during the menu selection
813 when the screen resolution is != than 640x480 */
814 TRACE(ddraw
, "Blt with stretching\n");
816 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
818 /* In this case, we cannot do any anti-aliasing */
819 if(dwFlags
& DDBLT_KEYSRC
) {
820 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
821 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
824 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
825 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
827 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
828 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
830 tmp
= sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
832 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
833 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
834 dbuf
[(y
* ddesc
.lPitch
) + x
] = tmp
;
838 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
839 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
841 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
842 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
844 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
845 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
847 dbuf
[(y
* ddesc
.lPitch
) + x
] = sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
852 FIXME(ddraw
, "Not done yet for depth != 8\n");
855 /* Same size => fast blit */
856 if (dwFlags
& DDBLT_KEYSRC
) {
859 unsigned char tmp
,*psrc
,*pdst
;
862 for (h
= 0; h
< srcheight
; h
++) {
863 psrc
=sdesc
.y
.lpSurface
+
864 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
865 pdst
=ddesc
.y
.lpSurface
+
866 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
867 for(i
=0;i
<srcwidth
;i
++) {
869 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
870 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
874 dwFlags
&=~(DDBLT_KEYSRC
);
878 unsigned short tmp
,*psrc
,*pdst
;
881 for (h
= 0; h
< srcheight
; h
++) {
882 psrc
=sdesc
.y
.lpSurface
+
883 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
884 pdst
=ddesc
.y
.lpSurface
+
885 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
886 for(i
=0;i
<srcwidth
;i
++) {
888 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
889 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
893 dwFlags
&=~(DDBLT_KEYSRC
);
897 FIXME(ddraw
, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
900 /* Non-stretching Blt without color keying */
901 for (h
= 0; h
< srcheight
; h
++) {
902 memcpy(ddesc
.y
.lpSurface
+ ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
* bpp
,
903 sdesc
.y
.lpSurface
+ ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
* bpp
,
910 if (dwFlags
&& FIXME_ON(ddraw
)) {
911 FIXME(ddraw
,"\tUnsupported flags: ");_dump_DDBLT(dwFlags
);
914 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
915 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
920 static HRESULT WINAPI
IDirectDrawSurface4_BltFast(
921 LPDIRECTDRAWSURFACE4
this,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT32 rsrc
,DWORD trans
924 DDSURFACEDESC ddesc
,sdesc
;
926 if (1 || TRACE_ON(ddraw
)) {
927 FIXME(ddraw
,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
928 this,dstx
,dsty
,src
,rsrc
,trans
930 FIXME(ddraw
," trans:");
932 _dump_DDBLTFAST(trans
);
933 FIXME(ddraw
," srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
935 /* We need to lock the surfaces, or we won't get refreshes when done. */
936 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
937 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
938 bpp
= this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
939 h
=rsrc
->bottom
-rsrc
->top
;
940 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
941 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
943 w
=rsrc
->right
-rsrc
->left
;
944 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
945 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
949 memcpy( ddesc
.y
.lpSurface
+(dsty
+i
)*ddesc
.lPitch
+dstx
*bpp
,
950 sdesc
.y
.lpSurface
+(rsrc
->top
+i
)*sdesc
.lPitch
+rsrc
->left
*bpp
,
954 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
955 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
959 static HRESULT WINAPI
IDirectDrawSurface4_BltBatch(
960 LPDIRECTDRAWSURFACE4
this,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
962 FIXME(ddraw
,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
968 static HRESULT WINAPI
IDirectDrawSurface4_GetCaps(
969 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS caps
971 TRACE(ddraw
,"(%p)->GetCaps(%p)\n",this,caps
);
972 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
976 static HRESULT WINAPI
IDirectDrawSurface4_GetSurfaceDesc(
977 LPDIRECTDRAWSURFACE4
this,LPDDSURFACEDESC ddsd
979 TRACE(ddraw
, "(%p)->GetSurfaceDesc(%p)\n",
982 /* Simply copy the surface description stored in the object */
983 *ddsd
= this->s
.surface_desc
;
985 if (TRACE_ON(ddraw
)) {
986 fprintf(stderr
," flags: ");
987 _dump_DDSD(ddsd
->dwFlags
);
988 if (ddsd
->dwFlags
& DDSD_CAPS
) {
989 fprintf(stderr
, " caps: ");
990 _dump_DDSCAPS(ddsd
->ddsCaps
.dwCaps
);
992 fprintf(stderr
,"\n");
998 static ULONG WINAPI
IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4
this) {
999 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1001 return ++(this->ref
);
1004 static ULONG WINAPI
DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
1005 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1007 #ifdef HAVE_LIBXXF86DGA
1008 if (!--(this->ref
)) {
1009 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
1010 /* clear out of surface list */
1011 if (this->t
.dga
.fb_height
== -1) {
1012 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1014 this->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(this->t
.dga
.fb_height
/this->s
.ddraw
->e
.dga
.fb_height
));
1017 /* Free the backbuffer */
1018 if (this->s
.backbuffer
)
1019 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1021 HeapFree(GetProcessHeap(),0,this);
1024 #endif /* defined(HAVE_LIBXXF86DGA) */
1028 static ULONG WINAPI
Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
1029 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1031 if (!--(this->ref
)) {
1032 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
1034 if( this->s
.backbuffer
)
1035 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1037 if (this->t
.xlib
.image
!= NULL
) {
1038 if (this->s
.ddraw
->d
.depth
!= this->s
.ddraw
->d
.screen_depth
) {
1039 /* In pixel conversion mode, there are two buffers to release... */
1040 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1042 #ifdef HAVE_LIBXXSHM
1043 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1044 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1045 TSXDestroyImage(this->t
.xlib
.image
);
1046 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1049 HeapFree(GetProcessHeap(),0,this->t
.xlib
.image
->data
);
1050 this->t
.xlib
.image
->data
= NULL
;
1051 TSXDestroyImage(this->t
.xlib
.image
);
1052 #ifdef HAVE_LIBXXSHM
1057 this->t
.xlib
.image
->data
= NULL
;
1059 #ifdef HAVE_LIBXXSHM
1060 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1061 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1062 TSXDestroyImage(this->t
.xlib
.image
);
1063 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1066 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1067 TSXDestroyImage(this->t
.xlib
.image
);
1068 #ifdef HAVE_LIBXXSHM
1073 this->t
.xlib
.image
= 0;
1075 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1078 if (this->s
.palette
)
1079 this->s
.palette
->lpvtbl
->fnRelease(this->s
.palette
);
1081 HeapFree(GetProcessHeap(),0,this);
1088 static HRESULT WINAPI
IDirectDrawSurface4_GetAttachedSurface(
1089 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1091 TRACE(ddraw
, "(%p)->GetAttachedSurface(%p,%p)\n",
1092 this, lpddsd
, lpdsf
);
1094 if (TRACE_ON(ddraw
)) {
1095 TRACE(ddraw
," caps ");
1096 _dump_DDSCAPS(lpddsd
->dwCaps
);
1099 if (!(lpddsd
->dwCaps
& DDSCAPS_BACKBUFFER
)) {
1100 FIXME(ddraw
,"whoops, can only handle backbuffers for now\n");
1104 /* FIXME: should handle more than one backbuffer */
1105 *lpdsf
= this->s
.backbuffer
;
1107 if( this->s
.backbuffer
)
1108 this->s
.backbuffer
->lpvtbl
->fnAddRef( this->s
.backbuffer
);
1113 static HRESULT WINAPI
IDirectDrawSurface4_Initialize(
1114 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1116 TRACE(ddraw
,"(%p)->(%p, %p)\n",this,ddraw
,lpdsfd
);
1118 return DDERR_ALREADYINITIALIZED
;
1121 static HRESULT WINAPI
IDirectDrawSurface4_GetPixelFormat(
1122 LPDIRECTDRAWSURFACE4
this,LPDDPIXELFORMAT pf
1124 TRACE(ddraw
,"(%p)->(%p)\n",this,pf
);
1126 *pf
= this->s
.surface_desc
.ddpfPixelFormat
;
1131 static HRESULT WINAPI
IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4
this,DWORD dwFlags
) {
1132 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,dwFlags
);
1136 static HRESULT WINAPI
IDirectDrawSurface4_GetOverlayPosition(
1137 LPDIRECTDRAWSURFACE4
this,LPLONG x1
,LPLONG x2
1139 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,x1
,x2
);
1143 static HRESULT WINAPI
IDirectDrawSurface4_SetClipper(
1144 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWCLIPPER clipper
1146 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,clipper
);
1150 static HRESULT WINAPI
IDirectDrawSurface4_AddAttachedSurface(
1151 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 surf
1153 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,surf
);
1155 this->lpvtbl
->fnAddRef(this);
1157 /* This hack will be enough for the moment */
1158 if (this->s
.backbuffer
== NULL
)
1159 this->s
.backbuffer
= surf
;
1163 static HRESULT WINAPI
IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4
this,HDC32
* lphdc
) {
1164 FIXME(ddraw
,"(%p)->GetDC(%p)\n",this,lphdc
);
1165 *lphdc
= BeginPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1169 static HRESULT WINAPI
IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4
this,HDC32 hdc
) {
1173 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,(long)hdc
);
1174 EndPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1176 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1177 I fill it with 'dummy' values to have something on the screen */
1178 this->lpvtbl
->fnLock(this,NULL
,&desc
,0,0);
1179 for (y
= 0; y
< desc
.dwHeight
; y
++) {
1180 for (x
= 0; x
< desc
.dwWidth
; x
++) {
1181 ((unsigned char *) desc
.y
.lpSurface
)[x
+ y
* desc
.dwWidth
] = (unsigned int) this + x
+ y
;
1184 this->lpvtbl
->fnUnlock(this,NULL
);
1190 static HRESULT WINAPI
IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4
this,REFIID refiid
,LPVOID
*obj
) {
1193 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1194 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1196 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1197 * the same interface. And IUnknown does that too of course.
1199 if ( !memcmp(&IID_IDirectDrawSurface4
,refiid
,sizeof(IID
)) ||
1200 !memcmp(&IID_IDirectDrawSurface3
,refiid
,sizeof(IID
)) ||
1201 !memcmp(&IID_IDirectDrawSurface2
,refiid
,sizeof(IID
)) ||
1202 !memcmp(&IID_IDirectDrawSurface
,refiid
,sizeof(IID
)) ||
1203 !memcmp(&IID_IUnknown
,refiid
,sizeof(IID
))
1206 this->lpvtbl
->fnAddRef(this);
1208 TRACE(ddraw
, " Creating IDirectDrawSurface interface (%p)\n", *obj
);
1212 else if (!memcmp(&IID_IDirect3DTexture2
,refiid
,sizeof(IID
)))
1214 /* Texture interface */
1215 *obj
= d3dtexture2_create(this);
1216 this->lpvtbl
->fnAddRef(this);
1218 TRACE(ddraw
, " Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1222 else if (!memcmp(&IID_IDirect3DTexture
,refiid
,sizeof(IID
)))
1224 /* Texture interface */
1225 *obj
= d3dtexture_create(this);
1226 this->lpvtbl
->fnAddRef(this);
1228 TRACE(ddraw
, " Creating IDirect3DTexture interface (%p)\n", *obj
);
1232 else if (is_OpenGL_dx3(refiid
, (LPDIRECTDRAWSURFACE
) this, (LPDIRECT3DDEVICE
*) obj
))
1234 /* It is the OpenGL Direct3D Device */
1235 this->lpvtbl
->fnAddRef(this);
1237 TRACE(ddraw
, " Creating IDirect3DDevice interface (%p)\n", *obj
);
1242 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1243 return OLE_E_ENUM_NOMORE
;
1246 static HRESULT WINAPI
IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4
this) {
1247 TRACE(ddraw
,"(%p)->(), stub!\n",this);
1248 return DD_OK
; /* hmm */
1251 static HRESULT WINAPI
IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4
this,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1252 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,context
,esfcb
);
1256 static HRESULT WINAPI
IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4
this) {
1257 FIXME(ddraw
,"(%p)->(),stub!\n",this);
1261 static HRESULT WINAPI
IDirectDrawSurface4_SetColorKey(
1262 LPDIRECTDRAWSURFACE4
this, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1264 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n",this,dwFlags
,ckey
);
1266 if( dwFlags
& DDCKEY_SRCBLT
)
1268 dwFlags
&= ~DDCKEY_SRCBLT
;
1269 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1270 memcpy( &(this->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1273 if( dwFlags
& DDCKEY_DESTBLT
)
1275 dwFlags
&= ~DDCKEY_DESTBLT
;
1276 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1277 memcpy( &(this->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1280 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1282 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1283 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1284 memcpy( &(this->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1287 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1289 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1290 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1291 memcpy( &(this->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1296 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1303 static HRESULT WINAPI
IDirectDrawSurface4_AddOverlayDirtyRect(
1304 LPDIRECTDRAWSURFACE4
this,
1307 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpRect
);
1312 static HRESULT WINAPI
IDirectDrawSurface4_DeleteAttachedSurface(
1313 LPDIRECTDRAWSURFACE4
this,
1315 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
1317 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags
,lpDDSAttachedSurface
);
1322 static HRESULT WINAPI
IDirectDrawSurface4_EnumOverlayZOrders(
1323 LPDIRECTDRAWSURFACE4
this,
1326 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1328 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags
,
1329 lpContext
, lpfnCallback
);
1334 static HRESULT WINAPI
IDirectDrawSurface4_GetClipper(
1335 LPDIRECTDRAWSURFACE4
this,
1336 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1338 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDClipper
);
1343 static HRESULT WINAPI
IDirectDrawSurface4_GetColorKey(
1344 LPDIRECTDRAWSURFACE4
this,
1346 LPDDCOLORKEY lpDDColorKey
)
1348 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n", this, dwFlags
, lpDDColorKey
);
1350 if( dwFlags
& DDCKEY_SRCBLT
) {
1351 dwFlags
&= ~DDCKEY_SRCBLT
;
1352 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
1355 if( dwFlags
& DDCKEY_DESTBLT
)
1357 dwFlags
&= ~DDCKEY_DESTBLT
;
1358 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
1361 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1363 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1364 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
1367 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1369 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1370 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
1375 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1381 static HRESULT WINAPI
IDirectDrawSurface4_GetFlipStatus(
1382 LPDIRECTDRAWSURFACE4
this,
1385 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1390 static HRESULT WINAPI
IDirectDrawSurface4_GetPalette(
1391 LPDIRECTDRAWSURFACE4
this,
1392 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1394 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDPalette
);
1399 static HRESULT WINAPI
IDirectDrawSurface4_SetOverlayPosition(
1400 LPDIRECTDRAWSURFACE4
this,
1404 FIXME(ddraw
,"(%p)->(%ld,%ld),stub!\n", this, lX
, lY
);
1409 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlay(
1410 LPDIRECTDRAWSURFACE4
this,
1412 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
1413 LPRECT32 lpDestRect
,
1415 LPDDOVERLAYFX lpDDOverlayFx
)
1417 FIXME(ddraw
,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1418 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1423 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayDisplay(
1424 LPDIRECTDRAWSURFACE4
this,
1427 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1432 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayZOrder(
1433 LPDIRECTDRAWSURFACE4
this,
1435 LPDIRECTDRAWSURFACE4 lpDDSReference
)
1437 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags
, lpDDSReference
);
1442 static HRESULT WINAPI
IDirectDrawSurface4_GetDDInterface(
1443 LPDIRECTDRAWSURFACE4
this,
1446 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDD
);
1448 /* Not sure about that... */
1449 *lplpDD
= (void *) this->s
.ddraw
;
1454 static HRESULT WINAPI
IDirectDrawSurface4_PageLock(
1455 LPDIRECTDRAWSURFACE4
this,
1458 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1463 static HRESULT WINAPI
IDirectDrawSurface4_PageUnlock(
1464 LPDIRECTDRAWSURFACE4
this,
1467 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1472 static HRESULT WINAPI
IDirectDrawSurface4_SetSurfaceDesc(
1473 LPDIRECTDRAWSURFACE4
this,
1474 LPDDSURFACEDESC lpDDSD
,
1477 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD
, dwFlags
);
1482 static HRESULT WINAPI
IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4
this,
1487 FIXME(ddraw
, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag
, lpData
, cbSize
, dwFlags
);
1492 static HRESULT WINAPI
IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4
this,
1495 LPDWORD lpcbBufferSize
) {
1496 FIXME(ddraw
, "(%p)->(%p,%p,%p)\n", this, guidTag
, lpBuffer
, lpcbBufferSize
);
1501 static HRESULT WINAPI
IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4
this,
1503 FIXME(ddraw
, "(%p)->(%p)\n", this, guidTag
);
1508 static HRESULT WINAPI
IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4
this,
1510 FIXME(ddraw
, "(%p)->(%p)\n", this, lpValue
);
1515 static HRESULT WINAPI
IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4
this) {
1516 FIXME(ddraw
, "(%p)\n", this);
1521 static struct IDirectDrawSurface4_VTable dga_dds4vt
= {
1522 IDirectDrawSurface4_QueryInterface
,
1523 IDirectDrawSurface4_AddRef
,
1524 DGA_IDirectDrawSurface4_Release
,
1525 IDirectDrawSurface4_AddAttachedSurface
,
1526 IDirectDrawSurface4_AddOverlayDirtyRect
,
1527 IDirectDrawSurface4_Blt
,
1528 IDirectDrawSurface4_BltBatch
,
1529 IDirectDrawSurface4_BltFast
,
1530 IDirectDrawSurface4_DeleteAttachedSurface
,
1531 IDirectDrawSurface4_EnumAttachedSurfaces
,
1532 IDirectDrawSurface4_EnumOverlayZOrders
,
1533 DGA_IDirectDrawSurface4_Flip
,
1534 IDirectDrawSurface4_GetAttachedSurface
,
1535 IDirectDrawSurface4_GetBltStatus
,
1536 IDirectDrawSurface4_GetCaps
,
1537 IDirectDrawSurface4_GetClipper
,
1538 IDirectDrawSurface4_GetColorKey
,
1539 IDirectDrawSurface4_GetDC
,
1540 IDirectDrawSurface4_GetFlipStatus
,
1541 IDirectDrawSurface4_GetOverlayPosition
,
1542 IDirectDrawSurface4_GetPalette
,
1543 IDirectDrawSurface4_GetPixelFormat
,
1544 IDirectDrawSurface4_GetSurfaceDesc
,
1545 IDirectDrawSurface4_Initialize
,
1546 IDirectDrawSurface4_IsLost
,
1547 IDirectDrawSurface4_Lock
,
1548 IDirectDrawSurface4_ReleaseDC
,
1549 IDirectDrawSurface4_Restore
,
1550 IDirectDrawSurface4_SetClipper
,
1551 IDirectDrawSurface4_SetColorKey
,
1552 IDirectDrawSurface4_SetOverlayPosition
,
1553 DGA_IDirectDrawSurface4_SetPalette
,
1554 DGA_IDirectDrawSurface4_Unlock
,
1555 IDirectDrawSurface4_UpdateOverlay
,
1556 IDirectDrawSurface4_UpdateOverlayDisplay
,
1557 IDirectDrawSurface4_UpdateOverlayZOrder
,
1558 IDirectDrawSurface4_GetDDInterface
,
1559 IDirectDrawSurface4_PageLock
,
1560 IDirectDrawSurface4_PageUnlock
,
1561 IDirectDrawSurface4_SetSurfaceDesc
,
1562 IDirectDrawSurface4_SetPrivateData
,
1563 IDirectDrawSurface4_GetPrivateData
,
1564 IDirectDrawSurface4_FreePrivateData
,
1565 IDirectDrawSurface4_GetUniquenessValue
,
1566 IDirectDrawSurface4_ChangeUniquenessValue
1569 static struct IDirectDrawSurface4_VTable xlib_dds4vt
= {
1570 IDirectDrawSurface4_QueryInterface
,
1571 IDirectDrawSurface4_AddRef
,
1572 Xlib_IDirectDrawSurface4_Release
,
1573 IDirectDrawSurface4_AddAttachedSurface
,
1574 IDirectDrawSurface4_AddOverlayDirtyRect
,
1575 IDirectDrawSurface4_Blt
,
1576 IDirectDrawSurface4_BltBatch
,
1577 IDirectDrawSurface4_BltFast
,
1578 IDirectDrawSurface4_DeleteAttachedSurface
,
1579 IDirectDrawSurface4_EnumAttachedSurfaces
,
1580 IDirectDrawSurface4_EnumOverlayZOrders
,
1581 Xlib_IDirectDrawSurface4_Flip
,
1582 IDirectDrawSurface4_GetAttachedSurface
,
1583 IDirectDrawSurface4_GetBltStatus
,
1584 IDirectDrawSurface4_GetCaps
,
1585 IDirectDrawSurface4_GetClipper
,
1586 IDirectDrawSurface4_GetColorKey
,
1587 IDirectDrawSurface4_GetDC
,
1588 IDirectDrawSurface4_GetFlipStatus
,
1589 IDirectDrawSurface4_GetOverlayPosition
,
1590 IDirectDrawSurface4_GetPalette
,
1591 IDirectDrawSurface4_GetPixelFormat
,
1592 IDirectDrawSurface4_GetSurfaceDesc
,
1593 IDirectDrawSurface4_Initialize
,
1594 IDirectDrawSurface4_IsLost
,
1595 IDirectDrawSurface4_Lock
,
1596 IDirectDrawSurface4_ReleaseDC
,
1597 IDirectDrawSurface4_Restore
,
1598 IDirectDrawSurface4_SetClipper
,
1599 IDirectDrawSurface4_SetColorKey
,
1600 IDirectDrawSurface4_SetOverlayPosition
,
1601 Xlib_IDirectDrawSurface4_SetPalette
,
1602 Xlib_IDirectDrawSurface4_Unlock
,
1603 IDirectDrawSurface4_UpdateOverlay
,
1604 IDirectDrawSurface4_UpdateOverlayDisplay
,
1605 IDirectDrawSurface4_UpdateOverlayZOrder
,
1606 IDirectDrawSurface4_GetDDInterface
,
1607 IDirectDrawSurface4_PageLock
,
1608 IDirectDrawSurface4_PageUnlock
,
1609 IDirectDrawSurface4_SetSurfaceDesc
,
1610 IDirectDrawSurface4_SetPrivateData
,
1611 IDirectDrawSurface4_GetPrivateData
,
1612 IDirectDrawSurface4_FreePrivateData
,
1613 IDirectDrawSurface4_GetUniquenessValue
,
1614 IDirectDrawSurface4_ChangeUniquenessValue
1617 /******************************************************************************
1618 * DirectDrawCreateClipper (DDRAW.7)
1620 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
1621 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
1622 LPUNKNOWN pUnkOuter
)
1624 TRACE(ddraw
, "(%08lx,%p,%p)\n", dwFlags
, lplpDDClipper
, pUnkOuter
);
1626 *lplpDDClipper
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
1627 (*lplpDDClipper
)->lpvtbl
= &ddclipvt
;
1628 (*lplpDDClipper
)->ref
= 1;
1633 /******************************************************************************
1634 * IDirectDrawClipper
1636 static HRESULT WINAPI
IDirectDrawClipper_SetHwnd(
1637 LPDIRECTDRAWCLIPPER
this,DWORD x
,HWND32 hwnd
1639 FIXME(ddraw
,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x
,(DWORD
)hwnd
);
1643 static ULONG WINAPI
IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER
this) {
1644 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1649 HeapFree(GetProcessHeap(),0,this);
1653 static HRESULT WINAPI
IDirectDrawClipper_GetClipList(
1654 LPDIRECTDRAWCLIPPER
this,LPRECT32 rects
,LPRGNDATA lprgn
,LPDWORD hmm
1656 FIXME(ddraw
,"(%p,%p,%p,%p),stub!\n",this,rects
,lprgn
,hmm
);
1661 static HRESULT WINAPI
IDirectDrawClipper_SetClipList(
1662 LPDIRECTDRAWCLIPPER
this,LPRGNDATA lprgn
,DWORD hmm
1664 FIXME(ddraw
,"(%p,%p,%ld),stub!\n",this,lprgn
,hmm
);
1668 static HRESULT WINAPI
IDirectDrawClipper_QueryInterface(
1669 LPDIRECTDRAWCLIPPER
this,
1673 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,riid
,ppvObj
);
1674 return OLE_E_ENUM_NOMORE
;
1677 static ULONG WINAPI
IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER
this )
1679 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1680 return ++(this->ref
);
1683 static HRESULT WINAPI
IDirectDrawClipper_GetHWnd(
1684 LPDIRECTDRAWCLIPPER
this,
1687 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,HWndPtr
);
1691 static HRESULT WINAPI
IDirectDrawClipper_Initialize(
1692 LPDIRECTDRAWCLIPPER
this,
1696 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD
,dwFlags
);
1700 static HRESULT WINAPI
IDirectDrawClipper_IsClipListChanged(
1701 LPDIRECTDRAWCLIPPER
this,
1702 BOOL32
* lpbChanged
)
1704 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpbChanged
);
1708 static struct IDirectDrawClipper_VTable ddclipvt
= {
1709 IDirectDrawClipper_QueryInterface
,
1710 IDirectDrawClipper_AddRef
,
1711 IDirectDrawClipper_Release
,
1712 IDirectDrawClipper_GetClipList
,
1713 IDirectDrawClipper_GetHWnd
,
1714 IDirectDrawClipper_Initialize
,
1715 IDirectDrawClipper_IsClipListChanged
,
1716 IDirectDrawClipper_SetClipList
,
1717 IDirectDrawClipper_SetHwnd
1721 /******************************************************************************
1722 * IDirectDrawPalette
1724 static HRESULT WINAPI
IDirectDrawPalette_GetEntries(
1725 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1729 TRACE(ddraw
,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1730 this,x
,start
,count
,palent
);
1732 if (!this->cm
) /* should not happen */ {
1733 FIXME(ddraw
,"app tried to read colormap for non-palettized mode\n");
1734 return DDERR_GENERIC
;
1736 for (i
=0;i
<count
;i
++) {
1737 palent
[i
].peRed
= this->palents
[start
+i
].peRed
;
1738 palent
[i
].peBlue
= this->palents
[start
+i
].peBlue
;
1739 palent
[i
].peGreen
= this->palents
[start
+i
].peGreen
;
1740 palent
[i
].peFlags
= this->palents
[start
+i
].peFlags
;
1746 static HRESULT WINAPI
Xlib_IDirectDrawPalette_SetEntries(
1747 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1752 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1753 this,x
,start
,count
,palent
1755 for (i
=0;i
<count
;i
++) {
1756 xc
.red
= palent
[i
].peRed
<<8;
1757 xc
.blue
= palent
[i
].peBlue
<<8;
1758 xc
.green
= palent
[i
].peGreen
<<8;
1759 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1763 TSXStoreColor(display
,this->cm
,&xc
);
1765 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1766 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1767 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1768 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1771 /* Now, if we are in 'depth conversion mode', update the screen palette */
1772 if (this->ddraw
->d
.depth
!= this->ddraw
->d
.screen_depth
) {
1775 switch (this->ddraw
->d
.screen_depth
) {
1777 unsigned short *screen_palette
= (unsigned short *) this->screen_palents
;
1779 for (i
= 0; i
< count
; i
++) {
1780 screen_palette
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
1781 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
1782 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
1787 ERR(ddraw
, "Memory corruption !\n");
1792 if (!this->cm
) /* should not happen */ {
1797 static HRESULT WINAPI
DGA_IDirectDrawPalette_SetEntries(
1798 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1800 #ifdef HAVE_LIBXXF86DGA
1805 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1806 this,x
,start
,count
,palent
1808 if (!this->cm
) /* should not happen */ {
1809 FIXME(ddraw
,"app tried to set colormap in non-palettized mode\n");
1810 return DDERR_GENERIC
;
1812 /* FIXME: free colorcells instead of freeing whole map */
1814 this->cm
= TSXCopyColormapAndFree(display
,this->cm
);
1815 TSXFreeColormap(display
,cm
);
1817 for (i
=0;i
<count
;i
++) {
1818 xc
.red
= palent
[i
].peRed
<<8;
1819 xc
.blue
= palent
[i
].peBlue
<<8;
1820 xc
.green
= palent
[i
].peGreen
<<8;
1821 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1824 TSXStoreColor(display
,this->cm
,&xc
);
1826 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1827 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1828 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1829 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1831 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->cm
);
1833 #else /* defined(HAVE_LIBXXF86DGA) */
1834 return E_UNEXPECTED
;
1835 #endif /* defined(HAVE_LIBXXF86DGA) */
1838 static ULONG WINAPI
IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE
this) {
1839 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1840 if (!--(this->ref
)) {
1842 TSXFreeColormap(display
,this->cm
);
1845 HeapFree(GetProcessHeap(),0,this);
1851 static ULONG WINAPI
IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE
this) {
1853 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1854 return ++(this->ref
);
1857 static HRESULT WINAPI
IDirectDrawPalette_Initialize(
1858 LPDIRECTDRAWPALETTE
this,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
1860 TRACE(ddraw
,"(%p)->(%p,%ld,%p)\n", this, ddraw
, x
, palent
);
1862 return DDERR_ALREADYINITIALIZED
;
1865 static HRESULT WINAPI
IDirectDrawPalette_GetCaps(
1866 LPDIRECTDRAWPALETTE
this, LPDWORD lpdwCaps
)
1868 FIXME( ddraw
, "(%p)->(%p) stub.\n", this, lpdwCaps
);
1872 static HRESULT WINAPI
IDirectDrawPalette_QueryInterface(
1873 LPDIRECTDRAWPALETTE
this,REFIID refiid
,LPVOID
*obj
)
1877 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1878 FIXME(ddraw
,"(%p)->(%s,%p) stub.\n",this,xrefiid
,obj
);
1883 static struct IDirectDrawPalette_VTable dga_ddpalvt
= {
1884 IDirectDrawPalette_QueryInterface
,
1885 IDirectDrawPalette_AddRef
,
1886 IDirectDrawPalette_Release
,
1887 IDirectDrawPalette_GetCaps
,
1888 IDirectDrawPalette_GetEntries
,
1889 IDirectDrawPalette_Initialize
,
1890 DGA_IDirectDrawPalette_SetEntries
1893 static struct IDirectDrawPalette_VTable xlib_ddpalvt
= {
1894 IDirectDrawPalette_QueryInterface
,
1895 IDirectDrawPalette_AddRef
,
1896 IDirectDrawPalette_Release
,
1897 IDirectDrawPalette_GetCaps
,
1898 IDirectDrawPalette_GetEntries
,
1899 IDirectDrawPalette_Initialize
,
1900 Xlib_IDirectDrawPalette_SetEntries
1903 /*******************************************************************************
1906 static HRESULT WINAPI
IDirect3D_QueryInterface(
1907 LPDIRECT3D
this,REFIID refiid
,LPVOID
*obj
1909 /* FIXME: Not sure if this is correct */
1912 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1913 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1914 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
1916 this->lpvtbl
->fnAddRef(this);
1918 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
1922 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
1925 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1927 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1928 this->lpvtbl
->fnAddRef(this);
1929 d3d
->lpvtbl
= &d3dvt
;
1932 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
1936 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
1939 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1941 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1942 this->lpvtbl
->fnAddRef(this);
1943 d3d
->lpvtbl
= &d3d2vt
;
1946 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
1950 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1951 return OLE_E_ENUM_NOMORE
;
1954 static ULONG WINAPI
IDirect3D_AddRef(LPDIRECT3D
this) {
1955 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1957 return ++(this->ref
);
1960 static ULONG WINAPI
IDirect3D_Release(LPDIRECT3D
this)
1962 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1964 if (!--(this->ref
)) {
1965 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
1966 HeapFree(GetProcessHeap(),0,this);
1972 static HRESULT WINAPI
IDirect3D_Initialize(
1973 LPDIRECT3D
this, REFIID refiid
)
1975 /* FIXME: Not sure if this is correct */
1978 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1979 FIXME(ddraw
,"(%p)->(%s):stub.\n",this,xrefiid
);
1981 return DDERR_ALREADYINITIALIZED
;
1984 static HRESULT WINAPI
IDirect3D_EnumDevices(LPDIRECT3D
this,
1985 LPD3DENUMDEVICESCALLBACK cb
,
1987 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
1989 /* Call functions defined in d3ddevices.c */
1990 if (d3d_OpenGL_dx3(cb
, context
))
1996 static HRESULT WINAPI
IDirect3D_CreateLight(LPDIRECT3D
this,
1997 LPDIRECT3DLIGHT
*lplight
,
2000 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
2002 /* Call the creation function that is located in d3dlight.c */
2003 *lplight
= d3dlight_create_dx3(this);
2008 static HRESULT WINAPI
IDirect3D_CreateMaterial(LPDIRECT3D
this,
2009 LPDIRECT3DMATERIAL
*lpmaterial
,
2012 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
2014 /* Call the creation function that is located in d3dviewport.c */
2015 *lpmaterial
= d3dmaterial_create(this);
2020 static HRESULT WINAPI
IDirect3D_CreateViewport(LPDIRECT3D
this,
2021 LPDIRECT3DVIEWPORT
*lpviewport
,
2024 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
2026 /* Call the creation function that is located in d3dviewport.c */
2027 *lpviewport
= d3dviewport_create(this);
2032 static HRESULT WINAPI
IDirect3D_FindDevice(LPDIRECT3D
this,
2033 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2034 LPD3DFINDDEVICERESULT lpfinddevrst
)
2036 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2041 static struct IDirect3D_VTable d3dvt
= {
2042 IDirect3D_QueryInterface
,
2045 IDirect3D_Initialize
,
2046 IDirect3D_EnumDevices
,
2047 IDirect3D_CreateLight
,
2048 IDirect3D_CreateMaterial
,
2049 IDirect3D_CreateViewport
,
2050 IDirect3D_FindDevice
2053 /*******************************************************************************
2056 static HRESULT WINAPI
IDirect3D2_QueryInterface(
2057 LPDIRECT3D2
this,REFIID refiid
,LPVOID
*obj
) {
2058 /* For the moment, we use the same function as in IDirect3D */
2059 TRACE(ddraw
, "Calling IDirect3D enumerating function.\n");
2061 return IDirect3D_QueryInterface((LPDIRECT3D
) this, refiid
, obj
);
2064 static ULONG WINAPI
IDirect3D2_AddRef(LPDIRECT3D2
this) {
2065 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
2067 return ++(this->ref
);
2070 static ULONG WINAPI
IDirect3D2_Release(LPDIRECT3D2
this) {
2071 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
2073 if (!--(this->ref
)) {
2074 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
2075 HeapFree(GetProcessHeap(),0,this);
2081 static HRESULT WINAPI
IDirect3D2_EnumDevices(
2082 LPDIRECT3D2
this,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2084 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
2086 /* Call functions defined in d3ddevices.c */
2087 if (d3d_OpenGL(cb
, context
))
2093 static HRESULT WINAPI
IDirect3D2_CreateLight(LPDIRECT3D2
this,
2094 LPDIRECT3DLIGHT
*lplight
,
2097 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
2099 /* Call the creation function that is located in d3dlight.c */
2100 *lplight
= d3dlight_create(this);
2105 static HRESULT WINAPI
IDirect3D2_CreateMaterial(LPDIRECT3D2
this,
2106 LPDIRECT3DMATERIAL2
*lpmaterial
,
2109 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
2111 /* Call the creation function that is located in d3dviewport.c */
2112 *lpmaterial
= d3dmaterial2_create(this);
2117 static HRESULT WINAPI
IDirect3D2_CreateViewport(LPDIRECT3D2
this,
2118 LPDIRECT3DVIEWPORT2
*lpviewport
,
2121 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
2123 /* Call the creation function that is located in d3dviewport.c */
2124 *lpviewport
= d3dviewport2_create(this);
2129 static HRESULT WINAPI
IDirect3D2_FindDevice(LPDIRECT3D2
this,
2130 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2131 LPD3DFINDDEVICERESULT lpfinddevrst
)
2133 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2138 static HRESULT WINAPI
IDirect3D2_CreateDevice(LPDIRECT3D2
this,
2140 LPDIRECTDRAWSURFACE surface
,
2141 LPDIRECT3DDEVICE2
*device
)
2145 WINE_StringFromCLSID(rguid
,xbuf
);
2146 FIXME(ddraw
,"(%p)->(%s,%p,%p): stub\n",this,xbuf
,surface
,device
);
2148 if (is_OpenGL(rguid
, surface
, device
, this)) {
2149 this->lpvtbl
->fnAddRef(this);
2153 return DDERR_INVALIDPARAMS
;
2156 static struct IDirect3D2_VTable d3d2vt
= {
2157 IDirect3D2_QueryInterface
,
2160 IDirect3D2_EnumDevices
,
2161 IDirect3D2_CreateLight
,
2162 IDirect3D2_CreateMaterial
,
2163 IDirect3D2_CreateViewport
,
2164 IDirect3D2_FindDevice
,
2165 IDirect3D2_CreateDevice
2168 /*******************************************************************************
2172 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2173 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2175 static INT32 ddrawXlibThisOffset
= 0;
2177 static HRESULT
common_off_screen_CreateSurface(LPDIRECTDRAW2
this,
2178 LPDDSURFACEDESC lpddsd
,
2179 LPDIRECTDRAWSURFACE lpdsf
)
2183 /* The surface was already allocated when entering in this function */
2184 TRACE(ddraw
,"using system memory for a surface (%p)\n", lpdsf
);
2186 if (lpddsd
->dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
2187 /* This is a Z Buffer */
2188 TRACE(ddraw
, "Creating Z-Buffer of %ld bit depth\n", lpddsd
->x
.dwZBufferBitDepth
);
2189 bpp
= lpddsd
->x
.dwZBufferBitDepth
/ 8;
2191 /* This is a standard image */
2192 if (!(lpddsd
->dwFlags
& DDSD_PIXELFORMAT
)) {
2193 /* No pixel format => use DirectDraw's format */
2194 _getpixelformat(this,&(lpddsd
->ddpfPixelFormat
));
2195 lpddsd
->dwFlags
|= DDSD_PIXELFORMAT
;
2197 /* To check what the program wants */
2198 if (TRACE_ON(ddraw
)) {
2199 _dump_pixelformat(&(lpddsd
->ddpfPixelFormat
));
2203 if (lpddsd
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) {
2206 bpp
= lpddsd
->ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
2210 /* Copy the surface description */
2211 lpdsf
->s
.surface_desc
= *lpddsd
;
2213 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2214 lpdsf
->s
.surface_desc
.y
.lpSurface
= (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpddsd
->dwWidth
* lpddsd
->dwHeight
* bpp
);
2215 lpdsf
->s
.surface_desc
.lPitch
= lpddsd
->dwWidth
* bpp
;
2220 static HRESULT WINAPI
DGA_IDirectDraw2_CreateSurface(
2221 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2223 #ifdef HAVE_LIBXXF86DGA
2226 TRACE(ddraw
, "(%p)->(%p,%p,%p)\n",this,lpddsd
,lpdsf
,lpunk
);
2227 if (TRACE_ON(ddraw
)) {
2228 DUMP("[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2229 _dump_DDSD(lpddsd
->dwFlags
);
2230 fprintf(stderr
,"caps ");
2231 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2232 fprintf(stderr
,"]\n");
2235 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2236 this->lpvtbl
->fnAddRef(this);
2239 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&dga_dds4vt
;
2240 (*lpdsf
)->s
.ddraw
= this;
2241 (*lpdsf
)->s
.palette
= NULL
;
2242 (*lpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
2244 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2245 lpddsd
->dwWidth
= this->d
.width
;
2246 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2247 lpddsd
->dwHeight
= this->d
.height
;
2249 /* Check if this a 'primary surface' or not */
2250 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2251 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2253 /* This is THE primary surface => there is DGA-specific code */
2254 /* First, store the surface description */
2255 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2257 /* Find a viewport */
2259 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2261 TRACE(ddraw
,"using viewport %d for a primary surface\n",i
);
2262 /* if i == 32 or maximum ... return error */
2263 this->e
.dga
.vpmask
|=(1<<i
);
2264 (*lpdsf
)->s
.surface_desc
.y
.lpSurface
=
2265 this->e
.dga
.fb_addr
+((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
2266 (*lpdsf
)->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2267 (*lpdsf
)->s
.surface_desc
.lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
2268 lpddsd
->lPitch
= (*lpdsf
)->s
.surface_desc
.lPitch
;
2270 /* Add flags if there were not present */
2271 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2272 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2273 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2274 TRACE(ddraw
,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d
.width
,this->d
.height
,lpddsd
->lPitch
);
2275 /* We put our surface always in video memory */
2276 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2277 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
2278 (*lpdsf
)->s
.backbuffer
= NULL
;
2280 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2281 LPDIRECTDRAWSURFACE4 back
;
2283 if (lpddsd
->dwBackBufferCount
>1)
2284 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2286 (*lpdsf
)->s
.backbuffer
= back
=
2287 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2288 this->lpvtbl
->fnAddRef(this);
2290 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&dga_dds4vt
;
2292 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2294 TRACE(ddraw
,"using viewport %d for backbuffer\n",i
);
2295 /* if i == 32 or maximum ... return error */
2296 this->e
.dga
.vpmask
|=(1<<i
);
2297 back
->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2299 /* Copy the surface description from the front buffer */
2300 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2301 /* Change the parameters that are not the same */
2302 back
->s
.surface_desc
.y
.lpSurface
= this->e
.dga
.fb_addr
+
2303 ((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
2304 back
->s
.ddraw
= this;
2305 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2308 /* Add relevant info to front and back buffers */
2309 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2310 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2311 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2312 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2313 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2316 /* There is no DGA-specific code here...
2317 Go to the common surface creation function */
2318 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2322 #else /* defined(HAVE_LIBXXF86DGA) */
2323 return E_UNEXPECTED
;
2324 #endif /* defined(HAVE_LIBXXF86DGA) */
2327 #ifdef HAVE_LIBXXSHM
2328 /* Error handlers for Image creation */
2329 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
2334 static XImage
*create_xshmimage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2336 int (*WineXHandler
)(Display
*, XErrorEvent
*);
2338 img
= TSXShmCreateImage(display
,
2339 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2340 this->d
.screen_depth
,
2343 &(lpdsf
->t
.xlib
.shminfo
),
2344 lpdsf
->s
.surface_desc
.dwWidth
,
2345 lpdsf
->s
.surface_desc
.dwHeight
);
2348 ERR(ddraw
, "Error creating XShm image. Reverting to standard X images !\n");
2349 this->e
.xlib
.xshm_active
= 0;
2353 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
2354 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
2355 ERR(ddraw
, "Error creating shared memory segment. Reverting to standard X images !\n");
2356 this->e
.xlib
.xshm_active
= 0;
2357 TSXDestroyImage(img
);
2361 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
2363 if (img
->data
== (char *) -1) {
2364 ERR(ddraw
, "Error attaching shared memory segment. Reverting to standard X images !\n");
2365 this->e
.xlib
.xshm_active
= 0;
2366 TSXDestroyImage(img
);
2367 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2370 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
2372 /* This is where things start to get trickier....
2373 First, we flush the current X connections to be sure to catch all non-XShm related
2375 TSXSync(display
, False
);
2376 /* Then we enter in the non-thread safe part of the tests */
2377 EnterCriticalSection( &X11DRV_CritSection
);
2379 /* Reset the error flag, sets our new error handler and try to attach the surface */
2381 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
2382 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
2383 XSync(display
, False
);
2385 /* Check the error flag */
2386 if (XShmErrorFlag
) {
2387 /* An error occured */
2391 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
2392 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2393 XSetErrorHandler(WineXHandler
);
2395 ERR(ddraw
, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2396 this->e
.xlib
.xshm_active
= 0;
2398 /* Leave the critical section */
2399 LeaveCriticalSection( &X11DRV_CritSection
);
2404 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2405 but it may be a bit overkill.... */
2406 XSetErrorHandler(WineXHandler
);
2407 LeaveCriticalSection( &X11DRV_CritSection
);
2409 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2411 if (this->d
.depth
!= this->d
.screen_depth
) {
2412 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2413 lpdsf
->s
.surface_desc
.dwWidth
*
2414 lpdsf
->s
.surface_desc
.dwHeight
*
2415 (this->d
.depth
/ 8));
2417 lpdsf
->s
.surface_desc
.y
.lpSurface
= img
->data
;
2422 #endif /* HAVE_LIBXXSHM */
2424 static XImage
*create_ximage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2428 #ifdef HAVE_LIBXXSHM
2429 if (this->e
.xlib
.xshm_active
) {
2430 img
= create_xshmimage(this, lpdsf
);
2435 /* Allocate surface memory */
2436 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2437 lpdsf
->s
.surface_desc
.dwWidth
*
2438 lpdsf
->s
.surface_desc
.dwHeight
*
2439 (this->d
.depth
/ 8));
2441 if (this->d
.depth
!= this->d
.screen_depth
) {
2442 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2443 lpdsf
->s
.surface_desc
.dwWidth
*
2444 lpdsf
->s
.surface_desc
.dwHeight
*
2445 (this->d
.screen_depth
/ 8));
2447 img_data
= lpdsf
->s
.surface_desc
.y
.lpSurface
;
2450 /* In this case, create an XImage */
2452 TSXCreateImage(display
,
2453 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2454 this->d
.screen_depth
,
2458 lpdsf
->s
.surface_desc
.dwWidth
,
2459 lpdsf
->s
.surface_desc
.dwHeight
,
2461 lpdsf
->s
.surface_desc
.dwWidth
* (this->d
.screen_depth
/ 8)
2464 #ifdef HAVE_LIBXXSHM
2467 if (this->d
.depth
!= this->d
.screen_depth
) {
2468 lpdsf
->s
.surface_desc
.lPitch
= (this->d
.depth
/ 8) * lpdsf
->s
.surface_desc
.dwWidth
;
2470 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
2476 static HRESULT WINAPI
Xlib_IDirectDraw2_CreateSurface(
2477 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2479 TRACE(ddraw
, "(%p)->CreateSurface(%p,%p,%p)\n",
2480 this,lpddsd
,lpdsf
,lpunk
);
2482 if (TRACE_ON(ddraw
)) {
2483 fprintf(stderr
,"[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2484 _dump_DDSD(lpddsd
->dwFlags
);
2485 fprintf(stderr
,"caps ");
2486 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2487 fprintf(stderr
,"]\n");
2490 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2492 this->lpvtbl
->fnAddRef(this);
2493 (*lpdsf
)->s
.ddraw
= this;
2495 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&xlib_dds4vt
;
2496 (*lpdsf
)->s
.palette
= NULL
;
2497 (*lpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
2499 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2500 lpddsd
->dwWidth
= this->d
.width
;
2501 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2502 lpddsd
->dwHeight
= this->d
.height
;
2504 /* Check if this a 'primary surface' or not */
2505 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2506 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2509 TRACE(ddraw
,"using standard XImage for a primary surface (%p)\n", *lpdsf
);
2511 /* First, store the surface description */
2512 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2514 /* Create the XImage */
2515 img
= create_ximage(this, (LPDIRECTDRAWSURFACE4
) *lpdsf
);
2517 return DDERR_OUTOFMEMORY
;
2518 (*lpdsf
)->t
.xlib
.image
= img
;
2520 /* Add flags if there were not present */
2521 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2522 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2523 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2524 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2525 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
2526 (*lpdsf
)->s
.backbuffer
= NULL
;
2528 /* Check for backbuffers */
2529 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2530 LPDIRECTDRAWSURFACE4 back
;
2533 if (lpddsd
->dwBackBufferCount
>1)
2534 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2536 (*lpdsf
)->s
.backbuffer
= back
=
2537 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2539 TRACE(ddraw
,"allocated back-buffer (%p)\n", back
);
2541 this->lpvtbl
->fnAddRef(this);
2542 back
->s
.ddraw
= this;
2545 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&xlib_dds4vt
;
2546 /* Copy the surface description from the front buffer */
2547 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2549 /* Create the XImage */
2550 img
= create_ximage(this, back
);
2552 return DDERR_OUTOFMEMORY
;
2553 back
->t
.xlib
.image
= img
;
2555 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2558 /* Add relevant info to front and back buffers */
2559 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2560 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2561 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2562 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2563 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2566 /* There is no Xlib-specific code here...
2567 Go to the common surface creation function */
2568 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2574 static HRESULT WINAPI
IDirectDraw2_DuplicateSurface(
2575 LPDIRECTDRAW2
this,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
2577 FIXME(ddraw
,"(%p)->(%p,%p) simply copies\n",this,src
,dst
);
2578 *dst
= src
; /* FIXME */
2583 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2584 * even when the approbiate bitmasks are not specified.
2586 static HRESULT WINAPI
IDirectDraw2_SetCooperativeLevel(
2587 LPDIRECTDRAW2
this,HWND32 hwnd
,DWORD cooplevel
2594 FE(DDSCL_FULLSCREEN
)
2595 FE(DDSCL_ALLOWREBOOT
)
2596 FE(DDSCL_NOWINDOWCHANGES
)
2598 FE(DDSCL_ALLOWMODEX
)
2600 FE(DDSCL_SETFOCUSWINDOW
)
2601 FE(DDSCL_SETDEVICEWINDOW
)
2602 FE(DDSCL_CREATEDEVICEWINDOW
)
2605 FIXME(ddraw
,"(%p)->(%08lx,%08lx)\n",this,(DWORD
)hwnd
,cooplevel
);
2606 if(TRACE_ON(ddraw
)){
2607 dbg_decl_str(ddraw
, 512);
2608 for (i
=0;i
<sizeof(flagmap
)/sizeof(flagmap
[0]);i
++)
2609 if (flagmap
[i
].mask
& cooplevel
)
2610 dsprintf(ddraw
, "%s ", flagmap
[i
].name
);
2611 TRACE(ddraw
," cooperative level %s\n", dbg_str(ddraw
));
2613 this->d
.mainWindow
= hwnd
;
2615 /* This will be overwritten in the case of Full Screen mode.
2616 Windowed games could work with that :-) */
2618 this->d
.drawable
= X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd
));
2623 /* Small helper to either use the cooperative window or create a new
2624 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2626 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW
this) {
2629 /* Do not destroy the application supplied cooperative window */
2630 if (this->d
.window
&& this->d
.window
!= this->d
.mainWindow
) {
2631 DestroyWindow32(this->d
.window
);
2634 /* Sanity check cooperative window before assigning it to drawing. */
2635 if ( IsWindow32(this->d
.mainWindow
) &&
2636 IsWindowVisible32(this->d
.mainWindow
)
2638 GetWindowRect32(this->d
.mainWindow
,&rect
);
2639 if (((rect
.right
-rect
.left
) >= this->d
.width
) &&
2640 ((rect
.bottom
-rect
.top
) >= this->d
.height
)
2642 this->d
.window
= this->d
.mainWindow
;
2644 /* ... failed, create new one. */
2645 if (!this->d
.window
) {
2646 this->d
.window
= CreateWindowEx32A(
2650 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
2659 /*Store THIS with the window. We'll use it in the window procedure*/
2660 SetWindowLong32A(this->d
.window
,ddrawXlibThisOffset
,(LONG
)this);
2661 ShowWindow32(this->d
.window
,TRUE
);
2662 UpdateWindow32(this->d
.window
);
2664 SetFocus32(this->d
.window
);
2667 static HRESULT WINAPI
DGA_IDirectDraw_SetDisplayMode(
2668 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2670 #ifdef HAVE_LIBXXF86DGA
2671 int i
,*depths
,depcount
,mode_count
;
2673 TRACE(ddraw
, "(%p)->(%ld,%ld,%ld)\n", this, width
, height
, depth
);
2675 /* We hope getting the asked for depth */
2676 this->d
.screen_depth
= depth
;
2678 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
2680 for (i
=0;i
<depcount
;i
++)
2681 if (depths
[i
]==depth
)
2684 if (i
==depcount
) {/* not found */
2685 ERR(ddraw
,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
2686 return DDERR_UNSUPPORTEDMODE
;
2688 if (this->d
.width
< width
) {
2689 ERR(ddraw
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,this->d
.width
);
2690 return DDERR_UNSUPPORTEDMODE
;
2692 this->d
.width
= width
;
2693 this->d
.height
= height
;
2694 this->d
.depth
= depth
;
2696 /* adjust fb_height, so we don't overlap */
2697 if (this->e
.dga
.fb_height
< height
)
2698 this->e
.dga
.fb_height
= height
;
2699 _common_IDirectDraw_SetDisplayMode(this);
2701 #ifdef HAVE_LIBXXF86VM
2703 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
2704 XF86VidModeModeLine mod_tmp
;
2705 /* int dotclock_tmp; */
2707 /* save original video mode and set fullscreen if available*/
2708 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
2709 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
2710 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
2711 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
2712 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
2713 orig_mode
->htotal
= mod_tmp
.htotal
;
2714 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
2715 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
2716 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
2717 orig_mode
->vtotal
= mod_tmp
.vtotal
;
2718 orig_mode
->flags
= mod_tmp
.flags
;
2719 orig_mode
->private = mod_tmp
.private;
2721 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
2722 for (i
=0;i
<mode_count
;i
++)
2724 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
2726 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
2727 *vidmode
= *(all_modes
[i
]);
2730 TSXFree(all_modes
[i
]->private);
2732 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
2736 WARN(ddraw
, "Fullscreen mode not available!\n");
2740 TRACE(ddraw
,"SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
2741 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
2742 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2743 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
2749 /* FIXME: this function OVERWRITES several signal handlers.
2750 * can we save them? and restore them later? In a way that
2751 * it works for the library too?
2753 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
2755 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,this->e
.dga
.fb_height
);
2757 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
2760 #ifdef RESTORE_SIGNALS
2761 SIGNAL_InitHandlers();
2764 #else /* defined(HAVE_LIBXXF86DGA) */
2765 return E_UNEXPECTED
;
2766 #endif /* defined(HAVE_LIBXXF86DGA) */
2769 static HRESULT WINAPI
Xlib_IDirectDraw_SetDisplayMode(
2770 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2772 int i
,*depths
,depcount
;
2775 TRACE(ddraw
, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2776 this, width
, height
, depth
);
2778 /* We hope getting the asked for depth */
2779 this->d
.screen_depth
= depth
;
2781 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
2783 for (i
=0;i
<depcount
;i
++)
2784 if (depths
[i
]==depth
)
2786 if (i
==depcount
) {/* not found */
2787 for (i
=0;i
<depcount
;i
++)
2792 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
2793 MessageBox32A(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
2795 return DDERR_UNSUPPORTEDMODE
;
2797 WARN(ddraw
, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
2798 this->d
.screen_depth
= 16;
2803 this->d
.width
= width
;
2804 this->d
.height
= height
;
2805 this->d
.depth
= depth
;
2807 _common_IDirectDraw_SetDisplayMode(this);
2809 this->d
.paintable
= 1;
2810 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_FindWndPtr(this->d
.window
)->pDriverData
)->window
;
2811 /* We don't have a context for this window. Host off the desktop */
2812 if( !this->d
.drawable
)
2813 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
2817 static HRESULT WINAPI
DGA_IDirectDraw2_GetCaps(
2818 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2820 #ifdef HAVE_LIBXXF86DGA
2821 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2822 caps1
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2823 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2824 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2826 caps2
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2827 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2828 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2831 #else /* defined(HAVE_LIBXXF86DGA) */
2832 return E_UNEXPECTED
;
2833 #endif /* defined(HAVE_LIBXXF86DGA) */
2836 static void fill_caps(LPDDCAPS caps
) {
2837 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2838 Need to be fixed, though.. */
2842 caps
->dwSize
= sizeof(*caps
);
2843 caps
->dwCaps
= DDCAPS_3D
| DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
|
2844 DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
| DDCAPS_ZBLTS
;
2845 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NO2DDURING3DSCENE
| DDCAPS2_NOPAGELOCKREQUIRED
|
2846 DDCAPS2_WIDESURFACES
;
2847 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
2849 caps
->dwFXAlphaCaps
= 0;
2850 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
2852 caps
->dwZBufferBitDepths
= DDBD_16
;
2853 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2854 to put textures in video memory.
2855 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2857 caps
->dwVidMemTotal
= 8192 * 1024;
2858 caps
->dwVidMemFree
= 8192 * 1024;
2859 /* These are all the supported capabilities of the surfaces */
2860 caps
->ddsCaps
.dwCaps
= DDSCAPS_3DDEVICE
| DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
2861 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_MIPMAP
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
2862 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
|
2863 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
| DDSCAPS_ZBUFFER
;
2866 static HRESULT WINAPI
Xlib_IDirectDraw2_GetCaps(
2867 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2869 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2871 /* Put the same caps for the two capabilities */
2878 static HRESULT WINAPI
IDirectDraw2_CreateClipper(
2879 LPDIRECTDRAW2
this,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
2881 FIXME(ddraw
,"(%p)->(%08lx,%p,%p),stub!\n",
2882 this,x
,lpddclip
,lpunk
2884 *lpddclip
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
2885 (*lpddclip
)->ref
= 1;
2886 (*lpddclip
)->lpvtbl
= &ddclipvt
;
2890 static HRESULT WINAPI
common_IDirectDraw2_CreatePalette(
2891 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
,int *psize
2895 if (TRACE_ON(ddraw
))
2896 _dump_paletteformat(dwFlags
);
2898 *lpddpal
= (LPDIRECTDRAWPALETTE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPalette
));
2899 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
2900 (*lpddpal
)->ref
= 1;
2901 (*lpddpal
)->ddraw
= (LPDIRECTDRAW
)this;
2902 (*lpddpal
)->installed
= 0;
2904 if (dwFlags
& DDPCAPS_1BIT
)
2906 else if (dwFlags
& DDPCAPS_2BIT
)
2908 else if (dwFlags
& DDPCAPS_4BIT
)
2910 else if (dwFlags
& DDPCAPS_8BIT
)
2913 ERR(ddraw
, "unhandled palette format\n");
2918 /* Now, if we are in 'depth conversion mode', create the screen palette */
2919 if (this->d
.depth
!= this->d
.screen_depth
) {
2922 switch (this->d
.screen_depth
) {
2924 unsigned short *screen_palette
= (unsigned short *) (*lpddpal
)->screen_palents
;
2926 for (i
= 0; i
< size
; i
++) {
2927 screen_palette
[i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
2928 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
2929 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
2934 ERR(ddraw
, "Memory corruption ! (depth=%ld, screen_depth=%ld)\n",this->d
.depth
,this->d
.screen_depth
);
2939 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
2940 } else if (this->d
.depth
!= this->d
.screen_depth
) {
2943 switch (this->d
.screen_depth
) {
2945 unsigned short *screen_palette
= (unsigned short *) (*lpddpal
)->screen_palents
;
2947 for (i
= 0; i
< size
; i
++) {
2948 screen_palette
[i
] = 0xFFFF;
2953 ERR(ddraw
, "Memory corruption !\n");
2961 static HRESULT WINAPI
DGA_IDirectDraw2_CreatePalette(
2962 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2967 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
2968 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
2969 if (res
!= 0) return res
;
2970 (*lpddpal
)->lpvtbl
= &dga_ddpalvt
;
2971 if (this->d
.depth
<=8) {
2972 (*lpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
2974 FIXME(ddraw
,"why are we doing CreatePalette in hi/truecolor?\n");
2977 if (((*lpddpal
)->cm
)&&xsize
) {
2978 for (i
=0;i
<xsize
;i
++) {
2981 xc
.red
= (*lpddpal
)->palents
[i
].peRed
<<8;
2982 xc
.blue
= (*lpddpal
)->palents
[i
].peBlue
<<8;
2983 xc
.green
= (*lpddpal
)->palents
[i
].peGreen
<<8;
2984 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2986 TSXStoreColor(display
,(*lpddpal
)->cm
,&xc
);
2992 static HRESULT WINAPI
Xlib_IDirectDraw2_CreatePalette(
2993 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2998 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
2999 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
3000 if (res
!= 0) return res
;
3001 (*lpddpal
)->lpvtbl
= &xlib_ddpalvt
;
3005 static HRESULT WINAPI
DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3006 #ifdef HAVE_LIBXXF86DGA
3007 TRACE(ddraw
, "(%p)->()\n",this);
3009 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3010 #ifdef RESTORE_SIGNALS
3011 SIGNAL_InitHandlers();
3014 #else /* defined(HAVE_LIBXXF86DGA) */
3015 return E_UNEXPECTED
;
3019 static HRESULT WINAPI
Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3020 TRACE(ddraw
, "(%p)->RestoreDisplayMode()\n", this);
3025 static HRESULT WINAPI
IDirectDraw2_WaitForVerticalBlank(
3026 LPDIRECTDRAW2
this,DWORD x
,HANDLE32 h
3028 TRACE(ddraw
,"(%p)->(0x%08lx,0x%08x)\n",this,x
,h
);
3032 static ULONG WINAPI
IDirectDraw2_AddRef(LPDIRECTDRAW2
this) {
3033 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
3035 return ++(this->ref
);
3038 static ULONG WINAPI
DGA_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3039 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3041 #ifdef HAVE_LIBXXF86DGA
3042 if (!--(this->ref
)) {
3043 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3044 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3045 DestroyWindow32(this->d
.window
);
3046 #ifdef HAVE_LIBXXF86VM
3048 TSXF86VidModeSwitchToMode(
3050 DefaultScreen(display
),
3052 if (orig_mode
->privsize
)
3053 TSXFree(orig_mode
->private);
3059 #ifdef RESTORE_SIGNALS
3060 SIGNAL_InitHandlers();
3062 HeapFree(GetProcessHeap(),0,this);
3065 #endif /* defined(HAVE_LIBXXF86DGA) */
3069 static ULONG WINAPI
Xlib_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3070 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3072 if (!--(this->ref
)) {
3073 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3074 DestroyWindow32(this->d
.window
);
3075 HeapFree(GetProcessHeap(),0,this);
3078 /* FIXME: destroy window ... */
3082 static HRESULT WINAPI
DGA_IDirectDraw2_QueryInterface(
3083 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3087 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3088 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3089 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3091 this->lpvtbl
->fnAddRef(this);
3093 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3097 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3098 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_ddvt
;
3099 this->lpvtbl
->fnAddRef(this);
3102 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3106 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3107 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd2vt
;
3108 this->lpvtbl
->fnAddRef(this);
3111 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3115 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3116 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd4vt
;
3117 this->lpvtbl
->fnAddRef(this);
3120 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3124 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3127 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3129 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3130 this->lpvtbl
->fnAddRef(this);
3131 d3d
->lpvtbl
= &d3dvt
;
3134 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3138 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
3141 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3143 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3144 this->lpvtbl
->fnAddRef(this);
3145 d3d
->lpvtbl
= &d3d2vt
;
3148 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3152 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3153 return OLE_E_ENUM_NOMORE
;
3156 static HRESULT WINAPI
Xlib_IDirectDraw2_QueryInterface(
3157 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3161 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3162 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3163 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3165 this->lpvtbl
->fnAddRef(this);
3167 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3171 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3172 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_ddvt
;
3173 this->lpvtbl
->fnAddRef(this);
3176 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3180 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3181 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd2vt
;
3182 this->lpvtbl
->fnAddRef(this);
3185 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3189 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3190 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd4vt
;
3191 this->lpvtbl
->fnAddRef(this);
3194 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3198 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3201 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3203 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3204 this->lpvtbl
->fnAddRef(this);
3205 d3d
->lpvtbl
= &d3dvt
;
3208 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3212 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
3215 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3217 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3218 this->lpvtbl
->fnAddRef(this);
3219 d3d
->lpvtbl
= &d3d2vt
;
3222 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3226 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3227 return OLE_E_ENUM_NOMORE
;
3230 static HRESULT WINAPI
IDirectDraw2_GetVerticalBlankStatus(
3231 LPDIRECTDRAW2
this,BOOL32
*status
3233 TRACE(ddraw
,"(%p)->(%p)\n",this,status
);
3238 static HRESULT WINAPI
IDirectDraw2_EnumDisplayModes(
3239 LPDIRECTDRAW2
this,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
3241 DDSURFACEDESC ddsfd
;
3244 } modes
[5] = { /* some of the usual modes */
3251 static int depths
[4] = {8,16,24,32};
3254 TRACE(ddraw
,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags
,lpddsfd
,context
,modescb
);
3255 ddsfd
.dwSize
= sizeof(ddsfd
);
3256 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3257 if (dwFlags
& DDEDM_REFRESHRATES
) {
3258 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
3259 ddsfd
.x
.dwRefreshRate
= 60;
3262 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
3263 ddsfd
.dwBackBufferCount
= 1;
3264 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
3265 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
3266 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= depths
[i
];
3267 /* FIXME: those masks would have to be set in depth > 8 */
3269 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
3270 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
3271 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
3272 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3273 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
3274 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
3276 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3278 /* FIXME: We should query those from X itself */
3279 switch (depths
[i
]) {
3281 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0xF800;
3282 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x07E0;
3283 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x001F;
3286 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3287 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3288 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3291 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3292 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3293 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3298 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3299 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3300 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3301 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3303 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
3304 ddsfd
.dwWidth
= modes
[j
].w
;
3305 ddsfd
.dwHeight
= modes
[j
].h
;
3306 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3307 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3310 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
3311 /* modeX is not standard VGA */
3313 ddsfd
.dwHeight
= 200;
3314 ddsfd
.dwWidth
= 320;
3315 TRACE(ddraw
," enumerating (320x200x%d)\n",depths
[i
]);
3316 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3322 static HRESULT WINAPI
DGA_IDirectDraw2_GetDisplayMode(
3323 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3325 #ifdef HAVE_LIBXXF86DGA
3326 TRACE(ddraw
,"(%p)->(%p)\n",this,lpddsfd
);
3327 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3328 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3329 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3330 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
3331 lpddsfd
->dwBackBufferCount
= 1;
3332 lpddsfd
->x
.dwRefreshRate
= 60;
3333 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3334 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
3336 #else /* defined(HAVE_LIBXXF86DGA) */
3337 return E_UNEXPECTED
;
3338 #endif /* defined(HAVE_LIBXXF86DGA) */
3341 static HRESULT WINAPI
Xlib_IDirectDraw2_GetDisplayMode(
3342 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3344 TRACE(ddraw
,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd
);
3345 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3346 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3347 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3348 /* POOLE FIXME: Xlib */
3349 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
3350 /* END FIXME: Xlib */
3351 lpddsfd
->dwBackBufferCount
= 1;
3352 lpddsfd
->x
.dwRefreshRate
= 60;
3353 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3354 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
3358 static HRESULT WINAPI
IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2
this) {
3359 TRACE(ddraw
,"(%p)->()\n",this);
3363 static HRESULT WINAPI
IDirectDraw2_GetMonitorFrequency(
3364 LPDIRECTDRAW2
this,LPDWORD freq
3366 FIXME(ddraw
,"(%p)->(%p) returns 60 Hz always\n",this,freq
);
3367 *freq
= 60*100; /* 60 Hz */
3371 /* what can we directly decompress? */
3372 static HRESULT WINAPI
IDirectDraw2_GetFourCCCodes(
3373 LPDIRECTDRAW2
this,LPDWORD x
,LPDWORD y
3375 FIXME(ddraw
,"(%p,%p,%p), stub\n",this,x
,y
);
3379 static HRESULT WINAPI
IDirectDraw2_EnumSurfaces(
3380 LPDIRECTDRAW2
this,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
3382 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x
,ddsfd
,context
,ddsfcb
);
3386 static HRESULT WINAPI
IDirectDraw2_Compact(
3387 LPDIRECTDRAW2
this )
3389 FIXME(ddraw
,"(%p)->()\n", this );
3394 static HRESULT WINAPI
IDirectDraw2_GetGDISurface(LPDIRECTDRAW2
this,
3395 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
3396 FIXME(ddraw
,"(%p)->(%p)\n", this, lplpGDIDDSSurface
);
3401 static HRESULT WINAPI
IDirectDraw2_GetScanLine(LPDIRECTDRAW2
this,
3402 LPDWORD lpdwScanLine
) {
3403 FIXME(ddraw
,"(%p)->(%p)\n", this, lpdwScanLine
);
3408 static HRESULT WINAPI
IDirectDraw2_Initialize(LPDIRECTDRAW2
this,
3410 FIXME(ddraw
,"(%p)->(%p)\n", this, lpGUID
);
3415 /* Note: Hack so we can reuse the old functions without compiler warnings */
3417 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3419 # define XCAST(fun) (void*)
3422 static struct IDirectDraw_VTable dga_ddvt
= {
3423 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3424 XCAST(AddRef
)IDirectDraw2_AddRef
,
3425 XCAST(Release
)DGA_IDirectDraw2_Release
,
3426 XCAST(Compact
)IDirectDraw2_Compact
,
3427 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3428 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3429 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3430 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3431 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3432 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3433 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3434 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3435 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3436 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3437 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3438 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3439 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3440 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3441 XCAST(Initialize
)IDirectDraw2_Initialize
,
3442 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3443 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3444 DGA_IDirectDraw_SetDisplayMode
,
3445 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3448 static struct IDirectDraw_VTable xlib_ddvt
= {
3449 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3450 XCAST(AddRef
)IDirectDraw2_AddRef
,
3451 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3452 XCAST(Compact
)IDirectDraw2_Compact
,
3453 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3454 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3455 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3456 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3457 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3458 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3459 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3460 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3461 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3462 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3463 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3464 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3465 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3466 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3467 XCAST(Initialize
)IDirectDraw2_Initialize
,
3468 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3469 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3470 Xlib_IDirectDraw_SetDisplayMode
,
3471 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3476 /*****************************************************************************
3482 static HRESULT WINAPI
DGA_IDirectDraw2_SetDisplayMode(
3483 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3485 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3488 static HRESULT WINAPI
Xlib_IDirectDraw2_SetDisplayMode(
3489 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3491 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3494 static HRESULT WINAPI
DGA_IDirectDraw2_GetAvailableVidMem(
3495 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3497 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3498 this,ddscaps
,total
,free
3500 if (total
) *total
= this->e
.dga
.fb_memsize
* 1024;
3501 if (free
) *free
= this->e
.dga
.fb_memsize
* 1024;
3505 static HRESULT WINAPI
Xlib_IDirectDraw2_GetAvailableVidMem(
3506 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3508 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3509 this,ddscaps
,total
,free
3511 if (total
) *total
= 2048 * 1024;
3512 if (free
) *free
= 2048 * 1024;
3516 static IDirectDraw2_VTable dga_dd2vt
= {
3517 DGA_IDirectDraw2_QueryInterface
,
3518 IDirectDraw2_AddRef
,
3519 DGA_IDirectDraw2_Release
,
3520 IDirectDraw2_Compact
,
3521 IDirectDraw2_CreateClipper
,
3522 DGA_IDirectDraw2_CreatePalette
,
3523 DGA_IDirectDraw2_CreateSurface
,
3524 IDirectDraw2_DuplicateSurface
,
3525 IDirectDraw2_EnumDisplayModes
,
3526 IDirectDraw2_EnumSurfaces
,
3527 IDirectDraw2_FlipToGDISurface
,
3528 DGA_IDirectDraw2_GetCaps
,
3529 DGA_IDirectDraw2_GetDisplayMode
,
3530 IDirectDraw2_GetFourCCCodes
,
3531 IDirectDraw2_GetGDISurface
,
3532 IDirectDraw2_GetMonitorFrequency
,
3533 IDirectDraw2_GetScanLine
,
3534 IDirectDraw2_GetVerticalBlankStatus
,
3535 IDirectDraw2_Initialize
,
3536 DGA_IDirectDraw2_RestoreDisplayMode
,
3537 IDirectDraw2_SetCooperativeLevel
,
3538 DGA_IDirectDraw2_SetDisplayMode
,
3539 IDirectDraw2_WaitForVerticalBlank
,
3540 DGA_IDirectDraw2_GetAvailableVidMem
3543 static struct IDirectDraw2_VTable xlib_dd2vt
= {
3544 Xlib_IDirectDraw2_QueryInterface
,
3545 IDirectDraw2_AddRef
,
3546 Xlib_IDirectDraw2_Release
,
3547 IDirectDraw2_Compact
,
3548 IDirectDraw2_CreateClipper
,
3549 Xlib_IDirectDraw2_CreatePalette
,
3550 Xlib_IDirectDraw2_CreateSurface
,
3551 IDirectDraw2_DuplicateSurface
,
3552 IDirectDraw2_EnumDisplayModes
,
3553 IDirectDraw2_EnumSurfaces
,
3554 IDirectDraw2_FlipToGDISurface
,
3555 Xlib_IDirectDraw2_GetCaps
,
3556 Xlib_IDirectDraw2_GetDisplayMode
,
3557 IDirectDraw2_GetFourCCCodes
,
3558 IDirectDraw2_GetGDISurface
,
3559 IDirectDraw2_GetMonitorFrequency
,
3560 IDirectDraw2_GetScanLine
,
3561 IDirectDraw2_GetVerticalBlankStatus
,
3562 IDirectDraw2_Initialize
,
3563 Xlib_IDirectDraw2_RestoreDisplayMode
,
3564 IDirectDraw2_SetCooperativeLevel
,
3565 Xlib_IDirectDraw2_SetDisplayMode
,
3566 IDirectDraw2_WaitForVerticalBlank
,
3567 Xlib_IDirectDraw2_GetAvailableVidMem
3570 /*****************************************************************************
3575 static HRESULT WINAPI
IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4
this,
3577 LPDIRECTDRAWSURFACE
*lpDDS
) {
3578 FIXME(ddraw
, "(%p)->(%08ld,%p)\n", this, (DWORD
) hdc
, lpDDS
);
3583 static HRESULT WINAPI
IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4
this) {
3584 FIXME(ddraw
, "(%p)->()\n", this);
3589 static HRESULT WINAPI
IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4
this) {
3590 FIXME(ddraw
, "(%p)->()\n", this);
3595 static HRESULT WINAPI
IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4
this,
3596 LPDDDEVICEIDENTIFIER lpdddi
,
3598 FIXME(ddraw
, "(%p)->(%p,%08lx)\n", this, lpdddi
, dwFlags
);
3604 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3606 # define XCAST(fun) (void*)
3610 static struct IDirectDraw4_VTable dga_dd4vt
= {
3611 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3612 XCAST(AddRef
)IDirectDraw2_AddRef
,
3613 XCAST(Release
)DGA_IDirectDraw2_Release
,
3614 XCAST(Compact
)IDirectDraw2_Compact
,
3615 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3616 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3617 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3618 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3619 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3620 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3621 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3622 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3623 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3624 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3625 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3626 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3627 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3628 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3629 XCAST(Initialize
)IDirectDraw2_Initialize
,
3630 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3631 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3632 XCAST(SetDisplayMode
)DGA_IDirectDraw_SetDisplayMode
,
3633 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3634 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2_GetAvailableVidMem
,
3635 IDirectDraw4_GetSurfaceFromDC
,
3636 IDirectDraw4_RestoreAllSurfaces
,
3637 IDirectDraw4_TestCooperativeLevel
,
3638 IDirectDraw4_GetDeviceIdentifier
3641 static struct IDirectDraw4_VTable xlib_dd4vt
= {
3642 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3643 XCAST(AddRef
)IDirectDraw2_AddRef
,
3644 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3645 XCAST(Compact
)IDirectDraw2_Compact
,
3646 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3647 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3648 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3649 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3650 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3651 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3652 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3653 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3654 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3655 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3656 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3657 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3658 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3659 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3660 XCAST(Initialize
)IDirectDraw2_Initialize
,
3661 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3662 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3663 XCAST(SetDisplayMode
)Xlib_IDirectDraw_SetDisplayMode
,
3664 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3665 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2_GetAvailableVidMem
,
3666 IDirectDraw4_GetSurfaceFromDC
,
3667 IDirectDraw4_RestoreAllSurfaces
,
3668 IDirectDraw4_TestCooperativeLevel
,
3669 IDirectDraw4_GetDeviceIdentifier
3674 /******************************************************************************
3678 LRESULT WINAPI
Xlib_DDWndProc(HWND32 hwnd
,UINT32 msg
,WPARAM32 wParam
,LPARAM lParam
)
3681 LPDIRECTDRAW ddraw
= NULL
;
3684 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3686 SetLastError( ERROR_SUCCESS
);
3687 ddraw
= (LPDIRECTDRAW
)GetWindowLong32A( hwnd
, ddrawXlibThisOffset
);
3689 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
3692 ERR( ddraw
, "Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
3697 /* Perform any special direct draw functions */
3699 ddraw
->d
.paintable
= 1;
3701 /* Now let the application deal with the rest of this */
3702 if( ddraw
->d
.mainWindow
)
3705 /* Don't think that we actually need to call this but...
3706 might as well be on the safe side of things... */
3708 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3709 it should be the procedures of our fake window that gets called
3710 instead of those of the window provided by the application.
3711 And with this patch, mouse clicks work with Monkey Island III
3713 ret
= DefWindowProc32A( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3717 /* We didn't handle the message - give it to the application */
3718 if (ddraw
&& ddraw
->d
.mainWindow
&& WIN_FindWndPtr(ddraw
->d
.mainWindow
)) {
3719 ret
= CallWindowProc32A( WIN_FindWndPtr( ddraw
->d
.mainWindow
)->winproc
,
3720 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3725 ret
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
3731 ret
= DefWindowProc32A(hwnd
,msg
,wParam
,lParam
);
3737 HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3738 #ifdef HAVE_LIBXXF86DGA
3739 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
3743 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3744 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
3748 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3749 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
3750 return E_UNEXPECTED
;
3752 if (!DDRAW_DGA_Available()) {
3753 TRACE(ddraw
,"No XF86DGA detected.\n");
3754 return DDERR_GENERIC
;
3756 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
3757 (*lplpDD
)->lpvtbl
= &dga_ddvt
;
3759 TSXF86DGAQueryVersion(display
,&major
,&minor
);
3760 TRACE(ddraw
,"XF86DGA is version %d.%d\n",major
,minor
);
3761 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
3762 if (!(flags
& XF86DGADirectPresent
))
3763 MSG("direct video is NOT PRESENT.\n");
3764 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
3765 TRACE(ddraw
,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3766 addr
,width
,banksize
,memsize
3768 (*lplpDD
)->e
.dga
.fb_width
= width
;
3769 (*lplpDD
)->d
.width
= width
;
3770 (*lplpDD
)->e
.dga
.fb_addr
= addr
;
3771 (*lplpDD
)->e
.dga
.fb_memsize
= memsize
;
3772 (*lplpDD
)->e
.dga
.fb_banksize
= banksize
;
3774 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
3775 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
3776 (*lplpDD
)->e
.dga
.fb_height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3778 (*lplpDD
)->e
.dga
.vpmask
= 1;
3780 (*lplpDD
)->e
.dga
.vpmask
= 0;
3783 /* just assume the default depth is the DGA depth too */
3784 (*lplpDD
)->d
.screen_depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3785 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3786 #ifdef RESTORE_SIGNALS
3787 SIGNAL_InitHandlers();
3791 #else /* defined(HAVE_LIBXXF86DGA) */
3792 return DDERR_INVALIDDIRECTDRAWGUID
;
3793 #endif /* defined(HAVE_LIBXXF86DGA) */
3797 DDRAW_XSHM_Available(void)
3799 #ifdef HAVE_LIBXXSHM
3800 if (TSXShmQueryExtension(display
))
3805 if (TSXShmQueryVersion(display
, &major
, &minor
, &shpix
))
3817 HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3819 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
3820 (*lplpDD
)->lpvtbl
= &xlib_ddvt
;
3822 (*lplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
3824 /* At DirectDraw creation, the depth is the default depth */
3825 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3826 (*lplpDD
)->d
.screen_depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3827 (*lplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3828 (*lplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3830 #ifdef HAVE_LIBXXSHM
3831 /* Test if XShm is available. */
3832 if (((*lplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available()))
3833 TRACE(ddraw
, "Using XShm extension.\n");
3839 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3846 WINE_StringFromCLSID(lpGUID
,xclsid
);
3848 sprintf(xclsid
,"<guid-0x%08x>",(int)lpGUID
);
3852 TRACE(ddraw
,"(%s,%p,%p)\n",xclsid
,lplpDD
,pUnkOuter
);
3855 /* if they didn't request a particular interface, use the best
3857 if (DDRAW_DGA_Available())
3858 lpGUID
= &DGA_DirectDraw_GUID
;
3860 lpGUID
= &XLIB_DirectDraw_GUID
;
3863 wc
.style
= CS_GLOBALCLASS
;
3864 wc
.lpfnWndProc
= Xlib_DDWndProc
;
3866 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
3867 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
3869 /* We can be a child of the desktop since we're really important */
3870 pParentWindow
= WIN_GetDesktop();
3871 wc
.hInstance
= pParentWindow
? pParentWindow
->hwndSelf
: 0;
3875 wc
.hCursor
= (HCURSOR32
)IDC_ARROW32A
;
3876 wc
.hbrBackground
= NULL_BRUSH
;
3877 wc
.lpszMenuName
= 0;
3878 wc
.lpszClassName
= "WINE_DirectDraw";
3879 RegisterClass32A(&wc
);
3881 if (!memcmp(lpGUID
, &DGA_DirectDraw_GUID
, sizeof(GUID
)))
3882 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
3883 else if (!memcmp(lpGUID
, &XLIB_DirectDraw_GUID
, sizeof(GUID
)))
3884 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
3889 (*lplpDD
)->d
.winclass
= RegisterClass32A(&wc
);
3893 fprintf(stderr
,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
3894 return DDERR_INVALIDDIRECTDRAWGUID
;