1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
4 * Copyright 1998 Lionel Ulmer (most of Direct3D stuff)
7 * When DirectVideo mode is enabled you can no longer use 'normal' X
8 * applications nor can you switch to a virtual console. Also, enabling
9 * only works, if you have switched to the screen where the application
11 * Some ways to debug this stuff are:
12 * - A terminal connected to the serial port. Can be bought used for cheap.
13 * (This is the method I am using.)
14 * - Another machine connected over some kind of network.
23 #include <sys/types.h>
27 #endif /* defined(HAVE_LIBXXSHM) */
29 #ifdef HAVE_LIBXXF86DGA
30 #include "ts_xf86dga.h"
31 #endif /* defined(HAVE_LIBXXF86DGA) */
33 #ifdef HAVE_LIBXXF86VM
34 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
35 this is a crude hack to get around it */
38 #include "ts_xf86vmode.h"
39 #endif /* defined(HAVE_LIBXXF86VM) */
45 #include <sys/signal.h>
64 /* This for all the enumeration and creation of D3D-related objects */
65 #include "d3d_private.h"
67 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
70 /* Restore signal handlers overwritten by XF86DGA
72 #define RESTORE_SIGNALS
74 /* Where do these GUIDs come from? mkuuid.
75 * They exist solely to distinguish between the targets Wine support,
76 * and should be different than any other GUIDs in existence.
78 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
82 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
85 static GUID XLIB_DirectDraw_GUID
= { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
89 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
92 static struct IDirectDrawSurface4_VTable dga_dds4vt
, xlib_dds4vt
;
93 static struct IDirectDraw_VTable dga_ddvt
, xlib_ddvt
;
94 static struct IDirectDraw2_VTable dga_dd2vt
, xlib_dd2vt
;
95 static struct IDirectDraw4_VTable dga_dd4vt
, xlib_dd4vt
;
96 static struct IDirectDrawClipper_VTable ddclipvt
;
97 static struct IDirectDrawPalette_VTable dga_ddpalvt
, xlib_ddpalvt
;
98 static struct IDirect3D_VTable d3dvt
;
99 static struct IDirect3D2_VTable d3d2vt
;
101 #ifdef HAVE_LIBXXF86VM
102 static XF86VidModeModeInfo
*orig_mode
= NULL
;
106 static int XShmErrorFlag
= 0;
110 DDRAW_DGA_Available(void)
112 #ifdef HAVE_LIBXXF86DGA
113 int evbase
, evret
, fd
;
118 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
119 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
120 /* others. --stephenc */
121 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
124 return (fd
!= -1) && TSXF86DGAQueryExtension(display
,&evbase
,&evret
);
125 #else /* defined(HAVE_LIBXXF86DGA) */
127 #endif /* defined(HAVE_LIBXXF86DGA) */
131 DirectDrawEnumerateA(LPDDENUMCALLBACKA ddenumproc
,LPVOID data
) {
132 TRACE(ddraw
, "(%p,%p)\n", ddenumproc
, data
);
134 if (DDRAW_DGA_Available()) {
135 TRACE(ddraw
, "Enumerating DGA interface\n");
136 if (!ddenumproc(&DGA_DirectDraw_GUID
,"WINE with XFree86 DGA","display",data
))
140 TRACE(ddraw
, "Enumerating Xlib interface\n");
141 if (!ddenumproc(&XLIB_DirectDraw_GUID
,"WINE with Xlib","display",data
))
144 TRACE(ddraw
, "Enumerating Default interface\n");
145 if (!ddenumproc(NULL
,"WINE (default)","display",data
))
152 DirectDrawEnumerateExA(LPDDENUMCALLBACKEXA ddenumproc
,LPVOID data
, DWORD dwFlags
) {
153 TRACE(ddraw
, "(%p,%p, %08lx)\n", ddenumproc
, data
, dwFlags
);
155 if (TRACE_ON(ddraw
)) {
157 if (dwFlags
& DDENUM_ATTACHEDSECONDARYDEVICES
)
158 DUMP("DDENUM_ATTACHEDSECONDARYDEVICES ");
159 if (dwFlags
& DDENUM_DETACHEDSECONDARYDEVICES
)
160 DUMP("DDENUM_DETACHEDSECONDARYDEVICES ");
161 if (dwFlags
& DDENUM_NONDISPLAYDEVICES
)
162 DUMP("DDENUM_NONDISPLAYDEVICES ");
166 if (dwFlags
& DDENUM_NONDISPLAYDEVICES
) {
167 /* For the moment, Wine does not support any 3D only accelerators */
171 if (DDRAW_DGA_Available()) {
172 TRACE(ddraw
, "Enumerating DGA interface\n");
173 if (!ddenumproc(&DGA_DirectDraw_GUID
,"WINE with XFree86 DGA","display",data
, NULL
))
177 TRACE(ddraw
, "Enumerating Xlib interface\n");
178 if (!ddenumproc(&XLIB_DirectDraw_GUID
,"WINE with Xlib","display",data
, NULL
))
181 TRACE(ddraw
, "Enumerating Default interface\n");
182 if (!ddenumproc(NULL
,"WINE (default)","display",data
, NULL
))
188 /* What is this doing here? */
190 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
191 FIXME(ddraw
,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
196 /******************************************************************************
197 * internal helper functions
199 static void _dump_DDBLTFX(DWORD flagmask
) {
205 #define FE(x) { x, #x},
206 FE(DDBLTFX_ARITHSTRETCHY
)
207 FE(DDBLTFX_MIRRORLEFTRIGHT
)
208 FE(DDBLTFX_MIRRORUPDOWN
)
209 FE(DDBLTFX_NOTEARING
)
210 FE(DDBLTFX_ROTATE180
)
211 FE(DDBLTFX_ROTATE270
)
213 FE(DDBLTFX_ZBUFFERRANGE
)
214 FE(DDBLTFX_ZBUFFERBASEDEST
)
216 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
217 if (flags
[i
].mask
& flagmask
) {
218 DUMP("%s ",flags
[i
].name
);
225 static void _dump_DDBLTFAST(DWORD flagmask
) {
231 #define FE(x) { x, #x},
232 FE(DDBLTFAST_NOCOLORKEY
)
233 FE(DDBLTFAST_SRCCOLORKEY
)
234 FE(DDBLTFAST_DESTCOLORKEY
)
237 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
238 if (flags
[i
].mask
& flagmask
)
239 DUMP("%s ",flags
[i
].name
);
243 static void _dump_DDBLT(DWORD flagmask
) {
249 #define FE(x) { x, #x},
251 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
252 FE(DDBLT_ALPHADESTNEG
)
253 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
254 FE(DDBLT_ALPHAEDGEBLEND
)
256 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
257 FE(DDBLT_ALPHASRCNEG
)
258 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
264 FE(DDBLT_KEYDESTOVERRIDE
)
266 FE(DDBLT_KEYSRCOVERRIDE
)
268 FE(DDBLT_ROTATIONANGLE
)
270 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
271 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
272 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
273 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
277 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
278 if (flags
[i
].mask
& flagmask
)
279 DUMP("%s ",flags
[i
].name
);
283 static void _dump_DDSCAPS(DWORD flagmask
) {
289 #define FE(x) { x, #x},
290 FE(DDSCAPS_RESERVED1
)
292 FE(DDSCAPS_BACKBUFFER
)
295 FE(DDSCAPS_FRONTBUFFER
)
296 FE(DDSCAPS_OFFSCREENPLAIN
)
299 FE(DDSCAPS_PRIMARYSURFACE
)
300 FE(DDSCAPS_PRIMARYSURFACELEFT
)
301 FE(DDSCAPS_SYSTEMMEMORY
)
304 FE(DDSCAPS_VIDEOMEMORY
)
306 FE(DDSCAPS_WRITEONLY
)
309 FE(DDSCAPS_LIVEVIDEO
)
313 FE(DDSCAPS_RESERVED2
)
314 FE(DDSCAPS_ALLOCONLOAD
)
315 FE(DDSCAPS_VIDEOPORT
)
316 FE(DDSCAPS_LOCALVIDMEM
)
317 FE(DDSCAPS_NONLOCALVIDMEM
)
318 FE(DDSCAPS_STANDARDVGAMODE
)
319 FE(DDSCAPS_OPTIMIZED
)
321 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
322 if (flags
[i
].mask
& flagmask
)
323 DUMP("%s ",flags
[i
].name
);
327 static void _dump_DDSD(DWORD flagmask
) {
337 FE(DDSD_BACKBUFFERCOUNT
)
338 FE(DDSD_ZBUFFERBITDEPTH
)
339 FE(DDSD_ALPHABITDEPTH
)
341 FE(DDSD_CKDESTOVERLAY
)
343 FE(DDSD_CKSRCOVERLAY
)
350 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
351 if (flags
[i
].mask
& flagmask
)
352 DUMP("%s ",flags
[i
].name
);
356 static void _dump_DDCOLORKEY(DWORD flagmask
) {
362 #define FE(x) { x, #x},
366 FE(DDPF_PALETTEINDEXED4
)
367 FE(DDPF_PALETTEINDEXEDTO8
)
368 FE(DDPF_PALETTEINDEXED8
)
374 FE(DDPF_PALETTEINDEXED1
)
375 FE(DDPF_PALETTEINDEXED2
)
378 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
379 if (flags
[i
].mask
& flagmask
)
380 DUMP("%s ",flags
[i
].name
);
384 static void _dump_paletteformat(DWORD dwFlags
) {
390 #define FE(x) { x, #x},
392 FE(DDPCAPS_8BITENTRIES
)
394 FE(DDPCAPS_INITIALIZE
)
395 FE(DDPCAPS_PRIMARYSURFACE
)
396 FE(DDPCAPS_PRIMARYSURFACELEFT
)
403 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
404 if (flags
[i
].mask
& dwFlags
)
405 DUMP("%s ",flags
[i
].name
);
409 static void _dump_pixelformat(LPDDPIXELFORMAT pf
) {
410 DUMP("Size : %ld\n", pf
->dwSize
);
412 _dump_DDCOLORKEY(pf
->dwFlags
);
413 DUMP("dwFourCC : %ld\n", pf
->dwFourCC
);
414 DUMP("RGB bit count : %ld\n", pf
->x
.dwRGBBitCount
);
415 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
416 pf
->y
.dwRBitMask
, pf
->z
.dwGBitMask
, pf
->xx
.dwBBitMask
, pf
->xy
.dwRGBAlphaBitMask
);
419 /******************************************************************************
420 * IDirectDrawSurface methods
422 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
423 * DDS and DDS2 use those functions. (Function calls did not change (except
424 * using different DirectDrawSurfaceX version), just added flags and functions)
426 static HRESULT WINAPI
IDirectDrawSurface4_Lock(
427 LPDIRECTDRAWSURFACE4
this,LPRECT lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE hnd
429 TRACE(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
430 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
431 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
432 WARN(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
433 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
435 /* First, copy the Surface description */
436 *lpddsd
= this->s
.surface_desc
;
437 TRACE(ddraw
,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
438 lpddsd
->dwHeight
,lpddsd
->dwWidth
,lpddsd
->lPitch
);
440 /* If asked only for a part, change the surface pointer */
442 FIXME(ddraw
," lprect: %dx%d-%dx%d\n",
443 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
445 lpddsd
->y
.lpSurface
= this->s
.surface_desc
.y
.lpSurface
+
446 (lprect
->top
*this->s
.surface_desc
.lPitch
) +
447 (lprect
->left
*(this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8));
449 assert(this->s
.surface_desc
.y
.lpSurface
);
454 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Unlock(
455 LPDIRECTDRAWSURFACE4
this,LPVOID surface
457 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
461 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4
this) {
462 if (this->s
.ddraw
->d
.pixel_convert
!= NULL
)
463 this->s
.ddraw
->d
.pixel_convert(this->s
.surface_desc
.y
.lpSurface
,
464 this->t
.xlib
.image
->data
,
465 this->s
.surface_desc
.dwWidth
,
466 this->s
.surface_desc
.dwHeight
,
467 this->s
.surface_desc
.lPitch
,
471 if (this->s
.ddraw
->e
.xlib
.xshm_active
)
472 TSXShmPutImage(display
,
473 this->s
.ddraw
->d
.drawable
,
474 DefaultGCOfScreen(X11DRV_GetXScreen()),
477 this->t
.xlib
.image
->width
,
478 this->t
.xlib
.image
->height
,
482 TSXPutImage( display
,
483 this->s
.ddraw
->d
.drawable
,
484 DefaultGCOfScreen(X11DRV_GetXScreen()),
487 this->t
.xlib
.image
->width
,
488 this->t
.xlib
.image
->height
);
491 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Unlock(
492 LPDIRECTDRAWSURFACE4
this,LPVOID surface
)
494 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
496 if (!this->s
.ddraw
->d
.paintable
)
499 /* Only redraw the screen when unlocking the buffer that is on screen */
500 if ((this->t
.xlib
.image
!= NULL
) &&
501 (this->s
.surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VISIBLE
)) {
502 Xlib_copy_surface_on_screen(this);
504 if (this->s
.palette
&& this->s
.palette
->cm
)
505 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
511 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Flip(
512 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
514 #ifdef HAVE_LIBXXF86DGA
515 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
517 if (this->s
.backbuffer
)
518 flipto
= this->s
.backbuffer
;
522 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,flipto
->t
.dga
.fb_height
);
524 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
525 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),flipto
->s
.palette
->cm
);
527 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
533 tmp
= this->t
.dga
.fb_height
;
534 this->t
.dga
.fb_height
= flipto
->t
.dga
.fb_height
;
535 flipto
->t
.dga
.fb_height
= tmp
;
537 ptmp
= this->s
.surface_desc
.y
.lpSurface
;
538 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
539 flipto
->s
.surface_desc
.y
.lpSurface
= ptmp
;
542 #else /* defined(HAVE_LIBXXF86DGA) */
544 #endif /* defined(HAVE_LIBXXF86DGA) */
547 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Flip(
548 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
550 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
551 if (!this->s
.ddraw
->d
.paintable
)
555 if (this->s
.backbuffer
)
556 flipto
= this->s
.backbuffer
;
561 Xlib_copy_surface_on_screen(this);
563 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
564 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,flipto
->s
.palette
->cm
);
569 tmp
= this->t
.xlib
.image
;
570 this->t
.xlib
.image
= flipto
->t
.xlib
.image
;
571 flipto
->t
.xlib
.image
= tmp
;
572 surf
= this->s
.surface_desc
.y
.lpSurface
;
573 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
574 flipto
->s
.surface_desc
.y
.lpSurface
= surf
;
580 /* The IDirectDrawSurface4::SetPalette method attaches the specified
581 * DirectDrawPalette object to a surface. The surface uses this palette for all
582 * subsequent operations. The palette change takes place immediately.
584 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_SetPalette(
585 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
588 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
591 if( this->s
.palette
!= NULL
)
592 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
593 this->s
.palette
= pal
;
598 if( !(pal
->cm
) && (this->s
.ddraw
->d
.screen_pixelformat
.x
.dwRGBBitCount
<=8))
600 pal
->cm
= TSXCreateColormap(display
,this->s
.ddraw
->d
.drawable
,
601 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
603 if (!Options
.managed
)
604 TSXInstallColormap(display
,pal
->cm
);
606 for (i
=0;i
<256;i
++) {
609 xc
.red
= pal
->palents
[i
].peRed
<<8;
610 xc
.blue
= pal
->palents
[i
].peBlue
<<8;
611 xc
.green
= pal
->palents
[i
].peGreen
<<8;
612 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
614 TSXStoreColor(display
,pal
->cm
,&xc
);
616 TSXInstallColormap(display
,pal
->cm
);
619 /* According to spec, we are only supposed to
620 * AddRef if this is not the same palette.
622 if( this->s
.palette
!= pal
)
625 pal
->lpvtbl
->fnAddRef( pal
);
626 if( this->s
.palette
!= NULL
)
627 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
628 this->s
.palette
= pal
;
630 /* I think that we need to attach it to all backbuffers...*/
631 if( this->s
.backbuffer
) {
632 if( this->s
.backbuffer
->s
.palette
)
633 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(
634 this->s
.backbuffer
->s
.palette
);
635 this->s
.backbuffer
->s
.palette
= pal
;
637 pal
->lpvtbl
->fnAddRef( pal
);
639 /* Perform the refresh */
640 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
645 static HRESULT WINAPI
DGA_IDirectDrawSurface4_SetPalette(
646 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
648 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
649 #ifdef HAVE_LIBXXF86DGA
650 /* According to spec, we are only supposed to
651 * AddRef if this is not the same palette.
653 if( this->s
.palette
!= pal
)
656 pal
->lpvtbl
->fnAddRef( pal
);
657 if( this->s
.palette
!= NULL
)
658 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
659 this->s
.palette
= pal
;
661 /* I think that we need to attach it to all backbuffers...*/
662 if( this->s
.backbuffer
) {
663 if( this->s
.backbuffer
->s
.palette
)
664 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(this->s
.backbuffer
->s
.palette
);
665 this->s
.backbuffer
->s
.palette
= pal
;
666 if( pal
) pal
->lpvtbl
->fnAddRef( pal
);
668 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->s
.palette
->cm
);
671 #else /* defined(HAVE_LIBXXF86DGA) */
673 #endif /* defined(HAVE_LIBXXF86DGA) */
678 static HRESULT WINAPI
IDirectDrawSurface4_Blt(
679 LPDIRECTDRAWSURFACE4
this,LPRECT rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
682 DDSURFACEDESC ddesc
,sdesc
;
685 TRACE(ddraw
,"(%p)->(%p,%p,%p,%08lx,%p)\n",
686 this,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
689 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,0,0);
690 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,0,0);
692 if (TRACE_ON(ddraw
)) {
693 if (rdst
) TRACE(ddraw
," destrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
694 if (rsrc
) TRACE(ddraw
," srcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
695 TRACE(ddraw
,"\tflags: "); _dump_DDBLT(dwFlags
);
696 if (dwFlags
& DDBLT_DDFX
) {
697 TRACE(ddraw
," blitfx: \n");_dump_DDBLTFX(lpbltfx
->dwDDFX
);
702 memcpy(&xdst
,rdst
,sizeof(xdst
));
705 xdst
.bottom
= ddesc
.dwHeight
;
707 xdst
.right
= ddesc
.dwWidth
;
711 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
715 xsrc
.bottom
= sdesc
.dwHeight
;
717 xsrc
.right
= sdesc
.dwWidth
;
719 memset(&xsrc
,0,sizeof(xsrc
));
723 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
725 /* First, all the 'source-less' blits */
726 if (dwFlags
& DDBLT_COLORFILL
) {
727 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
730 xline
= (LPBYTE
) ddesc
.y
.lpSurface
+ xdst
.top
* ddesc
.lPitch
;
731 for (i
=xdst
.top
;i
<xdst
.bottom
;i
++) {
732 xpixel
= xline
+bpp
*xdst
.left
;
734 for (j
=xdst
.left
;j
<xdst
.right
;j
++) {
735 /* FIXME: this only works on little endian
736 * architectures, where DWORD starts with low
739 memcpy(xpixel
,&(lpbltfx
->b
.dwFillColor
),bpp
);
742 xline
+= ddesc
.lPitch
;
744 dwFlags
&= ~(DDBLT_COLORFILL
);
747 if (dwFlags
& DDBLT_DEPTHFILL
) {
751 /* Clears the screen */
752 TRACE(ddraw
, " Filling depth buffer with %ld\n", lpbltfx
->b
.dwFillDepth
);
753 glClearDepth(lpbltfx
->b
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
754 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
755 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
756 glClear(GL_DEPTH_BUFFER_BIT
);
759 dwFlags
&= ~(DDBLT_DEPTHFILL
);
765 TRACE(ddraw
,"\t(src=NULL):Unsupported flags: "); _dump_DDBLT(dwFlags
);
767 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
771 /* Now the 'with source' blits */
773 /* Standard 'full-surface' blit without special effects */
774 if ( (xsrc
.top
==0) && (xsrc
.bottom
==ddesc
.dwHeight
) &&
775 (xsrc
.left
==0) && (xsrc
.right
==ddesc
.dwWidth
) &&
776 (xdst
.top
==0) && (xdst
.bottom
==ddesc
.dwHeight
) &&
777 (xdst
.left
==0) && (xdst
.right
==ddesc
.dwWidth
) &&
780 memcpy(ddesc
.y
.lpSurface
,
782 ddesc
.dwHeight
* ddesc
.lPitch
);
784 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
785 int srcheight
= xsrc
.bottom
- xsrc
.top
;
786 int srcwidth
= xsrc
.right
- xsrc
.left
;
787 int dstheight
= xdst
.bottom
- xdst
.top
;
788 int dstwidth
= xdst
.right
- xdst
.left
;
789 int width
= (xsrc
.right
- xsrc
.left
) * bpp
;
792 /* Sanity check for rectangle sizes */
793 if ((srcheight
!= dstheight
) || (srcwidth
!= dstwidth
)) {
796 /* I think we should do a Blit with 'stretching' here....
797 Tomb Raider II uses this to display the background during the menu selection
798 when the screen resolution is != than 640x480 */
799 TRACE(ddraw
, "Blt with stretching\n");
801 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
803 /* In this case, we cannot do any anti-aliasing */
804 if(dwFlags
& DDBLT_KEYSRC
) {
805 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
806 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
809 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
810 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
812 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
813 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
815 tmp
= sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
817 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
818 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
819 dbuf
[(y
* ddesc
.lPitch
) + x
] = tmp
;
823 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
824 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
826 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
827 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
829 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
830 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
832 dbuf
[(y
* ddesc
.lPitch
) + x
] = sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
837 FIXME(ddraw
, "Not done yet for depth != 8\n");
840 /* Same size => fast blit */
841 if (dwFlags
& DDBLT_KEYSRC
) {
844 unsigned char tmp
,*psrc
,*pdst
;
847 for (h
= 0; h
< srcheight
; h
++) {
848 psrc
=sdesc
.y
.lpSurface
+
849 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
850 pdst
=ddesc
.y
.lpSurface
+
851 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
852 for(i
=0;i
<srcwidth
;i
++) {
854 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
855 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
859 dwFlags
&=~(DDBLT_KEYSRC
);
863 unsigned short tmp
,*psrc
,*pdst
;
866 for (h
= 0; h
< srcheight
; h
++) {
867 psrc
=sdesc
.y
.lpSurface
+
868 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
869 pdst
=ddesc
.y
.lpSurface
+
870 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
871 for(i
=0;i
<srcwidth
;i
++) {
873 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
874 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
878 dwFlags
&=~(DDBLT_KEYSRC
);
882 FIXME(ddraw
, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
885 /* Non-stretching Blt without color keying */
886 for (h
= 0; h
< srcheight
; h
++) {
887 memcpy(ddesc
.y
.lpSurface
+ ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
* bpp
,
888 sdesc
.y
.lpSurface
+ ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
* bpp
,
895 if (dwFlags
&& FIXME_ON(ddraw
)) {
896 FIXME(ddraw
,"\tUnsupported flags: ");_dump_DDBLT(dwFlags
);
899 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
900 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
905 static HRESULT WINAPI
IDirectDrawSurface4_BltFast(
906 LPDIRECTDRAWSURFACE4
this,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT rsrc
,DWORD trans
909 DDSURFACEDESC ddesc
,sdesc
;
911 if (1 || TRACE_ON(ddraw
)) {
912 FIXME(ddraw
,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
913 this,dstx
,dsty
,src
,rsrc
,trans
915 FIXME(ddraw
," trans:");
917 _dump_DDBLTFAST(trans
);
918 FIXME(ddraw
," srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
920 /* We need to lock the surfaces, or we won't get refreshes when done. */
921 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
922 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
923 bpp
= this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
924 h
=rsrc
->bottom
-rsrc
->top
;
925 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
926 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
928 w
=rsrc
->right
-rsrc
->left
;
929 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
930 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
934 memcpy( ddesc
.y
.lpSurface
+(dsty
+i
)*ddesc
.lPitch
+dstx
*bpp
,
935 sdesc
.y
.lpSurface
+(rsrc
->top
+i
)*sdesc
.lPitch
+rsrc
->left
*bpp
,
939 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
940 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
944 static HRESULT WINAPI
IDirectDrawSurface4_BltBatch(
945 LPDIRECTDRAWSURFACE4
this,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
947 FIXME(ddraw
,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
953 static HRESULT WINAPI
IDirectDrawSurface4_GetCaps(
954 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS caps
956 TRACE(ddraw
,"(%p)->GetCaps(%p)\n",this,caps
);
957 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
961 static HRESULT WINAPI
IDirectDrawSurface4_GetSurfaceDesc(
962 LPDIRECTDRAWSURFACE4
this,LPDDSURFACEDESC ddsd
964 TRACE(ddraw
, "(%p)->GetSurfaceDesc(%p)\n",
967 /* Simply copy the surface description stored in the object */
968 *ddsd
= this->s
.surface_desc
;
970 if (TRACE_ON(ddraw
)) {
972 _dump_DDSD(ddsd
->dwFlags
);
973 if (ddsd
->dwFlags
& DDSD_CAPS
) {
975 _dump_DDSCAPS(ddsd
->ddsCaps
.dwCaps
);
977 if (ddsd
->dwFlags
& DDSD_PIXELFORMAT
) {
978 DUMP(" pixel format : \n");
979 _dump_pixelformat(&(ddsd
->ddpfPixelFormat
));
986 static ULONG WINAPI
IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4
this) {
987 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
989 return ++(this->ref
);
992 static ULONG WINAPI
DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
993 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
995 #ifdef HAVE_LIBXXF86DGA
996 if (!--(this->ref
)) {
997 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
998 /* clear out of surface list */
999 if (this->t
.dga
.fb_height
== -1) {
1000 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1002 this->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(this->t
.dga
.fb_height
/this->s
.ddraw
->e
.dga
.fb_height
));
1005 /* Free the backbuffer */
1006 if (this->s
.backbuffer
)
1007 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1009 HeapFree(GetProcessHeap(),0,this);
1012 #endif /* defined(HAVE_LIBXXF86DGA) */
1016 static ULONG WINAPI
Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
1017 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1019 if (!--(this->ref
)) {
1020 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
1022 if( this->s
.backbuffer
)
1023 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1025 if (this->t
.xlib
.image
!= NULL
) {
1026 if (this->s
.ddraw
->d
.pixel_convert
!= NULL
) {
1027 /* In pixel conversion mode, there are two buffers to release... */
1028 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1030 #ifdef HAVE_LIBXXSHM
1031 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1032 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1033 TSXDestroyImage(this->t
.xlib
.image
);
1034 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1037 HeapFree(GetProcessHeap(),0,this->t
.xlib
.image
->data
);
1038 this->t
.xlib
.image
->data
= NULL
;
1039 TSXDestroyImage(this->t
.xlib
.image
);
1040 #ifdef HAVE_LIBXXSHM
1045 this->t
.xlib
.image
->data
= NULL
;
1047 #ifdef HAVE_LIBXXSHM
1048 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1049 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1050 TSXDestroyImage(this->t
.xlib
.image
);
1051 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1054 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1055 TSXDestroyImage(this->t
.xlib
.image
);
1056 #ifdef HAVE_LIBXXSHM
1061 this->t
.xlib
.image
= 0;
1063 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1066 if (this->s
.palette
)
1067 this->s
.palette
->lpvtbl
->fnRelease(this->s
.palette
);
1069 HeapFree(GetProcessHeap(),0,this);
1076 static HRESULT WINAPI
IDirectDrawSurface4_GetAttachedSurface(
1077 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1079 TRACE(ddraw
, "(%p)->GetAttachedSurface(%p,%p)\n",
1080 this, lpddsd
, lpdsf
);
1082 if (TRACE_ON(ddraw
)) {
1083 TRACE(ddraw
," caps ");
1084 _dump_DDSCAPS(lpddsd
->dwCaps
);
1087 if (!(lpddsd
->dwCaps
& DDSCAPS_BACKBUFFER
)) {
1088 FIXME(ddraw
,"whoops, can only handle backbuffers for now\n");
1092 /* FIXME: should handle more than one backbuffer */
1093 *lpdsf
= this->s
.backbuffer
;
1095 if( this->s
.backbuffer
)
1096 this->s
.backbuffer
->lpvtbl
->fnAddRef( this->s
.backbuffer
);
1101 static HRESULT WINAPI
IDirectDrawSurface4_Initialize(
1102 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1104 TRACE(ddraw
,"(%p)->(%p, %p)\n",this,ddraw
,lpdsfd
);
1106 return DDERR_ALREADYINITIALIZED
;
1109 static HRESULT WINAPI
IDirectDrawSurface4_GetPixelFormat(
1110 LPDIRECTDRAWSURFACE4
this,LPDDPIXELFORMAT pf
1112 TRACE(ddraw
,"(%p)->(%p)\n",this,pf
);
1114 *pf
= this->s
.surface_desc
.ddpfPixelFormat
;
1119 static HRESULT WINAPI
IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4
this,DWORD dwFlags
) {
1120 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,dwFlags
);
1124 static HRESULT WINAPI
IDirectDrawSurface4_GetOverlayPosition(
1125 LPDIRECTDRAWSURFACE4
this,LPLONG x1
,LPLONG x2
1127 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,x1
,x2
);
1131 static HRESULT WINAPI
IDirectDrawSurface4_SetClipper(
1132 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWCLIPPER clipper
1134 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,clipper
);
1138 static HRESULT WINAPI
IDirectDrawSurface4_AddAttachedSurface(
1139 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 surf
1141 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,surf
);
1143 this->lpvtbl
->fnAddRef(this);
1145 /* This hack will be enough for the moment */
1146 if (this->s
.backbuffer
== NULL
)
1147 this->s
.backbuffer
= surf
;
1151 static HRESULT WINAPI
IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4
this,HDC
* lphdc
) {
1152 FIXME(ddraw
,"(%p)->GetDC(%p)\n",this,lphdc
);
1153 *lphdc
= BeginPaint(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1157 static HRESULT WINAPI
IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4
this,HDC hdc
) {
1161 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,(long)hdc
);
1162 EndPaint(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1164 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1165 I fill it with 'dummy' values to have something on the screen */
1166 this->lpvtbl
->fnLock(this,NULL
,&desc
,0,0);
1167 for (y
= 0; y
< desc
.dwHeight
; y
++) {
1168 for (x
= 0; x
< desc
.dwWidth
; x
++) {
1169 ((unsigned char *) desc
.y
.lpSurface
)[x
+ y
* desc
.dwWidth
] = (unsigned int) this + x
+ y
;
1172 this->lpvtbl
->fnUnlock(this,NULL
);
1178 static HRESULT WINAPI
IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4
this,REFIID refiid
,LPVOID
*obj
) {
1181 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1182 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1184 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1185 * the same interface. And IUnknown does that too of course.
1187 if ( !memcmp(&IID_IDirectDrawSurface4
,refiid
,sizeof(IID
)) ||
1188 !memcmp(&IID_IDirectDrawSurface3
,refiid
,sizeof(IID
)) ||
1189 !memcmp(&IID_IDirectDrawSurface2
,refiid
,sizeof(IID
)) ||
1190 !memcmp(&IID_IDirectDrawSurface
,refiid
,sizeof(IID
)) ||
1191 !memcmp(&IID_IUnknown
,refiid
,sizeof(IID
))
1194 this->lpvtbl
->fnAddRef(this);
1196 TRACE(ddraw
, " Creating IDirectDrawSurface interface (%p)\n", *obj
);
1200 else if (!memcmp(&IID_IDirect3DTexture2
,refiid
,sizeof(IID
)))
1202 /* Texture interface */
1203 *obj
= d3dtexture2_create(this);
1204 this->lpvtbl
->fnAddRef(this);
1206 TRACE(ddraw
, " Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1210 else if (!memcmp(&IID_IDirect3DTexture
,refiid
,sizeof(IID
)))
1212 /* Texture interface */
1213 *obj
= d3dtexture_create(this);
1214 this->lpvtbl
->fnAddRef(this);
1216 TRACE(ddraw
, " Creating IDirect3DTexture interface (%p)\n", *obj
);
1220 else if (is_OpenGL_dx3(refiid
, (LPDIRECTDRAWSURFACE
) this, (LPDIRECT3DDEVICE
*) obj
))
1222 /* It is the OpenGL Direct3D Device */
1223 this->lpvtbl
->fnAddRef(this);
1225 TRACE(ddraw
, " Creating IDirect3DDevice interface (%p)\n", *obj
);
1230 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1231 return OLE_E_ENUM_NOMORE
;
1234 static HRESULT WINAPI
IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4
this) {
1235 TRACE(ddraw
,"(%p)->(), stub!\n",this);
1236 return DD_OK
; /* hmm */
1239 static HRESULT WINAPI
IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4
this,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1240 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,context
,esfcb
);
1244 static HRESULT WINAPI
IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4
this) {
1245 FIXME(ddraw
,"(%p)->(),stub!\n",this);
1249 static HRESULT WINAPI
IDirectDrawSurface4_SetColorKey(
1250 LPDIRECTDRAWSURFACE4
this, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1252 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n",this,dwFlags
,ckey
);
1254 if( dwFlags
& DDCKEY_SRCBLT
)
1256 dwFlags
&= ~DDCKEY_SRCBLT
;
1257 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1258 memcpy( &(this->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1261 if( dwFlags
& DDCKEY_DESTBLT
)
1263 dwFlags
&= ~DDCKEY_DESTBLT
;
1264 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1265 memcpy( &(this->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1268 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1270 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1271 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1272 memcpy( &(this->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1275 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1277 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1278 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1279 memcpy( &(this->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1284 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1291 static HRESULT WINAPI
IDirectDrawSurface4_AddOverlayDirtyRect(
1292 LPDIRECTDRAWSURFACE4
this,
1295 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpRect
);
1300 static HRESULT WINAPI
IDirectDrawSurface4_DeleteAttachedSurface(
1301 LPDIRECTDRAWSURFACE4
this,
1303 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
1305 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags
,lpDDSAttachedSurface
);
1310 static HRESULT WINAPI
IDirectDrawSurface4_EnumOverlayZOrders(
1311 LPDIRECTDRAWSURFACE4
this,
1314 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1316 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags
,
1317 lpContext
, lpfnCallback
);
1322 static HRESULT WINAPI
IDirectDrawSurface4_GetClipper(
1323 LPDIRECTDRAWSURFACE4
this,
1324 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1326 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDClipper
);
1331 static HRESULT WINAPI
IDirectDrawSurface4_GetColorKey(
1332 LPDIRECTDRAWSURFACE4
this,
1334 LPDDCOLORKEY lpDDColorKey
)
1336 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n", this, dwFlags
, lpDDColorKey
);
1338 if( dwFlags
& DDCKEY_SRCBLT
) {
1339 dwFlags
&= ~DDCKEY_SRCBLT
;
1340 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
1343 if( dwFlags
& DDCKEY_DESTBLT
)
1345 dwFlags
&= ~DDCKEY_DESTBLT
;
1346 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
1349 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1351 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1352 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
1355 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1357 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1358 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
1363 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1369 static HRESULT WINAPI
IDirectDrawSurface4_GetFlipStatus(
1370 LPDIRECTDRAWSURFACE4
this,
1373 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1378 static HRESULT WINAPI
IDirectDrawSurface4_GetPalette(
1379 LPDIRECTDRAWSURFACE4
this,
1380 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1382 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDPalette
);
1387 static HRESULT WINAPI
IDirectDrawSurface4_SetOverlayPosition(
1388 LPDIRECTDRAWSURFACE4
this,
1392 FIXME(ddraw
,"(%p)->(%ld,%ld),stub!\n", this, lX
, lY
);
1397 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlay(
1398 LPDIRECTDRAWSURFACE4
this,
1400 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
1403 LPDDOVERLAYFX lpDDOverlayFx
)
1405 FIXME(ddraw
,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1406 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1411 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayDisplay(
1412 LPDIRECTDRAWSURFACE4
this,
1415 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1420 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayZOrder(
1421 LPDIRECTDRAWSURFACE4
this,
1423 LPDIRECTDRAWSURFACE4 lpDDSReference
)
1425 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags
, lpDDSReference
);
1430 static HRESULT WINAPI
IDirectDrawSurface4_GetDDInterface(
1431 LPDIRECTDRAWSURFACE4
this,
1434 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDD
);
1436 /* Not sure about that... */
1437 *lplpDD
= (void *) this->s
.ddraw
;
1442 static HRESULT WINAPI
IDirectDrawSurface4_PageLock(
1443 LPDIRECTDRAWSURFACE4
this,
1446 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1451 static HRESULT WINAPI
IDirectDrawSurface4_PageUnlock(
1452 LPDIRECTDRAWSURFACE4
this,
1455 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1460 static HRESULT WINAPI
IDirectDrawSurface4_SetSurfaceDesc(
1461 LPDIRECTDRAWSURFACE4
this,
1462 LPDDSURFACEDESC lpDDSD
,
1465 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD
, dwFlags
);
1470 static HRESULT WINAPI
IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4
this,
1475 FIXME(ddraw
, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag
, lpData
, cbSize
, dwFlags
);
1480 static HRESULT WINAPI
IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4
this,
1483 LPDWORD lpcbBufferSize
) {
1484 FIXME(ddraw
, "(%p)->(%p,%p,%p)\n", this, guidTag
, lpBuffer
, lpcbBufferSize
);
1489 static HRESULT WINAPI
IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4
this,
1491 FIXME(ddraw
, "(%p)->(%p)\n", this, guidTag
);
1496 static HRESULT WINAPI
IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4
this,
1498 FIXME(ddraw
, "(%p)->(%p)\n", this, lpValue
);
1503 static HRESULT WINAPI
IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4
this) {
1504 FIXME(ddraw
, "(%p)\n", this);
1509 static struct IDirectDrawSurface4_VTable dga_dds4vt
= {
1510 IDirectDrawSurface4_QueryInterface
,
1511 IDirectDrawSurface4_AddRef
,
1512 DGA_IDirectDrawSurface4_Release
,
1513 IDirectDrawSurface4_AddAttachedSurface
,
1514 IDirectDrawSurface4_AddOverlayDirtyRect
,
1515 IDirectDrawSurface4_Blt
,
1516 IDirectDrawSurface4_BltBatch
,
1517 IDirectDrawSurface4_BltFast
,
1518 IDirectDrawSurface4_DeleteAttachedSurface
,
1519 IDirectDrawSurface4_EnumAttachedSurfaces
,
1520 IDirectDrawSurface4_EnumOverlayZOrders
,
1521 DGA_IDirectDrawSurface4_Flip
,
1522 IDirectDrawSurface4_GetAttachedSurface
,
1523 IDirectDrawSurface4_GetBltStatus
,
1524 IDirectDrawSurface4_GetCaps
,
1525 IDirectDrawSurface4_GetClipper
,
1526 IDirectDrawSurface4_GetColorKey
,
1527 IDirectDrawSurface4_GetDC
,
1528 IDirectDrawSurface4_GetFlipStatus
,
1529 IDirectDrawSurface4_GetOverlayPosition
,
1530 IDirectDrawSurface4_GetPalette
,
1531 IDirectDrawSurface4_GetPixelFormat
,
1532 IDirectDrawSurface4_GetSurfaceDesc
,
1533 IDirectDrawSurface4_Initialize
,
1534 IDirectDrawSurface4_IsLost
,
1535 IDirectDrawSurface4_Lock
,
1536 IDirectDrawSurface4_ReleaseDC
,
1537 IDirectDrawSurface4_Restore
,
1538 IDirectDrawSurface4_SetClipper
,
1539 IDirectDrawSurface4_SetColorKey
,
1540 IDirectDrawSurface4_SetOverlayPosition
,
1541 DGA_IDirectDrawSurface4_SetPalette
,
1542 DGA_IDirectDrawSurface4_Unlock
,
1543 IDirectDrawSurface4_UpdateOverlay
,
1544 IDirectDrawSurface4_UpdateOverlayDisplay
,
1545 IDirectDrawSurface4_UpdateOverlayZOrder
,
1546 IDirectDrawSurface4_GetDDInterface
,
1547 IDirectDrawSurface4_PageLock
,
1548 IDirectDrawSurface4_PageUnlock
,
1549 IDirectDrawSurface4_SetSurfaceDesc
,
1550 IDirectDrawSurface4_SetPrivateData
,
1551 IDirectDrawSurface4_GetPrivateData
,
1552 IDirectDrawSurface4_FreePrivateData
,
1553 IDirectDrawSurface4_GetUniquenessValue
,
1554 IDirectDrawSurface4_ChangeUniquenessValue
1557 static struct IDirectDrawSurface4_VTable xlib_dds4vt
= {
1558 IDirectDrawSurface4_QueryInterface
,
1559 IDirectDrawSurface4_AddRef
,
1560 Xlib_IDirectDrawSurface4_Release
,
1561 IDirectDrawSurface4_AddAttachedSurface
,
1562 IDirectDrawSurface4_AddOverlayDirtyRect
,
1563 IDirectDrawSurface4_Blt
,
1564 IDirectDrawSurface4_BltBatch
,
1565 IDirectDrawSurface4_BltFast
,
1566 IDirectDrawSurface4_DeleteAttachedSurface
,
1567 IDirectDrawSurface4_EnumAttachedSurfaces
,
1568 IDirectDrawSurface4_EnumOverlayZOrders
,
1569 Xlib_IDirectDrawSurface4_Flip
,
1570 IDirectDrawSurface4_GetAttachedSurface
,
1571 IDirectDrawSurface4_GetBltStatus
,
1572 IDirectDrawSurface4_GetCaps
,
1573 IDirectDrawSurface4_GetClipper
,
1574 IDirectDrawSurface4_GetColorKey
,
1575 IDirectDrawSurface4_GetDC
,
1576 IDirectDrawSurface4_GetFlipStatus
,
1577 IDirectDrawSurface4_GetOverlayPosition
,
1578 IDirectDrawSurface4_GetPalette
,
1579 IDirectDrawSurface4_GetPixelFormat
,
1580 IDirectDrawSurface4_GetSurfaceDesc
,
1581 IDirectDrawSurface4_Initialize
,
1582 IDirectDrawSurface4_IsLost
,
1583 IDirectDrawSurface4_Lock
,
1584 IDirectDrawSurface4_ReleaseDC
,
1585 IDirectDrawSurface4_Restore
,
1586 IDirectDrawSurface4_SetClipper
,
1587 IDirectDrawSurface4_SetColorKey
,
1588 IDirectDrawSurface4_SetOverlayPosition
,
1589 Xlib_IDirectDrawSurface4_SetPalette
,
1590 Xlib_IDirectDrawSurface4_Unlock
,
1591 IDirectDrawSurface4_UpdateOverlay
,
1592 IDirectDrawSurface4_UpdateOverlayDisplay
,
1593 IDirectDrawSurface4_UpdateOverlayZOrder
,
1594 IDirectDrawSurface4_GetDDInterface
,
1595 IDirectDrawSurface4_PageLock
,
1596 IDirectDrawSurface4_PageUnlock
,
1597 IDirectDrawSurface4_SetSurfaceDesc
,
1598 IDirectDrawSurface4_SetPrivateData
,
1599 IDirectDrawSurface4_GetPrivateData
,
1600 IDirectDrawSurface4_FreePrivateData
,
1601 IDirectDrawSurface4_GetUniquenessValue
,
1602 IDirectDrawSurface4_ChangeUniquenessValue
1605 /******************************************************************************
1606 * DirectDrawCreateClipper (DDRAW.7)
1608 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
1609 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
1610 LPUNKNOWN pUnkOuter
)
1612 TRACE(ddraw
, "(%08lx,%p,%p)\n", dwFlags
, lplpDDClipper
, pUnkOuter
);
1614 *lplpDDClipper
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
1615 (*lplpDDClipper
)->lpvtbl
= &ddclipvt
;
1616 (*lplpDDClipper
)->ref
= 1;
1621 /******************************************************************************
1622 * IDirectDrawClipper
1624 static HRESULT WINAPI
IDirectDrawClipper_SetHwnd(
1625 LPDIRECTDRAWCLIPPER
this,DWORD x
,HWND hwnd
1627 FIXME(ddraw
,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x
,(DWORD
)hwnd
);
1631 static ULONG WINAPI
IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER
this) {
1632 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1637 HeapFree(GetProcessHeap(),0,this);
1641 static HRESULT WINAPI
IDirectDrawClipper_GetClipList(
1642 LPDIRECTDRAWCLIPPER
this,LPRECT rects
,LPRGNDATA lprgn
,LPDWORD hmm
1644 FIXME(ddraw
,"(%p,%p,%p,%p),stub!\n",this,rects
,lprgn
,hmm
);
1649 static HRESULT WINAPI
IDirectDrawClipper_SetClipList(
1650 LPDIRECTDRAWCLIPPER
this,LPRGNDATA lprgn
,DWORD hmm
1652 FIXME(ddraw
,"(%p,%p,%ld),stub!\n",this,lprgn
,hmm
);
1656 static HRESULT WINAPI
IDirectDrawClipper_QueryInterface(
1657 LPDIRECTDRAWCLIPPER
this,
1661 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,riid
,ppvObj
);
1662 return OLE_E_ENUM_NOMORE
;
1665 static ULONG WINAPI
IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER
this )
1667 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1668 return ++(this->ref
);
1671 static HRESULT WINAPI
IDirectDrawClipper_GetHWnd(
1672 LPDIRECTDRAWCLIPPER
this,
1675 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,HWndPtr
);
1679 static HRESULT WINAPI
IDirectDrawClipper_Initialize(
1680 LPDIRECTDRAWCLIPPER
this,
1684 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD
,dwFlags
);
1688 static HRESULT WINAPI
IDirectDrawClipper_IsClipListChanged(
1689 LPDIRECTDRAWCLIPPER
this,
1692 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpbChanged
);
1696 static struct IDirectDrawClipper_VTable ddclipvt
= {
1697 IDirectDrawClipper_QueryInterface
,
1698 IDirectDrawClipper_AddRef
,
1699 IDirectDrawClipper_Release
,
1700 IDirectDrawClipper_GetClipList
,
1701 IDirectDrawClipper_GetHWnd
,
1702 IDirectDrawClipper_Initialize
,
1703 IDirectDrawClipper_IsClipListChanged
,
1704 IDirectDrawClipper_SetClipList
,
1705 IDirectDrawClipper_SetHwnd
1709 /******************************************************************************
1710 * IDirectDrawPalette
1712 static HRESULT WINAPI
IDirectDrawPalette_GetEntries(
1713 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1717 TRACE(ddraw
,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1718 this,x
,start
,count
,palent
);
1720 if (!this->cm
) /* should not happen */ {
1721 FIXME(ddraw
,"app tried to read colormap for non-palettized mode\n");
1722 return DDERR_GENERIC
;
1724 for (i
=0;i
<count
;i
++) {
1725 palent
[i
].peRed
= this->palents
[start
+i
].peRed
;
1726 palent
[i
].peBlue
= this->palents
[start
+i
].peBlue
;
1727 palent
[i
].peGreen
= this->palents
[start
+i
].peGreen
;
1728 palent
[i
].peFlags
= this->palents
[start
+i
].peFlags
;
1734 static HRESULT WINAPI
Xlib_IDirectDrawPalette_SetEntries(
1735 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1740 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1741 this,x
,start
,count
,palent
1743 for (i
=0;i
<count
;i
++) {
1744 xc
.red
= palent
[i
].peRed
<<8;
1745 xc
.blue
= palent
[i
].peBlue
<<8;
1746 xc
.green
= palent
[i
].peGreen
<<8;
1747 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1751 TSXStoreColor(display
,this->cm
,&xc
);
1753 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1754 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1755 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1756 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1759 /* Now, if we are in 'depth conversion mode', update the screen palette */
1760 if (this->ddraw
->d
.palette_convert
!= NULL
)
1761 this->ddraw
->d
.palette_convert(palent
, this->screen_palents
, start
, count
);
1766 static HRESULT WINAPI
DGA_IDirectDrawPalette_SetEntries(
1767 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1769 #ifdef HAVE_LIBXXF86DGA
1774 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1775 this,x
,start
,count
,palent
1777 if (!this->cm
) /* should not happen */ {
1778 FIXME(ddraw
,"app tried to set colormap in non-palettized mode\n");
1779 return DDERR_GENERIC
;
1781 /* FIXME: free colorcells instead of freeing whole map */
1783 this->cm
= TSXCopyColormapAndFree(display
,this->cm
);
1784 TSXFreeColormap(display
,cm
);
1786 for (i
=0;i
<count
;i
++) {
1787 xc
.red
= palent
[i
].peRed
<<8;
1788 xc
.blue
= palent
[i
].peBlue
<<8;
1789 xc
.green
= palent
[i
].peGreen
<<8;
1790 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1793 TSXStoreColor(display
,this->cm
,&xc
);
1795 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1796 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1797 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1798 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1800 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->cm
);
1802 #else /* defined(HAVE_LIBXXF86DGA) */
1803 return E_UNEXPECTED
;
1804 #endif /* defined(HAVE_LIBXXF86DGA) */
1807 static ULONG WINAPI
IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE
this) {
1808 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1809 if (!--(this->ref
)) {
1811 TSXFreeColormap(display
,this->cm
);
1814 HeapFree(GetProcessHeap(),0,this);
1820 static ULONG WINAPI
IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE
this) {
1822 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1823 return ++(this->ref
);
1826 static HRESULT WINAPI
IDirectDrawPalette_Initialize(
1827 LPDIRECTDRAWPALETTE
this,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
1829 TRACE(ddraw
,"(%p)->(%p,%ld,%p)\n", this, ddraw
, x
, palent
);
1831 return DDERR_ALREADYINITIALIZED
;
1834 static HRESULT WINAPI
IDirectDrawPalette_GetCaps(
1835 LPDIRECTDRAWPALETTE
this, LPDWORD lpdwCaps
)
1837 FIXME( ddraw
, "(%p)->(%p) stub.\n", this, lpdwCaps
);
1841 static HRESULT WINAPI
IDirectDrawPalette_QueryInterface(
1842 LPDIRECTDRAWPALETTE
this,REFIID refiid
,LPVOID
*obj
)
1846 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1847 FIXME(ddraw
,"(%p)->(%s,%p) stub.\n",this,xrefiid
,obj
);
1852 static struct IDirectDrawPalette_VTable dga_ddpalvt
= {
1853 IDirectDrawPalette_QueryInterface
,
1854 IDirectDrawPalette_AddRef
,
1855 IDirectDrawPalette_Release
,
1856 IDirectDrawPalette_GetCaps
,
1857 IDirectDrawPalette_GetEntries
,
1858 IDirectDrawPalette_Initialize
,
1859 DGA_IDirectDrawPalette_SetEntries
1862 static struct IDirectDrawPalette_VTable xlib_ddpalvt
= {
1863 IDirectDrawPalette_QueryInterface
,
1864 IDirectDrawPalette_AddRef
,
1865 IDirectDrawPalette_Release
,
1866 IDirectDrawPalette_GetCaps
,
1867 IDirectDrawPalette_GetEntries
,
1868 IDirectDrawPalette_Initialize
,
1869 Xlib_IDirectDrawPalette_SetEntries
1872 /*******************************************************************************
1875 static HRESULT WINAPI
IDirect3D_QueryInterface(
1876 LPDIRECT3D
this,REFIID refiid
,LPVOID
*obj
1878 /* FIXME: Not sure if this is correct */
1881 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1882 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1883 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
1885 this->lpvtbl
->fnAddRef(this);
1887 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
1891 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
1894 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1896 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1897 this->lpvtbl
->fnAddRef(this);
1898 d3d
->lpvtbl
= &d3dvt
;
1901 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
1905 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
1908 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1910 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1911 this->lpvtbl
->fnAddRef(this);
1912 d3d
->lpvtbl
= &d3d2vt
;
1915 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
1919 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1920 return OLE_E_ENUM_NOMORE
;
1923 static ULONG WINAPI
IDirect3D_AddRef(LPDIRECT3D
this) {
1924 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1926 return ++(this->ref
);
1929 static ULONG WINAPI
IDirect3D_Release(LPDIRECT3D
this)
1931 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1933 if (!--(this->ref
)) {
1934 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
1935 HeapFree(GetProcessHeap(),0,this);
1941 static HRESULT WINAPI
IDirect3D_Initialize(
1942 LPDIRECT3D
this, REFIID refiid
)
1944 /* FIXME: Not sure if this is correct */
1947 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1948 FIXME(ddraw
,"(%p)->(%s):stub.\n",this,xrefiid
);
1950 return DDERR_ALREADYINITIALIZED
;
1953 static HRESULT WINAPI
IDirect3D_EnumDevices(LPDIRECT3D
this,
1954 LPD3DENUMDEVICESCALLBACK cb
,
1956 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
1958 /* Call functions defined in d3ddevices.c */
1959 if (!d3d_OpenGL_dx3(cb
, context
))
1965 static HRESULT WINAPI
IDirect3D_CreateLight(LPDIRECT3D
this,
1966 LPDIRECT3DLIGHT
*lplight
,
1969 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
1971 /* Call the creation function that is located in d3dlight.c */
1972 *lplight
= d3dlight_create_dx3(this);
1977 static HRESULT WINAPI
IDirect3D_CreateMaterial(LPDIRECT3D
this,
1978 LPDIRECT3DMATERIAL
*lpmaterial
,
1981 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
1983 /* Call the creation function that is located in d3dviewport.c */
1984 *lpmaterial
= d3dmaterial_create(this);
1989 static HRESULT WINAPI
IDirect3D_CreateViewport(LPDIRECT3D
this,
1990 LPDIRECT3DVIEWPORT
*lpviewport
,
1993 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
1995 /* Call the creation function that is located in d3dviewport.c */
1996 *lpviewport
= d3dviewport_create(this);
2001 static HRESULT WINAPI
IDirect3D_FindDevice(LPDIRECT3D
this,
2002 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2003 LPD3DFINDDEVICERESULT lpfinddevrst
)
2005 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2010 static struct IDirect3D_VTable d3dvt
= {
2011 IDirect3D_QueryInterface
,
2014 IDirect3D_Initialize
,
2015 IDirect3D_EnumDevices
,
2016 IDirect3D_CreateLight
,
2017 IDirect3D_CreateMaterial
,
2018 IDirect3D_CreateViewport
,
2019 IDirect3D_FindDevice
2022 /*******************************************************************************
2025 static HRESULT WINAPI
IDirect3D2_QueryInterface(
2026 LPDIRECT3D2
this,REFIID refiid
,LPVOID
*obj
) {
2027 /* For the moment, we use the same function as in IDirect3D */
2028 TRACE(ddraw
, "Calling IDirect3D enumerating function.\n");
2030 return IDirect3D_QueryInterface((LPDIRECT3D
) this, refiid
, obj
);
2033 static ULONG WINAPI
IDirect3D2_AddRef(LPDIRECT3D2
this) {
2034 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
2036 return ++(this->ref
);
2039 static ULONG WINAPI
IDirect3D2_Release(LPDIRECT3D2
this) {
2040 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
2042 if (!--(this->ref
)) {
2043 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
2044 HeapFree(GetProcessHeap(),0,this);
2050 static HRESULT WINAPI
IDirect3D2_EnumDevices(
2051 LPDIRECT3D2
this,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2053 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
2055 /* Call functions defined in d3ddevices.c */
2056 if (!d3d_OpenGL(cb
, context
))
2062 static HRESULT WINAPI
IDirect3D2_CreateLight(LPDIRECT3D2
this,
2063 LPDIRECT3DLIGHT
*lplight
,
2066 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
2068 /* Call the creation function that is located in d3dlight.c */
2069 *lplight
= d3dlight_create(this);
2074 static HRESULT WINAPI
IDirect3D2_CreateMaterial(LPDIRECT3D2
this,
2075 LPDIRECT3DMATERIAL2
*lpmaterial
,
2078 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
2080 /* Call the creation function that is located in d3dviewport.c */
2081 *lpmaterial
= d3dmaterial2_create(this);
2086 static HRESULT WINAPI
IDirect3D2_CreateViewport(LPDIRECT3D2
this,
2087 LPDIRECT3DVIEWPORT2
*lpviewport
,
2090 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
2092 /* Call the creation function that is located in d3dviewport.c */
2093 *lpviewport
= d3dviewport2_create(this);
2098 static HRESULT WINAPI
IDirect3D2_FindDevice(LPDIRECT3D2
this,
2099 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2100 LPD3DFINDDEVICERESULT lpfinddevrst
)
2102 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2107 static HRESULT WINAPI
IDirect3D2_CreateDevice(LPDIRECT3D2
this,
2109 LPDIRECTDRAWSURFACE surface
,
2110 LPDIRECT3DDEVICE2
*device
)
2114 WINE_StringFromCLSID(rguid
,xbuf
);
2115 FIXME(ddraw
,"(%p)->(%s,%p,%p): stub\n",this,xbuf
,surface
,device
);
2117 if (is_OpenGL(rguid
, surface
, device
, this)) {
2118 this->lpvtbl
->fnAddRef(this);
2122 return DDERR_INVALIDPARAMS
;
2125 static struct IDirect3D2_VTable d3d2vt
= {
2126 IDirect3D2_QueryInterface
,
2129 IDirect3D2_EnumDevices
,
2130 IDirect3D2_CreateLight
,
2131 IDirect3D2_CreateMaterial
,
2132 IDirect3D2_CreateViewport
,
2133 IDirect3D2_FindDevice
,
2134 IDirect3D2_CreateDevice
2137 /*******************************************************************************
2141 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2142 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2144 static INT ddrawXlibThisOffset
= 0;
2146 static HRESULT
common_off_screen_CreateSurface(LPDIRECTDRAW2
this,
2147 LPDDSURFACEDESC lpddsd
,
2148 LPDIRECTDRAWSURFACE lpdsf
)
2152 /* The surface was already allocated when entering in this function */
2153 TRACE(ddraw
,"using system memory for a surface (%p)\n", lpdsf
);
2155 if (lpddsd
->dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
2156 /* This is a Z Buffer */
2157 TRACE(ddraw
, "Creating Z-Buffer of %ld bit depth\n", lpddsd
->x
.dwZBufferBitDepth
);
2158 bpp
= lpddsd
->x
.dwZBufferBitDepth
/ 8;
2160 /* This is a standard image */
2161 if (!(lpddsd
->dwFlags
& DDSD_PIXELFORMAT
)) {
2162 /* No pixel format => use DirectDraw's format */
2163 lpddsd
->ddpfPixelFormat
= this->d
.directdraw_pixelformat
;
2164 lpddsd
->dwFlags
|= DDSD_PIXELFORMAT
;
2166 /* To check what the program wants */
2167 if (TRACE_ON(ddraw
)) {
2168 _dump_pixelformat(&(lpddsd
->ddpfPixelFormat
));
2172 if (lpddsd
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) {
2175 bpp
= lpddsd
->ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
2179 /* Copy the surface description */
2180 lpdsf
->s
.surface_desc
= *lpddsd
;
2182 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2183 lpdsf
->s
.surface_desc
.y
.lpSurface
= (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpddsd
->dwWidth
* lpddsd
->dwHeight
* bpp
);
2184 lpdsf
->s
.surface_desc
.lPitch
= lpddsd
->dwWidth
* bpp
;
2189 static HRESULT WINAPI
DGA_IDirectDraw2_CreateSurface(
2190 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2192 #ifdef HAVE_LIBXXF86DGA
2195 TRACE(ddraw
, "(%p)->(%p,%p,%p)\n",this,lpddsd
,lpdsf
,lpunk
);
2196 if (TRACE_ON(ddraw
)) {
2197 DUMP(" w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2198 _dump_DDSD(lpddsd
->dwFlags
);
2200 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2203 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2204 this->lpvtbl
->fnAddRef(this);
2207 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&dga_dds4vt
;
2208 (*lpdsf
)->s
.ddraw
= this;
2209 (*lpdsf
)->s
.palette
= NULL
;
2210 (*lpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
2212 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2213 lpddsd
->dwWidth
= this->d
.width
;
2214 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2215 lpddsd
->dwHeight
= this->d
.height
;
2217 /* Check if this a 'primary surface' or not */
2218 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2219 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2221 /* This is THE primary surface => there is DGA-specific code */
2222 /* First, store the surface description */
2223 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2225 /* Find a viewport */
2227 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2229 TRACE(ddraw
,"using viewport %d for a primary surface\n",i
);
2230 /* if i == 32 or maximum ... return error */
2231 this->e
.dga
.vpmask
|=(1<<i
);
2232 (*lpdsf
)->s
.surface_desc
.y
.lpSurface
=
2233 this->e
.dga
.fb_addr
+((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8);
2234 (*lpdsf
)->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2235 (*lpdsf
)->s
.surface_desc
.lPitch
= this->e
.dga
.fb_width
*this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8;
2236 lpddsd
->lPitch
= (*lpdsf
)->s
.surface_desc
.lPitch
;
2238 /* Add flags if there were not present */
2239 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
2240 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2241 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2242 TRACE(ddraw
,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d
.width
,this->d
.height
,lpddsd
->lPitch
);
2243 /* We put our surface always in video memory */
2244 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2245 (*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
= this->d
.directdraw_pixelformat
;
2246 (*lpdsf
)->s
.backbuffer
= NULL
;
2248 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2249 LPDIRECTDRAWSURFACE4 back
;
2251 if (lpddsd
->dwBackBufferCount
>1)
2252 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2254 (*lpdsf
)->s
.backbuffer
= back
=
2255 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2256 this->lpvtbl
->fnAddRef(this);
2258 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&dga_dds4vt
;
2260 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2262 TRACE(ddraw
,"using viewport %d for backbuffer\n",i
);
2263 /* if i == 32 or maximum ... return error */
2264 this->e
.dga
.vpmask
|=(1<<i
);
2265 back
->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2267 /* Copy the surface description from the front buffer */
2268 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2269 /* Change the parameters that are not the same */
2270 back
->s
.surface_desc
.y
.lpSurface
= this->e
.dga
.fb_addr
+
2271 ((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8);
2272 back
->s
.ddraw
= this;
2273 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2276 /* Add relevant info to front and back buffers */
2277 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2278 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2279 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2280 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2281 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2284 /* There is no DGA-specific code here...
2285 Go to the common surface creation function */
2286 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2290 #else /* defined(HAVE_LIBXXF86DGA) */
2291 return E_UNEXPECTED
;
2292 #endif /* defined(HAVE_LIBXXF86DGA) */
2295 #ifdef HAVE_LIBXXSHM
2296 /* Error handlers for Image creation */
2297 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
2302 static XImage
*create_xshmimage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2304 int (*WineXHandler
)(Display
*, XErrorEvent
*);
2306 img
= TSXShmCreateImage(display
,
2307 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2308 this->d
.pixmap_depth
,
2311 &(lpdsf
->t
.xlib
.shminfo
),
2312 lpdsf
->s
.surface_desc
.dwWidth
,
2313 lpdsf
->s
.surface_desc
.dwHeight
);
2316 ERR(ddraw
, "Error creating XShm image. Reverting to standard X images !\n");
2317 this->e
.xlib
.xshm_active
= 0;
2321 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
2322 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
2323 ERR(ddraw
, "Error creating shared memory segment. Reverting to standard X images !\n");
2324 this->e
.xlib
.xshm_active
= 0;
2325 TSXDestroyImage(img
);
2329 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
2331 if (img
->data
== (char *) -1) {
2332 ERR(ddraw
, "Error attaching shared memory segment. Reverting to standard X images !\n");
2333 this->e
.xlib
.xshm_active
= 0;
2334 TSXDestroyImage(img
);
2335 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2338 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
2340 /* This is where things start to get trickier....
2341 First, we flush the current X connections to be sure to catch all non-XShm related
2343 TSXSync(display
, False
);
2344 /* Then we enter in the non-thread safe part of the tests */
2345 EnterCriticalSection( &X11DRV_CritSection
);
2347 /* Reset the error flag, sets our new error handler and try to attach the surface */
2349 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
2350 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
2351 XSync(display
, False
);
2353 /* Check the error flag */
2354 if (XShmErrorFlag
) {
2355 /* An error occured */
2359 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
2360 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2361 XSetErrorHandler(WineXHandler
);
2363 ERR(ddraw
, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2364 this->e
.xlib
.xshm_active
= 0;
2366 /* Leave the critical section */
2367 LeaveCriticalSection( &X11DRV_CritSection
);
2372 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2373 but it may be a bit overkill.... */
2374 XSetErrorHandler(WineXHandler
);
2375 LeaveCriticalSection( &X11DRV_CritSection
);
2377 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2379 if (this->d
.pixel_convert
!= NULL
) {
2380 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2381 lpdsf
->s
.surface_desc
.dwWidth
*
2382 lpdsf
->s
.surface_desc
.dwHeight
*
2383 (this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
));
2385 lpdsf
->s
.surface_desc
.y
.lpSurface
= img
->data
;
2390 #endif /* HAVE_LIBXXSHM */
2392 static XImage
*create_ximage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2396 #ifdef HAVE_LIBXXSHM
2397 if (this->e
.xlib
.xshm_active
) {
2398 img
= create_xshmimage(this, lpdsf
);
2403 /* Allocate surface memory */
2404 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2405 lpdsf
->s
.surface_desc
.dwWidth
*
2406 lpdsf
->s
.surface_desc
.dwHeight
*
2407 (this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/ 8));
2409 if (this->d
.pixel_convert
!= NULL
) {
2410 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2411 lpdsf
->s
.surface_desc
.dwWidth
*
2412 lpdsf
->s
.surface_desc
.dwHeight
*
2413 (this->d
.screen_pixelformat
.x
.dwRGBBitCount
/ 8));
2415 img_data
= lpdsf
->s
.surface_desc
.y
.lpSurface
;
2418 /* In this case, create an XImage */
2420 TSXCreateImage(display
,
2421 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2422 this->d
.pixmap_depth
,
2426 lpdsf
->s
.surface_desc
.dwWidth
,
2427 lpdsf
->s
.surface_desc
.dwHeight
,
2429 lpdsf
->s
.surface_desc
.dwWidth
* (this->d
.screen_pixelformat
.x
.dwRGBBitCount
/ 8)
2432 #ifdef HAVE_LIBXXSHM
2435 if (this->d
.pixel_convert
!= NULL
) {
2436 lpdsf
->s
.surface_desc
.lPitch
= (this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/ 8) * lpdsf
->s
.surface_desc
.dwWidth
;
2438 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
2444 static HRESULT WINAPI
Xlib_IDirectDraw2_CreateSurface(
2445 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2447 TRACE(ddraw
, "(%p)->CreateSurface(%p,%p,%p)\n",
2448 this,lpddsd
,lpdsf
,lpunk
);
2450 if (TRACE_ON(ddraw
)) {
2451 DUMP(" w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2452 _dump_DDSD(lpddsd
->dwFlags
);
2454 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2457 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2459 this->lpvtbl
->fnAddRef(this);
2460 (*lpdsf
)->s
.ddraw
= this;
2462 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&xlib_dds4vt
;
2463 (*lpdsf
)->s
.palette
= NULL
;
2464 (*lpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
2466 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2467 lpddsd
->dwWidth
= this->d
.width
;
2468 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2469 lpddsd
->dwHeight
= this->d
.height
;
2471 /* Check if this a 'primary surface' or not */
2472 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2473 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2476 TRACE(ddraw
,"using standard XImage for a primary surface (%p)\n", *lpdsf
);
2478 /* First, store the surface description */
2479 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2481 /* Create the XImage */
2482 img
= create_ximage(this, (LPDIRECTDRAWSURFACE4
) *lpdsf
);
2484 return DDERR_OUTOFMEMORY
;
2485 (*lpdsf
)->t
.xlib
.image
= img
;
2487 /* Add flags if there were not present */
2488 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
|DDSD_PIXELFORMAT
;
2489 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2490 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2491 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2492 (*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
= this->d
.directdraw_pixelformat
;
2493 (*lpdsf
)->s
.backbuffer
= NULL
;
2495 /* Check for backbuffers */
2496 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2497 LPDIRECTDRAWSURFACE4 back
;
2500 if (lpddsd
->dwBackBufferCount
>1)
2501 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2503 (*lpdsf
)->s
.backbuffer
= back
=
2504 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2506 TRACE(ddraw
,"allocated back-buffer (%p)\n", back
);
2508 this->lpvtbl
->fnAddRef(this);
2509 back
->s
.ddraw
= this;
2512 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&xlib_dds4vt
;
2513 /* Copy the surface description from the front buffer */
2514 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2516 /* Create the XImage */
2517 img
= create_ximage(this, back
);
2519 return DDERR_OUTOFMEMORY
;
2520 back
->t
.xlib
.image
= img
;
2522 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2525 /* Add relevant info to front and back buffers */
2526 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2527 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2528 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2529 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2530 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2533 /* There is no Xlib-specific code here...
2534 Go to the common surface creation function */
2535 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2541 static HRESULT WINAPI
IDirectDraw2_DuplicateSurface(
2542 LPDIRECTDRAW2
this,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
2544 FIXME(ddraw
,"(%p)->(%p,%p) simply copies\n",this,src
,dst
);
2545 *dst
= src
; /* FIXME */
2550 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2551 * even when the approbiate bitmasks are not specified.
2553 static HRESULT WINAPI
IDirectDraw2_SetCooperativeLevel(
2554 LPDIRECTDRAW2
this,HWND hwnd
,DWORD cooplevel
2561 FE(DDSCL_FULLSCREEN
)
2562 FE(DDSCL_ALLOWREBOOT
)
2563 FE(DDSCL_NOWINDOWCHANGES
)
2565 FE(DDSCL_ALLOWMODEX
)
2567 FE(DDSCL_SETFOCUSWINDOW
)
2568 FE(DDSCL_SETDEVICEWINDOW
)
2569 FE(DDSCL_CREATEDEVICEWINDOW
)
2572 FIXME(ddraw
,"(%p)->(%08lx,%08lx)\n",this,(DWORD
)hwnd
,cooplevel
);
2573 if(TRACE_ON(ddraw
)){
2574 dbg_decl_str(ddraw
, 512);
2575 for (i
=0;i
<sizeof(flagmap
)/sizeof(flagmap
[0]);i
++)
2576 if (flagmap
[i
].mask
& cooplevel
)
2577 dsprintf(ddraw
, "%s ", flagmap
[i
].name
);
2578 TRACE(ddraw
," cooperative level %s\n", dbg_str(ddraw
));
2580 this->d
.mainWindow
= hwnd
;
2582 /* This will be overwritten in the case of Full Screen mode.
2583 Windowed games could work with that :-) */
2585 this->d
.drawable
= X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd
));
2590 /* Small helper to either use the cooperative window or create a new
2591 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2593 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW
this) {
2596 /* Do not destroy the application supplied cooperative window */
2597 if (this->d
.window
&& this->d
.window
!= this->d
.mainWindow
) {
2598 DestroyWindow(this->d
.window
);
2601 /* Sanity check cooperative window before assigning it to drawing. */
2602 if ( IsWindow(this->d
.mainWindow
) &&
2603 IsWindowVisible(this->d
.mainWindow
)
2605 GetWindowRect(this->d
.mainWindow
,&rect
);
2606 if (((rect
.right
-rect
.left
) >= this->d
.width
) &&
2607 ((rect
.bottom
-rect
.top
) >= this->d
.height
)
2609 this->d
.window
= this->d
.mainWindow
;
2611 /* ... failed, create new one. */
2612 if (!this->d
.window
) {
2613 this->d
.window
= CreateWindowExA(
2617 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
2626 /*Store THIS with the window. We'll use it in the window procedure*/
2627 SetWindowLongA(this->d
.window
,ddrawXlibThisOffset
,(LONG
)this);
2628 ShowWindow(this->d
.window
,TRUE
);
2629 UpdateWindow(this->d
.window
);
2631 SetFocus(this->d
.window
);
2634 static int _common_depth_to_pixelformat(DWORD depth
, DDPIXELFORMAT
*pixelformat
, DDPIXELFORMAT
*screen_pixelformat
, int *pix_depth
) {
2636 XPixmapFormatValues
*pf
;
2638 int nvisuals
, npixmap
, i
;
2641 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
2642 pf
= XListPixmapFormats(display
, &npixmap
);
2644 for (i
= 0; i
< npixmap
; i
++) {
2645 if (pf
[i
].bits_per_pixel
== depth
) {
2648 for (j
= 0; j
< nvisuals
; j
++) {
2649 if (vi
[j
].depth
== pf
[i
].depth
) {
2650 pixelformat
->dwSize
= sizeof(*pixelformat
);
2652 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
2653 pixelformat
->y
.dwRBitMask
= 0;
2654 pixelformat
->z
.dwGBitMask
= 0;
2655 pixelformat
->xx
.dwBBitMask
= 0;
2657 pixelformat
->dwFlags
= DDPF_RGB
;
2658 pixelformat
->y
.dwRBitMask
= vi
[j
].red_mask
;
2659 pixelformat
->z
.dwGBitMask
= vi
[j
].green_mask
;
2660 pixelformat
->xx
.dwBBitMask
= vi
[j
].blue_mask
;
2662 pixelformat
->dwFourCC
= 0;
2663 pixelformat
->x
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
2664 pixelformat
->xy
.dwRGBAlphaBitMask
= 0;
2666 *screen_pixelformat
= *pixelformat
;
2668 if (pix_depth
!= NULL
)
2669 *pix_depth
= vi
[j
].depth
;
2678 ERR(ddraw
, "No visual corresponding to pixmap format !\n");
2682 if ((match
== 0) && (depth
== 8)) {
2683 pixelformat
->dwSize
= sizeof(*pixelformat
);
2684 pixelformat
->dwFlags
= DDPF_PALETTEINDEXED8
;
2685 pixelformat
->dwFourCC
= 0;
2686 pixelformat
->x
.dwRGBBitCount
= 8;
2687 pixelformat
->y
.dwRBitMask
= 0;
2688 pixelformat
->z
.dwGBitMask
= 0;
2689 pixelformat
->xx
.dwBBitMask
= 0;
2690 pixelformat
->xy
.dwRGBAlphaBitMask
= 0;
2692 /* In that case, find a visual to emulate the 8 bpp format */
2693 for (i
= 0; i
< npixmap
; i
++) {
2694 if (pf
[i
].bits_per_pixel
>= depth
) {
2697 for (j
= 0; j
< nvisuals
; j
++) {
2698 if (vi
[j
].depth
== pf
[i
].depth
) {
2699 screen_pixelformat
->dwSize
= sizeof(*screen_pixelformat
);
2700 screen_pixelformat
->dwFlags
= DDPF_RGB
;
2701 screen_pixelformat
->dwFourCC
= 0;
2702 screen_pixelformat
->x
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
2703 screen_pixelformat
->y
.dwRBitMask
= vi
[j
].red_mask
;
2704 screen_pixelformat
->z
.dwGBitMask
= vi
[j
].green_mask
;
2705 screen_pixelformat
->xx
.dwBBitMask
= vi
[j
].blue_mask
;
2706 screen_pixelformat
->xy
.dwRGBAlphaBitMask
= 0;
2708 if (pix_depth
!= NULL
)
2709 *pix_depth
= vi
[j
].depth
;
2718 ERR(ddraw
, "No visual corresponding to pixmap format !\n");
2729 static HRESULT WINAPI
DGA_IDirectDraw_SetDisplayMode(
2730 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2732 #ifdef HAVE_LIBXXF86DGA
2735 TRACE(ddraw
, "(%p)->(%ld,%ld,%ld)\n", this, width
, height
, depth
);
2737 /* We hope getting the asked for depth */
2738 if (_common_depth_to_pixelformat(depth
, &(this->d
.directdraw_pixelformat
), &(this->d
.screen_pixelformat
), NULL
) != 1) {
2739 /* I.e. no visual found or emulated */
2740 ERR(ddraw
,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
2741 return DDERR_UNSUPPORTEDMODE
;
2744 if (this->d
.width
< width
) {
2745 ERR(ddraw
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,this->d
.width
);
2746 return DDERR_UNSUPPORTEDMODE
;
2748 this->d
.width
= width
;
2749 this->d
.height
= height
;
2751 /* adjust fb_height, so we don't overlap */
2752 if (this->e
.dga
.fb_height
< height
)
2753 this->e
.dga
.fb_height
= height
;
2754 _common_IDirectDraw_SetDisplayMode(this);
2756 #ifdef HAVE_LIBXXF86VM
2758 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
2759 XF86VidModeModeLine mod_tmp
;
2760 /* int dotclock_tmp; */
2762 /* save original video mode and set fullscreen if available*/
2763 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
2764 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
2765 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
2766 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
2767 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
2768 orig_mode
->htotal
= mod_tmp
.htotal
;
2769 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
2770 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
2771 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
2772 orig_mode
->vtotal
= mod_tmp
.vtotal
;
2773 orig_mode
->flags
= mod_tmp
.flags
;
2774 orig_mode
->private = mod_tmp
.private;
2776 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
2777 for (i
=0;i
<mode_count
;i
++)
2779 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
2781 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
2782 *vidmode
= *(all_modes
[i
]);
2785 TSXFree(all_modes
[i
]->private);
2787 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
2791 WARN(ddraw
, "Fullscreen mode not available!\n");
2795 TRACE(ddraw
,"SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
2796 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
2797 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2798 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
2804 /* FIXME: this function OVERWRITES several signal handlers.
2805 * can we save them? and restore them later? In a way that
2806 * it works for the library too?
2808 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
2810 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,this->e
.dga
.fb_height
);
2812 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
2815 #ifdef RESTORE_SIGNALS
2816 SIGNAL_InitHandlers();
2819 #else /* defined(HAVE_LIBXXF86DGA) */
2820 return E_UNEXPECTED
;
2821 #endif /* defined(HAVE_LIBXXF86DGA) */
2824 /* *************************************
2825 16 / 15 bpp to palettized 8 bpp
2826 ************************************* */
2827 static void pixel_convert_16_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, LPDIRECTDRAWPALETTE palette
) {
2828 unsigned char *c_src
= (unsigned char *) src
;
2829 unsigned short *c_dst
= (unsigned short *) dst
;
2832 if (palette
!= NULL
) {
2833 unsigned short *pal
= (unsigned short *) palette
->screen_palents
;
2835 for (y
= 0; y
< height
; y
++) {
2836 for (x
= 0; x
< width
; x
++) {
2837 c_dst
[x
+ y
* width
] = pal
[c_src
[x
+ y
* pitch
]];
2841 WARN(ddraw
, "No palette set...\n");
2842 memset(dst
, 0, width
* height
* 2);
2845 static void palette_convert_16_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
2847 unsigned short *pal
= (unsigned short *) screen_palette
;
2849 for (i
= 0; i
< count
; i
++)
2850 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
2851 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
2852 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
2854 static void palette_convert_15_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
2856 unsigned short *pal
= (unsigned short *) screen_palette
;
2858 for (i
= 0; i
< count
; i
++)
2859 pal
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 7) |
2860 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
2861 ((((unsigned short) palent
[i
].peGreen
) & 0xF8) << 2));
2864 /* *************************************
2865 24 / 32 bpp to palettized 8 bpp
2866 ************************************* */
2867 static void pixel_convert_32_to_8(void *src
, void *dst
, DWORD width
, DWORD height
, LONG pitch
, LPDIRECTDRAWPALETTE palette
) {
2868 unsigned char *c_src
= (unsigned char *) src
;
2869 unsigned int *c_dst
= (unsigned int *) dst
;
2872 if (palette
!= NULL
) {
2873 unsigned int *pal
= (unsigned int *) palette
->screen_palents
;
2875 for (y
= 0; y
< height
; y
++) {
2876 for (x
= 0; x
< width
; x
++) {
2877 c_dst
[x
+ y
* width
] = pal
[c_src
[x
+ y
* pitch
]];
2881 WARN(ddraw
, "No palette set...\n");
2882 memset(dst
, 0, width
* height
* 4);
2885 static void palette_convert_24_to_8(LPPALETTEENTRY palent
, void *screen_palette
, DWORD start
, DWORD count
) {
2887 unsigned int *pal
= (unsigned int *) screen_palette
;
2889 for (i
= 0; i
< count
; i
++)
2890 pal
[start
+ i
] = ((((unsigned int) palent
[i
].peRed
) << 16) |
2891 (((unsigned int) palent
[i
].peGreen
) << 8) |
2892 ((unsigned int) palent
[i
].peBlue
));
2895 static HRESULT WINAPI
Xlib_IDirectDraw_SetDisplayMode(
2896 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2900 TRACE(ddraw
, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2901 this, width
, height
, depth
);
2903 switch (_common_depth_to_pixelformat(depth
,
2904 &(this->d
.directdraw_pixelformat
),
2905 &(this->d
.screen_pixelformat
),
2906 &(this->d
.pixmap_depth
))) {
2908 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
2909 MessageBoxA(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
2910 return DDERR_UNSUPPORTEDMODE
;
2914 this->d
.pixel_convert
= NULL
;
2915 this->d
.palette_convert
= NULL
;
2921 WARN(ddraw
, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
2923 /* Set the depth convertion routines */
2924 switch (this->d
.screen_pixelformat
.x
.dwRGBBitCount
) {
2926 if ((this->d
.screen_pixelformat
.y
.dwRBitMask
== 0xF800) &&
2927 (this->d
.screen_pixelformat
.z
.dwGBitMask
== 0x07E0) &&
2928 (this->d
.screen_pixelformat
.xx
.dwBBitMask
== 0x001F)) {
2932 this->d
.pixel_convert
= pixel_convert_16_to_8
;
2933 this->d
.palette_convert
= palette_convert_16_to_8
;
2934 } else if ((this->d
.screen_pixelformat
.y
.dwRBitMask
== 0x7C00) &&
2935 (this->d
.screen_pixelformat
.z
.dwGBitMask
== 0x03E0) &&
2936 (this->d
.screen_pixelformat
.xx
.dwBBitMask
== 0x001F)) {
2940 this->d
.pixel_convert
= pixel_convert_16_to_8
;
2941 this->d
.palette_convert
= palette_convert_15_to_8
;
2946 /* Not handled yet :/ */
2951 if ((this->d
.screen_pixelformat
.y
.dwRBitMask
== 0xFF0000) &&
2952 (this->d
.screen_pixelformat
.z
.dwGBitMask
== 0x00FF00) &&
2953 (this->d
.screen_pixelformat
.xx
.dwBBitMask
== 0x0000FF)) {
2957 this->d
.pixel_convert
= pixel_convert_32_to_8
;
2958 this->d
.palette_convert
= palette_convert_24_to_8
;
2964 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
2965 MessageBoxA(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
2966 return DDERR_UNSUPPORTEDMODE
;
2971 this->d
.width
= width
;
2972 this->d
.height
= height
;
2974 _common_IDirectDraw_SetDisplayMode(this);
2976 this->d
.paintable
= 1;
2977 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_FindWndPtr(this->d
.window
)->pDriverData
)->window
;
2978 /* We don't have a context for this window. Host off the desktop */
2979 if( !this->d
.drawable
)
2980 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
2984 static HRESULT WINAPI
DGA_IDirectDraw2_GetCaps(
2985 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2987 #ifdef HAVE_LIBXXF86DGA
2988 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2989 caps1
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2990 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2991 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2993 caps2
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2994 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2995 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2998 #else /* defined(HAVE_LIBXXF86DGA) */
2999 return E_UNEXPECTED
;
3000 #endif /* defined(HAVE_LIBXXF86DGA) */
3003 static void fill_caps(LPDDCAPS caps
) {
3004 /* This function tries to fill the capabilities of Wine's DDraw implementation.
3005 Need to be fixed, though.. */
3009 caps
->dwSize
= sizeof(*caps
);
3010 caps
->dwCaps
= DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
|
3011 DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
;
3012 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NOPAGELOCKREQUIRED
| DDCAPS2_WIDESURFACES
;
3013 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
3015 caps
->dwFXAlphaCaps
= 0;
3016 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
3018 caps
->dwZBufferBitDepths
= DDBD_16
;
3019 /* I put here 8 Mo so that D3D applications will believe they have enough memory
3020 to put textures in video memory.
3021 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
3023 caps
->dwVidMemTotal
= 8192 * 1024;
3024 caps
->dwVidMemFree
= 8192 * 1024;
3025 /* These are all the supported capabilities of the surfaces */
3026 caps
->ddsCaps
.dwCaps
= DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
3027 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
3028 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
|
3029 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
;
3031 caps
->dwCaps
|= DDCAPS_3D
| DDCAPS_ZBLTS
;
3032 caps
->dwCaps2
|= DDCAPS2_NO2DDURING3DSCENE
;
3033 caps
->ddsCaps
.dwCaps
|= DDSCAPS_3DDEVICE
| DDSCAPS_MIPMAP
| DDSCAPS_TEXTURE
| DDSCAPS_ZBUFFER
;
3037 static HRESULT WINAPI
Xlib_IDirectDraw2_GetCaps(
3038 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
3040 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
3042 /* Put the same caps for the two capabilities */
3049 static HRESULT WINAPI
IDirectDraw2_CreateClipper(
3050 LPDIRECTDRAW2
this,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
3052 FIXME(ddraw
,"(%p)->(%08lx,%p,%p),stub!\n",
3053 this,x
,lpddclip
,lpunk
3055 *lpddclip
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
3056 (*lpddclip
)->ref
= 1;
3057 (*lpddclip
)->lpvtbl
= &ddclipvt
;
3061 static HRESULT WINAPI
common_IDirectDraw2_CreatePalette(
3062 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
,int *psize
3066 if (TRACE_ON(ddraw
))
3067 _dump_paletteformat(dwFlags
);
3069 *lpddpal
= (LPDIRECTDRAWPALETTE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPalette
));
3070 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
3071 (*lpddpal
)->ref
= 1;
3072 (*lpddpal
)->ddraw
= (LPDIRECTDRAW
)this;
3073 (*lpddpal
)->installed
= 0;
3075 if (dwFlags
& DDPCAPS_1BIT
)
3077 else if (dwFlags
& DDPCAPS_2BIT
)
3079 else if (dwFlags
& DDPCAPS_4BIT
)
3081 else if (dwFlags
& DDPCAPS_8BIT
)
3084 ERR(ddraw
, "unhandled palette format\n");
3089 /* Now, if we are in 'depth conversion mode', create the screen palette */
3090 if (this->d
.palette_convert
!= NULL
)
3091 this->d
.palette_convert(palent
, (*lpddpal
)->screen_palents
, 0, size
);
3093 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
3094 } else if (this->d
.palette_convert
!= NULL
) {
3095 /* In that case, put all 0xFF */
3096 memset((*lpddpal
)->screen_palents
, 0xFF, 256 * sizeof(int));
3102 static HRESULT WINAPI
DGA_IDirectDraw2_CreatePalette(
3103 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3108 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
3109 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
3110 if (res
!= 0) return res
;
3111 (*lpddpal
)->lpvtbl
= &dga_ddpalvt
;
3112 if (this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
<=8) {
3113 (*lpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
3115 FIXME(ddraw
,"why are we doing CreatePalette in hi/truecolor?\n");
3118 if (((*lpddpal
)->cm
)&&xsize
) {
3119 for (i
=0;i
<xsize
;i
++) {
3122 xc
.red
= (*lpddpal
)->palents
[i
].peRed
<<8;
3123 xc
.blue
= (*lpddpal
)->palents
[i
].peBlue
<<8;
3124 xc
.green
= (*lpddpal
)->palents
[i
].peGreen
<<8;
3125 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
3127 TSXStoreColor(display
,(*lpddpal
)->cm
,&xc
);
3133 static HRESULT WINAPI
Xlib_IDirectDraw2_CreatePalette(
3134 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
3139 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
3140 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
3141 if (res
!= 0) return res
;
3142 (*lpddpal
)->lpvtbl
= &xlib_ddpalvt
;
3146 static HRESULT WINAPI
DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3147 #ifdef HAVE_LIBXXF86DGA
3148 TRACE(ddraw
, "(%p)->()\n",this);
3150 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3151 #ifdef RESTORE_SIGNALS
3152 SIGNAL_InitHandlers();
3155 #else /* defined(HAVE_LIBXXF86DGA) */
3156 return E_UNEXPECTED
;
3160 static HRESULT WINAPI
Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3161 TRACE(ddraw
, "(%p)->RestoreDisplayMode()\n", this);
3166 static HRESULT WINAPI
IDirectDraw2_WaitForVerticalBlank(
3167 LPDIRECTDRAW2
this,DWORD x
,HANDLE h
3169 TRACE(ddraw
,"(%p)->(0x%08lx,0x%08x)\n",this,x
,h
);
3173 static ULONG WINAPI
IDirectDraw2_AddRef(LPDIRECTDRAW2
this) {
3174 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
3176 return ++(this->ref
);
3179 static ULONG WINAPI
DGA_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3180 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3182 #ifdef HAVE_LIBXXF86DGA
3183 if (!--(this->ref
)) {
3184 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3185 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3186 DestroyWindow(this->d
.window
);
3187 #ifdef HAVE_LIBXXF86VM
3189 TSXF86VidModeSwitchToMode(
3191 DefaultScreen(display
),
3193 if (orig_mode
->privsize
)
3194 TSXFree(orig_mode
->private);
3200 #ifdef RESTORE_SIGNALS
3201 SIGNAL_InitHandlers();
3203 HeapFree(GetProcessHeap(),0,this);
3206 #endif /* defined(HAVE_LIBXXF86DGA) */
3210 static ULONG WINAPI
Xlib_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3211 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3213 if (!--(this->ref
)) {
3214 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3215 DestroyWindow(this->d
.window
);
3216 HeapFree(GetProcessHeap(),0,this);
3219 /* FIXME: destroy window ... */
3223 static HRESULT WINAPI
DGA_IDirectDraw2_QueryInterface(
3224 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3228 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3229 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3230 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3232 this->lpvtbl
->fnAddRef(this);
3234 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3238 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3239 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_ddvt
;
3240 this->lpvtbl
->fnAddRef(this);
3243 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3247 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3248 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd2vt
;
3249 this->lpvtbl
->fnAddRef(this);
3252 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3256 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3257 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd4vt
;
3258 this->lpvtbl
->fnAddRef(this);
3261 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3265 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3268 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3270 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3271 this->lpvtbl
->fnAddRef(this);
3272 d3d
->lpvtbl
= &d3dvt
;
3275 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3279 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
3282 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3284 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3285 this->lpvtbl
->fnAddRef(this);
3286 d3d
->lpvtbl
= &d3d2vt
;
3289 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3293 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3294 return OLE_E_ENUM_NOMORE
;
3297 static HRESULT WINAPI
Xlib_IDirectDraw2_QueryInterface(
3298 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3302 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3303 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3304 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3306 this->lpvtbl
->fnAddRef(this);
3308 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3312 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3313 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_ddvt
;
3314 this->lpvtbl
->fnAddRef(this);
3317 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3321 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3322 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd2vt
;
3323 this->lpvtbl
->fnAddRef(this);
3326 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3330 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3331 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd4vt
;
3332 this->lpvtbl
->fnAddRef(this);
3335 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3339 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3342 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3344 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3345 this->lpvtbl
->fnAddRef(this);
3346 d3d
->lpvtbl
= &d3dvt
;
3349 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3353 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
3356 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3358 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3359 this->lpvtbl
->fnAddRef(this);
3360 d3d
->lpvtbl
= &d3d2vt
;
3363 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3367 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3368 return OLE_E_ENUM_NOMORE
;
3371 static HRESULT WINAPI
IDirectDraw2_GetVerticalBlankStatus(
3372 LPDIRECTDRAW2
this,BOOL
*status
3374 TRACE(ddraw
,"(%p)->(%p)\n",this,status
);
3379 static HRESULT WINAPI
DGA_IDirectDraw2_EnumDisplayModes(
3380 LPDIRECTDRAW2
this,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
3382 DDSURFACEDESC ddsfd
;
3385 } modes
[5] = { /* some of the usual modes */
3392 static int depths
[4] = {8,16,24,32};
3395 TRACE(ddraw
,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags
,lpddsfd
,context
,modescb
);
3396 ddsfd
.dwSize
= sizeof(ddsfd
);
3397 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3398 if (dwFlags
& DDEDM_REFRESHRATES
) {
3399 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
3400 ddsfd
.x
.dwRefreshRate
= 60;
3403 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
3404 ddsfd
.dwBackBufferCount
= 1;
3405 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
3406 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
3407 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= depths
[i
];
3408 /* FIXME: those masks would have to be set in depth > 8 */
3410 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
3411 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
3412 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
3413 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3414 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
3415 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
3417 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3419 /* FIXME: We should query those from X itself */
3420 switch (depths
[i
]) {
3422 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0xF800;
3423 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x07E0;
3424 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x001F;
3427 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3428 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3429 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3432 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3433 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3434 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3439 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3440 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3441 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3442 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3444 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
3445 ddsfd
.dwWidth
= modes
[j
].w
;
3446 ddsfd
.dwHeight
= modes
[j
].h
;
3447 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3448 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3451 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
3452 /* modeX is not standard VGA */
3454 ddsfd
.dwHeight
= 200;
3455 ddsfd
.dwWidth
= 320;
3456 TRACE(ddraw
," enumerating (320x200x%d)\n",depths
[i
]);
3457 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3463 static HRESULT WINAPI
Xlib_IDirectDraw2_EnumDisplayModes(
3464 LPDIRECTDRAW2
this,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
3467 XPixmapFormatValues
*pf
;
3469 int nvisuals
, npixmap
, i
;
3472 DDSURFACEDESC ddsfd
;
3475 } modes
[] = { /* some of the usual modes */
3483 DWORD maxWidth
, maxHeight
;
3485 TRACE(ddraw
,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags
,lpddsfd
,context
,modescb
);
3486 ddsfd
.dwSize
= sizeof(ddsfd
);
3487 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3488 if (dwFlags
& DDEDM_REFRESHRATES
) {
3489 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
3490 ddsfd
.x
.dwRefreshRate
= 60;
3492 maxWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3493 maxHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3495 vi
= TSXGetVisualInfo(display
, VisualNoMask
, &vt
, &nvisuals
);
3496 pf
= XListPixmapFormats(display
, &npixmap
);
3500 while (i
< npixmap
) {
3501 if ((has_8bpp
== 0) && (pf
[i
].depth
== 8)) {
3502 /* Special case of a 8bpp depth */
3506 ddsfd
.ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3507 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
3508 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_PALETTEINDEXED8
;
3509 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
3510 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= 8;
3511 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
3512 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
3513 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
3514 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3515 } else if (pf
[i
].depth
> 8) {
3518 /* All the 'true color' depths (15, 16 and 24)
3519 First, find the corresponding visual to extract the bit masks */
3520 for (j
= 0; j
< nvisuals
; j
++) {
3521 if (vi
[j
].depth
== pf
[i
].depth
) {
3522 ddsfd
.ddsCaps
.dwCaps
= 0;
3523 ddsfd
.ddpfPixelFormat
.dwSize
= sizeof(ddsfd
.ddpfPixelFormat
);
3524 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
3525 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
3526 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= pf
[i
].bits_per_pixel
;
3527 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= vi
[j
].red_mask
;
3528 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= vi
[j
].green_mask
;
3529 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= vi
[j
].blue_mask
;
3530 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3538 ERR(ddraw
, "Did not find visual corresponding the the pixmap format !\n");
3546 if (TRACE_ON(ddraw
)) {
3547 TRACE(ddraw
, "Enumerating with pixel format : \n");
3548 _dump_pixelformat(&(ddsfd
.ddpfPixelFormat
));
3551 for (mode
= 0; mode
< sizeof(modes
)/sizeof(modes
[0]); mode
++) {
3552 /* Do not enumerate modes we cannot handle anyway */
3553 if ((modes
[mode
].w
> maxWidth
) || (modes
[mode
].h
> maxHeight
))
3556 ddsfd
.dwWidth
= modes
[mode
].w
;
3557 ddsfd
.dwHeight
= modes
[mode
].h
;
3559 /* Now, send the mode description to the application */
3560 TRACE(ddraw
, " - mode %4ld - %4ld\n", ddsfd
.dwWidth
, ddsfd
.dwHeight
);
3561 if (!modescb(&ddsfd
, context
))
3565 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
3566 /* modeX is not standard VGA */
3567 ddsfd
.dwWidth
= 320;
3568 ddsfd
.dwHeight
= 200;
3569 if (!modescb(&ddsfd
, context
))
3574 /* Hack to always enumerate a 8bpp depth */
3576 if ((i
== npixmap
) && (has_8bpp
== 0)) {
3589 static HRESULT WINAPI
DGA_IDirectDraw2_GetDisplayMode(
3590 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3592 #ifdef HAVE_LIBXXF86DGA
3593 TRACE(ddraw
,"(%p)->(%p)\n",this,lpddsfd
);
3594 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3595 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3596 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3597 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8;
3598 lpddsfd
->dwBackBufferCount
= 1;
3599 lpddsfd
->x
.dwRefreshRate
= 60;
3600 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3601 lpddsfd
->ddpfPixelFormat
= this->d
.directdraw_pixelformat
;
3603 #else /* defined(HAVE_LIBXXF86DGA) */
3604 return E_UNEXPECTED
;
3605 #endif /* defined(HAVE_LIBXXF86DGA) */
3608 static HRESULT WINAPI
Xlib_IDirectDraw2_GetDisplayMode(
3609 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3611 TRACE(ddraw
,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd
);
3612 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3613 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3614 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3615 lpddsfd
->lPitch
= lpddsfd
->dwWidth
* this->d
.directdraw_pixelformat
.x
.dwRGBBitCount
/8;
3616 lpddsfd
->dwBackBufferCount
= 1;
3617 lpddsfd
->x
.dwRefreshRate
= 60;
3618 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3619 lpddsfd
->ddpfPixelFormat
= this->d
.directdraw_pixelformat
;
3623 static HRESULT WINAPI
IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2
this) {
3624 TRACE(ddraw
,"(%p)->()\n",this);
3628 static HRESULT WINAPI
IDirectDraw2_GetMonitorFrequency(
3629 LPDIRECTDRAW2
this,LPDWORD freq
3631 FIXME(ddraw
,"(%p)->(%p) returns 60 Hz always\n",this,freq
);
3632 *freq
= 60*100; /* 60 Hz */
3636 /* what can we directly decompress? */
3637 static HRESULT WINAPI
IDirectDraw2_GetFourCCCodes(
3638 LPDIRECTDRAW2
this,LPDWORD x
,LPDWORD y
3640 FIXME(ddraw
,"(%p,%p,%p), stub\n",this,x
,y
);
3644 static HRESULT WINAPI
IDirectDraw2_EnumSurfaces(
3645 LPDIRECTDRAW2
this,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
3647 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x
,ddsfd
,context
,ddsfcb
);
3651 static HRESULT WINAPI
IDirectDraw2_Compact(
3652 LPDIRECTDRAW2
this )
3654 FIXME(ddraw
,"(%p)->()\n", this );
3659 static HRESULT WINAPI
IDirectDraw2_GetGDISurface(LPDIRECTDRAW2
this,
3660 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
3661 FIXME(ddraw
,"(%p)->(%p)\n", this, lplpGDIDDSSurface
);
3666 static HRESULT WINAPI
IDirectDraw2_GetScanLine(LPDIRECTDRAW2
this,
3667 LPDWORD lpdwScanLine
) {
3668 FIXME(ddraw
,"(%p)->(%p)\n", this, lpdwScanLine
);
3673 static HRESULT WINAPI
IDirectDraw2_Initialize(LPDIRECTDRAW2
this,
3675 FIXME(ddraw
,"(%p)->(%p)\n", this, lpGUID
);
3680 /* Note: Hack so we can reuse the old functions without compiler warnings */
3682 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3684 # define XCAST(fun) (void*)
3687 static struct IDirectDraw_VTable dga_ddvt
= {
3688 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3689 XCAST(AddRef
)IDirectDraw2_AddRef
,
3690 XCAST(Release
)DGA_IDirectDraw2_Release
,
3691 XCAST(Compact
)IDirectDraw2_Compact
,
3692 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3693 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3694 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3695 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3696 XCAST(EnumDisplayModes
)DGA_IDirectDraw2_EnumDisplayModes
,
3697 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3698 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3699 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3700 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3701 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3702 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3703 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3704 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3705 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3706 XCAST(Initialize
)IDirectDraw2_Initialize
,
3707 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3708 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3709 DGA_IDirectDraw_SetDisplayMode
,
3710 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3713 static struct IDirectDraw_VTable xlib_ddvt
= {
3714 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3715 XCAST(AddRef
)IDirectDraw2_AddRef
,
3716 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3717 XCAST(Compact
)IDirectDraw2_Compact
,
3718 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3719 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3720 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3721 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3722 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2_EnumDisplayModes
,
3723 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3724 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3725 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3726 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3727 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3728 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3729 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3730 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3731 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3732 XCAST(Initialize
)IDirectDraw2_Initialize
,
3733 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3734 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3735 Xlib_IDirectDraw_SetDisplayMode
,
3736 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3741 /*****************************************************************************
3747 static HRESULT WINAPI
DGA_IDirectDraw2_SetDisplayMode(
3748 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3750 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3753 static HRESULT WINAPI
Xlib_IDirectDraw2_SetDisplayMode(
3754 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3756 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3759 static HRESULT WINAPI
DGA_IDirectDraw2_GetAvailableVidMem(
3760 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3762 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3763 this,ddscaps
,total
,free
3765 if (total
) *total
= this->e
.dga
.fb_memsize
* 1024;
3766 if (free
) *free
= this->e
.dga
.fb_memsize
* 1024;
3770 static HRESULT WINAPI
Xlib_IDirectDraw2_GetAvailableVidMem(
3771 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3773 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3774 this,ddscaps
,total
,free
3776 if (total
) *total
= 2048 * 1024;
3777 if (free
) *free
= 2048 * 1024;
3781 static IDirectDraw2_VTable dga_dd2vt
= {
3782 DGA_IDirectDraw2_QueryInterface
,
3783 IDirectDraw2_AddRef
,
3784 DGA_IDirectDraw2_Release
,
3785 IDirectDraw2_Compact
,
3786 IDirectDraw2_CreateClipper
,
3787 DGA_IDirectDraw2_CreatePalette
,
3788 DGA_IDirectDraw2_CreateSurface
,
3789 IDirectDraw2_DuplicateSurface
,
3790 DGA_IDirectDraw2_EnumDisplayModes
,
3791 IDirectDraw2_EnumSurfaces
,
3792 IDirectDraw2_FlipToGDISurface
,
3793 DGA_IDirectDraw2_GetCaps
,
3794 DGA_IDirectDraw2_GetDisplayMode
,
3795 IDirectDraw2_GetFourCCCodes
,
3796 IDirectDraw2_GetGDISurface
,
3797 IDirectDraw2_GetMonitorFrequency
,
3798 IDirectDraw2_GetScanLine
,
3799 IDirectDraw2_GetVerticalBlankStatus
,
3800 IDirectDraw2_Initialize
,
3801 DGA_IDirectDraw2_RestoreDisplayMode
,
3802 IDirectDraw2_SetCooperativeLevel
,
3803 DGA_IDirectDraw2_SetDisplayMode
,
3804 IDirectDraw2_WaitForVerticalBlank
,
3805 DGA_IDirectDraw2_GetAvailableVidMem
3808 static struct IDirectDraw2_VTable xlib_dd2vt
= {
3809 Xlib_IDirectDraw2_QueryInterface
,
3810 IDirectDraw2_AddRef
,
3811 Xlib_IDirectDraw2_Release
,
3812 IDirectDraw2_Compact
,
3813 IDirectDraw2_CreateClipper
,
3814 Xlib_IDirectDraw2_CreatePalette
,
3815 Xlib_IDirectDraw2_CreateSurface
,
3816 IDirectDraw2_DuplicateSurface
,
3817 Xlib_IDirectDraw2_EnumDisplayModes
,
3818 IDirectDraw2_EnumSurfaces
,
3819 IDirectDraw2_FlipToGDISurface
,
3820 Xlib_IDirectDraw2_GetCaps
,
3821 Xlib_IDirectDraw2_GetDisplayMode
,
3822 IDirectDraw2_GetFourCCCodes
,
3823 IDirectDraw2_GetGDISurface
,
3824 IDirectDraw2_GetMonitorFrequency
,
3825 IDirectDraw2_GetScanLine
,
3826 IDirectDraw2_GetVerticalBlankStatus
,
3827 IDirectDraw2_Initialize
,
3828 Xlib_IDirectDraw2_RestoreDisplayMode
,
3829 IDirectDraw2_SetCooperativeLevel
,
3830 Xlib_IDirectDraw2_SetDisplayMode
,
3831 IDirectDraw2_WaitForVerticalBlank
,
3832 Xlib_IDirectDraw2_GetAvailableVidMem
3835 /*****************************************************************************
3840 static HRESULT WINAPI
IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4
this,
3842 LPDIRECTDRAWSURFACE
*lpDDS
) {
3843 FIXME(ddraw
, "(%p)->(%08ld,%p)\n", this, (DWORD
) hdc
, lpDDS
);
3848 static HRESULT WINAPI
IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4
this) {
3849 FIXME(ddraw
, "(%p)->()\n", this);
3854 static HRESULT WINAPI
IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4
this) {
3855 FIXME(ddraw
, "(%p)->()\n", this);
3860 static HRESULT WINAPI
IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4
this,
3861 LPDDDEVICEIDENTIFIER lpdddi
,
3863 FIXME(ddraw
, "(%p)->(%p,%08lx)\n", this, lpdddi
, dwFlags
);
3869 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3871 # define XCAST(fun) (void*)
3875 static struct IDirectDraw4_VTable dga_dd4vt
= {
3876 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3877 XCAST(AddRef
)IDirectDraw2_AddRef
,
3878 XCAST(Release
)DGA_IDirectDraw2_Release
,
3879 XCAST(Compact
)IDirectDraw2_Compact
,
3880 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3881 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3882 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3883 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3884 XCAST(EnumDisplayModes
)DGA_IDirectDraw2_EnumDisplayModes
,
3885 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3886 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3887 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3888 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3889 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3890 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3891 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3892 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3893 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3894 XCAST(Initialize
)IDirectDraw2_Initialize
,
3895 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3896 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3897 XCAST(SetDisplayMode
)DGA_IDirectDraw_SetDisplayMode
,
3898 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3899 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2_GetAvailableVidMem
,
3900 IDirectDraw4_GetSurfaceFromDC
,
3901 IDirectDraw4_RestoreAllSurfaces
,
3902 IDirectDraw4_TestCooperativeLevel
,
3903 IDirectDraw4_GetDeviceIdentifier
3906 static struct IDirectDraw4_VTable xlib_dd4vt
= {
3907 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3908 XCAST(AddRef
)IDirectDraw2_AddRef
,
3909 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3910 XCAST(Compact
)IDirectDraw2_Compact
,
3911 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3912 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3913 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3914 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3915 XCAST(EnumDisplayModes
)Xlib_IDirectDraw2_EnumDisplayModes
,
3916 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3917 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3918 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3919 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3920 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3921 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3922 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3923 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3924 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3925 XCAST(Initialize
)IDirectDraw2_Initialize
,
3926 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3927 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3928 XCAST(SetDisplayMode
)Xlib_IDirectDraw_SetDisplayMode
,
3929 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3930 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2_GetAvailableVidMem
,
3931 IDirectDraw4_GetSurfaceFromDC
,
3932 IDirectDraw4_RestoreAllSurfaces
,
3933 IDirectDraw4_TestCooperativeLevel
,
3934 IDirectDraw4_GetDeviceIdentifier
3939 /******************************************************************************
3943 LRESULT WINAPI
Xlib_DDWndProc(HWND hwnd
,UINT msg
,WPARAM wParam
,LPARAM lParam
)
3946 LPDIRECTDRAW ddraw
= NULL
;
3949 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3951 SetLastError( ERROR_SUCCESS
);
3952 ddraw
= (LPDIRECTDRAW
)GetWindowLongA( hwnd
, ddrawXlibThisOffset
);
3954 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
3957 ERR( ddraw
, "Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
3962 /* Perform any special direct draw functions */
3964 ddraw
->d
.paintable
= 1;
3966 /* Now let the application deal with the rest of this */
3967 if( ddraw
->d
.mainWindow
)
3970 /* Don't think that we actually need to call this but...
3971 might as well be on the safe side of things... */
3973 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3974 it should be the procedures of our fake window that gets called
3975 instead of those of the window provided by the application.
3976 And with this patch, mouse clicks work with Monkey Island III
3978 ret
= DefWindowProcA( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3982 /* We didn't handle the message - give it to the application */
3983 if (ddraw
&& ddraw
->d
.mainWindow
&& WIN_FindWndPtr(ddraw
->d
.mainWindow
)) {
3984 ret
= CallWindowProcA( WIN_FindWndPtr( ddraw
->d
.mainWindow
)->winproc
,
3985 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3990 ret
= DefWindowProcA(hwnd
, msg
, wParam
, lParam
);
3996 ret
= DefWindowProcA(hwnd
,msg
,wParam
,lParam
);
4002 HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4003 #ifdef HAVE_LIBXXF86DGA
4004 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
4009 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
4010 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
4014 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
4015 MessageBoxA(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
4016 return E_UNEXPECTED
;
4018 if (!DDRAW_DGA_Available()) {
4019 TRACE(ddraw
,"No XF86DGA detected.\n");
4020 return DDERR_GENERIC
;
4022 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
4023 (*lplpDD
)->lpvtbl
= &dga_ddvt
;
4025 TSXF86DGAQueryVersion(display
,&major
,&minor
);
4026 TRACE(ddraw
,"XF86DGA is version %d.%d\n",major
,minor
);
4027 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
4028 if (!(flags
& XF86DGADirectPresent
))
4029 MSG("direct video is NOT PRESENT.\n");
4030 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
4031 TRACE(ddraw
,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
4032 addr
,width
,banksize
,memsize
4034 (*lplpDD
)->e
.dga
.fb_width
= width
;
4035 (*lplpDD
)->d
.width
= width
;
4036 (*lplpDD
)->e
.dga
.fb_addr
= addr
;
4037 (*lplpDD
)->e
.dga
.fb_memsize
= memsize
;
4038 (*lplpDD
)->e
.dga
.fb_banksize
= banksize
;
4040 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
4041 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
4042 (*lplpDD
)->e
.dga
.fb_height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4044 (*lplpDD
)->e
.dga
.vpmask
= 1;
4046 (*lplpDD
)->e
.dga
.vpmask
= 0;
4049 /* just assume the default depth is the DGA depth too */
4050 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
4051 _common_depth_to_pixelformat(depth
, &((*lplpDD
)->d
.directdraw_pixelformat
), &((*lplpDD
)->d
.screen_pixelformat
), NULL
);
4052 #ifdef RESTORE_SIGNALS
4053 SIGNAL_InitHandlers();
4057 #else /* defined(HAVE_LIBXXF86DGA) */
4058 return DDERR_INVALIDDIRECTDRAWGUID
;
4059 #endif /* defined(HAVE_LIBXXF86DGA) */
4063 DDRAW_XSHM_Available(void)
4065 #ifdef HAVE_LIBXXSHM
4066 if (TSXShmQueryExtension(display
))
4071 if (TSXShmQueryVersion(display
, &major
, &minor
, &shpix
))
4083 HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4086 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
4087 (*lplpDD
)->lpvtbl
= &xlib_ddvt
;
4089 (*lplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
4091 /* At DirectDraw creation, the depth is the default depth */
4092 depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
4093 _common_depth_to_pixelformat(depth
, &((*lplpDD
)->d
.directdraw_pixelformat
), &((*lplpDD
)->d
.screen_pixelformat
), NULL
);
4094 (*lplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
4095 (*lplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
4097 #ifdef HAVE_LIBXXSHM
4098 /* Test if XShm is available. */
4099 if (((*lplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available()))
4100 TRACE(ddraw
, "Using XShm extension.\n");
4106 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
4113 WINE_StringFromCLSID(lpGUID
,xclsid
);
4115 sprintf(xclsid
,"<guid-0x%08x>",(int)lpGUID
);
4119 TRACE(ddraw
,"(%s,%p,%p)\n",xclsid
,lplpDD
,pUnkOuter
);
4122 /* if they didn't request a particular interface, use the best
4124 if (DDRAW_DGA_Available())
4125 lpGUID
= &DGA_DirectDraw_GUID
;
4127 lpGUID
= &XLIB_DirectDraw_GUID
;
4130 wc
.style
= CS_GLOBALCLASS
;
4131 wc
.lpfnWndProc
= Xlib_DDWndProc
;
4133 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
4134 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
4136 /* We can be a child of the desktop since we're really important */
4137 pParentWindow
= WIN_GetDesktop();
4138 wc
.hInstance
= pParentWindow
? pParentWindow
->hwndSelf
: 0;
4142 wc
.hCursor
= (HCURSOR
)IDC_ARROWA
;
4143 wc
.hbrBackground
= NULL_BRUSH
;
4144 wc
.lpszMenuName
= 0;
4145 wc
.lpszClassName
= "WINE_DirectDraw";
4146 RegisterClassA(&wc
);
4148 if (!memcmp(lpGUID
, &DGA_DirectDraw_GUID
, sizeof(GUID
)))
4149 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
4150 else if (!memcmp(lpGUID
, &XLIB_DirectDraw_GUID
, sizeof(GUID
)))
4151 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
4156 (*lplpDD
)->d
.winclass
= RegisterClassA(&wc
);
4160 ERR(ddraw
, "DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
4161 return DDERR_INVALIDDIRECTDRAWGUID
;