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>
66 /* This for all the enumeration and creation of D3D-related objects */
67 #include "d3d_private.h"
69 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
72 /* Restore signal handlers overwritten by XF86DGA
74 #define RESTORE_SIGNALS
76 /* Where do these GUIDs come from? mkuuid.
77 * They exist solely to distinguish between the targets Wine support,
78 * and should be different than any other GUIDs in existence.
80 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
84 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
87 static GUID XLIB_DirectDraw_GUID
= { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
91 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
94 static struct IDirectDrawSurface4_VTable dga_dds4vt
, xlib_dds4vt
;
95 static struct IDirectDraw_VTable dga_ddvt
, xlib_ddvt
;
96 static struct IDirectDraw2_VTable dga_dd2vt
, xlib_dd2vt
;
97 static struct IDirectDraw4_VTable dga_dd4vt
, xlib_dd4vt
;
98 static struct IDirectDrawClipper_VTable ddclipvt
;
99 static struct IDirectDrawPalette_VTable dga_ddpalvt
, xlib_ddpalvt
;
100 static struct IDirect3D_VTable d3dvt
;
101 static struct IDirect3D2_VTable d3d2vt
;
103 #ifdef HAVE_LIBXXF86VM
104 static XF86VidModeModeInfo
*orig_mode
= NULL
;
108 static int XShmErrorFlag
= 0;
112 DDRAW_DGA_Available(void)
114 #ifdef HAVE_LIBXXF86DGA
115 int evbase
, evret
, fd
;
120 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
121 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
122 /* others. --stephenc */
123 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
126 return (fd
!= -1) && TSXF86DGAQueryExtension(display
,&evbase
,&evret
);
127 #else /* defined(HAVE_LIBXXF86DGA) */
129 #endif /* defined(HAVE_LIBXXF86DGA) */
133 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc
,LPVOID data
) {
134 if (DDRAW_DGA_Available()) {
135 TRACE(ddraw
, "Enumerating DGA interface\n");
136 ddenumproc(&DGA_DirectDraw_GUID
,"WINE with XFree86 DGA","display",data
);
138 TRACE(ddraw
, "Enumerating Xlib interface\n");
139 ddenumproc(&XLIB_DirectDraw_GUID
,"WINE with Xlib","display",data
);
140 TRACE(ddraw
, "Enumerating Default interface\n");
141 ddenumproc(NULL
,"WINE (default)","display",data
);
145 /* What is this doing here? */
147 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
148 FIXME(ddraw
,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
153 /******************************************************************************
154 * internal helper functions
156 static void _dump_DDBLTFX(DWORD flagmask
) {
162 #define FE(x) { x, #x},
163 FE(DDBLTFX_ARITHSTRETCHY
)
164 FE(DDBLTFX_MIRRORLEFTRIGHT
)
165 FE(DDBLTFX_MIRRORUPDOWN
)
166 FE(DDBLTFX_NOTEARING
)
167 FE(DDBLTFX_ROTATE180
)
168 FE(DDBLTFX_ROTATE270
)
170 FE(DDBLTFX_ZBUFFERRANGE
)
171 FE(DDBLTFX_ZBUFFERBASEDEST
)
173 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
174 if (flags
[i
].mask
& flagmask
) {
175 DUMP("%s ",flags
[i
].name
);
182 static void _dump_DDBLTFAST(DWORD flagmask
) {
188 #define FE(x) { x, #x},
189 FE(DDBLTFAST_NOCOLORKEY
)
190 FE(DDBLTFAST_SRCCOLORKEY
)
191 FE(DDBLTFAST_DESTCOLORKEY
)
194 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
195 if (flags
[i
].mask
& flagmask
)
196 DUMP("%s ",flags
[i
].name
);
200 static void _dump_DDBLT(DWORD flagmask
) {
206 #define FE(x) { x, #x},
208 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
209 FE(DDBLT_ALPHADESTNEG
)
210 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
211 FE(DDBLT_ALPHAEDGEBLEND
)
213 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
214 FE(DDBLT_ALPHASRCNEG
)
215 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
221 FE(DDBLT_KEYDESTOVERRIDE
)
223 FE(DDBLT_KEYSRCOVERRIDE
)
225 FE(DDBLT_ROTATIONANGLE
)
227 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
228 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
229 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
230 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
234 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
235 if (flags
[i
].mask
& flagmask
)
236 DUMP("%s ",flags
[i
].name
);
240 static void _dump_DDSCAPS(DWORD flagmask
) {
246 #define FE(x) { x, #x},
247 FE(DDSCAPS_RESERVED1
)
249 FE(DDSCAPS_BACKBUFFER
)
252 FE(DDSCAPS_FRONTBUFFER
)
253 FE(DDSCAPS_OFFSCREENPLAIN
)
256 FE(DDSCAPS_PRIMARYSURFACE
)
257 FE(DDSCAPS_PRIMARYSURFACELEFT
)
258 FE(DDSCAPS_SYSTEMMEMORY
)
261 FE(DDSCAPS_VIDEOMEMORY
)
263 FE(DDSCAPS_WRITEONLY
)
266 FE(DDSCAPS_LIVEVIDEO
)
270 FE(DDSCAPS_RESERVED2
)
271 FE(DDSCAPS_ALLOCONLOAD
)
272 FE(DDSCAPS_VIDEOPORT
)
273 FE(DDSCAPS_LOCALVIDMEM
)
274 FE(DDSCAPS_NONLOCALVIDMEM
)
275 FE(DDSCAPS_STANDARDVGAMODE
)
276 FE(DDSCAPS_OPTIMIZED
)
278 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
279 if (flags
[i
].mask
& flagmask
)
280 DUMP("%s ",flags
[i
].name
);
284 static void _dump_DDSD(DWORD flagmask
) {
294 FE(DDSD_BACKBUFFERCOUNT
)
295 FE(DDSD_ZBUFFERBITDEPTH
)
296 FE(DDSD_ALPHABITDEPTH
)
298 FE(DDSD_CKDESTOVERLAY
)
300 FE(DDSD_CKSRCOVERLAY
)
307 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
308 if (flags
[i
].mask
& flagmask
)
309 DUMP("%s ",flags
[i
].name
);
313 static void _dump_DDCOLORKEY(DWORD flagmask
) {
319 #define FE(x) { x, #x},
323 FE(DDPF_PALETTEINDEXED4
)
324 FE(DDPF_PALETTEINDEXEDTO8
)
325 FE(DDPF_PALETTEINDEXED8
)
331 FE(DDPF_PALETTEINDEXED1
)
332 FE(DDPF_PALETTEINDEXED2
)
335 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
336 if (flags
[i
].mask
& flagmask
)
337 DUMP("%s ",flags
[i
].name
);
341 static void _dump_paletteformat(DWORD dwFlags
) {
347 #define FE(x) { x, #x},
349 FE(DDPCAPS_8BITENTRIES
)
351 FE(DDPCAPS_INITIALIZE
)
352 FE(DDPCAPS_PRIMARYSURFACE
)
353 FE(DDPCAPS_PRIMARYSURFACELEFT
)
360 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
361 if (flags
[i
].mask
& dwFlags
)
362 DUMP("%s ",flags
[i
].name
);
366 static void _dump_pixelformat(LPDDPIXELFORMAT pf
) {
367 DUMP("Size : %ld\n", pf
->dwSize
);
369 _dump_DDCOLORKEY(pf
->dwFlags
);
370 DUMP("dwFourCC : %ld\n", pf
->dwFourCC
);
371 DUMP("RGB bit count : %ld\n", pf
->x
.dwRGBBitCount
);
372 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
373 pf
->y
.dwRBitMask
, pf
->z
.dwGBitMask
, pf
->xx
.dwBBitMask
, pf
->xy
.dwRGBAlphaBitMask
);
376 static int _getpixelformat(LPDIRECTDRAW2 ddraw
,LPDDPIXELFORMAT pf
) {
377 static XVisualInfo
*vi
;
382 vi
= TSXGetVisualInfo(display
,VisualNoMask
,&vt
,&nitems
);
385 pf
->dwSize
= sizeof(DDPIXELFORMAT
);
386 if (ddraw
->d
.depth
==8) {
387 pf
->dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
388 pf
->x
.dwRGBBitCount
= 8;
389 pf
->y
.dwRBitMask
= 0;
390 pf
->z
.dwGBitMask
= 0;
391 pf
->xx
.dwBBitMask
= 0;
392 pf
->xy
.dwRGBAlphaBitMask
= 0;
395 if (ddraw
->d
.depth
==16) {
396 pf
->dwFlags
= DDPF_RGB
;
397 pf
->x
.dwRGBBitCount
= 16;
398 pf
->y
.dwRBitMask
= vi
[0].red_mask
;
399 pf
->z
.dwGBitMask
= vi
[0].green_mask
;
400 pf
->xx
.dwBBitMask
= vi
[0].blue_mask
;
401 pf
->xy
.dwRGBAlphaBitMask
= 0;
404 if (ddraw
->d
.depth
==24) {
405 pf
->dwFlags
= DDPF_RGB
;
406 pf
->x
.dwRGBBitCount
= 24;
407 pf
->y
.dwRBitMask
= vi
[0].red_mask
;
408 pf
->z
.dwGBitMask
= vi
[0].green_mask
;
409 pf
->xx
.dwBBitMask
= vi
[0].blue_mask
;
410 pf
->xy
.dwRGBAlphaBitMask
= 0;
413 FIXME(ddraw
,"_getpixelformat:unknown depth %ld?\n",ddraw
->d
.depth
);
414 return DDERR_GENERIC
;
417 /******************************************************************************
418 * IDirectDrawSurface methods
420 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
421 * DDS and DDS2 use those functions. (Function calls did not change (except
422 * using different DirectDrawSurfaceX version), just added flags and functions)
424 static HRESULT WINAPI
IDirectDrawSurface4_Lock(
425 LPDIRECTDRAWSURFACE4
this,LPRECT32 lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE32 hnd
427 TRACE(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
428 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
429 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
430 WARN(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
431 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
433 /* First, copy the Surface description */
434 *lpddsd
= this->s
.surface_desc
;
435 TRACE(ddraw
,"locked surface: height=%ld, width=%ld, pitch=%ld\n",
436 lpddsd
->dwHeight
,lpddsd
->dwWidth
,lpddsd
->lPitch
);
438 /* If asked only for a part, change the surface pointer */
440 FIXME(ddraw
," lprect: %dx%d-%dx%d\n",
441 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
443 lpddsd
->y
.lpSurface
= this->s
.surface_desc
.y
.lpSurface
+
444 (lprect
->top
*this->s
.surface_desc
.lPitch
) +
445 (lprect
->left
*(this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8));
447 assert(this->s
.surface_desc
.y
.lpSurface
);
452 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Unlock(
453 LPDIRECTDRAWSURFACE4
this,LPVOID surface
455 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
459 static void Xlib_copy_surface_on_screen(LPDIRECTDRAWSURFACE4
this) {
460 if (this->s
.ddraw
->d
.depth
!= this->s
.ddraw
->d
.screen_depth
) {
461 /* Pixel convertion ! */
462 if ((this->s
.ddraw
->d
.depth
== 8) && (this->s
.ddraw
->d
.screen_depth
== 16)) {
463 unsigned char *src
= (unsigned char *) this->s
.surface_desc
.y
.lpSurface
;
464 unsigned short *dst
= (unsigned short *) this->t
.xlib
.image
->data
;
468 if (this->s
.palette
!= NULL
) {
469 pal
= (unsigned short *) this->s
.palette
->screen_palents
;
470 for (y
= 0; y
< this->s
.surface_desc
.dwHeight
; y
++) {
471 for (x
= 0; x
< this->s
.surface_desc
.dwWidth
; x
++) {
472 dst
[x
+ y
* this->s
.surface_desc
.lPitch
] = pal
[src
[x
+ y
* this->s
.surface_desc
.lPitch
]];
476 WARN(ddraw
, "No palette set...\n");
477 memset(dst
, 0, this->s
.surface_desc
.lPitch
* this->s
.surface_desc
.dwHeight
* 2);
480 ERR(ddraw
, "Unsupported pixel convertion...\n");
485 if (this->s
.ddraw
->e
.xlib
.xshm_active
)
486 TSXShmPutImage(display
,
487 this->s
.ddraw
->d
.drawable
,
488 DefaultGCOfScreen(X11DRV_GetXScreen()),
491 this->t
.xlib
.image
->width
,
492 this->t
.xlib
.image
->height
,
496 TSXPutImage( display
,
497 this->s
.ddraw
->d
.drawable
,
498 DefaultGCOfScreen(X11DRV_GetXScreen()),
501 this->t
.xlib
.image
->width
,
502 this->t
.xlib
.image
->height
);
505 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Unlock(
506 LPDIRECTDRAWSURFACE4
this,LPVOID surface
)
508 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
510 if (!this->s
.ddraw
->d
.paintable
)
513 /* Only redraw the screen when unlocking the buffer that is on screen */
514 if ((this->t
.xlib
.image
!= NULL
) &&
515 (this->s
.surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VISIBLE
)) {
516 Xlib_copy_surface_on_screen(this);
518 if (this->s
.palette
&& this->s
.palette
->cm
)
519 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
525 static HRESULT WINAPI
DGA_IDirectDrawSurface4_Flip(
526 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
528 #ifdef HAVE_LIBXXF86DGA
529 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
531 if (this->s
.backbuffer
)
532 flipto
= this->s
.backbuffer
;
536 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,flipto
->t
.dga
.fb_height
);
538 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
539 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),flipto
->s
.palette
->cm
);
541 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
547 tmp
= this->t
.dga
.fb_height
;
548 this->t
.dga
.fb_height
= flipto
->t
.dga
.fb_height
;
549 flipto
->t
.dga
.fb_height
= tmp
;
551 ptmp
= this->s
.surface_desc
.y
.lpSurface
;
552 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
553 flipto
->s
.surface_desc
.y
.lpSurface
= ptmp
;
556 #else /* defined(HAVE_LIBXXF86DGA) */
558 #endif /* defined(HAVE_LIBXXF86DGA) */
561 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_Flip(
562 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 flipto
,DWORD dwFlags
564 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
565 if (!this->s
.ddraw
->d
.paintable
)
569 if (this->s
.backbuffer
)
570 flipto
= this->s
.backbuffer
;
575 Xlib_copy_surface_on_screen(this);
577 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
578 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,flipto
->s
.palette
->cm
);
583 tmp
= this->t
.xlib
.image
;
584 this->t
.xlib
.image
= flipto
->t
.xlib
.image
;
585 flipto
->t
.xlib
.image
= tmp
;
586 surf
= this->s
.surface_desc
.y
.lpSurface
;
587 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
588 flipto
->s
.surface_desc
.y
.lpSurface
= surf
;
594 /* The IDirectDrawSurface4::SetPalette method attaches the specified
595 * DirectDrawPalette object to a surface. The surface uses this palette for all
596 * subsequent operations. The palette change takes place immediately.
598 static HRESULT WINAPI
Xlib_IDirectDrawSurface4_SetPalette(
599 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
602 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
605 if( this->s
.palette
!= NULL
)
606 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
607 this->s
.palette
= pal
;
612 if( !(pal
->cm
) && (this->s
.ddraw
->d
.screen_depth
<=8))
614 pal
->cm
= TSXCreateColormap(display
,this->s
.ddraw
->d
.drawable
,
615 DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
617 if (!Options
.managed
)
618 TSXInstallColormap(display
,pal
->cm
);
620 for (i
=0;i
<256;i
++) {
623 xc
.red
= pal
->palents
[i
].peRed
<<8;
624 xc
.blue
= pal
->palents
[i
].peBlue
<<8;
625 xc
.green
= pal
->palents
[i
].peGreen
<<8;
626 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
628 TSXStoreColor(display
,pal
->cm
,&xc
);
630 TSXInstallColormap(display
,pal
->cm
);
633 /* According to spec, we are only supposed to
634 * AddRef if this is not the same palette.
636 if( this->s
.palette
!= pal
)
639 pal
->lpvtbl
->fnAddRef( pal
);
640 if( this->s
.palette
!= NULL
)
641 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
642 this->s
.palette
= pal
;
644 /* I think that we need to attach it to all backbuffers...*/
645 if( this->s
.backbuffer
) {
646 if( this->s
.backbuffer
->s
.palette
)
647 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(
648 this->s
.backbuffer
->s
.palette
);
649 this->s
.backbuffer
->s
.palette
= pal
;
651 pal
->lpvtbl
->fnAddRef( pal
);
653 /* Perform the refresh */
654 TSXSetWindowColormap(display
,this->s
.ddraw
->d
.drawable
,this->s
.palette
->cm
);
659 static HRESULT WINAPI
DGA_IDirectDrawSurface4_SetPalette(
660 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWPALETTE pal
662 TRACE(ddraw
,"(%p)->(%p)\n",this,pal
);
663 #ifdef HAVE_LIBXXF86DGA
664 /* According to spec, we are only supposed to
665 * AddRef if this is not the same palette.
667 if( this->s
.palette
!= pal
)
670 pal
->lpvtbl
->fnAddRef( pal
);
671 if( this->s
.palette
!= NULL
)
672 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
673 this->s
.palette
= pal
;
675 /* I think that we need to attach it to all backbuffers...*/
676 if( this->s
.backbuffer
) {
677 if( this->s
.backbuffer
->s
.palette
)
678 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(this->s
.backbuffer
->s
.palette
);
679 this->s
.backbuffer
->s
.palette
= pal
;
680 if( pal
) pal
->lpvtbl
->fnAddRef( pal
);
682 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->s
.palette
->cm
);
685 #else /* defined(HAVE_LIBXXF86DGA) */
687 #endif /* defined(HAVE_LIBXXF86DGA) */
692 static HRESULT WINAPI
IDirectDrawSurface4_Blt(
693 LPDIRECTDRAWSURFACE4
this,LPRECT32 rdst
,LPDIRECTDRAWSURFACE4 src
,LPRECT32 rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
696 DDSURFACEDESC ddesc
,sdesc
;
699 TRACE(ddraw
,"(%p)->(%p,%p,%p,%08lx,%p)\n",
700 this,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
703 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,0,0);
704 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,0,0);
706 if (TRACE_ON(ddraw
)) {
707 if (rdst
) TRACE(ddraw
," destrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
708 if (rsrc
) TRACE(ddraw
," srcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
709 TRACE(ddraw
,"\tflags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
710 if (dwFlags
& DDBLT_DDFX
) {
711 TRACE(ddraw
," blitfx: \n");_dump_DDBLTFX(lpbltfx
->dwDDFX
);
716 memcpy(&xdst
,rdst
,sizeof(xdst
));
719 xdst
.bottom
= ddesc
.dwHeight
;
721 xdst
.right
= ddesc
.dwWidth
;
725 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
729 xsrc
.bottom
= sdesc
.dwHeight
;
731 xsrc
.right
= sdesc
.dwWidth
;
733 memset(&xsrc
,0,sizeof(xsrc
));
737 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
739 /* First, all the 'source-less' blits */
740 if (dwFlags
& DDBLT_COLORFILL
) {
741 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
744 xline
= (LPBYTE
) ddesc
.y
.lpSurface
+ xdst
.top
* ddesc
.lPitch
;
745 for (i
=xdst
.top
;i
<xdst
.bottom
;i
++) {
746 xpixel
= xline
+bpp
*xdst
.left
;
748 for (j
=xdst
.left
;j
<xdst
.right
;j
++) {
749 /* FIXME: this only works on little endian
750 * architectures, where DWORD starts with low
753 memcpy(xpixel
,&(lpbltfx
->b
.dwFillColor
),bpp
);
756 xline
+= ddesc
.lPitch
;
758 dwFlags
&= ~(DDBLT_COLORFILL
);
761 if (dwFlags
& DDBLT_DEPTHFILL
) {
765 /* Clears the screen */
766 TRACE(ddraw
, " Filling depth buffer with %ld\n", lpbltfx
->b
.dwFillDepth
);
767 glClearDepth(lpbltfx
->b
.dwFillDepth
/ 65535.0); /* We suppose a 16 bit Z Buffer */
768 glGetBooleanv(GL_DEPTH_TEST
, &ztest
);
769 glDepthMask(GL_TRUE
); /* Enables Z writing to be sure to delete also the Z buffer */
770 glClear(GL_DEPTH_BUFFER_BIT
);
773 dwFlags
&= ~(DDBLT_DEPTHFILL
);
779 TRACE(ddraw
,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
781 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
785 /* Now the 'with source' blits */
787 /* Standard 'full-surface' blit without special effects */
788 if ( (xsrc
.top
==0) && (xsrc
.bottom
==ddesc
.dwHeight
) &&
789 (xsrc
.left
==0) && (xsrc
.right
==ddesc
.dwWidth
) &&
790 (xdst
.top
==0) && (xdst
.bottom
==ddesc
.dwHeight
) &&
791 (xdst
.left
==0) && (xdst
.right
==ddesc
.dwWidth
) &&
794 memcpy(ddesc
.y
.lpSurface
,
796 ddesc
.dwHeight
* ddesc
.lPitch
);
798 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
799 int srcheight
= xsrc
.bottom
- xsrc
.top
;
800 int srcwidth
= xsrc
.right
- xsrc
.left
;
801 int dstheight
= xdst
.bottom
- xdst
.top
;
802 int dstwidth
= xdst
.right
- xdst
.left
;
803 int width
= (xsrc
.right
- xsrc
.left
) * bpp
;
806 /* Sanity check for rectangle sizes */
807 if ((srcheight
!= dstheight
) || (srcwidth
!= dstwidth
)) {
810 /* I think we should do a Blit with 'stretching' here....
811 Tomb Raider II uses this to display the background during the menu selection
812 when the screen resolution is != than 640x480 */
813 TRACE(ddraw
, "Blt with stretching\n");
815 /* This is a basic stretch implementation. It is painfully slow and quite ugly. */
817 /* In this case, we cannot do any anti-aliasing */
818 if(dwFlags
& DDBLT_KEYSRC
) {
819 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
820 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
823 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
824 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
826 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
827 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
829 tmp
= sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
831 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
832 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
833 dbuf
[(y
* ddesc
.lPitch
) + x
] = tmp
;
837 for (y
= xdst
.top
; y
< xdst
.bottom
; y
++) {
838 for (x
= xdst
.left
; x
< xdst
.right
; x
++) {
840 unsigned char *dbuf
= (unsigned char *) ddesc
.y
.lpSurface
;
841 unsigned char *sbuf
= (unsigned char *) sdesc
.y
.lpSurface
;
843 sx
= (((double) (x
- xdst
.left
) / dstwidth
) * srcwidth
) + xsrc
.left
;
844 sy
= (((double) (y
- xdst
.top
) / dstheight
) * srcheight
) + xsrc
.top
;
846 dbuf
[(y
* ddesc
.lPitch
) + x
] = sbuf
[(((int) sy
) * sdesc
.lPitch
) + ((int) sx
)];
851 FIXME(ddraw
, "Not done yet for depth != 8\n");
854 /* Same size => fast blit */
855 if (dwFlags
& DDBLT_KEYSRC
) {
858 unsigned char tmp
,*psrc
,*pdst
;
861 for (h
= 0; h
< srcheight
; h
++) {
862 psrc
=sdesc
.y
.lpSurface
+
863 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
864 pdst
=ddesc
.y
.lpSurface
+
865 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
866 for(i
=0;i
<srcwidth
;i
++) {
868 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
869 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
873 dwFlags
&=~(DDBLT_KEYSRC
);
877 unsigned short tmp
,*psrc
,*pdst
;
880 for (h
= 0; h
< srcheight
; h
++) {
881 psrc
=sdesc
.y
.lpSurface
+
882 ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
;
883 pdst
=ddesc
.y
.lpSurface
+
884 ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
;
885 for(i
=0;i
<srcwidth
;i
++) {
887 if ((tmp
< src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceLowValue
) ||
888 (tmp
> src
->s
.surface_desc
.ddckCKSrcBlt
.dwColorSpaceHighValue
))
892 dwFlags
&=~(DDBLT_KEYSRC
);
896 FIXME(ddraw
, "Bitblt, KEYSRC: Not done yet for depth > 16\n");
899 /* Non-stretching Blt without color keying */
900 for (h
= 0; h
< srcheight
; h
++) {
901 memcpy(ddesc
.y
.lpSurface
+ ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
* bpp
,
902 sdesc
.y
.lpSurface
+ ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
* bpp
,
909 if (dwFlags
&& FIXME_ON(ddraw
)) {
910 FIXME(ddraw
,"\tUnsupported flags: ");_dump_DDBLT(dwFlags
);
913 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
914 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
919 static HRESULT WINAPI
IDirectDrawSurface4_BltFast(
920 LPDIRECTDRAWSURFACE4
this,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE4 src
,LPRECT32 rsrc
,DWORD trans
923 DDSURFACEDESC ddesc
,sdesc
;
925 if (1 || TRACE_ON(ddraw
)) {
926 FIXME(ddraw
,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
927 this,dstx
,dsty
,src
,rsrc
,trans
929 FIXME(ddraw
," trans:");
931 _dump_DDBLTFAST(trans
);
932 FIXME(ddraw
," srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
934 /* We need to lock the surfaces, or we won't get refreshes when done. */
935 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
936 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
937 bpp
= this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
938 h
=rsrc
->bottom
-rsrc
->top
;
939 if (h
>ddesc
.dwHeight
-dsty
) h
=ddesc
.dwHeight
-dsty
;
940 if (h
>sdesc
.dwHeight
-rsrc
->top
) h
=sdesc
.dwHeight
-rsrc
->top
;
942 w
=rsrc
->right
-rsrc
->left
;
943 if (w
>ddesc
.dwWidth
-dstx
) w
=ddesc
.dwWidth
-dstx
;
944 if (w
>sdesc
.dwWidth
-rsrc
->left
) w
=sdesc
.dwWidth
-rsrc
->left
;
948 memcpy( ddesc
.y
.lpSurface
+(dsty
+i
)*ddesc
.lPitch
+dstx
*bpp
,
949 sdesc
.y
.lpSurface
+(rsrc
->top
+i
)*sdesc
.lPitch
+rsrc
->left
*bpp
,
953 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
954 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
958 static HRESULT WINAPI
IDirectDrawSurface4_BltBatch(
959 LPDIRECTDRAWSURFACE4
this,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
961 FIXME(ddraw
,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
967 static HRESULT WINAPI
IDirectDrawSurface4_GetCaps(
968 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS caps
970 TRACE(ddraw
,"(%p)->GetCaps(%p)\n",this,caps
);
971 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
975 static HRESULT WINAPI
IDirectDrawSurface4_GetSurfaceDesc(
976 LPDIRECTDRAWSURFACE4
this,LPDDSURFACEDESC ddsd
978 TRACE(ddraw
, "(%p)->GetSurfaceDesc(%p)\n",
981 /* Simply copy the surface description stored in the object */
982 *ddsd
= this->s
.surface_desc
;
984 if (TRACE_ON(ddraw
)) {
985 fprintf(stderr
," flags: ");
986 _dump_DDSD(ddsd
->dwFlags
);
987 if (ddsd
->dwFlags
& DDSD_CAPS
) {
988 fprintf(stderr
, " caps: ");
989 _dump_DDSCAPS(ddsd
->ddsCaps
.dwCaps
);
991 fprintf(stderr
,"\n");
997 static ULONG WINAPI
IDirectDrawSurface4_AddRef(LPDIRECTDRAWSURFACE4
this) {
998 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1000 return ++(this->ref
);
1003 static ULONG WINAPI
DGA_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
1004 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1006 #ifdef HAVE_LIBXXF86DGA
1007 if (!--(this->ref
)) {
1008 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
1009 /* clear out of surface list */
1010 if (this->t
.dga
.fb_height
== -1) {
1011 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1013 this->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(this->t
.dga
.fb_height
/this->s
.ddraw
->e
.dga
.fb_height
));
1016 /* Free the backbuffer */
1017 if (this->s
.backbuffer
)
1018 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1020 HeapFree(GetProcessHeap(),0,this);
1023 #endif /* defined(HAVE_LIBXXF86DGA) */
1027 static ULONG WINAPI
Xlib_IDirectDrawSurface4_Release(LPDIRECTDRAWSURFACE4
this) {
1028 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1030 if (!--(this->ref
)) {
1031 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
1033 if( this->s
.backbuffer
)
1034 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
1036 if (this->t
.xlib
.image
!= NULL
) {
1037 if (this->s
.ddraw
->d
.depth
!= this->s
.ddraw
->d
.screen_depth
) {
1038 /* In pixel conversion mode, there are two buffers to release... */
1039 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1041 #ifdef HAVE_LIBXXSHM
1042 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1043 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1044 TSXDestroyImage(this->t
.xlib
.image
);
1045 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1048 HeapFree(GetProcessHeap(),0,this->t
.xlib
.image
->data
);
1049 this->t
.xlib
.image
->data
= NULL
;
1050 TSXDestroyImage(this->t
.xlib
.image
);
1051 #ifdef HAVE_LIBXXSHM
1056 this->t
.xlib
.image
->data
= NULL
;
1058 #ifdef HAVE_LIBXXSHM
1059 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
1060 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
1061 TSXDestroyImage(this->t
.xlib
.image
);
1062 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
1065 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1066 TSXDestroyImage(this->t
.xlib
.image
);
1067 #ifdef HAVE_LIBXXSHM
1072 this->t
.xlib
.image
= 0;
1074 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
1077 if (this->s
.palette
)
1078 this->s
.palette
->lpvtbl
->fnRelease(this->s
.palette
);
1080 HeapFree(GetProcessHeap(),0,this);
1087 static HRESULT WINAPI
IDirectDrawSurface4_GetAttachedSurface(
1088 LPDIRECTDRAWSURFACE4
this,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE4
*lpdsf
1090 TRACE(ddraw
, "(%p)->GetAttachedSurface(%p,%p)\n",
1091 this, lpddsd
, lpdsf
);
1093 if (TRACE_ON(ddraw
)) {
1094 TRACE(ddraw
," caps ");
1095 _dump_DDSCAPS(lpddsd
->dwCaps
);
1098 if (!(lpddsd
->dwCaps
& DDSCAPS_BACKBUFFER
)) {
1099 FIXME(ddraw
,"whoops, can only handle backbuffers for now\n");
1103 /* FIXME: should handle more than one backbuffer */
1104 *lpdsf
= this->s
.backbuffer
;
1106 if( this->s
.backbuffer
)
1107 this->s
.backbuffer
->lpvtbl
->fnAddRef( this->s
.backbuffer
);
1112 static HRESULT WINAPI
IDirectDrawSurface4_Initialize(
1113 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
1115 TRACE(ddraw
,"(%p)->(%p, %p)\n",this,ddraw
,lpdsfd
);
1117 return DDERR_ALREADYINITIALIZED
;
1120 static HRESULT WINAPI
IDirectDrawSurface4_GetPixelFormat(
1121 LPDIRECTDRAWSURFACE4
this,LPDDPIXELFORMAT pf
1123 TRACE(ddraw
,"(%p)->(%p)\n",this,pf
);
1125 *pf
= this->s
.surface_desc
.ddpfPixelFormat
;
1130 static HRESULT WINAPI
IDirectDrawSurface4_GetBltStatus(LPDIRECTDRAWSURFACE4
this,DWORD dwFlags
) {
1131 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,dwFlags
);
1135 static HRESULT WINAPI
IDirectDrawSurface4_GetOverlayPosition(
1136 LPDIRECTDRAWSURFACE4
this,LPLONG x1
,LPLONG x2
1138 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,x1
,x2
);
1142 static HRESULT WINAPI
IDirectDrawSurface4_SetClipper(
1143 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWCLIPPER clipper
1145 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,clipper
);
1149 static HRESULT WINAPI
IDirectDrawSurface4_AddAttachedSurface(
1150 LPDIRECTDRAWSURFACE4
this,LPDIRECTDRAWSURFACE4 surf
1152 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,surf
);
1154 this->lpvtbl
->fnAddRef(this);
1156 /* This hack will be enough for the moment */
1157 if (this->s
.backbuffer
== NULL
)
1158 this->s
.backbuffer
= surf
;
1162 static HRESULT WINAPI
IDirectDrawSurface4_GetDC(LPDIRECTDRAWSURFACE4
this,HDC32
* lphdc
) {
1163 FIXME(ddraw
,"(%p)->GetDC(%p)\n",this,lphdc
);
1164 *lphdc
= BeginPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1168 static HRESULT WINAPI
IDirectDrawSurface4_ReleaseDC(LPDIRECTDRAWSURFACE4
this,HDC32 hdc
) {
1172 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,(long)hdc
);
1173 EndPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
1175 /* Well, as what the application did paint in this DC is NOT saved in the surface,
1176 I fill it with 'dummy' values to have something on the screen */
1177 this->lpvtbl
->fnLock(this,NULL
,&desc
,0,0);
1178 for (y
= 0; y
< desc
.dwHeight
; y
++) {
1179 for (x
= 0; x
< desc
.dwWidth
; x
++) {
1180 ((unsigned char *) desc
.y
.lpSurface
)[x
+ y
* desc
.dwWidth
] = (unsigned int) this + x
+ y
;
1183 this->lpvtbl
->fnUnlock(this,NULL
);
1189 static HRESULT WINAPI
IDirectDrawSurface4_QueryInterface(LPDIRECTDRAWSURFACE4
this,REFIID refiid
,LPVOID
*obj
) {
1192 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1193 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1195 /* All DirectDrawSurface versions (1, 2, 3 and 4) use
1196 * the same interface. And IUnknown does that too of course.
1198 if ( !memcmp(&IID_IDirectDrawSurface4
,refiid
,sizeof(IID
)) ||
1199 !memcmp(&IID_IDirectDrawSurface3
,refiid
,sizeof(IID
)) ||
1200 !memcmp(&IID_IDirectDrawSurface2
,refiid
,sizeof(IID
)) ||
1201 !memcmp(&IID_IDirectDrawSurface
,refiid
,sizeof(IID
)) ||
1202 !memcmp(&IID_IUnknown
,refiid
,sizeof(IID
))
1205 this->lpvtbl
->fnAddRef(this);
1207 TRACE(ddraw
, " Creating IDirectDrawSurface interface (%p)\n", *obj
);
1211 else if (!memcmp(&IID_IDirect3DTexture2
,refiid
,sizeof(IID
)))
1213 /* Texture interface */
1214 *obj
= d3dtexture2_create(this);
1215 this->lpvtbl
->fnAddRef(this);
1217 TRACE(ddraw
, " Creating IDirect3DTexture2 interface (%p)\n", *obj
);
1221 else if (!memcmp(&IID_IDirect3DTexture
,refiid
,sizeof(IID
)))
1223 /* Texture interface */
1224 *obj
= d3dtexture_create(this);
1225 this->lpvtbl
->fnAddRef(this);
1227 TRACE(ddraw
, " Creating IDirect3DTexture interface (%p)\n", *obj
);
1231 else if (is_OpenGL_dx3(refiid
, (LPDIRECTDRAWSURFACE
) this, (LPDIRECT3DDEVICE
*) obj
))
1233 /* It is the OpenGL Direct3D Device */
1234 this->lpvtbl
->fnAddRef(this);
1236 TRACE(ddraw
, " Creating IDirect3DDevice interface (%p)\n", *obj
);
1241 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1242 return OLE_E_ENUM_NOMORE
;
1245 static HRESULT WINAPI
IDirectDrawSurface4_IsLost(LPDIRECTDRAWSURFACE4
this) {
1246 TRACE(ddraw
,"(%p)->(), stub!\n",this);
1247 return DD_OK
; /* hmm */
1250 static HRESULT WINAPI
IDirectDrawSurface4_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE4
this,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
1251 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,context
,esfcb
);
1255 static HRESULT WINAPI
IDirectDrawSurface4_Restore(LPDIRECTDRAWSURFACE4
this) {
1256 FIXME(ddraw
,"(%p)->(),stub!\n",this);
1260 static HRESULT WINAPI
IDirectDrawSurface4_SetColorKey(
1261 LPDIRECTDRAWSURFACE4
this, DWORD dwFlags
, LPDDCOLORKEY ckey
)
1263 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n",this,dwFlags
,ckey
);
1265 if( dwFlags
& DDCKEY_SRCBLT
)
1267 dwFlags
&= ~DDCKEY_SRCBLT
;
1268 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCBLT
;
1269 memcpy( &(this->s
.surface_desc
.ddckCKSrcBlt
), ckey
, sizeof( *ckey
) );
1272 if( dwFlags
& DDCKEY_DESTBLT
)
1274 dwFlags
&= ~DDCKEY_DESTBLT
;
1275 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTBLT
;
1276 memcpy( &(this->s
.surface_desc
.ddckCKDestBlt
), ckey
, sizeof( *ckey
) );
1279 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1281 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1282 this->s
.surface_desc
.dwFlags
|= DDSD_CKSRCOVERLAY
;
1283 memcpy( &(this->s
.surface_desc
.ddckCKSrcOverlay
), ckey
, sizeof( *ckey
) );
1286 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1288 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1289 this->s
.surface_desc
.dwFlags
|= DDSD_CKDESTOVERLAY
;
1290 memcpy( &(this->s
.surface_desc
.ddckCKDestOverlay
), ckey
, sizeof( *ckey
) );
1295 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1302 static HRESULT WINAPI
IDirectDrawSurface4_AddOverlayDirtyRect(
1303 LPDIRECTDRAWSURFACE4
this,
1306 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpRect
);
1311 static HRESULT WINAPI
IDirectDrawSurface4_DeleteAttachedSurface(
1312 LPDIRECTDRAWSURFACE4
this,
1314 LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface
)
1316 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags
,lpDDSAttachedSurface
);
1321 static HRESULT WINAPI
IDirectDrawSurface4_EnumOverlayZOrders(
1322 LPDIRECTDRAWSURFACE4
this,
1325 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1327 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags
,
1328 lpContext
, lpfnCallback
);
1333 static HRESULT WINAPI
IDirectDrawSurface4_GetClipper(
1334 LPDIRECTDRAWSURFACE4
this,
1335 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1337 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDClipper
);
1342 static HRESULT WINAPI
IDirectDrawSurface4_GetColorKey(
1343 LPDIRECTDRAWSURFACE4
this,
1345 LPDDCOLORKEY lpDDColorKey
)
1347 TRACE(ddraw
,"(%p)->(0x%08lx,%p)\n", this, dwFlags
, lpDDColorKey
);
1349 if( dwFlags
& DDCKEY_SRCBLT
) {
1350 dwFlags
&= ~DDCKEY_SRCBLT
;
1351 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcBlt
), sizeof( *lpDDColorKey
) );
1354 if( dwFlags
& DDCKEY_DESTBLT
)
1356 dwFlags
&= ~DDCKEY_DESTBLT
;
1357 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestBlt
), sizeof( *lpDDColorKey
) );
1360 if( dwFlags
& DDCKEY_SRCOVERLAY
)
1362 dwFlags
&= ~DDCKEY_SRCOVERLAY
;
1363 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKSrcOverlay
), sizeof( *lpDDColorKey
) );
1366 if( dwFlags
& DDCKEY_DESTOVERLAY
)
1368 dwFlags
&= ~DDCKEY_DESTOVERLAY
;
1369 memcpy( lpDDColorKey
, &(this->s
.surface_desc
.ddckCKDestOverlay
), sizeof( *lpDDColorKey
) );
1374 FIXME( ddraw
, "unhandled dwFlags: 0x%08lx\n", dwFlags
);
1380 static HRESULT WINAPI
IDirectDrawSurface4_GetFlipStatus(
1381 LPDIRECTDRAWSURFACE4
this,
1384 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1389 static HRESULT WINAPI
IDirectDrawSurface4_GetPalette(
1390 LPDIRECTDRAWSURFACE4
this,
1391 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1393 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDPalette
);
1398 static HRESULT WINAPI
IDirectDrawSurface4_SetOverlayPosition(
1399 LPDIRECTDRAWSURFACE4
this,
1403 FIXME(ddraw
,"(%p)->(%ld,%ld),stub!\n", this, lX
, lY
);
1408 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlay(
1409 LPDIRECTDRAWSURFACE4
this,
1411 LPDIRECTDRAWSURFACE4 lpDDDestSurface
,
1412 LPRECT32 lpDestRect
,
1414 LPDDOVERLAYFX lpDDOverlayFx
)
1416 FIXME(ddraw
,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1417 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1422 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayDisplay(
1423 LPDIRECTDRAWSURFACE4
this,
1426 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1431 static HRESULT WINAPI
IDirectDrawSurface4_UpdateOverlayZOrder(
1432 LPDIRECTDRAWSURFACE4
this,
1434 LPDIRECTDRAWSURFACE4 lpDDSReference
)
1436 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags
, lpDDSReference
);
1441 static HRESULT WINAPI
IDirectDrawSurface4_GetDDInterface(
1442 LPDIRECTDRAWSURFACE4
this,
1445 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDD
);
1447 /* Not sure about that... */
1448 *lplpDD
= (void *) this->s
.ddraw
;
1453 static HRESULT WINAPI
IDirectDrawSurface4_PageLock(
1454 LPDIRECTDRAWSURFACE4
this,
1457 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1462 static HRESULT WINAPI
IDirectDrawSurface4_PageUnlock(
1463 LPDIRECTDRAWSURFACE4
this,
1466 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1471 static HRESULT WINAPI
IDirectDrawSurface4_SetSurfaceDesc(
1472 LPDIRECTDRAWSURFACE4
this,
1473 LPDDSURFACEDESC lpDDSD
,
1476 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD
, dwFlags
);
1481 static HRESULT WINAPI
IDirectDrawSurface4_SetPrivateData(LPDIRECTDRAWSURFACE4
this,
1486 FIXME(ddraw
, "(%p)->(%p,%p,%ld,%08lx\n", this, guidTag
, lpData
, cbSize
, dwFlags
);
1491 static HRESULT WINAPI
IDirectDrawSurface4_GetPrivateData(LPDIRECTDRAWSURFACE4
this,
1494 LPDWORD lpcbBufferSize
) {
1495 FIXME(ddraw
, "(%p)->(%p,%p,%p)\n", this, guidTag
, lpBuffer
, lpcbBufferSize
);
1500 static HRESULT WINAPI
IDirectDrawSurface4_FreePrivateData(LPDIRECTDRAWSURFACE4
this,
1502 FIXME(ddraw
, "(%p)->(%p)\n", this, guidTag
);
1507 static HRESULT WINAPI
IDirectDrawSurface4_GetUniquenessValue(LPDIRECTDRAWSURFACE4
this,
1509 FIXME(ddraw
, "(%p)->(%p)\n", this, lpValue
);
1514 static HRESULT WINAPI
IDirectDrawSurface4_ChangeUniquenessValue(LPDIRECTDRAWSURFACE4
this) {
1515 FIXME(ddraw
, "(%p)\n", this);
1520 static struct IDirectDrawSurface4_VTable dga_dds4vt
= {
1521 IDirectDrawSurface4_QueryInterface
,
1522 IDirectDrawSurface4_AddRef
,
1523 DGA_IDirectDrawSurface4_Release
,
1524 IDirectDrawSurface4_AddAttachedSurface
,
1525 IDirectDrawSurface4_AddOverlayDirtyRect
,
1526 IDirectDrawSurface4_Blt
,
1527 IDirectDrawSurface4_BltBatch
,
1528 IDirectDrawSurface4_BltFast
,
1529 IDirectDrawSurface4_DeleteAttachedSurface
,
1530 IDirectDrawSurface4_EnumAttachedSurfaces
,
1531 IDirectDrawSurface4_EnumOverlayZOrders
,
1532 DGA_IDirectDrawSurface4_Flip
,
1533 IDirectDrawSurface4_GetAttachedSurface
,
1534 IDirectDrawSurface4_GetBltStatus
,
1535 IDirectDrawSurface4_GetCaps
,
1536 IDirectDrawSurface4_GetClipper
,
1537 IDirectDrawSurface4_GetColorKey
,
1538 IDirectDrawSurface4_GetDC
,
1539 IDirectDrawSurface4_GetFlipStatus
,
1540 IDirectDrawSurface4_GetOverlayPosition
,
1541 IDirectDrawSurface4_GetPalette
,
1542 IDirectDrawSurface4_GetPixelFormat
,
1543 IDirectDrawSurface4_GetSurfaceDesc
,
1544 IDirectDrawSurface4_Initialize
,
1545 IDirectDrawSurface4_IsLost
,
1546 IDirectDrawSurface4_Lock
,
1547 IDirectDrawSurface4_ReleaseDC
,
1548 IDirectDrawSurface4_Restore
,
1549 IDirectDrawSurface4_SetClipper
,
1550 IDirectDrawSurface4_SetColorKey
,
1551 IDirectDrawSurface4_SetOverlayPosition
,
1552 DGA_IDirectDrawSurface4_SetPalette
,
1553 DGA_IDirectDrawSurface4_Unlock
,
1554 IDirectDrawSurface4_UpdateOverlay
,
1555 IDirectDrawSurface4_UpdateOverlayDisplay
,
1556 IDirectDrawSurface4_UpdateOverlayZOrder
,
1557 IDirectDrawSurface4_GetDDInterface
,
1558 IDirectDrawSurface4_PageLock
,
1559 IDirectDrawSurface4_PageUnlock
,
1560 IDirectDrawSurface4_SetSurfaceDesc
,
1561 IDirectDrawSurface4_SetPrivateData
,
1562 IDirectDrawSurface4_GetPrivateData
,
1563 IDirectDrawSurface4_FreePrivateData
,
1564 IDirectDrawSurface4_GetUniquenessValue
,
1565 IDirectDrawSurface4_ChangeUniquenessValue
1568 static struct IDirectDrawSurface4_VTable xlib_dds4vt
= {
1569 IDirectDrawSurface4_QueryInterface
,
1570 IDirectDrawSurface4_AddRef
,
1571 Xlib_IDirectDrawSurface4_Release
,
1572 IDirectDrawSurface4_AddAttachedSurface
,
1573 IDirectDrawSurface4_AddOverlayDirtyRect
,
1574 IDirectDrawSurface4_Blt
,
1575 IDirectDrawSurface4_BltBatch
,
1576 IDirectDrawSurface4_BltFast
,
1577 IDirectDrawSurface4_DeleteAttachedSurface
,
1578 IDirectDrawSurface4_EnumAttachedSurfaces
,
1579 IDirectDrawSurface4_EnumOverlayZOrders
,
1580 Xlib_IDirectDrawSurface4_Flip
,
1581 IDirectDrawSurface4_GetAttachedSurface
,
1582 IDirectDrawSurface4_GetBltStatus
,
1583 IDirectDrawSurface4_GetCaps
,
1584 IDirectDrawSurface4_GetClipper
,
1585 IDirectDrawSurface4_GetColorKey
,
1586 IDirectDrawSurface4_GetDC
,
1587 IDirectDrawSurface4_GetFlipStatus
,
1588 IDirectDrawSurface4_GetOverlayPosition
,
1589 IDirectDrawSurface4_GetPalette
,
1590 IDirectDrawSurface4_GetPixelFormat
,
1591 IDirectDrawSurface4_GetSurfaceDesc
,
1592 IDirectDrawSurface4_Initialize
,
1593 IDirectDrawSurface4_IsLost
,
1594 IDirectDrawSurface4_Lock
,
1595 IDirectDrawSurface4_ReleaseDC
,
1596 IDirectDrawSurface4_Restore
,
1597 IDirectDrawSurface4_SetClipper
,
1598 IDirectDrawSurface4_SetColorKey
,
1599 IDirectDrawSurface4_SetOverlayPosition
,
1600 Xlib_IDirectDrawSurface4_SetPalette
,
1601 Xlib_IDirectDrawSurface4_Unlock
,
1602 IDirectDrawSurface4_UpdateOverlay
,
1603 IDirectDrawSurface4_UpdateOverlayDisplay
,
1604 IDirectDrawSurface4_UpdateOverlayZOrder
,
1605 IDirectDrawSurface4_GetDDInterface
,
1606 IDirectDrawSurface4_PageLock
,
1607 IDirectDrawSurface4_PageUnlock
,
1608 IDirectDrawSurface4_SetSurfaceDesc
,
1609 IDirectDrawSurface4_SetPrivateData
,
1610 IDirectDrawSurface4_GetPrivateData
,
1611 IDirectDrawSurface4_FreePrivateData
,
1612 IDirectDrawSurface4_GetUniquenessValue
,
1613 IDirectDrawSurface4_ChangeUniquenessValue
1616 /******************************************************************************
1617 * DirectDrawCreateClipper (DDRAW.7)
1619 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
1620 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
1621 LPUNKNOWN pUnkOuter
)
1623 TRACE(ddraw
, "(%08lx,%p,%p)\n", dwFlags
, lplpDDClipper
, pUnkOuter
);
1625 *lplpDDClipper
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
1626 (*lplpDDClipper
)->lpvtbl
= &ddclipvt
;
1627 (*lplpDDClipper
)->ref
= 1;
1632 /******************************************************************************
1633 * IDirectDrawClipper
1635 static HRESULT WINAPI
IDirectDrawClipper_SetHwnd(
1636 LPDIRECTDRAWCLIPPER
this,DWORD x
,HWND32 hwnd
1638 FIXME(ddraw
,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x
,(DWORD
)hwnd
);
1642 static ULONG WINAPI
IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER
this) {
1643 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1648 HeapFree(GetProcessHeap(),0,this);
1652 static HRESULT WINAPI
IDirectDrawClipper_GetClipList(
1653 LPDIRECTDRAWCLIPPER
this,LPRECT32 rects
,LPRGNDATA lprgn
,LPDWORD hmm
1655 FIXME(ddraw
,"(%p,%p,%p,%p),stub!\n",this,rects
,lprgn
,hmm
);
1660 static HRESULT WINAPI
IDirectDrawClipper_SetClipList(
1661 LPDIRECTDRAWCLIPPER
this,LPRGNDATA lprgn
,DWORD hmm
1663 FIXME(ddraw
,"(%p,%p,%ld),stub!\n",this,lprgn
,hmm
);
1667 static HRESULT WINAPI
IDirectDrawClipper_QueryInterface(
1668 LPDIRECTDRAWCLIPPER
this,
1672 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,riid
,ppvObj
);
1673 return OLE_E_ENUM_NOMORE
;
1676 static ULONG WINAPI
IDirectDrawClipper_AddRef( LPDIRECTDRAWCLIPPER
this )
1678 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1679 return ++(this->ref
);
1682 static HRESULT WINAPI
IDirectDrawClipper_GetHWnd(
1683 LPDIRECTDRAWCLIPPER
this,
1686 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,HWndPtr
);
1690 static HRESULT WINAPI
IDirectDrawClipper_Initialize(
1691 LPDIRECTDRAWCLIPPER
this,
1695 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n",this,lpDD
,dwFlags
);
1699 static HRESULT WINAPI
IDirectDrawClipper_IsClipListChanged(
1700 LPDIRECTDRAWCLIPPER
this,
1701 BOOL32
* lpbChanged
)
1703 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpbChanged
);
1707 static struct IDirectDrawClipper_VTable ddclipvt
= {
1708 IDirectDrawClipper_QueryInterface
,
1709 IDirectDrawClipper_AddRef
,
1710 IDirectDrawClipper_Release
,
1711 IDirectDrawClipper_GetClipList
,
1712 IDirectDrawClipper_GetHWnd
,
1713 IDirectDrawClipper_Initialize
,
1714 IDirectDrawClipper_IsClipListChanged
,
1715 IDirectDrawClipper_SetClipList
,
1716 IDirectDrawClipper_SetHwnd
1720 /******************************************************************************
1721 * IDirectDrawPalette
1723 static HRESULT WINAPI
IDirectDrawPalette_GetEntries(
1724 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1728 TRACE(ddraw
,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1729 this,x
,start
,count
,palent
);
1731 if (!this->cm
) /* should not happen */ {
1732 FIXME(ddraw
,"app tried to read colormap for non-palettized mode\n");
1733 return DDERR_GENERIC
;
1735 for (i
=0;i
<count
;i
++) {
1736 palent
[i
].peRed
= this->palents
[start
+i
].peRed
;
1737 palent
[i
].peBlue
= this->palents
[start
+i
].peBlue
;
1738 palent
[i
].peGreen
= this->palents
[start
+i
].peGreen
;
1739 palent
[i
].peFlags
= this->palents
[start
+i
].peFlags
;
1745 static HRESULT WINAPI
Xlib_IDirectDrawPalette_SetEntries(
1746 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1751 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1752 this,x
,start
,count
,palent
1754 for (i
=0;i
<count
;i
++) {
1755 xc
.red
= palent
[i
].peRed
<<8;
1756 xc
.blue
= palent
[i
].peBlue
<<8;
1757 xc
.green
= palent
[i
].peGreen
<<8;
1758 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1762 TSXStoreColor(display
,this->cm
,&xc
);
1764 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1765 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1766 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1767 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1770 /* Now, if we are in 'depth conversion mode', update the screen palette */
1771 if (this->ddraw
->d
.depth
!= this->ddraw
->d
.screen_depth
) {
1774 switch (this->ddraw
->d
.screen_depth
) {
1776 unsigned short *screen_palette
= (unsigned short *) this->screen_palents
;
1778 for (i
= 0; i
< count
; i
++) {
1779 screen_palette
[start
+ i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
1780 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
1781 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
1786 ERR(ddraw
, "Memory corruption !\n");
1791 if (!this->cm
) /* should not happen */ {
1796 static HRESULT WINAPI
DGA_IDirectDrawPalette_SetEntries(
1797 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1799 #ifdef HAVE_LIBXXF86DGA
1804 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1805 this,x
,start
,count
,palent
1807 if (!this->cm
) /* should not happen */ {
1808 FIXME(ddraw
,"app tried to set colormap in non-palettized mode\n");
1809 return DDERR_GENERIC
;
1811 /* FIXME: free colorcells instead of freeing whole map */
1813 this->cm
= TSXCopyColormapAndFree(display
,this->cm
);
1814 TSXFreeColormap(display
,cm
);
1816 for (i
=0;i
<count
;i
++) {
1817 xc
.red
= palent
[i
].peRed
<<8;
1818 xc
.blue
= palent
[i
].peBlue
<<8;
1819 xc
.green
= palent
[i
].peGreen
<<8;
1820 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1823 TSXStoreColor(display
,this->cm
,&xc
);
1825 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1826 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1827 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1828 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1830 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->cm
);
1832 #else /* defined(HAVE_LIBXXF86DGA) */
1833 return E_UNEXPECTED
;
1834 #endif /* defined(HAVE_LIBXXF86DGA) */
1837 static ULONG WINAPI
IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE
this) {
1838 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1839 if (!--(this->ref
)) {
1841 TSXFreeColormap(display
,this->cm
);
1844 HeapFree(GetProcessHeap(),0,this);
1850 static ULONG WINAPI
IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE
this) {
1852 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1853 return ++(this->ref
);
1856 static HRESULT WINAPI
IDirectDrawPalette_Initialize(
1857 LPDIRECTDRAWPALETTE
this,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
1859 TRACE(ddraw
,"(%p)->(%p,%ld,%p)\n", this, ddraw
, x
, palent
);
1861 return DDERR_ALREADYINITIALIZED
;
1864 static HRESULT WINAPI
IDirectDrawPalette_GetCaps(
1865 LPDIRECTDRAWPALETTE
this, LPDWORD lpdwCaps
)
1867 FIXME( ddraw
, "(%p)->(%p) stub.\n", this, lpdwCaps
);
1871 static HRESULT WINAPI
IDirectDrawPalette_QueryInterface(
1872 LPDIRECTDRAWPALETTE
this,REFIID refiid
,LPVOID
*obj
)
1876 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1877 FIXME(ddraw
,"(%p)->(%s,%p) stub.\n",this,xrefiid
,obj
);
1882 static struct IDirectDrawPalette_VTable dga_ddpalvt
= {
1883 IDirectDrawPalette_QueryInterface
,
1884 IDirectDrawPalette_AddRef
,
1885 IDirectDrawPalette_Release
,
1886 IDirectDrawPalette_GetCaps
,
1887 IDirectDrawPalette_GetEntries
,
1888 IDirectDrawPalette_Initialize
,
1889 DGA_IDirectDrawPalette_SetEntries
1892 static struct IDirectDrawPalette_VTable xlib_ddpalvt
= {
1893 IDirectDrawPalette_QueryInterface
,
1894 IDirectDrawPalette_AddRef
,
1895 IDirectDrawPalette_Release
,
1896 IDirectDrawPalette_GetCaps
,
1897 IDirectDrawPalette_GetEntries
,
1898 IDirectDrawPalette_Initialize
,
1899 Xlib_IDirectDrawPalette_SetEntries
1902 /*******************************************************************************
1905 static HRESULT WINAPI
IDirect3D_QueryInterface(
1906 LPDIRECT3D
this,REFIID refiid
,LPVOID
*obj
1908 /* FIXME: Not sure if this is correct */
1911 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1912 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1913 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
1915 this->lpvtbl
->fnAddRef(this);
1917 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
1921 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
1924 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1926 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1927 this->lpvtbl
->fnAddRef(this);
1928 d3d
->lpvtbl
= &d3dvt
;
1931 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
1935 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
1938 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1940 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1941 this->lpvtbl
->fnAddRef(this);
1942 d3d
->lpvtbl
= &d3d2vt
;
1945 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
1949 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1950 return OLE_E_ENUM_NOMORE
;
1953 static ULONG WINAPI
IDirect3D_AddRef(LPDIRECT3D
this) {
1954 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1956 return ++(this->ref
);
1959 static ULONG WINAPI
IDirect3D_Release(LPDIRECT3D
this)
1961 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1963 if (!--(this->ref
)) {
1964 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
1965 HeapFree(GetProcessHeap(),0,this);
1971 static HRESULT WINAPI
IDirect3D_Initialize(
1972 LPDIRECT3D
this, REFIID refiid
)
1974 /* FIXME: Not sure if this is correct */
1977 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1978 FIXME(ddraw
,"(%p)->(%s):stub.\n",this,xrefiid
);
1980 return DDERR_ALREADYINITIALIZED
;
1983 static HRESULT WINAPI
IDirect3D_EnumDevices(LPDIRECT3D
this,
1984 LPD3DENUMDEVICESCALLBACK cb
,
1986 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
1988 /* Call functions defined in d3ddevices.c */
1989 if (d3d_OpenGL_dx3(cb
, context
))
1995 static HRESULT WINAPI
IDirect3D_CreateLight(LPDIRECT3D
this,
1996 LPDIRECT3DLIGHT
*lplight
,
1999 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
2001 /* Call the creation function that is located in d3dlight.c */
2002 *lplight
= d3dlight_create_dx3(this);
2007 static HRESULT WINAPI
IDirect3D_CreateMaterial(LPDIRECT3D
this,
2008 LPDIRECT3DMATERIAL
*lpmaterial
,
2011 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
2013 /* Call the creation function that is located in d3dviewport.c */
2014 *lpmaterial
= d3dmaterial_create(this);
2019 static HRESULT WINAPI
IDirect3D_CreateViewport(LPDIRECT3D
this,
2020 LPDIRECT3DVIEWPORT
*lpviewport
,
2023 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
2025 /* Call the creation function that is located in d3dviewport.c */
2026 *lpviewport
= d3dviewport_create(this);
2031 static HRESULT WINAPI
IDirect3D_FindDevice(LPDIRECT3D
this,
2032 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2033 LPD3DFINDDEVICERESULT lpfinddevrst
)
2035 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2040 static struct IDirect3D_VTable d3dvt
= {
2041 IDirect3D_QueryInterface
,
2044 IDirect3D_Initialize
,
2045 IDirect3D_EnumDevices
,
2046 IDirect3D_CreateLight
,
2047 IDirect3D_CreateMaterial
,
2048 IDirect3D_CreateViewport
,
2049 IDirect3D_FindDevice
2052 /*******************************************************************************
2055 static HRESULT WINAPI
IDirect3D2_QueryInterface(
2056 LPDIRECT3D2
this,REFIID refiid
,LPVOID
*obj
) {
2057 /* For the moment, we use the same function as in IDirect3D */
2058 TRACE(ddraw
, "Calling IDirect3D enumerating function.\n");
2060 return IDirect3D_QueryInterface((LPDIRECT3D
) this, refiid
, obj
);
2063 static ULONG WINAPI
IDirect3D2_AddRef(LPDIRECT3D2
this) {
2064 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
2066 return ++(this->ref
);
2069 static ULONG WINAPI
IDirect3D2_Release(LPDIRECT3D2
this) {
2070 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
2072 if (!--(this->ref
)) {
2073 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
2074 HeapFree(GetProcessHeap(),0,this);
2080 static HRESULT WINAPI
IDirect3D2_EnumDevices(
2081 LPDIRECT3D2
this,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
2083 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
2085 /* Call functions defined in d3ddevices.c */
2086 if (d3d_OpenGL(cb
, context
))
2092 static HRESULT WINAPI
IDirect3D2_CreateLight(LPDIRECT3D2
this,
2093 LPDIRECT3DLIGHT
*lplight
,
2096 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lplight
, lpunk
);
2098 /* Call the creation function that is located in d3dlight.c */
2099 *lplight
= d3dlight_create(this);
2104 static HRESULT WINAPI
IDirect3D2_CreateMaterial(LPDIRECT3D2
this,
2105 LPDIRECT3DMATERIAL2
*lpmaterial
,
2108 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpmaterial
, lpunk
);
2110 /* Call the creation function that is located in d3dviewport.c */
2111 *lpmaterial
= d3dmaterial2_create(this);
2116 static HRESULT WINAPI
IDirect3D2_CreateViewport(LPDIRECT3D2
this,
2117 LPDIRECT3DVIEWPORT2
*lpviewport
,
2120 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpviewport
, lpunk
);
2122 /* Call the creation function that is located in d3dviewport.c */
2123 *lpviewport
= d3dviewport2_create(this);
2128 static HRESULT WINAPI
IDirect3D2_FindDevice(LPDIRECT3D2
this,
2129 LPD3DFINDDEVICESEARCH lpfinddevsrc
,
2130 LPD3DFINDDEVICERESULT lpfinddevrst
)
2132 TRACE(ddraw
, "(%p)->(%p,%p): stub\n", this, lpfinddevsrc
, lpfinddevrst
);
2137 static HRESULT WINAPI
IDirect3D2_CreateDevice(LPDIRECT3D2
this,
2139 LPDIRECTDRAWSURFACE surface
,
2140 LPDIRECT3DDEVICE2
*device
)
2144 WINE_StringFromCLSID(rguid
,xbuf
);
2145 FIXME(ddraw
,"(%p)->(%s,%p,%p): stub\n",this,xbuf
,surface
,device
);
2147 if (is_OpenGL(rguid
, surface
, device
, this)) {
2148 this->lpvtbl
->fnAddRef(this);
2152 return DDERR_INVALIDPARAMS
;
2155 static struct IDirect3D2_VTable d3d2vt
= {
2156 IDirect3D2_QueryInterface
,
2159 IDirect3D2_EnumDevices
,
2160 IDirect3D2_CreateLight
,
2161 IDirect3D2_CreateMaterial
,
2162 IDirect3D2_CreateViewport
,
2163 IDirect3D2_FindDevice
,
2164 IDirect3D2_CreateDevice
2167 /*******************************************************************************
2171 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
2172 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
2174 static INT32 ddrawXlibThisOffset
= 0;
2176 static HRESULT
common_off_screen_CreateSurface(LPDIRECTDRAW2
this,
2177 LPDDSURFACEDESC lpddsd
,
2178 LPDIRECTDRAWSURFACE lpdsf
)
2182 /* The surface was already allocated when entering in this function */
2183 TRACE(ddraw
,"using system memory for a surface (%p)\n", lpdsf
);
2185 if (lpddsd
->dwFlags
& DDSD_ZBUFFERBITDEPTH
) {
2186 /* This is a Z Buffer */
2187 TRACE(ddraw
, "Creating Z-Buffer of %ld bit depth\n", lpddsd
->x
.dwZBufferBitDepth
);
2188 bpp
= lpddsd
->x
.dwZBufferBitDepth
/ 8;
2190 /* This is a standard image */
2191 if (!(lpddsd
->dwFlags
& DDSD_PIXELFORMAT
)) {
2192 /* No pixel format => use DirectDraw's format */
2193 _getpixelformat(this,&(lpddsd
->ddpfPixelFormat
));
2194 lpddsd
->dwFlags
|= DDSD_PIXELFORMAT
;
2196 /* To check what the program wants */
2197 if (TRACE_ON(ddraw
)) {
2198 _dump_pixelformat(&(lpddsd
->ddpfPixelFormat
));
2202 if (lpddsd
->ddpfPixelFormat
.dwFlags
& DDPF_PALETTEINDEXED8
) {
2205 bpp
= lpddsd
->ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
2209 /* Copy the surface description */
2210 lpdsf
->s
.surface_desc
= *lpddsd
;
2212 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2213 lpdsf
->s
.surface_desc
.y
.lpSurface
= (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpddsd
->dwWidth
* lpddsd
->dwHeight
* bpp
);
2214 lpdsf
->s
.surface_desc
.lPitch
= lpddsd
->dwWidth
* bpp
;
2219 static HRESULT WINAPI
DGA_IDirectDraw2_CreateSurface(
2220 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2222 #ifdef HAVE_LIBXXF86DGA
2225 TRACE(ddraw
, "(%p)->(%p,%p,%p)\n",this,lpddsd
,lpdsf
,lpunk
);
2226 if (TRACE_ON(ddraw
)) {
2227 DUMP("[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2228 _dump_DDSD(lpddsd
->dwFlags
);
2229 fprintf(stderr
,"caps ");
2230 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2231 fprintf(stderr
,"]\n");
2234 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2235 this->lpvtbl
->fnAddRef(this);
2238 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&dga_dds4vt
;
2239 (*lpdsf
)->s
.ddraw
= this;
2240 (*lpdsf
)->s
.palette
= NULL
;
2241 (*lpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
2243 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2244 lpddsd
->dwWidth
= this->d
.width
;
2245 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2246 lpddsd
->dwHeight
= this->d
.height
;
2248 /* Check if this a 'primary surface' or not */
2249 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2250 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2252 /* This is THE primary surface => there is DGA-specific code */
2253 /* First, store the surface description */
2254 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2256 /* Find a viewport */
2258 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2260 TRACE(ddraw
,"using viewport %d for a primary surface\n",i
);
2261 /* if i == 32 or maximum ... return error */
2262 this->e
.dga
.vpmask
|=(1<<i
);
2263 (*lpdsf
)->s
.surface_desc
.y
.lpSurface
=
2264 this->e
.dga
.fb_addr
+((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
2265 (*lpdsf
)->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2266 (*lpdsf
)->s
.surface_desc
.lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
2267 lpddsd
->lPitch
= (*lpdsf
)->s
.surface_desc
.lPitch
;
2269 /* Add flags if there were not present */
2270 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2271 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2272 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2273 TRACE(ddraw
,"primary surface: dwWidth=%ld, dwHeight=%ld, lPitch=%ld\n",this->d
.width
,this->d
.height
,lpddsd
->lPitch
);
2274 /* We put our surface always in video memory */
2275 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2276 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
2277 (*lpdsf
)->s
.backbuffer
= NULL
;
2279 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2280 LPDIRECTDRAWSURFACE4 back
;
2282 if (lpddsd
->dwBackBufferCount
>1)
2283 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2285 (*lpdsf
)->s
.backbuffer
= back
=
2286 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2287 this->lpvtbl
->fnAddRef(this);
2289 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&dga_dds4vt
;
2291 if (!(this->e
.dga
.vpmask
& (1<<i
)))
2293 TRACE(ddraw
,"using viewport %d for backbuffer\n",i
);
2294 /* if i == 32 or maximum ... return error */
2295 this->e
.dga
.vpmask
|=(1<<i
);
2296 back
->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
2298 /* Copy the surface description from the front buffer */
2299 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2300 /* Change the parameters that are not the same */
2301 back
->s
.surface_desc
.y
.lpSurface
= this->e
.dga
.fb_addr
+
2302 ((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
2303 back
->s
.ddraw
= this;
2304 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2307 /* Add relevant info to front and back buffers */
2308 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2309 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2310 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2311 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2312 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2315 /* There is no DGA-specific code here...
2316 Go to the common surface creation function */
2317 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2321 #else /* defined(HAVE_LIBXXF86DGA) */
2322 return E_UNEXPECTED
;
2323 #endif /* defined(HAVE_LIBXXF86DGA) */
2326 #ifdef HAVE_LIBXXSHM
2327 /* Error handlers for Image creation */
2328 static int XShmErrorHandler(Display
*dpy
, XErrorEvent
*event
) {
2333 static XImage
*create_xshmimage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2335 int (*WineXHandler
)(Display
*, XErrorEvent
*);
2337 img
= TSXShmCreateImage(display
,
2338 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2339 this->d
.screen_depth
,
2342 &(lpdsf
->t
.xlib
.shminfo
),
2343 lpdsf
->s
.surface_desc
.dwWidth
,
2344 lpdsf
->s
.surface_desc
.dwHeight
);
2347 ERR(ddraw
, "Error creating XShm image. Reverting to standard X images !\n");
2348 this->e
.xlib
.xshm_active
= 0;
2352 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
2353 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
2354 ERR(ddraw
, "Error creating shared memory segment. Reverting to standard X images !\n");
2355 this->e
.xlib
.xshm_active
= 0;
2356 TSXDestroyImage(img
);
2360 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
2362 if (img
->data
== (char *) -1) {
2363 ERR(ddraw
, "Error attaching shared memory segment. Reverting to standard X images !\n");
2364 this->e
.xlib
.xshm_active
= 0;
2365 TSXDestroyImage(img
);
2366 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2369 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
2371 /* This is where things start to get trickier....
2372 First, we flush the current X connections to be sure to catch all non-XShm related
2374 TSXSync(display
, False
);
2375 /* Then we enter in the non-thread safe part of the tests */
2376 EnterCriticalSection( &X11DRV_CritSection
);
2378 /* Reset the error flag, sets our new error handler and try to attach the surface */
2380 WineXHandler
= XSetErrorHandler(XShmErrorHandler
);
2381 XShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
2382 XSync(display
, False
);
2384 /* Check the error flag */
2385 if (XShmErrorFlag
) {
2386 /* An error occured */
2390 shmdt(lpdsf
->t
.xlib
.shminfo
.shmaddr
);
2391 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2392 XSetErrorHandler(WineXHandler
);
2394 ERR(ddraw
, "Error attaching shared memory segment to X server. Reverting to standard X images !\n");
2395 this->e
.xlib
.xshm_active
= 0;
2397 /* Leave the critical section */
2398 LeaveCriticalSection( &X11DRV_CritSection
);
2403 /* Here, to be REALLY sure, I should do a XShmPutImage to check if this works,
2404 but it may be a bit overkill.... */
2405 XSetErrorHandler(WineXHandler
);
2406 LeaveCriticalSection( &X11DRV_CritSection
);
2408 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
2410 if (this->d
.depth
!= this->d
.screen_depth
) {
2411 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2412 lpdsf
->s
.surface_desc
.dwWidth
*
2413 lpdsf
->s
.surface_desc
.dwHeight
*
2414 (this->d
.depth
/ 8));
2416 lpdsf
->s
.surface_desc
.y
.lpSurface
= img
->data
;
2421 #endif /* HAVE_LIBXXSHM */
2423 static XImage
*create_ximage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE4 lpdsf
) {
2427 #ifdef HAVE_LIBXXSHM
2428 if (this->e
.xlib
.xshm_active
) {
2429 img
= create_xshmimage(this, lpdsf
);
2434 /* Allocate surface memory */
2435 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2436 lpdsf
->s
.surface_desc
.dwWidth
*
2437 lpdsf
->s
.surface_desc
.dwHeight
*
2438 (this->d
.depth
/ 8));
2440 if (this->d
.depth
!= this->d
.screen_depth
) {
2441 img_data
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
2442 lpdsf
->s
.surface_desc
.dwWidth
*
2443 lpdsf
->s
.surface_desc
.dwHeight
*
2444 (this->d
.screen_depth
/ 8));
2446 img_data
= lpdsf
->s
.surface_desc
.y
.lpSurface
;
2449 /* In this case, create an XImage */
2451 TSXCreateImage(display
,
2452 DefaultVisualOfScreen(X11DRV_GetXScreen()),
2453 this->d
.screen_depth
,
2457 lpdsf
->s
.surface_desc
.dwWidth
,
2458 lpdsf
->s
.surface_desc
.dwHeight
,
2460 lpdsf
->s
.surface_desc
.dwWidth
* (this->d
.screen_depth
/ 8)
2463 #ifdef HAVE_LIBXXSHM
2466 if (this->d
.depth
!= this->d
.screen_depth
) {
2467 lpdsf
->s
.surface_desc
.lPitch
= (this->d
.depth
/ 8) * lpdsf
->s
.surface_desc
.dwWidth
;
2469 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
2475 static HRESULT WINAPI
Xlib_IDirectDraw2_CreateSurface(
2476 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
2478 TRACE(ddraw
, "(%p)->CreateSurface(%p,%p,%p)\n",
2479 this,lpddsd
,lpdsf
,lpunk
);
2481 if (TRACE_ON(ddraw
)) {
2482 fprintf(stderr
,"[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
2483 _dump_DDSD(lpddsd
->dwFlags
);
2484 fprintf(stderr
,"caps ");
2485 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
2486 fprintf(stderr
,"]\n");
2489 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
2491 this->lpvtbl
->fnAddRef(this);
2492 (*lpdsf
)->s
.ddraw
= this;
2494 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&xlib_dds4vt
;
2495 (*lpdsf
)->s
.palette
= NULL
;
2496 (*lpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
2498 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
2499 lpddsd
->dwWidth
= this->d
.width
;
2500 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
2501 lpddsd
->dwHeight
= this->d
.height
;
2503 /* Check if this a 'primary surface' or not */
2504 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
2505 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
2508 TRACE(ddraw
,"using standard XImage for a primary surface (%p)\n", *lpdsf
);
2510 /* First, store the surface description */
2511 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
2513 /* Create the XImage */
2514 img
= create_ximage(this, (LPDIRECTDRAWSURFACE4
) *lpdsf
);
2516 return DDERR_OUTOFMEMORY
;
2517 (*lpdsf
)->t
.xlib
.image
= img
;
2519 /* Add flags if there were not present */
2520 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
2521 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
2522 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
2523 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
|DDSCAPS_VIDEOMEMORY
;
2524 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
2525 (*lpdsf
)->s
.backbuffer
= NULL
;
2527 /* Check for backbuffers */
2528 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
2529 LPDIRECTDRAWSURFACE4 back
;
2532 if (lpddsd
->dwBackBufferCount
>1)
2533 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
2535 (*lpdsf
)->s
.backbuffer
= back
=
2536 (LPDIRECTDRAWSURFACE4
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface4
));
2538 TRACE(ddraw
,"allocated back-buffer (%p)\n", back
);
2540 this->lpvtbl
->fnAddRef(this);
2541 back
->s
.ddraw
= this;
2544 back
->lpvtbl
= (LPDIRECTDRAWSURFACE4_VTABLE
)&xlib_dds4vt
;
2545 /* Copy the surface description from the front buffer */
2546 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
2548 /* Create the XImage */
2549 img
= create_ximage(this, back
);
2551 return DDERR_OUTOFMEMORY
;
2552 back
->t
.xlib
.image
= img
;
2554 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
2557 /* Add relevant info to front and back buffers */
2558 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
2559 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
2560 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
2561 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
2562 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VIDEOMEMORY
;
2565 /* There is no Xlib-specific code here...
2566 Go to the common surface creation function */
2567 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
2573 static HRESULT WINAPI
IDirectDraw2_DuplicateSurface(
2574 LPDIRECTDRAW2
this,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
2576 FIXME(ddraw
,"(%p)->(%p,%p) simply copies\n",this,src
,dst
);
2577 *dst
= src
; /* FIXME */
2582 * The Xlib Implementation tries to use the passed hwnd as drawing window,
2583 * even when the approbiate bitmasks are not specified.
2585 static HRESULT WINAPI
IDirectDraw2_SetCooperativeLevel(
2586 LPDIRECTDRAW2
this,HWND32 hwnd
,DWORD cooplevel
2593 FE(DDSCL_FULLSCREEN
)
2594 FE(DDSCL_ALLOWREBOOT
)
2595 FE(DDSCL_NOWINDOWCHANGES
)
2597 FE(DDSCL_ALLOWMODEX
)
2599 FE(DDSCL_SETFOCUSWINDOW
)
2600 FE(DDSCL_SETDEVICEWINDOW
)
2601 FE(DDSCL_CREATEDEVICEWINDOW
)
2604 FIXME(ddraw
,"(%p)->(%08lx,%08lx)\n",this,(DWORD
)hwnd
,cooplevel
);
2605 if(TRACE_ON(ddraw
)){
2606 dbg_decl_str(ddraw
, 512);
2607 for (i
=0;i
<sizeof(flagmap
)/sizeof(flagmap
[0]);i
++)
2608 if (flagmap
[i
].mask
& cooplevel
)
2609 dsprintf(ddraw
, "%s ", flagmap
[i
].name
);
2610 TRACE(ddraw
," cooperative level %s\n", dbg_str(ddraw
));
2612 this->d
.mainWindow
= hwnd
;
2614 /* This will be overwritten in the case of Full Screen mode.
2615 Windowed games could work with that :-) */
2617 this->d
.drawable
= X11DRV_WND_GetXWindow(WIN_FindWndPtr(hwnd
));
2622 /* Small helper to either use the cooperative window or create a new
2623 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
2625 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW
this) {
2628 /* Do not destroy the application supplied cooperative window */
2629 if (this->d
.window
&& this->d
.window
!= this->d
.mainWindow
) {
2630 DestroyWindow32(this->d
.window
);
2633 /* Sanity check cooperative window before assigning it to drawing. */
2634 if ( IsWindow32(this->d
.mainWindow
) &&
2635 IsWindowVisible32(this->d
.mainWindow
)
2637 GetWindowRect32(this->d
.mainWindow
,&rect
);
2638 if (((rect
.right
-rect
.left
) >= this->d
.width
) &&
2639 ((rect
.bottom
-rect
.top
) >= this->d
.height
)
2641 this->d
.window
= this->d
.mainWindow
;
2643 /* ... failed, create new one. */
2644 if (!this->d
.window
) {
2645 this->d
.window
= CreateWindowEx32A(
2649 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
2658 /*Store THIS with the window. We'll use it in the window procedure*/
2659 SetWindowLong32A(this->d
.window
,ddrawXlibThisOffset
,(LONG
)this);
2660 ShowWindow32(this->d
.window
,TRUE
);
2661 UpdateWindow32(this->d
.window
);
2663 SetFocus32(this->d
.window
);
2666 static HRESULT WINAPI
DGA_IDirectDraw_SetDisplayMode(
2667 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2669 #ifdef HAVE_LIBXXF86DGA
2670 int i
,*depths
,depcount
,mode_count
;
2672 TRACE(ddraw
, "(%p)->(%ld,%ld,%ld)\n", this, width
, height
, depth
);
2674 /* We hope getting the asked for depth */
2675 this->d
.screen_depth
= depth
;
2677 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
2679 for (i
=0;i
<depcount
;i
++)
2680 if (depths
[i
]==depth
)
2683 if (i
==depcount
) {/* not found */
2684 ERR(ddraw
,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
2685 return DDERR_UNSUPPORTEDMODE
;
2687 if (this->d
.width
< width
) {
2688 ERR(ddraw
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,this->d
.width
);
2689 return DDERR_UNSUPPORTEDMODE
;
2691 this->d
.width
= width
;
2692 this->d
.height
= height
;
2693 this->d
.depth
= depth
;
2695 /* adjust fb_height, so we don't overlap */
2696 if (this->e
.dga
.fb_height
< height
)
2697 this->e
.dga
.fb_height
= height
;
2698 _common_IDirectDraw_SetDisplayMode(this);
2700 #ifdef HAVE_LIBXXF86VM
2702 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
2703 XF86VidModeModeLine mod_tmp
;
2704 /* int dotclock_tmp; */
2706 /* save original video mode and set fullscreen if available*/
2707 orig_mode
= (XF86VidModeModeInfo
*) malloc (sizeof(XF86VidModeModeInfo
));
2708 TSXF86VidModeGetModeLine(display
, DefaultScreen(display
), &orig_mode
->dotclock
, &mod_tmp
);
2709 orig_mode
->hdisplay
= mod_tmp
.hdisplay
;
2710 orig_mode
->hsyncstart
= mod_tmp
.hsyncstart
;
2711 orig_mode
->hsyncend
= mod_tmp
.hsyncend
;
2712 orig_mode
->htotal
= mod_tmp
.htotal
;
2713 orig_mode
->vdisplay
= mod_tmp
.vdisplay
;
2714 orig_mode
->vsyncstart
= mod_tmp
.vsyncstart
;
2715 orig_mode
->vsyncend
= mod_tmp
.vsyncend
;
2716 orig_mode
->vtotal
= mod_tmp
.vtotal
;
2717 orig_mode
->flags
= mod_tmp
.flags
;
2718 orig_mode
->private = mod_tmp
.private;
2720 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
2721 for (i
=0;i
<mode_count
;i
++)
2723 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
2725 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
2726 *vidmode
= *(all_modes
[i
]);
2729 TSXFree(all_modes
[i
]->private);
2731 for (i
++;i
<mode_count
;i
++) TSXFree(all_modes
[i
]->private);
2735 WARN(ddraw
, "Fullscreen mode not available!\n");
2739 TRACE(ddraw
,"SwitchToMode(%dx%d)\n",vidmode
->hdisplay
,vidmode
->vdisplay
);
2740 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
2741 #if 0 /* This messes up my screen (XF86_Mach64, 3.3.2.3a) for some reason, and should now be unnecessary */
2742 TSXF86VidModeSetViewPort(display
, DefaultScreen(display
), 0, 0);
2748 /* FIXME: this function OVERWRITES several signal handlers.
2749 * can we save them? and restore them later? In a way that
2750 * it works for the library too?
2752 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
2754 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,this->e
.dga
.fb_height
);
2756 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
2759 #ifdef RESTORE_SIGNALS
2760 SIGNAL_InitHandlers();
2763 #else /* defined(HAVE_LIBXXF86DGA) */
2764 return E_UNEXPECTED
;
2765 #endif /* defined(HAVE_LIBXXF86DGA) */
2768 static HRESULT WINAPI
Xlib_IDirectDraw_SetDisplayMode(
2769 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2771 int i
,*depths
,depcount
;
2774 TRACE(ddraw
, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2775 this, width
, height
, depth
);
2777 /* We hope getting the asked for depth */
2778 this->d
.screen_depth
= depth
;
2780 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
2782 for (i
=0;i
<depcount
;i
++)
2783 if (depths
[i
]==depth
)
2785 if (i
==depcount
) {/* not found */
2786 for (i
=0;i
<depcount
;i
++)
2791 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
2792 MessageBox32A(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
2794 return DDERR_UNSUPPORTEDMODE
;
2796 WARN(ddraw
, "Warning : running in depth-convertion mode. Should run using a %ld depth for optimal performances.\n", depth
);
2797 this->d
.screen_depth
= 16;
2802 this->d
.width
= width
;
2803 this->d
.height
= height
;
2804 this->d
.depth
= depth
;
2806 _common_IDirectDraw_SetDisplayMode(this);
2808 this->d
.paintable
= 1;
2809 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_FindWndPtr(this->d
.window
)->pDriverData
)->window
;
2810 /* We don't have a context for this window. Host off the desktop */
2811 if( !this->d
.drawable
)
2812 this->d
.drawable
= ((X11DRV_WND_DATA
*) WIN_GetDesktop()->pDriverData
)->window
;
2816 static HRESULT WINAPI
DGA_IDirectDraw2_GetCaps(
2817 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2819 #ifdef HAVE_LIBXXF86DGA
2820 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2821 caps1
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2822 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2823 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2825 caps2
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2826 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2827 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2830 #else /* defined(HAVE_LIBXXF86DGA) */
2831 return E_UNEXPECTED
;
2832 #endif /* defined(HAVE_LIBXXF86DGA) */
2835 static void fill_caps(LPDDCAPS caps
) {
2836 /* This function tries to fill the capabilities of Wine's DDraw implementation.
2837 Need to be fixed, though.. */
2841 caps
->dwSize
= sizeof(*caps
);
2842 caps
->dwCaps
= DDCAPS_3D
| DDCAPS_ALPHA
| DDCAPS_BLT
| DDCAPS_BLTSTRETCH
| DDCAPS_BLTCOLORFILL
| DDCAPS_BLTDEPTHFILL
|
2843 DDCAPS_CANBLTSYSMEM
| DDCAPS_COLORKEY
| DDCAPS_PALETTE
| DDCAPS_ZBLTS
;
2844 caps
->dwCaps2
= DDCAPS2_CERTIFIED
| DDCAPS2_NO2DDURING3DSCENE
| DDCAPS2_NOPAGELOCKREQUIRED
|
2845 DDCAPS2_WIDESURFACES
;
2846 caps
->dwCKeyCaps
= 0xFFFFFFFF; /* Should put real caps here one day... */
2848 caps
->dwFXAlphaCaps
= 0;
2849 caps
->dwPalCaps
= DDPCAPS_8BIT
| DDPCAPS_ALLOW256
;
2851 caps
->dwZBufferBitDepths
= DDBD_16
;
2852 /* I put here 8 Mo so that D3D applications will believe they have enough memory
2853 to put textures in video memory.
2854 BTW, is this only frame buffer memory or also texture memory (for Voodoo boards
2856 caps
->dwVidMemTotal
= 8192 * 1024;
2857 caps
->dwVidMemFree
= 8192 * 1024;
2858 /* These are all the supported capabilities of the surfaces */
2859 caps
->ddsCaps
.dwCaps
= DDSCAPS_3DDEVICE
| DDSCAPS_ALPHA
| DDSCAPS_BACKBUFFER
| DDSCAPS_COMPLEX
| DDSCAPS_FLIP
|
2860 DDSCAPS_FRONTBUFFER
| DDSCAPS_LOCALVIDMEM
| DDSCAPS_MIPMAP
| DDSCAPS_NONLOCALVIDMEM
| DDSCAPS_OFFSCREENPLAIN
|
2861 DDSCAPS_OVERLAY
| DDSCAPS_PALETTE
| DDSCAPS_PRIMARYSURFACE
| DDSCAPS_SYSTEMMEMORY
| DDSCAPS_TEXTURE
|
2862 DDSCAPS_VIDEOMEMORY
| DDSCAPS_VISIBLE
| DDSCAPS_ZBUFFER
;
2865 static HRESULT WINAPI
Xlib_IDirectDraw2_GetCaps(
2866 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2868 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2870 /* Put the same caps for the two capabilities */
2877 static HRESULT WINAPI
IDirectDraw2_CreateClipper(
2878 LPDIRECTDRAW2
this,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
2880 FIXME(ddraw
,"(%p)->(%08lx,%p,%p),stub!\n",
2881 this,x
,lpddclip
,lpunk
2883 *lpddclip
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
2884 (*lpddclip
)->ref
= 1;
2885 (*lpddclip
)->lpvtbl
= &ddclipvt
;
2889 static HRESULT WINAPI
common_IDirectDraw2_CreatePalette(
2890 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
,int *psize
2894 if (TRACE_ON(ddraw
))
2895 _dump_paletteformat(dwFlags
);
2897 *lpddpal
= (LPDIRECTDRAWPALETTE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPalette
));
2898 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
2899 (*lpddpal
)->ref
= 1;
2900 (*lpddpal
)->ddraw
= (LPDIRECTDRAW
)this;
2901 (*lpddpal
)->installed
= 0;
2903 if (dwFlags
& DDPCAPS_1BIT
)
2905 else if (dwFlags
& DDPCAPS_2BIT
)
2907 else if (dwFlags
& DDPCAPS_4BIT
)
2909 else if (dwFlags
& DDPCAPS_8BIT
)
2912 ERR(ddraw
, "unhandled palette format\n");
2917 /* Now, if we are in 'depth conversion mode', create the screen palette */
2918 if (this->d
.depth
!= this->d
.screen_depth
) {
2921 switch (this->d
.screen_depth
) {
2923 unsigned short *screen_palette
= (unsigned short *) (*lpddpal
)->screen_palents
;
2925 for (i
= 0; i
< size
; i
++) {
2926 screen_palette
[i
] = (((((unsigned short) palent
[i
].peRed
) & 0xF8) << 8) |
2927 ((((unsigned short) palent
[i
].peBlue
) & 0xF8) >> 3) |
2928 ((((unsigned short) palent
[i
].peGreen
) & 0xFC) << 3));
2933 ERR(ddraw
, "Memory corruption ! (depth=%ld, screen_depth=%ld)\n",this->d
.depth
,this->d
.screen_depth
);
2938 memcpy((*lpddpal
)->palents
, palent
, size
* sizeof(PALETTEENTRY
));
2939 } else if (this->d
.depth
!= this->d
.screen_depth
) {
2942 switch (this->d
.screen_depth
) {
2944 unsigned short *screen_palette
= (unsigned short *) (*lpddpal
)->screen_palents
;
2946 for (i
= 0; i
< size
; i
++) {
2947 screen_palette
[i
] = 0xFFFF;
2952 ERR(ddraw
, "Memory corruption !\n");
2960 static HRESULT WINAPI
DGA_IDirectDraw2_CreatePalette(
2961 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2966 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
2967 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
2968 if (res
!= 0) return res
;
2969 (*lpddpal
)->lpvtbl
= &dga_ddpalvt
;
2970 if (this->d
.depth
<=8) {
2971 (*lpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(X11DRV_GetXScreen()),AllocAll
);
2973 FIXME(ddraw
,"why are we doing CreatePalette in hi/truecolor?\n");
2976 if (((*lpddpal
)->cm
)&&xsize
) {
2977 for (i
=0;i
<xsize
;i
++) {
2980 xc
.red
= (*lpddpal
)->palents
[i
].peRed
<<8;
2981 xc
.blue
= (*lpddpal
)->palents
[i
].peBlue
<<8;
2982 xc
.green
= (*lpddpal
)->palents
[i
].peGreen
<<8;
2983 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
2985 TSXStoreColor(display
,(*lpddpal
)->cm
,&xc
);
2991 static HRESULT WINAPI
Xlib_IDirectDraw2_CreatePalette(
2992 LPDIRECTDRAW2
this,DWORD dwFlags
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2997 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,dwFlags
,palent
,lpddpal
,lpunk
);
2998 res
= common_IDirectDraw2_CreatePalette(this,dwFlags
,palent
,lpddpal
,lpunk
,&xsize
);
2999 if (res
!= 0) return res
;
3000 (*lpddpal
)->lpvtbl
= &xlib_ddpalvt
;
3004 static HRESULT WINAPI
DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3005 #ifdef HAVE_LIBXXF86DGA
3006 TRACE(ddraw
, "(%p)->()\n",this);
3008 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3009 #ifdef RESTORE_SIGNALS
3010 SIGNAL_InitHandlers();
3013 #else /* defined(HAVE_LIBXXF86DGA) */
3014 return E_UNEXPECTED
;
3018 static HRESULT WINAPI
Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
3019 TRACE(ddraw
, "(%p)->RestoreDisplayMode()\n", this);
3024 static HRESULT WINAPI
IDirectDraw2_WaitForVerticalBlank(
3025 LPDIRECTDRAW2
this,DWORD x
,HANDLE32 h
3027 TRACE(ddraw
,"(%p)->(0x%08lx,0x%08x)\n",this,x
,h
);
3031 static ULONG WINAPI
IDirectDraw2_AddRef(LPDIRECTDRAW2
this) {
3032 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
3034 return ++(this->ref
);
3037 static ULONG WINAPI
DGA_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3038 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3040 #ifdef HAVE_LIBXXF86DGA
3041 if (!--(this->ref
)) {
3042 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
3043 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3044 DestroyWindow32(this->d
.window
);
3045 #ifdef HAVE_LIBXXF86VM
3047 TSXF86VidModeSwitchToMode(
3049 DefaultScreen(display
),
3051 if (orig_mode
->privsize
)
3052 TSXFree(orig_mode
->private);
3058 #ifdef RESTORE_SIGNALS
3059 SIGNAL_InitHandlers();
3061 HeapFree(GetProcessHeap(),0,this);
3064 #endif /* defined(HAVE_LIBXXF86DGA) */
3068 static ULONG WINAPI
Xlib_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
3069 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
3071 if (!--(this->ref
)) {
3072 if (this->d
.window
&& (this->d
.mainWindow
!= this->d
.window
))
3073 DestroyWindow32(this->d
.window
);
3074 HeapFree(GetProcessHeap(),0,this);
3077 /* FIXME: destroy window ... */
3081 static HRESULT WINAPI
DGA_IDirectDraw2_QueryInterface(
3082 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3086 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3087 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3088 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3090 this->lpvtbl
->fnAddRef(this);
3092 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3096 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3097 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_ddvt
;
3098 this->lpvtbl
->fnAddRef(this);
3101 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3105 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3106 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd2vt
;
3107 this->lpvtbl
->fnAddRef(this);
3110 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3114 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3115 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd4vt
;
3116 this->lpvtbl
->fnAddRef(this);
3119 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3123 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3126 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3128 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3129 this->lpvtbl
->fnAddRef(this);
3130 d3d
->lpvtbl
= &d3dvt
;
3133 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3137 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D2
))) {
3140 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3142 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3143 this->lpvtbl
->fnAddRef(this);
3144 d3d
->lpvtbl
= &d3d2vt
;
3147 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3151 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3152 return OLE_E_ENUM_NOMORE
;
3155 static HRESULT WINAPI
Xlib_IDirectDraw2_QueryInterface(
3156 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
3160 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
3161 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
3162 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
3164 this->lpvtbl
->fnAddRef(this);
3166 TRACE(ddraw
, " Creating IUnknown interface (%p)\n", *obj
);
3170 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
3171 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_ddvt
;
3172 this->lpvtbl
->fnAddRef(this);
3175 TRACE(ddraw
, " Creating IDirectDraw interface (%p)\n", *obj
);
3179 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
3180 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd2vt
;
3181 this->lpvtbl
->fnAddRef(this);
3184 TRACE(ddraw
, " Creating IDirectDraw2 interface (%p)\n", *obj
);
3188 if (!memcmp(&IID_IDirectDraw4
,refiid
,sizeof(IID_IDirectDraw4
))) {
3189 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd4vt
;
3190 this->lpvtbl
->fnAddRef(this);
3193 TRACE(ddraw
, " Creating IDirectDraw4 interface (%p)\n", *obj
);
3197 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
3200 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3202 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3203 this->lpvtbl
->fnAddRef(this);
3204 d3d
->lpvtbl
= &d3dvt
;
3207 TRACE(ddraw
, " Creating IDirect3D interface (%p)\n", *obj
);
3211 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
3214 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
3216 d3d
->ddraw
= (LPDIRECTDRAW
)this;
3217 this->lpvtbl
->fnAddRef(this);
3218 d3d
->lpvtbl
= &d3d2vt
;
3221 TRACE(ddraw
, " Creating IDirect3D2 interface (%p)\n", *obj
);
3225 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
3226 return OLE_E_ENUM_NOMORE
;
3229 static HRESULT WINAPI
IDirectDraw2_GetVerticalBlankStatus(
3230 LPDIRECTDRAW2
this,BOOL32
*status
3232 TRACE(ddraw
,"(%p)->(%p)\n",this,status
);
3237 static HRESULT WINAPI
IDirectDraw2_EnumDisplayModes(
3238 LPDIRECTDRAW2
this,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
3240 DDSURFACEDESC ddsfd
;
3243 } modes
[5] = { /* some of the usual modes */
3250 static int depths
[4] = {8,16,24,32};
3253 TRACE(ddraw
,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags
,lpddsfd
,context
,modescb
);
3254 ddsfd
.dwSize
= sizeof(ddsfd
);
3255 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3256 if (dwFlags
& DDEDM_REFRESHRATES
) {
3257 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
3258 ddsfd
.x
.dwRefreshRate
= 60;
3261 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
3262 ddsfd
.dwBackBufferCount
= 1;
3263 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
3264 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
3265 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= depths
[i
];
3266 /* FIXME: those masks would have to be set in depth > 8 */
3268 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
3269 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
3270 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
3271 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3272 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
3273 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
3275 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
3277 /* FIXME: We should query those from X itself */
3278 switch (depths
[i
]) {
3280 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0xF800;
3281 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x07E0;
3282 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x001F;
3285 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3286 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3287 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3290 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x00FF0000;
3291 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000FF00;
3292 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x000000FF;
3297 ddsfd
.dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3298 ddsfd
.dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3299 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3300 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3302 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
3303 ddsfd
.dwWidth
= modes
[j
].w
;
3304 ddsfd
.dwHeight
= modes
[j
].h
;
3305 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
3306 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3309 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
3310 /* modeX is not standard VGA */
3312 ddsfd
.dwHeight
= 200;
3313 ddsfd
.dwWidth
= 320;
3314 TRACE(ddraw
," enumerating (320x200x%d)\n",depths
[i
]);
3315 if (!modescb(&ddsfd
,context
)) return DD_OK
;
3321 static HRESULT WINAPI
DGA_IDirectDraw2_GetDisplayMode(
3322 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3324 #ifdef HAVE_LIBXXF86DGA
3325 TRACE(ddraw
,"(%p)->(%p)\n",this,lpddsfd
);
3326 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3327 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3328 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3329 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
3330 lpddsfd
->dwBackBufferCount
= 1;
3331 lpddsfd
->x
.dwRefreshRate
= 60;
3332 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3333 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
3335 #else /* defined(HAVE_LIBXXF86DGA) */
3336 return E_UNEXPECTED
;
3337 #endif /* defined(HAVE_LIBXXF86DGA) */
3340 static HRESULT WINAPI
Xlib_IDirectDraw2_GetDisplayMode(
3341 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
3343 TRACE(ddraw
,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd
);
3344 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
3345 lpddsfd
->dwHeight
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3346 lpddsfd
->dwWidth
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3347 /* POOLE FIXME: Xlib */
3348 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
3349 /* END FIXME: Xlib */
3350 lpddsfd
->dwBackBufferCount
= 1;
3351 lpddsfd
->x
.dwRefreshRate
= 60;
3352 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
3353 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
3357 static HRESULT WINAPI
IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2
this) {
3358 TRACE(ddraw
,"(%p)->()\n",this);
3362 static HRESULT WINAPI
IDirectDraw2_GetMonitorFrequency(
3363 LPDIRECTDRAW2
this,LPDWORD freq
3365 FIXME(ddraw
,"(%p)->(%p) returns 60 Hz always\n",this,freq
);
3366 *freq
= 60*100; /* 60 Hz */
3370 /* what can we directly decompress? */
3371 static HRESULT WINAPI
IDirectDraw2_GetFourCCCodes(
3372 LPDIRECTDRAW2
this,LPDWORD x
,LPDWORD y
3374 FIXME(ddraw
,"(%p,%p,%p), stub\n",this,x
,y
);
3378 static HRESULT WINAPI
IDirectDraw2_EnumSurfaces(
3379 LPDIRECTDRAW2
this,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
3381 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x
,ddsfd
,context
,ddsfcb
);
3385 static HRESULT WINAPI
IDirectDraw2_Compact(
3386 LPDIRECTDRAW2
this )
3388 FIXME(ddraw
,"(%p)->()\n", this );
3393 static HRESULT WINAPI
IDirectDraw2_GetGDISurface(LPDIRECTDRAW2
this,
3394 LPDIRECTDRAWSURFACE
*lplpGDIDDSSurface
) {
3395 FIXME(ddraw
,"(%p)->(%p)\n", this, lplpGDIDDSSurface
);
3400 static HRESULT WINAPI
IDirectDraw2_GetScanLine(LPDIRECTDRAW2
this,
3401 LPDWORD lpdwScanLine
) {
3402 FIXME(ddraw
,"(%p)->(%p)\n", this, lpdwScanLine
);
3407 static HRESULT WINAPI
IDirectDraw2_Initialize(LPDIRECTDRAW2
this,
3409 FIXME(ddraw
,"(%p)->(%p)\n", this, lpGUID
);
3414 /* Note: Hack so we can reuse the old functions without compiler warnings */
3416 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
3418 # define XCAST(fun) (void*)
3421 static struct IDirectDraw_VTable dga_ddvt
= {
3422 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3423 XCAST(AddRef
)IDirectDraw2_AddRef
,
3424 XCAST(Release
)DGA_IDirectDraw2_Release
,
3425 XCAST(Compact
)IDirectDraw2_Compact
,
3426 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3427 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3428 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3429 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3430 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3431 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3432 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3433 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3434 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3435 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3436 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3437 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3438 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3439 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3440 XCAST(Initialize
)IDirectDraw2_Initialize
,
3441 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3442 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3443 DGA_IDirectDraw_SetDisplayMode
,
3444 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3447 static struct IDirectDraw_VTable xlib_ddvt
= {
3448 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3449 XCAST(AddRef
)IDirectDraw2_AddRef
,
3450 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3451 XCAST(Compact
)IDirectDraw2_Compact
,
3452 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3453 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3454 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3455 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3456 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3457 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3458 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3459 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3460 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3461 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3462 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3463 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3464 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3465 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3466 XCAST(Initialize
)IDirectDraw2_Initialize
,
3467 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3468 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3469 Xlib_IDirectDraw_SetDisplayMode
,
3470 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3475 /*****************************************************************************
3481 static HRESULT WINAPI
DGA_IDirectDraw2_SetDisplayMode(
3482 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3484 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3487 static HRESULT WINAPI
Xlib_IDirectDraw2_SetDisplayMode(
3488 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
3490 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
3493 static HRESULT WINAPI
DGA_IDirectDraw2_GetAvailableVidMem(
3494 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3496 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3497 this,ddscaps
,total
,free
3499 if (total
) *total
= this->e
.dga
.fb_memsize
* 1024;
3500 if (free
) *free
= this->e
.dga
.fb_memsize
* 1024;
3504 static HRESULT WINAPI
Xlib_IDirectDraw2_GetAvailableVidMem(
3505 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
3507 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
3508 this,ddscaps
,total
,free
3510 if (total
) *total
= 2048 * 1024;
3511 if (free
) *free
= 2048 * 1024;
3515 static IDirectDraw2_VTable dga_dd2vt
= {
3516 DGA_IDirectDraw2_QueryInterface
,
3517 IDirectDraw2_AddRef
,
3518 DGA_IDirectDraw2_Release
,
3519 IDirectDraw2_Compact
,
3520 IDirectDraw2_CreateClipper
,
3521 DGA_IDirectDraw2_CreatePalette
,
3522 DGA_IDirectDraw2_CreateSurface
,
3523 IDirectDraw2_DuplicateSurface
,
3524 IDirectDraw2_EnumDisplayModes
,
3525 IDirectDraw2_EnumSurfaces
,
3526 IDirectDraw2_FlipToGDISurface
,
3527 DGA_IDirectDraw2_GetCaps
,
3528 DGA_IDirectDraw2_GetDisplayMode
,
3529 IDirectDraw2_GetFourCCCodes
,
3530 IDirectDraw2_GetGDISurface
,
3531 IDirectDraw2_GetMonitorFrequency
,
3532 IDirectDraw2_GetScanLine
,
3533 IDirectDraw2_GetVerticalBlankStatus
,
3534 IDirectDraw2_Initialize
,
3535 DGA_IDirectDraw2_RestoreDisplayMode
,
3536 IDirectDraw2_SetCooperativeLevel
,
3537 DGA_IDirectDraw2_SetDisplayMode
,
3538 IDirectDraw2_WaitForVerticalBlank
,
3539 DGA_IDirectDraw2_GetAvailableVidMem
3542 static struct IDirectDraw2_VTable xlib_dd2vt
= {
3543 Xlib_IDirectDraw2_QueryInterface
,
3544 IDirectDraw2_AddRef
,
3545 Xlib_IDirectDraw2_Release
,
3546 IDirectDraw2_Compact
,
3547 IDirectDraw2_CreateClipper
,
3548 Xlib_IDirectDraw2_CreatePalette
,
3549 Xlib_IDirectDraw2_CreateSurface
,
3550 IDirectDraw2_DuplicateSurface
,
3551 IDirectDraw2_EnumDisplayModes
,
3552 IDirectDraw2_EnumSurfaces
,
3553 IDirectDraw2_FlipToGDISurface
,
3554 Xlib_IDirectDraw2_GetCaps
,
3555 Xlib_IDirectDraw2_GetDisplayMode
,
3556 IDirectDraw2_GetFourCCCodes
,
3557 IDirectDraw2_GetGDISurface
,
3558 IDirectDraw2_GetMonitorFrequency
,
3559 IDirectDraw2_GetScanLine
,
3560 IDirectDraw2_GetVerticalBlankStatus
,
3561 IDirectDraw2_Initialize
,
3562 Xlib_IDirectDraw2_RestoreDisplayMode
,
3563 IDirectDraw2_SetCooperativeLevel
,
3564 Xlib_IDirectDraw2_SetDisplayMode
,
3565 IDirectDraw2_WaitForVerticalBlank
,
3566 Xlib_IDirectDraw2_GetAvailableVidMem
3569 /*****************************************************************************
3574 static HRESULT WINAPI
IDirectDraw4_GetSurfaceFromDC(LPDIRECTDRAW4
this,
3576 LPDIRECTDRAWSURFACE
*lpDDS
) {
3577 FIXME(ddraw
, "(%p)->(%08ld,%p)\n", this, (DWORD
) hdc
, lpDDS
);
3582 static HRESULT WINAPI
IDirectDraw4_RestoreAllSurfaces(LPDIRECTDRAW4
this) {
3583 FIXME(ddraw
, "(%p)->()\n", this);
3588 static HRESULT WINAPI
IDirectDraw4_TestCooperativeLevel(LPDIRECTDRAW4
this) {
3589 FIXME(ddraw
, "(%p)->()\n", this);
3594 static HRESULT WINAPI
IDirectDraw4_GetDeviceIdentifier(LPDIRECTDRAW4
this,
3595 LPDDDEVICEIDENTIFIER lpdddi
,
3597 FIXME(ddraw
, "(%p)->(%p,%08lx)\n", this, lpdddi
, dwFlags
);
3603 # define XCAST(fun) (typeof(dga_dd4vt.fn##fun))
3605 # define XCAST(fun) (void*)
3609 static struct IDirectDraw4_VTable dga_dd4vt
= {
3610 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
3611 XCAST(AddRef
)IDirectDraw2_AddRef
,
3612 XCAST(Release
)DGA_IDirectDraw2_Release
,
3613 XCAST(Compact
)IDirectDraw2_Compact
,
3614 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3615 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
3616 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
3617 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3618 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3619 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3620 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3621 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
3622 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
3623 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3624 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3625 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3626 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3627 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3628 XCAST(Initialize
)IDirectDraw2_Initialize
,
3629 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
3630 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3631 XCAST(SetDisplayMode
)DGA_IDirectDraw_SetDisplayMode
,
3632 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3633 XCAST(GetAvailableVidMem
)DGA_IDirectDraw2_GetAvailableVidMem
,
3634 IDirectDraw4_GetSurfaceFromDC
,
3635 IDirectDraw4_RestoreAllSurfaces
,
3636 IDirectDraw4_TestCooperativeLevel
,
3637 IDirectDraw4_GetDeviceIdentifier
3640 static struct IDirectDraw4_VTable xlib_dd4vt
= {
3641 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
3642 XCAST(AddRef
)IDirectDraw2_AddRef
,
3643 XCAST(Release
)Xlib_IDirectDraw2_Release
,
3644 XCAST(Compact
)IDirectDraw2_Compact
,
3645 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
3646 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
3647 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
3648 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
3649 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
3650 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
3651 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
3652 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
3653 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
3654 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
3655 XCAST(GetGDISurface
)IDirectDraw2_GetGDISurface
,
3656 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
3657 XCAST(GetScanLine
)IDirectDraw2_GetScanLine
,
3658 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
3659 XCAST(Initialize
)IDirectDraw2_Initialize
,
3660 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
3661 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
3662 XCAST(SetDisplayMode
)Xlib_IDirectDraw_SetDisplayMode
,
3663 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
3664 XCAST(GetAvailableVidMem
)Xlib_IDirectDraw2_GetAvailableVidMem
,
3665 IDirectDraw4_GetSurfaceFromDC
,
3666 IDirectDraw4_RestoreAllSurfaces
,
3667 IDirectDraw4_TestCooperativeLevel
,
3668 IDirectDraw4_GetDeviceIdentifier
3673 /******************************************************************************
3677 LRESULT WINAPI
Xlib_DDWndProc(HWND32 hwnd
,UINT32 msg
,WPARAM32 wParam
,LPARAM lParam
)
3680 LPDIRECTDRAW ddraw
= NULL
;
3683 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
3685 SetLastError( ERROR_SUCCESS
);
3686 ddraw
= (LPDIRECTDRAW
)GetWindowLong32A( hwnd
, ddrawXlibThisOffset
);
3688 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
3691 ERR( ddraw
, "Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
3696 /* Perform any special direct draw functions */
3698 ddraw
->d
.paintable
= 1;
3700 /* Now let the application deal with the rest of this */
3701 if( ddraw
->d
.mainWindow
)
3704 /* Don't think that we actually need to call this but...
3705 might as well be on the safe side of things... */
3707 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
3708 it should be the procedures of our fake window that gets called
3709 instead of those of the window provided by the application.
3710 And with this patch, mouse clicks work with Monkey Island III
3712 ret
= DefWindowProc32A( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3716 /* We didn't handle the message - give it to the application */
3717 if (ddraw
&& ddraw
->d
.mainWindow
&& WIN_FindWndPtr(ddraw
->d
.mainWindow
)) {
3718 ret
= CallWindowProc32A( WIN_FindWndPtr( ddraw
->d
.mainWindow
)->winproc
,
3719 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
3724 ret
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
3730 ret
= DefWindowProc32A(hwnd
,msg
,wParam
,lParam
);
3736 HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3737 #ifdef HAVE_LIBXXF86DGA
3738 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
3742 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
3743 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
3747 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
3748 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
3749 return E_UNEXPECTED
;
3751 if (!DDRAW_DGA_Available()) {
3752 TRACE(ddraw
,"No XF86DGA detected.\n");
3753 return DDERR_GENERIC
;
3755 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
3756 (*lplpDD
)->lpvtbl
= &dga_ddvt
;
3758 TSXF86DGAQueryVersion(display
,&major
,&minor
);
3759 TRACE(ddraw
,"XF86DGA is version %d.%d\n",major
,minor
);
3760 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
3761 if (!(flags
& XF86DGADirectPresent
))
3762 MSG("direct video is NOT PRESENT.\n");
3763 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
3764 TRACE(ddraw
,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
3765 addr
,width
,banksize
,memsize
3767 (*lplpDD
)->e
.dga
.fb_width
= width
;
3768 (*lplpDD
)->d
.width
= width
;
3769 (*lplpDD
)->e
.dga
.fb_addr
= addr
;
3770 (*lplpDD
)->e
.dga
.fb_memsize
= memsize
;
3771 (*lplpDD
)->e
.dga
.fb_banksize
= banksize
;
3773 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
3774 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
3775 (*lplpDD
)->e
.dga
.fb_height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3777 (*lplpDD
)->e
.dga
.vpmask
= 1;
3779 (*lplpDD
)->e
.dga
.vpmask
= 0;
3782 /* just assume the default depth is the DGA depth too */
3783 (*lplpDD
)->d
.screen_depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3784 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3785 #ifdef RESTORE_SIGNALS
3786 SIGNAL_InitHandlers();
3790 #else /* defined(HAVE_LIBXXF86DGA) */
3791 return DDERR_INVALIDDIRECTDRAWGUID
;
3792 #endif /* defined(HAVE_LIBXXF86DGA) */
3796 DDRAW_XSHM_Available(void)
3798 #ifdef HAVE_LIBXXSHM
3799 if (TSXShmQueryExtension(display
))
3804 if (TSXShmQueryVersion(display
, &major
, &minor
, &shpix
))
3816 HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3818 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
3819 (*lplpDD
)->lpvtbl
= &xlib_ddvt
;
3821 (*lplpDD
)->d
.drawable
= 0; /* in SetDisplayMode */
3823 /* At DirectDraw creation, the depth is the default depth */
3824 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3825 (*lplpDD
)->d
.screen_depth
= DefaultDepthOfScreen(X11DRV_GetXScreen());
3826 (*lplpDD
)->d
.height
= MONITOR_GetHeight(&MONITOR_PrimaryMonitor
);
3827 (*lplpDD
)->d
.width
= MONITOR_GetWidth(&MONITOR_PrimaryMonitor
);
3829 #ifdef HAVE_LIBXXSHM
3830 /* Test if XShm is available. */
3831 if (((*lplpDD
)->e
.xlib
.xshm_active
= DDRAW_XSHM_Available()))
3832 TRACE(ddraw
, "Using XShm extension.\n");
3838 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
3845 WINE_StringFromCLSID(lpGUID
,xclsid
);
3847 sprintf(xclsid
,"<guid-0x%08x>",(int)lpGUID
);
3851 TRACE(ddraw
,"(%s,%p,%p)\n",xclsid
,lplpDD
,pUnkOuter
);
3854 /* if they didn't request a particular interface, use the best
3856 if (DDRAW_DGA_Available())
3857 lpGUID
= &DGA_DirectDraw_GUID
;
3859 lpGUID
= &XLIB_DirectDraw_GUID
;
3862 wc
.style
= CS_GLOBALCLASS
;
3863 wc
.lpfnWndProc
= Xlib_DDWndProc
;
3865 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
3866 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
3868 /* We can be a child of the desktop since we're really important */
3869 pParentWindow
= WIN_GetDesktop();
3870 wc
.hInstance
= pParentWindow
? pParentWindow
->hwndSelf
: 0;
3874 wc
.hCursor
= (HCURSOR32
)IDC_ARROW32A
;
3875 wc
.hbrBackground
= NULL_BRUSH
;
3876 wc
.lpszMenuName
= 0;
3877 wc
.lpszClassName
= "WINE_DirectDraw";
3878 RegisterClass32A(&wc
);
3880 if (!memcmp(lpGUID
, &DGA_DirectDraw_GUID
, sizeof(GUID
)))
3881 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
3882 else if (!memcmp(lpGUID
, &XLIB_DirectDraw_GUID
, sizeof(GUID
)))
3883 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
3888 (*lplpDD
)->d
.winclass
= RegisterClass32A(&wc
);
3892 fprintf(stderr
,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
3893 return DDERR_INVALIDDIRECTDRAWGUID
;