1 /* DirectDraw using DGA or Xlib(XSHM)
3 * Copyright 1997,1998 Marcus Meissner
6 * When DirectVideo mode is enabled you can no longer use 'normal' X
7 * applications nor can you switch to a virtual console. Also, enabling
8 * only works, if you have switched to the screen where the application
10 * Some ways to debug this stuff are:
11 * - A terminal connected to the serial port. Can be bought used for cheap.
12 * (This is the method I am using.)
13 * - Another machine connected over some kind of network.
20 #include <sys/signal.h>
26 #ifdef HAVE_LIBXXF86VM
27 /* X is retarted and insists on declaring INT32, INT16 etc in Xmd.h,
28 this is a crude hack to get around it */
30 #include "ts_xf86vmode.h"
34 #include "interfaces.h"
50 #ifdef HAVE_LIBXXF86DGA
51 #include "ts_xf86dga.h"
55 #include <sys/types.h>
61 /* define this if you want to play Diablo using XF86DGA. (bug workaround) */
64 /* Restore signal handlers overwritten by XF86DGA
65 * this is a define, for it will only work in emulator mode
67 #undef RESTORE_SIGNALS
69 /* Where do these GUIDs come from? mkuuid.
70 * They exist solely to distinguish between the targets Wine support,
71 * and should be different than any other GUIDs in existence.
73 static GUID DGA_DirectDraw_GUID
= { /* e2dcb020-dc60-11d1-8407-9714f5d50802 */
77 {0x84, 0x07, 0x97, 0x14, 0xf5, 0xd5, 0x08, 0x02}
80 static GUID XLIB_DirectDraw_GUID
= { /* 1574a740-dc61-11d1-8407-f7875a7d1879 */
84 {0x84, 0x07, 0xf7, 0x87, 0x5a, 0x7d, 0x18, 0x79}
87 static struct IDirectDrawSurface3_VTable dga_dds3vt
, xlib_dds3vt
;
88 static struct IDirectDraw_VTable dga_ddvt
, xlib_ddvt
;
89 static struct IDirectDraw2_VTable dga_dd2vt
, xlib_dd2vt
;
90 static struct IDirectDrawClipper_VTable ddclipvt
;
91 static struct IDirectDrawPalette_VTable dga_ddpalvt
, xlib_ddpalvt
;
92 static struct IDirect3D_VTable d3dvt
;
93 static struct IDirect3D2_VTable d3d2vt
;
98 #ifdef HAVE_LIBXXF86DGA
99 int evbase
, evret
, fd
;
104 /* You don't have to be root to use DGA extensions. Simply having access to /dev/mem will do the trick */
105 /* This can be achieved by adding the user to the "kmem" group on Debian 2.x systems, don't know about */
106 /* others. --stephenc */
107 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
110 return (fd
!= -1) && TSXF86DGAQueryExtension(display
,&evbase
,&evret
);
111 #else /* defined(HAVE_LIBXXF86DGA) */
113 #endif /* defined(HAVE_LIBXXF86DGA) */
117 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc
,LPVOID data
) {
118 if (DDRAW_DGA_Available()) {
119 ddenumproc(&DGA_DirectDraw_GUID
,"WINE with XFree86 DGA","display",data
);
121 ddenumproc(&XLIB_DirectDraw_GUID
,"WINE with Xlib","display",data
);
122 ddenumproc(NULL
,"WINE","display",data
);
126 /* What is this doing here? */
128 DSoundHelp(DWORD x
,DWORD y
,DWORD z
) {
129 FIXME(ddraw
,"(0x%08lx,0x%08lx,0x%08lx),stub!\n",x
,y
,z
);
134 /******************************************************************************
135 * internal helper functions
137 static void _dump_DDBLTFX(DWORD flagmask
) {
143 #define FE(x) { x, #x},
144 FE(DDBLTFX_ARITHSTRETCHY
)
145 FE(DDBLTFX_MIRRORLEFTRIGHT
)
146 FE(DDBLTFX_MIRRORUPDOWN
)
147 FE(DDBLTFX_NOTEARING
)
148 FE(DDBLTFX_ROTATE180
)
149 FE(DDBLTFX_ROTATE270
)
151 FE(DDBLTFX_ZBUFFERRANGE
)
152 FE(DDBLTFX_ZBUFFERBASEDEST
)
154 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
155 if (flags
[i
].mask
& flagmask
) {
156 DUMP("%s ",flags
[i
].name
);
163 static void _dump_DDBLTFAST(DWORD flagmask
) {
169 #define FE(x) { x, #x},
170 FE(DDBLTFAST_NOCOLORKEY
)
171 FE(DDBLTFAST_SRCCOLORKEY
)
172 FE(DDBLTFAST_DESTCOLORKEY
)
175 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
176 if (flags
[i
].mask
& flagmask
)
177 DUMP("%s ",flags
[i
].name
);
181 static void _dump_DDBLT(DWORD flagmask
) {
187 #define FE(x) { x, #x},
189 FE(DDBLT_ALPHADESTCONSTOVERRIDE
)
190 FE(DDBLT_ALPHADESTNEG
)
191 FE(DDBLT_ALPHADESTSURFACEOVERRIDE
)
192 FE(DDBLT_ALPHAEDGEBLEND
)
194 FE(DDBLT_ALPHASRCCONSTOVERRIDE
)
195 FE(DDBLT_ALPHASRCNEG
)
196 FE(DDBLT_ALPHASRCSURFACEOVERRIDE
)
202 FE(DDBLT_KEYDESTOVERRIDE
)
204 FE(DDBLT_KEYSRCOVERRIDE
)
206 FE(DDBLT_ROTATIONANGLE
)
208 FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE
)
209 FE(DDBLT_ZBUFFERDESTOVERRIDE
)
210 FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE
)
211 FE(DDBLT_ZBUFFERSRCOVERRIDE
)
215 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
216 if (flags
[i
].mask
& flagmask
)
217 DUMP("%s ",flags
[i
].name
);
220 static void _dump_DDSCAPS(DWORD flagmask
) {
226 #define FE(x) { x, #x},
227 FE(DDSCAPS_RESERVED1
)
229 FE(DDSCAPS_BACKBUFFER
)
232 FE(DDSCAPS_FRONTBUFFER
)
233 FE(DDSCAPS_OFFSCREENPLAIN
)
236 FE(DDSCAPS_PRIMARYSURFACE
)
237 FE(DDSCAPS_PRIMARYSURFACELEFT
)
238 FE(DDSCAPS_SYSTEMMEMORY
)
241 FE(DDSCAPS_VIDEOMEMORY
)
243 FE(DDSCAPS_WRITEONLY
)
246 FE(DDSCAPS_LIVEVIDEO
)
250 FE(DDSCAPS_RESERVED2
)
251 FE(DDSCAPS_ALLOCONLOAD
)
252 FE(DDSCAPS_VIDEOPORT
)
253 FE(DDSCAPS_LOCALVIDMEM
)
254 FE(DDSCAPS_NONLOCALVIDMEM
)
255 FE(DDSCAPS_STANDARDVGAMODE
)
256 FE(DDSCAPS_OPTIMIZED
)
258 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
259 if (flags
[i
].mask
& flagmask
)
260 DUMP("%s ",flags
[i
].name
);
264 static void _dump_DDSD(DWORD flagmask
) {
274 FE(DDSD_BACKBUFFERCOUNT
)
275 FE(DDSD_ZBUFFERBITDEPTH
)
276 FE(DDSD_ALPHABITDEPTH
)
278 FE(DDSD_CKDESTOVERLAY
)
280 FE(DDSD_CKSRCOVERLAY
)
287 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
288 if (flags
[i
].mask
& flagmask
)
289 DUMP("%s ",flags
[i
].name
);
293 static void _dump_DDCOLORKEY(DWORD flagmask
) {
299 #define FE(x) { x, #x},
303 FE(DDPF_PALETTEINDEXED4
)
304 FE(DDPF_PALETTEINDEXEDTO8
)
305 FE(DDPF_PALETTEINDEXED8
)
311 FE(DDPF_PALETTEINDEXED1
)
312 FE(DDPF_PALETTEINDEXED2
)
315 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++)
316 if (flags
[i
].mask
& flagmask
)
317 DUMP("%s ",flags
[i
].name
);
321 static void _dump_pixelformat(LPDDPIXELFORMAT pf
) {
322 _dump_DDCOLORKEY(pf
->dwFlags
);
323 DUMP("dwFourCC : %ld\n", pf
->dwFourCC
);
324 DUMP("RBG bit cbout : %ld\n", pf
->x
.dwRGBBitCount
);
325 DUMP("Masks : R %08lx G %08lx B %08lx A %08lx\n",
326 pf
->y
.dwRBitMask
, pf
->z
.dwGBitMask
, pf
->xx
.dwBBitMask
, pf
->xy
.dwRGBAlphaBitMask
);
329 static int _getpixelformat(LPDIRECTDRAW2 ddraw
,LPDDPIXELFORMAT pf
) {
330 static XVisualInfo
*vi
;
335 vi
= TSXGetVisualInfo(display
,VisualNoMask
,&vt
,&nitems
);
338 if (ddraw
->d
.depth
==8) {
339 pf
->dwFlags
= DDPF_RGB
|DDPF_PALETTEINDEXED8
;
340 pf
->x
.dwRGBBitCount
= 8;
341 pf
->y
.dwRBitMask
= 0;
342 pf
->z
.dwGBitMask
= 0;
343 pf
->xx
.dwBBitMask
= 0;
344 pf
->xy
.dwRGBAlphaBitMask
= 0;
347 if (ddraw
->d
.depth
==16) {
348 pf
->dwFlags
= DDPF_RGB
;
349 pf
->x
.dwRGBBitCount
= 16;
350 pf
->y
.dwRBitMask
= vi
[0].red_mask
;
351 pf
->z
.dwGBitMask
= vi
[0].green_mask
;
352 pf
->xx
.dwBBitMask
= vi
[0].blue_mask
;
353 pf
->xy
.dwRGBAlphaBitMask
= 0;
356 FIXME(ddraw
,"_getpixelformat:unknown depth %ld?\n",ddraw
->d
.depth
);
357 return DDERR_GENERIC
;
360 /******************************************************************************
361 * IDirectDrawSurface,IDirectDrawSurface2,IDirectDrawSurface3
363 * Since DDS3 and DDS2 are supersets of DDS, we implement DDS3 and let
364 * DDS and DDS2 use those functions. (Function calls did not change (except
365 * using different DirectDrawSurfaceX version), just added flags and functions)
367 static HRESULT WINAPI
IDirectDrawSurface3_Lock(
368 LPDIRECTDRAWSURFACE3
this,LPRECT32 lprect
,LPDDSURFACEDESC lpddsd
,DWORD flags
, HANDLE32 hnd
370 TRACE(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
371 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
372 if (flags
& ~(DDLOCK_WAIT
|DDLOCK_READONLY
|DDLOCK_WRITEONLY
))
373 WARN(ddraw
, "(%p)->Lock(%p,%p,%08lx,%08lx)\n",
374 this,lprect
,lpddsd
,flags
,(DWORD
)hnd
);
376 /* First, copy the Surface description */
377 *lpddsd
= this->s
.surface_desc
;
379 /* If asked only for a part, change the surface pointer */
381 FIXME(ddraw
," lprect: %dx%d-%dx%d\n",
382 lprect
->top
,lprect
->left
,lprect
->bottom
,lprect
->right
384 lpddsd
->y
.lpSurface
= this->s
.surface_desc
.y
.lpSurface
+
385 (lprect
->top
*this->s
.surface_desc
.lPitch
) +
386 (lprect
->left
*(this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8));
388 assert(this->s
.surface_desc
.y
.lpSurface
);
393 static HRESULT WINAPI
DGA_IDirectDrawSurface3_Unlock(
394 LPDIRECTDRAWSURFACE3
this,LPVOID surface
396 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
400 static HRESULT WINAPI
Xlib_IDirectDrawSurface3_Unlock(
401 LPDIRECTDRAWSURFACE3
this,LPVOID surface
)
403 TRACE(ddraw
,"(%p)->Unlock(%p)\n",this,surface
);
405 if (!this->s
.ddraw
->e
.xlib
.paintable
)
408 /* Only redraw the screen when unlocking the buffer that is on screen */
409 if ((this->t
.xlib
.image
!= NULL
) &&
410 (this->s
.surface_desc
.ddsCaps
.dwCaps
& DDSCAPS_VISIBLE
)) {
412 if (this->s
.ddraw
->e
.xlib
.xshm_active
)
413 TSXShmPutImage(display
,
414 this->s
.ddraw
->e
.xlib
.drawable
,
415 DefaultGCOfScreen(screen
),
418 this->t
.xlib
.image
->width
,
419 this->t
.xlib
.image
->height
,
423 TSXPutImage( display
,
424 this->s
.ddraw
->e
.xlib
.drawable
,
425 DefaultGCOfScreen(screen
),
428 this->t
.xlib
.image
->width
,
429 this->t
.xlib
.image
->height
);
431 if (this->s
.palette
&& this->s
.palette
->cm
)
432 TSXSetWindowColormap(display
,this->s
.ddraw
->e
.xlib
.drawable
,this->s
.palette
->cm
);
438 static HRESULT WINAPI
DGA_IDirectDrawSurface3_Flip(
439 LPDIRECTDRAWSURFACE3
this,LPDIRECTDRAWSURFACE3 flipto
,DWORD dwFlags
441 #ifdef HAVE_LIBXXF86DGA
442 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
444 if (this->s
.backbuffer
)
445 flipto
= this->s
.backbuffer
;
449 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,flipto
->t
.dga
.fb_height
);
451 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
452 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),flipto
->s
.palette
->cm
);
454 while (!TSXF86DGAViewPortChanged(display
,DefaultScreen(display
),2)) {
460 tmp
= this->t
.dga
.fb_height
;
461 this->t
.dga
.fb_height
= flipto
->t
.dga
.fb_height
;
462 flipto
->t
.dga
.fb_height
= tmp
;
464 ptmp
= this->s
.surface_desc
.y
.lpSurface
;
465 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
466 flipto
->s
.surface_desc
.y
.lpSurface
= ptmp
;
469 #else /* defined(HAVE_LIBXXF86DGA) */
471 #endif /* defined(HAVE_LIBXXF86DGA) */
474 static HRESULT WINAPI
Xlib_IDirectDrawSurface3_Flip(
475 LPDIRECTDRAWSURFACE3
this,LPDIRECTDRAWSURFACE3 flipto
,DWORD dwFlags
477 TRACE(ddraw
,"(%p)->Flip(%p,%08lx)\n",this,flipto
,dwFlags
);
478 if (!this->s
.ddraw
->e
.xlib
.paintable
)
482 if (this->s
.backbuffer
)
483 flipto
= this->s
.backbuffer
;
489 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
490 TSXShmPutImage(display
,
491 this->s
.ddraw
->e
.xlib
.drawable
,
492 DefaultGCOfScreen(screen
),
493 flipto
->t
.xlib
.image
,
495 flipto
->t
.xlib
.image
->width
,
496 flipto
->t
.xlib
.image
->height
,
501 this->s
.ddraw
->e
.xlib
.drawable
,
502 DefaultGCOfScreen(screen
),
503 flipto
->t
.xlib
.image
,
505 flipto
->t
.xlib
.image
->width
,
506 flipto
->t
.xlib
.image
->height
);
508 if (flipto
->s
.palette
&& flipto
->s
.palette
->cm
) {
509 TSXSetWindowColormap(display
,this->s
.ddraw
->e
.xlib
.drawable
,flipto
->s
.palette
->cm
);
514 tmp
= this->t
.xlib
.image
;
515 this->t
.xlib
.image
= flipto
->t
.xlib
.image
;
516 flipto
->t
.xlib
.image
= tmp
;
517 surf
= this->s
.surface_desc
.y
.lpSurface
;
518 this->s
.surface_desc
.y
.lpSurface
= flipto
->s
.surface_desc
.y
.lpSurface
;
519 flipto
->s
.surface_desc
.y
.lpSurface
= surf
;
525 /* The IDirectDrawSurface3::SetPalette method attaches the specified
526 * DirectDrawPalette object to a surface. The surface uses this palette for all
527 * subsequent operations. The palette change takes place immediately.
529 static HRESULT WINAPI
Xlib_IDirectDrawSurface3_SetPalette(
530 LPDIRECTDRAWSURFACE3
this,LPDIRECTDRAWPALETTE pal
533 TRACE(ddraw
,"(%p)->SetPalette(%p)\n",this,pal
);
535 if (!(pal
->cm
) && (this->s
.ddraw
->d
.depth
<=8)) {
536 pal
->cm
= TSXCreateColormap(display
,this->s
.ddraw
->e
.xlib
.drawable
,DefaultVisualOfScreen(screen
),AllocAll
);
537 /* FIXME: this is not correct, when using -managed */
538 TSXInstallColormap(display
,pal
->cm
);
539 for (i
=0;i
<256;i
++) {
542 xc
.red
= pal
->palents
[i
].peRed
<<8;
543 xc
.blue
= pal
->palents
[i
].peBlue
<<8;
544 xc
.green
= pal
->palents
[i
].peGreen
<<8;
545 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
547 TSXStoreColor(display
,pal
->cm
,&xc
);
550 /* According to spec, we are only supposed to
551 * AddRef if this is not the same palette.
553 if( this->s
.palette
!= pal
)
556 pal
->lpvtbl
->fnAddRef( pal
);
557 if( this->s
.palette
!= NULL
)
558 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
559 this->s
.palette
= pal
;
561 /* I think that we need to attach it to all backbuffers...*/
562 if( this->s
.backbuffer
) {
563 if( this->s
.backbuffer
->s
.palette
)
564 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(
565 this->s
.backbuffer
->s
.palette
);
566 this->s
.backbuffer
->s
.palette
= pal
;
568 pal
->lpvtbl
->fnAddRef( pal
);
570 /* Perform the refresh */
571 TSXSetWindowColormap(display
,this->s
.ddraw
->e
.xlib
.drawable
,this->s
.palette
->cm
);
576 static HRESULT WINAPI
DGA_IDirectDrawSurface3_SetPalette(
577 LPDIRECTDRAWSURFACE3
this,LPDIRECTDRAWPALETTE pal
579 TRACE(ddraw
,"(%p)->SetPalette(%p)\n",this,pal
);
580 #ifdef HAVE_LIBXXF86DGA
581 /* According to spec, we are only supposed to
582 * AddRef if this is not the same palette.
584 if( this->s
.palette
!= pal
)
587 pal
->lpvtbl
->fnAddRef( pal
);
588 if( this->s
.palette
!= NULL
)
589 this->s
.palette
->lpvtbl
->fnRelease( this->s
.palette
);
590 this->s
.palette
= pal
;
592 /* I think that we need to attach it to all backbuffers...*/
593 if( this->s
.backbuffer
) {
594 if( this->s
.backbuffer
->s
.palette
)
595 this->s
.backbuffer
->s
.palette
->lpvtbl
->fnRelease(this->s
.backbuffer
->s
.palette
);
596 this->s
.backbuffer
->s
.palette
= pal
;
597 if( pal
) pal
->lpvtbl
->fnAddRef( pal
);
599 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->s
.palette
->cm
);
602 #else /* defined(HAVE_LIBXXF86DGA) */
604 #endif /* defined(HAVE_LIBXXF86DGA) */
609 static HRESULT WINAPI
IDirectDrawSurface3_Blt(
610 LPDIRECTDRAWSURFACE3
this,LPRECT32 rdst
,LPDIRECTDRAWSURFACE3 src
,LPRECT32 rsrc
,DWORD dwFlags
,LPDDBLTFX lpbltfx
613 DDSURFACEDESC ddesc
,sdesc
;
616 TRACE(ddraw
,"(%p)->(%p,%p,%p,%08lx,%p)\n",
617 this,rdst
,src
,rsrc
,dwFlags
,lpbltfx
);
620 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,0,0);
621 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,0,0);
623 if (TRACE_ON(ddraw
)) {
624 if (rdst
) TRACE(ddraw
," destrect :%dx%d-%dx%d\n",rdst
->left
,rdst
->top
,rdst
->right
,rdst
->bottom
);
625 if (rsrc
) TRACE(ddraw
," srcrect :%dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
626 TRACE(ddraw
,"\tflags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
627 if (dwFlags
& DDBLT_DDFX
) {
628 TRACE(ddraw
," blitfx: \n");_dump_DDBLTFX(lpbltfx
->dwDDFX
);
633 memcpy(&xdst
,rdst
,sizeof(xdst
));
636 xdst
.bottom
= ddesc
.dwHeight
;
638 xdst
.right
= ddesc
.dwWidth
;
642 memcpy(&xsrc
,rsrc
,sizeof(xsrc
));
646 xsrc
.bottom
= sdesc
.dwHeight
;
648 xsrc
.right
= sdesc
.dwWidth
;
650 memset(&xsrc
,0,sizeof(xsrc
));
654 dwFlags
&= ~(DDBLT_WAIT
|DDBLT_ASYNC
);/* FIXME: can't handle right now */
656 if (dwFlags
& DDBLT_COLORFILL
) {
657 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
660 xline
= (LPBYTE
) ddesc
.y
.lpSurface
+ xdst
.top
* ddesc
.lPitch
;
661 for (i
=xdst
.top
;i
<xdst
.bottom
;i
++) {
662 xpixel
= xline
+bpp
*xdst
.left
;
664 for (j
=xdst
.left
;j
<xdst
.right
;j
++) {
665 /* FIXME: this only works on little endian
666 * architectures, where DWORD starts with low
669 memcpy(xpixel
,&(lpbltfx
->b
.dwFillColor
),bpp
);
672 xline
+= ddesc
.lPitch
;
674 dwFlags
&= ~(DDBLT_COLORFILL
);
679 TRACE(ddraw
,"\t(src=NULL):Unsupported flags: ");_dump_DDBLT(dwFlags
);fprintf(stderr
,"\n");
684 if ( (xsrc
.top
==0) && (xsrc
.bottom
==ddesc
.dwHeight
) &&
685 (xsrc
.left
==0) && (xsrc
.right
==ddesc
.dwWidth
) &&
686 (xdst
.top
==0) && (xdst
.bottom
==ddesc
.dwHeight
) &&
687 (xdst
.left
==0) && (xdst
.right
==ddesc
.dwWidth
) &&
690 memcpy(ddesc
.y
.lpSurface
,
692 ddesc
.dwHeight
* ddesc
.lPitch
);
694 int bpp
= ddesc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
695 int height
= xsrc
.bottom
- xsrc
.top
;
696 int width
= (xsrc
.right
- xsrc
.left
) * bpp
;
699 for (h
= 0; h
< height
; h
++) {
700 memcpy(ddesc
.y
.lpSurface
+ ((h
+ xdst
.top
) * ddesc
.lPitch
) + xdst
.left
* bpp
,
701 sdesc
.y
.lpSurface
+ ((h
+ xsrc
.top
) * sdesc
.lPitch
) + xsrc
.left
* bpp
,
706 if (dwFlags
&& FIXME_ON(ddraw
)) {
707 FIXME(ddraw
,"\tUnsupported flags: ");_dump_DDBLT(dwFlags
);
710 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
711 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
716 static HRESULT WINAPI
IDirectDrawSurface3_BltFast(
717 LPDIRECTDRAWSURFACE3
this,DWORD dstx
,DWORD dsty
,LPDIRECTDRAWSURFACE3 src
,LPRECT32 rsrc
,DWORD trans
720 DDSURFACEDESC ddesc
,sdesc
;
722 if (TRACE_ON(ddraw
)) {
723 TRACE(ddraw
,"(%p)->(%ld,%ld,%p,%p,%08lx)\n",
724 this,dstx
,dsty
,src
,rsrc
,trans
726 TRACE(ddraw
," trans:");_dump_DDBLTFAST(trans
);fprintf(stderr
,"\n");
727 TRACE(ddraw
," srcrect: %dx%d-%dx%d\n",rsrc
->left
,rsrc
->top
,rsrc
->right
,rsrc
->bottom
);
729 /* We need to lock the surfaces, or we won't get refreshes when done. */
730 src
->lpvtbl
->fnLock(src
, NULL
,&sdesc
,DDLOCK_READONLY
, 0);
731 this->lpvtbl
->fnLock(this,NULL
,&ddesc
,DDLOCK_WRITEONLY
,0);
732 bpp
= this->s
.surface_desc
.ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
733 for (i
=0;i
<rsrc
->bottom
-rsrc
->top
;i
++) {
734 memcpy( ddesc
.y
.lpSurface
+(dsty
+i
)*ddesc
.lPitch
+dstx
*bpp
,
735 sdesc
.y
.lpSurface
+(rsrc
->top
+i
)*sdesc
.lPitch
+rsrc
->left
*bpp
,
736 (rsrc
->right
-rsrc
->left
)*bpp
739 this->lpvtbl
->fnUnlock(this,ddesc
.y
.lpSurface
);
740 src
->lpvtbl
->fnUnlock(src
,sdesc
.y
.lpSurface
);
744 static HRESULT WINAPI
IDirectDrawSurface3_BltBatch(
745 LPDIRECTDRAWSURFACE3
this,LPDDBLTBATCH ddbltbatch
,DWORD x
,DWORD y
747 FIXME(ddraw
,"(%p)->BltBatch(%p,%08lx,%08lx),stub!\n",
753 static HRESULT WINAPI
IDirectDrawSurface3_GetCaps(
754 LPDIRECTDRAWSURFACE3
this,LPDDSCAPS caps
756 TRACE(ddraw
,"(%p)->GetCaps(%p)\n",this,caps
);
757 caps
->dwCaps
= DDSCAPS_PALETTE
; /* probably more */
761 static HRESULT WINAPI
IDirectDrawSurface3_GetSurfaceDesc(
762 LPDIRECTDRAWSURFACE3
this,LPDDSURFACEDESC ddsd
764 TRACE(ddraw
, "(%p)->GetSurfaceDesc(%p)\n",
767 /* Simply copy the surface description stored in the object */
768 *ddsd
= this->s
.surface_desc
;
770 if (TRACE_ON(ddraw
)) {
771 fprintf(stderr
," flags: ");
772 _dump_DDSD(ddsd
->dwFlags
);
773 if (ddsd
->dwFlags
& DDSD_CAPS
) {
774 fprintf(stderr
, " caps: ");
775 _dump_DDSCAPS(ddsd
->ddsCaps
.dwCaps
);
777 fprintf(stderr
,"\n");
783 static ULONG WINAPI
IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3
this) {
784 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
786 return ++(this->ref
);
789 static ULONG WINAPI
DGA_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3
this) {
790 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
792 #ifdef HAVE_LIBXXF86DGA
793 if (!--(this->ref
)) {
794 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
795 /* clear out of surface list */
796 if (this->t
.dga
.fb_height
== -1) {
797 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
799 this->s
.ddraw
->e
.dga
.vpmask
&= ~(1<<(this->t
.dga
.fb_height
/this->s
.ddraw
->e
.dga
.fb_height
));
801 HeapFree(GetProcessHeap(),0,this);
804 #endif /* defined(HAVE_LIBXXF86DGA) */
808 static ULONG WINAPI
Xlib_IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3
this) {
809 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
811 if (!--(this->ref
)) {
812 this->s
.ddraw
->lpvtbl
->fnRelease(this->s
.ddraw
);
814 if( this->s
.backbuffer
)
815 this->s
.backbuffer
->lpvtbl
->fnRelease(this->s
.backbuffer
);
817 if (this->t
.xlib
.image
!= NULL
) {
818 this->t
.xlib
.image
->data
= NULL
;
821 if (this->s
.ddraw
->e
.xlib
.xshm_active
) {
822 TSXShmDetach(display
, &(this->t
.xlib
.shminfo
));
823 TSXDestroyImage(this->t
.xlib
.image
);
824 shmdt(this->t
.xlib
.shminfo
.shmaddr
);
827 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
828 TSXDestroyImage(this->t
.xlib
.image
);
833 this->t
.xlib
.image
= 0;
835 HeapFree(GetProcessHeap(),0,this->s
.surface_desc
.y
.lpSurface
);
839 this->s
.palette
->lpvtbl
->fnRelease(this->s
.palette
);
841 HeapFree(GetProcessHeap(),0,this);
848 static HRESULT WINAPI
IDirectDrawSurface3_GetAttachedSurface(
849 LPDIRECTDRAWSURFACE3
this,LPDDSCAPS lpddsd
,LPDIRECTDRAWSURFACE3
*lpdsf
851 TRACE(ddraw
, "(%p)->GetAttachedSurface(%p,%p)\n",
852 this, lpddsd
, lpdsf
);
854 if (TRACE_ON(ddraw
)) {
855 TRACE(ddraw
," caps ");
856 _dump_DDSCAPS(lpddsd
->dwCaps
);
859 if (!(lpddsd
->dwCaps
& DDSCAPS_BACKBUFFER
)) {
860 FIXME(ddraw
,"whoops, can only handle backbuffers for now\n");
864 /* FIXME: should handle more than one backbuffer */
865 *lpdsf
= this->s
.backbuffer
;
867 if( this->s
.backbuffer
)
868 this->s
.backbuffer
->lpvtbl
->fnAddRef( this->s
.backbuffer
);
873 static HRESULT WINAPI
IDirectDrawSurface3_Initialize(
874 LPDIRECTDRAWSURFACE3
this,LPDIRECTDRAW ddraw
,LPDDSURFACEDESC lpdsfd
876 TRACE(ddraw
,"(%p)->(%p, %p)\n",this,ddraw
,lpdsfd
);
878 return DDERR_ALREADYINITIALIZED
;
881 static HRESULT WINAPI
IDirectDrawSurface3_GetPixelFormat(
882 LPDIRECTDRAWSURFACE3
this,LPDDPIXELFORMAT pf
884 TRACE(ddraw
,"(%p)->(%p)\n",this,pf
);
886 *pf
= this->s
.surface_desc
.ddpfPixelFormat
;
891 static HRESULT WINAPI
IDirectDrawSurface3_GetBltStatus(LPDIRECTDRAWSURFACE3
this,DWORD dwFlags
) {
892 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,dwFlags
);
896 static HRESULT WINAPI
IDirectDrawSurface3_GetOverlayPosition(
897 LPDIRECTDRAWSURFACE3
this,LPLONG x1
,LPLONG x2
899 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,x1
,x2
);
903 static HRESULT WINAPI
IDirectDrawSurface3_SetClipper(
904 LPDIRECTDRAWSURFACE3
this,LPDIRECTDRAWCLIPPER clipper
906 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,clipper
);
910 static HRESULT WINAPI
IDirectDrawSurface3_AddAttachedSurface(
911 LPDIRECTDRAWSURFACE3
this,LPDIRECTDRAWSURFACE3 surf
913 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,surf
);
915 /* This hack will be enough for the moment */
916 if (this->s
.backbuffer
== NULL
)
917 this->s
.backbuffer
= surf
;
921 static HRESULT WINAPI
IDirectDrawSurface3_GetDC(LPDIRECTDRAWSURFACE3
this,HDC32
* lphdc
) {
922 FIXME(ddraw
,"(%p)->GetDC(%p)\n",this,lphdc
);
923 *lphdc
= BeginPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
927 static HRESULT WINAPI
IDirectDrawSurface3_ReleaseDC(LPDIRECTDRAWSURFACE3
this,HDC32 hdc
) {
928 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n",this,(long)hdc
);
929 EndPaint32(this->s
.ddraw
->d
.window
,&this->s
.ddraw
->d
.ps
);
934 static HRESULT WINAPI
IDirectDrawSurface3_QueryInterface(LPDIRECTDRAWSURFACE3
this,REFIID refiid
,LPVOID
*obj
) {
937 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
938 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
940 /* DirectDrawSurface,DirectDrawSurface2 and DirectDrawSurface3 use
941 * the same interface. And IUnknown does that too of course.
943 if ( !memcmp(&IID_IDirectDrawSurface3
,refiid
,sizeof(IID
)) ||
944 !memcmp(&IID_IDirectDrawSurface2
,refiid
,sizeof(IID
)) ||
945 !memcmp(&IID_IDirectDrawSurface
,refiid
,sizeof(IID
)) ||
946 !memcmp(&IID_IUnknown
,refiid
,sizeof(IID
))
949 this->lpvtbl
->fnAddRef(this);
952 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
953 return OLE_E_ENUM_NOMORE
;
956 static HRESULT WINAPI
IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3
this) {
957 TRACE(ddraw
,"(%p)->(), stub!\n",this);
961 static HRESULT WINAPI
IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3
this,LPVOID context
,LPDDENUMSURFACESCALLBACK esfcb
) {
962 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,context
,esfcb
);
966 static HRESULT WINAPI
IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3
this) {
967 FIXME(ddraw
,"(%p)->(),stub!\n",this);
971 static HRESULT WINAPI
IDirectDrawSurface3_SetColorKey(
972 LPDIRECTDRAWSURFACE3
this, DWORD dwFlags
, LPDDCOLORKEY ckey
974 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags
,ckey
);
976 if( dwFlags
& DDCKEY_SRCBLT
)
977 dwFlags
&= ~DDCKEY_SRCBLT
;
979 TRACE( ddraw
, "unhandled dwFlags: %08lx\n", dwFlags
);
983 static HRESULT WINAPI
IDirectDrawSurface3_AddOverlayDirtyRect(
984 LPDIRECTDRAWSURFACE3
this,
987 FIXME(ddraw
,"(%p)->(%p),stub!\n",this,lpRect
);
992 static HRESULT WINAPI
IDirectDrawSurface3_DeleteAttachedSurface(
993 LPDIRECTDRAWSURFACE3
this,
995 LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface
)
997 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n",this,dwFlags
,lpDDSAttachedSurface
);
1002 static HRESULT WINAPI
IDirectDrawSurface3_EnumOverlayZOrders(
1003 LPDIRECTDRAWSURFACE3
this,
1006 LPDDENUMSURFACESCALLBACK lpfnCallback
)
1008 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p),stub!\n", this,dwFlags
,
1009 lpContext
, lpfnCallback
);
1014 static HRESULT WINAPI
IDirectDrawSurface3_GetClipper(
1015 LPDIRECTDRAWSURFACE3
this,
1016 LPDIRECTDRAWCLIPPER
* lplpDDClipper
)
1018 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDClipper
);
1023 static HRESULT WINAPI
IDirectDrawSurface3_GetColorKey(
1024 LPDIRECTDRAWSURFACE3
this,
1026 LPDDCOLORKEY lpDDColorKey
)
1028 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags
, lpDDColorKey
);
1033 static HRESULT WINAPI
IDirectDrawSurface3_GetFlipStatus(
1034 LPDIRECTDRAWSURFACE3
this,
1037 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1042 static HRESULT WINAPI
IDirectDrawSurface3_GetPalette(
1043 LPDIRECTDRAWSURFACE3
this,
1044 LPDIRECTDRAWPALETTE
* lplpDDPalette
)
1046 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDDPalette
);
1051 static HRESULT WINAPI
IDirectDrawSurface3_SetOverlayPosition(
1052 LPDIRECTDRAWSURFACE3
this,
1056 FIXME(ddraw
,"(%p)->(%ld,%ld),stub!\n", this, lX
, lY
);
1061 static HRESULT WINAPI
IDirectDrawSurface3_UpdateOverlay(
1062 LPDIRECTDRAWSURFACE3
this,
1064 LPDIRECTDRAWSURFACE3 lpDDDestSurface
,
1065 LPRECT32 lpDestRect
,
1067 LPDDOVERLAYFX lpDDOverlayFx
)
1069 FIXME(ddraw
,"(%p)->(%p,%p,%p,0x%08lx,%p),stub!\n", this,
1070 lpSrcRect
, lpDDDestSurface
, lpDestRect
, dwFlags
, lpDDOverlayFx
);
1075 static HRESULT WINAPI
IDirectDrawSurface3_UpdateOverlayDisplay(
1076 LPDIRECTDRAWSURFACE3
this,
1079 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1084 static HRESULT WINAPI
IDirectDrawSurface3_UpdateOverlayZOrder(
1085 LPDIRECTDRAWSURFACE3
this,
1087 LPDIRECTDRAWSURFACE3 lpDDSReference
)
1089 FIXME(ddraw
,"(%p)->(0x%08lx,%p),stub!\n", this, dwFlags
, lpDDSReference
);
1094 static HRESULT WINAPI
IDirectDrawSurface3_GetDDInterface(
1095 LPDIRECTDRAWSURFACE3
this,
1098 FIXME(ddraw
,"(%p)->(%p),stub!\n", this, lplpDD
);
1103 static HRESULT WINAPI
IDirectDrawSurface3_PageLock(
1104 LPDIRECTDRAWSURFACE3
this,
1107 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1112 static HRESULT WINAPI
IDirectDrawSurface3_PageUnlock(
1113 LPDIRECTDRAWSURFACE3
this,
1116 FIXME(ddraw
,"(%p)->(0x%08lx),stub!\n", this, dwFlags
);
1121 static HRESULT WINAPI
IDirectDrawSurface3_SetSurfaceDesc(
1122 LPDIRECTDRAWSURFACE3
this,
1123 LPDDSURFACEDESC lpDDSD
,
1126 FIXME(ddraw
,"(%p)->(%p,0x%08lx),stub!\n", this, lpDDSD
, dwFlags
);
1131 static struct IDirectDrawSurface3_VTable dga_dds3vt
= {
1132 IDirectDrawSurface3_QueryInterface
,
1133 IDirectDrawSurface3_AddRef
,
1134 DGA_IDirectDrawSurface3_Release
,
1135 IDirectDrawSurface3_AddAttachedSurface
,
1136 IDirectDrawSurface3_AddOverlayDirtyRect
,
1137 IDirectDrawSurface3_Blt
,
1138 IDirectDrawSurface3_BltBatch
,
1139 IDirectDrawSurface3_BltFast
,
1140 IDirectDrawSurface3_DeleteAttachedSurface
,
1141 IDirectDrawSurface3_EnumAttachedSurfaces
,
1142 IDirectDrawSurface3_EnumOverlayZOrders
,
1143 DGA_IDirectDrawSurface3_Flip
,
1144 IDirectDrawSurface3_GetAttachedSurface
,
1145 IDirectDrawSurface3_GetBltStatus
,
1146 IDirectDrawSurface3_GetCaps
,
1147 IDirectDrawSurface3_GetClipper
,
1148 IDirectDrawSurface3_GetColorKey
,
1149 IDirectDrawSurface3_GetDC
,
1150 IDirectDrawSurface3_GetFlipStatus
,
1151 IDirectDrawSurface3_GetOverlayPosition
,
1152 IDirectDrawSurface3_GetPalette
,
1153 IDirectDrawSurface3_GetPixelFormat
,
1154 IDirectDrawSurface3_GetSurfaceDesc
,
1155 IDirectDrawSurface3_Initialize
,
1156 IDirectDrawSurface3_IsLost
,
1157 IDirectDrawSurface3_Lock
,
1158 IDirectDrawSurface3_ReleaseDC
,
1159 IDirectDrawSurface3_Restore
,
1160 IDirectDrawSurface3_SetClipper
,
1161 IDirectDrawSurface3_SetColorKey
,
1162 IDirectDrawSurface3_SetOverlayPosition
,
1163 DGA_IDirectDrawSurface3_SetPalette
,
1164 DGA_IDirectDrawSurface3_Unlock
,
1165 IDirectDrawSurface3_UpdateOverlay
,
1166 IDirectDrawSurface3_UpdateOverlayDisplay
,
1167 IDirectDrawSurface3_UpdateOverlayZOrder
,
1168 IDirectDrawSurface3_GetDDInterface
,
1169 IDirectDrawSurface3_PageLock
,
1170 IDirectDrawSurface3_PageUnlock
,
1171 IDirectDrawSurface3_SetSurfaceDesc
,
1174 static struct IDirectDrawSurface3_VTable xlib_dds3vt
= {
1175 IDirectDrawSurface3_QueryInterface
,
1176 IDirectDrawSurface3_AddRef
,
1177 Xlib_IDirectDrawSurface3_Release
,
1178 IDirectDrawSurface3_AddAttachedSurface
,
1179 IDirectDrawSurface3_AddOverlayDirtyRect
,
1180 IDirectDrawSurface3_Blt
,
1181 IDirectDrawSurface3_BltBatch
,
1182 IDirectDrawSurface3_BltFast
,
1183 IDirectDrawSurface3_DeleteAttachedSurface
,
1184 IDirectDrawSurface3_EnumAttachedSurfaces
,
1185 IDirectDrawSurface3_EnumOverlayZOrders
,
1186 Xlib_IDirectDrawSurface3_Flip
,
1187 IDirectDrawSurface3_GetAttachedSurface
,
1188 IDirectDrawSurface3_GetBltStatus
,
1189 IDirectDrawSurface3_GetCaps
,
1190 IDirectDrawSurface3_GetClipper
,
1191 IDirectDrawSurface3_GetColorKey
,
1192 IDirectDrawSurface3_GetDC
,
1193 IDirectDrawSurface3_GetFlipStatus
,
1194 IDirectDrawSurface3_GetOverlayPosition
,
1195 IDirectDrawSurface3_GetPalette
,
1196 IDirectDrawSurface3_GetPixelFormat
,
1197 IDirectDrawSurface3_GetSurfaceDesc
,
1198 IDirectDrawSurface3_Initialize
,
1199 IDirectDrawSurface3_IsLost
,
1200 IDirectDrawSurface3_Lock
,
1201 IDirectDrawSurface3_ReleaseDC
,
1202 IDirectDrawSurface3_Restore
,
1203 IDirectDrawSurface3_SetClipper
,
1204 IDirectDrawSurface3_SetColorKey
,
1205 IDirectDrawSurface3_SetOverlayPosition
,
1206 Xlib_IDirectDrawSurface3_SetPalette
,
1207 Xlib_IDirectDrawSurface3_Unlock
,
1208 IDirectDrawSurface3_UpdateOverlay
,
1209 IDirectDrawSurface3_UpdateOverlayDisplay
,
1210 IDirectDrawSurface3_UpdateOverlayZOrder
,
1211 IDirectDrawSurface3_GetDDInterface
,
1212 IDirectDrawSurface3_PageLock
,
1213 IDirectDrawSurface3_PageUnlock
,
1214 IDirectDrawSurface3_SetSurfaceDesc
,
1217 /******************************************************************************
1218 * DirectDrawCreateClipper (DDRAW.7)
1220 HRESULT WINAPI
DirectDrawCreateClipper( DWORD dwFlags
,
1221 LPDIRECTDRAWCLIPPER
*lplpDDClipper
,
1222 LPUNKNOWN pUnkOuter
)
1224 TRACE(ddraw
, "(%08lx,%p,%p)\n", dwFlags
, lplpDDClipper
, pUnkOuter
);
1226 *lplpDDClipper
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
1227 (*lplpDDClipper
)->lpvtbl
= &ddclipvt
;
1228 (*lplpDDClipper
)->ref
= 1;
1233 /******************************************************************************
1234 * IDirectDrawClipper
1236 static HRESULT WINAPI
IDirectDrawClipper_SetHwnd(
1237 LPDIRECTDRAWCLIPPER
this,DWORD x
,HWND32 hwnd
1239 FIXME(ddraw
,"(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x
,(DWORD
)hwnd
);
1243 static ULONG WINAPI
IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER
this) {
1244 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1249 HeapFree(GetProcessHeap(),0,this);
1253 static HRESULT WINAPI
IDirectDrawClipper_GetClipList(
1254 LPDIRECTDRAWCLIPPER
this,LPRECT32 rects
,LPRGNDATA lprgn
,LPDWORD hmm
1256 FIXME(ddraw
,"(%p,%p,%p,%p),stub!\n",this,rects
,lprgn
,hmm
);
1261 static HRESULT WINAPI
IDirectDrawClipper_SetClipList(
1262 LPDIRECTDRAWCLIPPER
this,LPRGNDATA lprgn
,DWORD hmm
1264 FIXME(ddraw
,"(%p,%p,%ld),stub!\n",this,lprgn
,hmm
);
1268 static struct IDirectDrawClipper_VTable ddclipvt
= {
1271 IDirectDrawClipper_Release
,
1272 IDirectDrawClipper_GetClipList
,
1276 IDirectDrawClipper_SetClipList
,
1277 IDirectDrawClipper_SetHwnd
1280 /******************************************************************************
1281 * IDirectDrawPalette
1283 static HRESULT WINAPI
IDirectDrawPalette_GetEntries(
1284 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1288 TRACE(ddraw
,"(%p)->GetEntries(%08lx,%ld,%ld,%p)\n",
1289 this,x
,start
,count
,palent
);
1291 if (!this->cm
) /* should not happen */ {
1292 FIXME(ddraw
,"app tried to read colormap for non-palettized mode\n");
1293 return DDERR_GENERIC
;
1295 for (i
=0;i
<count
;i
++) {
1296 palent
[i
].peRed
= this->palents
[start
+i
].peRed
;
1297 palent
[i
].peBlue
= this->palents
[start
+i
].peBlue
;
1298 palent
[i
].peGreen
= this->palents
[start
+i
].peGreen
;
1299 palent
[i
].peFlags
= this->palents
[start
+i
].peFlags
;
1305 static HRESULT WINAPI
Xlib_IDirectDrawPalette_SetEntries(
1306 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1311 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1312 this,x
,start
,count
,palent
1314 for (i
=0;i
<count
;i
++) {
1315 xc
.red
= palent
[i
].peRed
<<8;
1316 xc
.blue
= palent
[i
].peBlue
<<8;
1317 xc
.green
= palent
[i
].peGreen
<<8;
1318 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1322 TSXStoreColor(display
,this->cm
,&xc
);
1324 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1325 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1326 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1327 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1329 if (!this->cm
) /* should not happen */ {
1334 static HRESULT WINAPI
DGA_IDirectDrawPalette_SetEntries(
1335 LPDIRECTDRAWPALETTE
this,DWORD x
,DWORD start
,DWORD count
,LPPALETTEENTRY palent
1337 #ifdef HAVE_LIBXXF86DGA
1342 TRACE(ddraw
,"(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
1343 this,x
,start
,count
,palent
1345 if (!this->cm
) /* should not happen */ {
1346 FIXME(ddraw
,"app tried to set colormap in non-palettized mode\n");
1347 return DDERR_GENERIC
;
1349 /* FIXME: free colorcells instead of freeing whole map */
1351 this->cm
= TSXCopyColormapAndFree(display
,this->cm
);
1352 TSXFreeColormap(display
,cm
);
1354 for (i
=0;i
<count
;i
++) {
1355 xc
.red
= palent
[i
].peRed
<<8;
1356 xc
.blue
= palent
[i
].peBlue
<<8;
1357 xc
.green
= palent
[i
].peGreen
<<8;
1358 xc
.flags
= DoRed
|DoBlue
|DoGreen
;
1361 TSXStoreColor(display
,this->cm
,&xc
);
1363 this->palents
[start
+i
].peRed
= palent
[i
].peRed
;
1364 this->palents
[start
+i
].peBlue
= palent
[i
].peBlue
;
1365 this->palents
[start
+i
].peGreen
= palent
[i
].peGreen
;
1366 this->palents
[start
+i
].peFlags
= palent
[i
].peFlags
;
1368 TSXF86DGAInstallColormap(display
,DefaultScreen(display
),this->cm
);
1370 #else /* defined(HAVE_LIBXXF86DGA) */
1371 return E_UNEXPECTED
;
1372 #endif /* defined(HAVE_LIBXXF86DGA) */
1375 static ULONG WINAPI
IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE
this) {
1376 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1377 if (!--(this->ref
)) {
1379 TSXFreeColormap(display
,this->cm
);
1382 HeapFree(GetProcessHeap(),0,this);
1388 static ULONG WINAPI
IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE
this) {
1390 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1391 return ++(this->ref
);
1394 static HRESULT WINAPI
IDirectDrawPalette_Initialize(
1395 LPDIRECTDRAWPALETTE
this,LPDIRECTDRAW ddraw
,DWORD x
,LPPALETTEENTRY palent
1397 TRACE(ddraw
,"(%p)->(%p,%ld,%p)\n", this, ddraw
, x
, palent
);
1399 return DDERR_ALREADYINITIALIZED
;
1402 static HRESULT WINAPI
IDirectDrawPalette_GetCaps(
1403 LPDIRECTDRAWPALETTE
this, LPDWORD lpdwCaps
)
1405 FIXME( ddraw
, "(%p)->(%p) stub.\n", this, lpdwCaps
);
1409 static HRESULT WINAPI
IDirectDrawPalette_QueryInterface(
1410 LPDIRECTDRAWPALETTE
this,REFIID refiid
,LPVOID
*obj
)
1414 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1415 FIXME(ddraw
,"(%p)->(%s,%p) stub.\n",this,xrefiid
,obj
);
1420 static struct IDirectDrawPalette_VTable dga_ddpalvt
= {
1421 IDirectDrawPalette_QueryInterface
,
1422 IDirectDrawPalette_AddRef
,
1423 IDirectDrawPalette_Release
,
1424 IDirectDrawPalette_GetCaps
,
1425 IDirectDrawPalette_GetEntries
,
1426 IDirectDrawPalette_Initialize
,
1427 DGA_IDirectDrawPalette_SetEntries
1430 static struct IDirectDrawPalette_VTable xlib_ddpalvt
= {
1431 IDirectDrawPalette_QueryInterface
,
1432 IDirectDrawPalette_AddRef
,
1433 IDirectDrawPalette_Release
,
1434 IDirectDrawPalette_GetCaps
,
1435 IDirectDrawPalette_GetEntries
,
1436 IDirectDrawPalette_Initialize
,
1437 Xlib_IDirectDrawPalette_SetEntries
1440 /*******************************************************************************
1443 static HRESULT WINAPI
IDirect3D_QueryInterface(
1444 LPDIRECT3D
this,REFIID refiid
,LPVOID
*obj
1446 /* FIXME: Not sure if this is correct */
1449 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1450 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
1451 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
1453 this->lpvtbl
->fnAddRef(this);
1456 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
1459 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1461 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1462 this->lpvtbl
->fnAddRef(this);
1463 d3d
->lpvtbl
= &d3dvt
;
1467 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
1470 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
1472 d3d
->ddraw
= (LPDIRECTDRAW
)this;
1473 this->lpvtbl
->fnAddRef(this);
1474 d3d
->lpvtbl
= &d3d2vt
;
1478 FIXME(ddraw
,"(%p):interface for IID %s NOT found!\n",this,xrefiid
);
1479 return OLE_E_ENUM_NOMORE
;
1482 static ULONG WINAPI
IDirect3D_AddRef(LPDIRECT3D
this) {
1483 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
1485 return ++(this->ref
);
1488 static ULONG WINAPI
IDirect3D_Release(LPDIRECT3D
this)
1490 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1492 if (!--(this->ref
)) {
1493 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
1494 HeapFree(GetProcessHeap(),0,this);
1500 static HRESULT WINAPI
IDirect3D_Initialize(
1501 LPDIRECT3D
this, REFIID refiid
)
1503 /* FIXME: Not sure if this is correct */
1506 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
1507 FIXME(ddraw
,"(%p)->(%s):stub.\n",this,xrefiid
);
1509 return DDERR_ALREADYINITIALIZED
;
1512 /*******************************************************************************
1515 static struct IDirect3D_VTable d3dvt
= {
1516 (void*)IDirect3D_QueryInterface
,
1517 (void*)IDirect3D_AddRef
,
1518 (void*)IDirect3D_Release
,
1519 IDirect3D_Initialize
,
1527 /*******************************************************************************
1530 static ULONG WINAPI
IDirect3D2_Release(LPDIRECT3D2
this) {
1531 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
1533 if (!--(this->ref
)) {
1534 this->ddraw
->lpvtbl
->fnRelease(this->ddraw
);
1535 HeapFree(GetProcessHeap(),0,this);
1541 static HRESULT WINAPI
IDirect3D2_EnumDevices(
1542 LPDIRECT3D2
this,LPD3DENUMDEVICESCALLBACK cb
, LPVOID context
1544 D3DDEVICEDESC d1
,d2
;
1546 FIXME(ddraw
,"(%p)->(%p,%p),stub!\n",this,cb
,context
);
1548 d1
.dwSize
= sizeof(d1
);
1551 d2
.dwSize
= sizeof(d2
);
1553 cb((void*)&IID_IDirect3DHALDevice
,"WINE Direct3D HAL","direct3d",&d1
,&d2
,context
);
1558 static struct IDirect3D2_VTable d3d2vt
= {
1562 IDirect3D2_EnumDevices
,
1570 /*******************************************************************************
1574 /* Used in conjunction with cbWndExtra for storage of the this ptr for the window.
1575 * Please adjust allocation in Xlib_DirectDrawCreate if you store more data here.
1577 static INT32 ddrawXlibThisOffset
= 0;
1579 static HRESULT
common_off_screen_CreateSurface(LPDIRECTDRAW2
this,
1580 LPDDSURFACEDESC lpddsd
,
1581 LPDIRECTDRAWSURFACE lpdsf
)
1585 /* The surface was already allocated when entering in this function */
1586 if (!(lpddsd
->dwFlags
& DDSD_PIXELFORMAT
)) {
1587 /* No pixel format => use DirectDraw's format */
1588 _getpixelformat(this,&(lpddsd
->ddpfPixelFormat
));
1589 lpddsd
->dwFlags
|= DDSD_PIXELFORMAT
;
1591 /* To check what the program wants */
1592 if (TRACE_ON(ddraw
)) {
1593 _dump_pixelformat(&(lpddsd
->ddpfPixelFormat
));
1597 bpp
= lpddsd
->ddpfPixelFormat
.x
.dwRGBBitCount
/ 8;
1599 /* Copy the surface description */
1600 lpdsf
->s
.surface_desc
= *lpddsd
;
1602 lpdsf
->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
1603 lpdsf
->s
.surface_desc
.y
.lpSurface
= (LPBYTE
)HeapAlloc(GetProcessHeap(),0,lpddsd
->dwWidth
* lpddsd
->dwHeight
* bpp
);
1604 lpdsf
->s
.surface_desc
.lPitch
= lpddsd
->dwWidth
* bpp
;
1606 TRACE(ddraw
,"using system memory for a surface (%p)\n", lpdsf
);
1611 static HRESULT WINAPI
DGA_IDirectDraw2_CreateSurface(
1612 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
1614 #ifdef HAVE_LIBXXF86DGA
1617 TRACE(ddraw
, "(%p)->(%p,%p,%p)\n",this,lpddsd
,lpdsf
,lpunk
);
1618 if (TRACE_ON(ddraw
)) {
1619 DUMP("[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
1620 _dump_DDSD(lpddsd
->dwFlags
);
1621 fprintf(stderr
,"caps ");
1622 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
1623 fprintf(stderr
,"]\n");
1626 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
1627 this->lpvtbl
->fnAddRef(this);
1629 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&dga_dds3vt
;
1630 (*lpdsf
)->s
.ddraw
= this;
1631 (*lpdsf
)->s
.palette
= NULL
;
1632 (*lpdsf
)->t
.dga
.fb_height
= -1; /* This is to have non-on screen surfaces freed */
1634 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
1635 lpddsd
->dwWidth
= this->d
.width
;
1636 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
1637 lpddsd
->dwHeight
= this->d
.height
;
1639 /* Check if this a 'primary surface' or not */
1640 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
1641 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
1643 /* This is THE primary surface => there is DGA-specific code */
1644 /* First, store the surface description */
1645 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
1647 /* Find a viewport */
1649 if (!(this->e
.dga
.vpmask
& (1<<i
)))
1651 TRACE(ddraw
,"using viewport %d for a primary surface\n",i
);
1652 /* if i == 32 or maximum ... return error */
1653 this->e
.dga
.vpmask
|=(1<<i
);
1654 (*lpdsf
)->s
.surface_desc
.y
.lpSurface
=
1655 this->e
.dga
.fb_addr
+((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
1656 (*lpdsf
)->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
1657 (*lpdsf
)->s
.surface_desc
.lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
1658 lpddsd
->lPitch
= (*lpdsf
)->s
.surface_desc
.lPitch
;
1660 /* Add flags if there were not present */
1661 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
1662 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
1663 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
1664 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
;
1665 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
1666 (*lpdsf
)->s
.backbuffer
= NULL
;
1668 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
1669 LPDIRECTDRAWSURFACE3 back
;
1671 if (lpddsd
->dwBackBufferCount
>1)
1672 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
1674 (*lpdsf
)->s
.backbuffer
= back
=
1675 (LPDIRECTDRAWSURFACE3
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface3
));
1676 this->lpvtbl
->fnAddRef(this);
1678 back
->lpvtbl
= (LPDIRECTDRAWSURFACE3_VTABLE
)&dga_dds3vt
;
1680 if (!(this->e
.dga
.vpmask
& (1<<i
)))
1682 TRACE(ddraw
,"using viewport %d for backbuffer\n",i
);
1683 /* if i == 32 or maximum ... return error */
1684 this->e
.dga
.vpmask
|=(1<<i
);
1685 back
->t
.dga
.fb_height
= i
*this->e
.dga
.fb_height
;
1687 /* Copy the surface description from the front buffer */
1688 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
1689 /* Change the parameters that are not the same */
1690 back
->s
.surface_desc
.y
.lpSurface
= this->e
.dga
.fb_addr
+
1691 ((i
*this->e
.dga
.fb_height
)*this->e
.dga
.fb_width
*this->d
.depth
/8);
1692 back
->s
.ddraw
= this;
1693 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
1696 /* Add relevant info to front and back buffers */
1697 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
1698 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
1699 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
1700 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
1703 /* There is no DGA-specific code here...
1704 Go to the common surface creation function */
1705 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
1709 #else /* defined(HAVE_LIBXXF86DGA) */
1710 return E_UNEXPECTED
;
1711 #endif /* defined(HAVE_LIBXXF86DGA) */
1714 static XImage
*create_ximage(LPDIRECTDRAW2
this, LPDIRECTDRAWSURFACE3 lpdsf
) {
1717 #ifdef HAVE_LIBXXSHM
1718 if (this->e
.xlib
.xshm_active
) {
1719 img
= TSXShmCreateImage(display
,
1720 DefaultVisualOfScreen(screen
),
1724 &(lpdsf
->t
.xlib
.shminfo
),
1725 lpdsf
->s
.surface_desc
.dwWidth
,
1726 lpdsf
->s
.surface_desc
.dwHeight
);
1731 lpdsf
->t
.xlib
.shminfo
.shmid
= shmget( IPC_PRIVATE
, img
->bytes_per_line
* img
->height
, IPC_CREAT
|0777 );
1732 if (lpdsf
->t
.xlib
.shminfo
.shmid
< 0) {
1733 TSXDestroyImage(img
);
1737 lpdsf
->t
.xlib
.shminfo
.shmaddr
= img
->data
= (char*)shmat(lpdsf
->t
.xlib
.shminfo
.shmid
, 0, 0);
1739 if (img
->data
== (char *) -1) {
1740 TSXDestroyImage(img
);
1741 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
1744 lpdsf
->t
.xlib
.shminfo
.readOnly
= False
;
1746 TSXShmAttach(display
, &(lpdsf
->t
.xlib
.shminfo
));
1747 TSXSync(display
, False
);
1749 shmctl(lpdsf
->t
.xlib
.shminfo
.shmid
, IPC_RMID
, 0);
1751 lpdsf
->s
.surface_desc
.y
.lpSurface
= img
->data
;
1754 /* Allocate surface memory */
1755 lpdsf
->s
.surface_desc
.y
.lpSurface
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,
1756 lpdsf
->s
.surface_desc
.dwWidth
*
1757 lpdsf
->s
.surface_desc
.dwHeight
*
1758 (this->d
.depth
/ 8));
1760 /* In this case, create an XImage */
1762 TSXCreateImage(display
,
1763 DefaultVisualOfScreen(screen
),
1767 lpdsf
->s
.surface_desc
.y
.lpSurface
,
1768 lpdsf
->s
.surface_desc
.dwWidth
,
1769 lpdsf
->s
.surface_desc
.dwHeight
,
1771 lpdsf
->s
.surface_desc
.dwWidth
* (this->d
.depth
/ 8)
1774 #ifdef HAVE_LIBXXSHM
1777 lpdsf
->s
.surface_desc
.lPitch
= img
->bytes_per_line
;
1782 static HRESULT WINAPI
Xlib_IDirectDraw2_CreateSurface(
1783 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsd
,LPDIRECTDRAWSURFACE
*lpdsf
,IUnknown
*lpunk
1785 TRACE(ddraw
, "(%p)->CreateSurface(%p,%p,%p)\n",
1786 this,lpddsd
,lpdsf
,lpunk
);
1788 if (TRACE_ON(ddraw
)) {
1789 fprintf(stderr
,"[w=%ld,h=%ld,flags ",lpddsd
->dwWidth
,lpddsd
->dwHeight
);
1790 _dump_DDSD(lpddsd
->dwFlags
);
1791 fprintf(stderr
,"caps ");
1792 _dump_DDSCAPS(lpddsd
->ddsCaps
.dwCaps
);
1793 fprintf(stderr
,"]\n");
1796 *lpdsf
= (LPDIRECTDRAWSURFACE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface
));
1798 this->lpvtbl
->fnAddRef(this);
1799 (*lpdsf
)->s
.ddraw
= this;
1801 (*lpdsf
)->lpvtbl
= (LPDIRECTDRAWSURFACE_VTABLE
)&xlib_dds3vt
;
1802 (*lpdsf
)->s
.palette
= NULL
;
1803 (*lpdsf
)->t
.xlib
.image
= NULL
; /* This is for off-screen buffers */
1805 if (!(lpddsd
->dwFlags
& DDSD_WIDTH
))
1806 lpddsd
->dwWidth
= this->d
.width
;
1807 if (!(lpddsd
->dwFlags
& DDSD_HEIGHT
))
1808 lpddsd
->dwHeight
= this->d
.height
;
1810 /* Check if this a 'primary surface' or not */
1811 if ((lpddsd
->dwFlags
& DDSD_CAPS
) &&
1812 (lpddsd
->ddsCaps
.dwCaps
& DDSCAPS_PRIMARYSURFACE
)) {
1815 TRACE(ddraw
,"using standard XImage for a primary surface (%p)\n", *lpdsf
);
1817 /* First, store the surface description */
1818 (*lpdsf
)->s
.surface_desc
= *lpddsd
;
1820 /* Create the XImage */
1821 img
= create_ximage(this, (LPDIRECTDRAWSURFACE3
) *lpdsf
);
1823 return DDERR_OUTOFMEMORY
;
1824 (*lpdsf
)->t
.xlib
.image
= img
;
1826 /* Add flags if there were not present */
1827 (*lpdsf
)->s
.surface_desc
.dwFlags
|= DDSD_WIDTH
|DDSD_HEIGHT
|DDSD_PITCH
|DDSD_LPSURFACE
;
1828 (*lpdsf
)->s
.surface_desc
.dwWidth
= this->d
.width
;
1829 (*lpdsf
)->s
.surface_desc
.dwHeight
= this->d
.height
;
1830 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_VISIBLE
;
1831 _getpixelformat(this,&((*lpdsf
)->s
.surface_desc
.ddpfPixelFormat
));
1832 (*lpdsf
)->s
.backbuffer
= NULL
;
1834 /* Check for backbuffers */
1835 if (lpddsd
->dwFlags
& DDSD_BACKBUFFERCOUNT
) {
1836 LPDIRECTDRAWSURFACE3 back
;
1839 if (lpddsd
->dwBackBufferCount
>1)
1840 FIXME(ddraw
,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd
->dwBackBufferCount
);
1842 (*lpdsf
)->s
.backbuffer
= back
=
1843 (LPDIRECTDRAWSURFACE3
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawSurface3
));
1845 TRACE(ddraw
,"allocated back-buffer (%p)\n", back
);
1847 this->lpvtbl
->fnAddRef(this);
1848 back
->s
.ddraw
= this;
1851 back
->lpvtbl
= (LPDIRECTDRAWSURFACE3_VTABLE
)&xlib_dds3vt
;
1852 /* Copy the surface description from the front buffer */
1853 back
->s
.surface_desc
= (*lpdsf
)->s
.surface_desc
;
1855 /* Create the XImage */
1856 img
= create_ximage(this, back
);
1858 return DDERR_OUTOFMEMORY
;
1859 back
->t
.xlib
.image
= img
;
1861 back
->s
.backbuffer
= NULL
; /* does not have a backbuffer, it is
1864 /* Add relevant info to front and back buffers */
1865 (*lpdsf
)->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_FRONTBUFFER
;
1866 back
->s
.surface_desc
.ddsCaps
.dwCaps
|= DDSCAPS_BACKBUFFER
;
1867 back
->s
.surface_desc
.dwFlags
&= ~DDSD_BACKBUFFERCOUNT
;
1868 back
->s
.surface_desc
.ddsCaps
.dwCaps
&= ~DDSCAPS_VISIBLE
;
1871 /* There is no Xlib-specific code here...
1872 Go to the common surface creation function */
1873 return common_off_screen_CreateSurface(this, lpddsd
, *lpdsf
);
1879 static HRESULT WINAPI
IDirectDraw2_DuplicateSurface(
1880 LPDIRECTDRAW2
this,LPDIRECTDRAWSURFACE src
,LPDIRECTDRAWSURFACE
*dst
1882 FIXME(ddraw
,"(%p)->(%p,%p) simply copies\n",this,src
,dst
);
1883 *dst
= src
; /* FIXME */
1888 * The Xlib Implementation tries to use the passed hwnd as drawing window,
1889 * even when the approbiate bitmasks are not specified.
1891 static HRESULT WINAPI
IDirectDraw2_SetCooperativeLevel(
1892 LPDIRECTDRAW2
this,HWND32 hwnd
,DWORD cooplevel
1899 FE(DDSCL_FULLSCREEN
)
1900 FE(DDSCL_ALLOWREBOOT
)
1901 FE(DDSCL_NOWINDOWCHANGES
)
1903 FE(DDSCL_ALLOWMODEX
)
1905 FE(DDSCL_SETFOCUSWINDOW
)
1906 FE(DDSCL_SETDEVICEWINDOW
)
1907 FE(DDSCL_CREATEDEVICEWINDOW
)
1910 FIXME(ddraw
,"(%p)->(%08lx,%08lx)\n",this,(DWORD
)hwnd
,cooplevel
);
1911 if(TRACE_ON(ddraw
)){
1912 dbg_decl_str(ddraw
, 512);
1913 for (i
=0;i
<sizeof(flagmap
)/sizeof(flagmap
[0]);i
++)
1914 if (flagmap
[i
].mask
& cooplevel
)
1915 dsprintf(ddraw
, "%s ", flagmap
[i
].name
);
1916 TRACE(ddraw
," cooperative level %s\n", dbg_str(ddraw
));
1918 this->d
.mainWindow
= hwnd
;
1922 /* Small helper to either use the cooperative window or create a new
1923 * one (for mouse and keyboard input) and drawing in the Xlib implementation.
1925 static void _common_IDirectDraw_SetDisplayMode(LPDIRECTDRAW
this) {
1928 /* Do not destroy the application supplied cooperative window */
1929 if (this->d
.window
&& this->d
.window
!= this->d
.mainWindow
) {
1930 DestroyWindow32(this->d
.window
);
1933 /* Sanity check cooperative window before assigning it to drawing. */
1934 if ( IsWindow32(this->d
.mainWindow
) &&
1935 IsWindowVisible32(this->d
.mainWindow
)
1937 GetWindowRect32(this->d
.mainWindow
,&rect
);
1938 if (((rect
.right
-rect
.left
) >= this->d
.width
) &&
1939 ((rect
.bottom
-rect
.top
) >= this->d
.height
)
1941 this->d
.window
= this->d
.mainWindow
;
1943 /* ... failed, create new one. */
1944 if (!this->d
.window
) {
1945 this->d
.window
= CreateWindowEx32A(
1949 WS_VISIBLE
|WS_SYSMENU
|WS_THICKFRAME
,
1958 /*Store THIS with the window. We'll use it in the window procedure*/
1959 SetWindowLong32A(this->d
.window
,ddrawXlibThisOffset
,(LONG
)this);
1960 ShowWindow32(this->d
.window
,TRUE
);
1961 UpdateWindow32(this->d
.window
);
1963 SetFocus32(this->d
.window
);
1966 static HRESULT WINAPI
DGA_IDirectDraw_SetDisplayMode(
1967 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
1969 #ifdef HAVE_LIBXXF86DGA
1970 int i
,*depths
,depcount
,mode_count
;
1972 TRACE(ddraw
, "(%p)->(%ld,%ld,%ld)\n", this, width
, height
, depth
);
1974 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
1975 for (i
=0;i
<depcount
;i
++)
1976 if (depths
[i
]==depth
)
1979 if (i
==depcount
) {/* not found */
1980 ERR(ddraw
,"(w=%ld,h=%ld,d=%ld), unsupported depth!\n",width
,height
,depth
);
1981 return DDERR_UNSUPPORTEDMODE
;
1983 if (this->d
.width
< width
) {
1984 ERR(ddraw
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), width %ld exceeds framebuffer width %ld\n",width
,height
,depth
,width
,this->d
.width
);
1985 return DDERR_UNSUPPORTEDMODE
;
1987 this->d
.width
= width
;
1988 this->d
.height
= height
;
1989 this->d
.depth
= depth
;
1991 /* adjust fb_height, so we don't overlap */
1992 if (this->e
.dga
.fb_height
< height
)
1993 this->e
.dga
.fb_height
= height
;
1994 _common_IDirectDraw_SetDisplayMode(this);
1996 #ifdef HAVE_LIBXXF86VM
1998 XF86VidModeModeInfo
**all_modes
, *vidmode
= NULL
;
1999 /* set fullscreen mode */
2000 /* do we need to save the old video mode and restore it when we exit? */
2002 TSXF86VidModeGetAllModeLines(display
,DefaultScreen(display
),&mode_count
,&all_modes
);
2003 for (i
=0;i
<mode_count
;i
++)
2005 if (all_modes
[i
]->hdisplay
== width
&& all_modes
[i
]->vdisplay
== height
)
2007 vidmode
= (XF86VidModeModeInfo
*)malloc(sizeof(XF86VidModeModeInfo
));
2008 *vidmode
= *(all_modes
[i
]);
2011 TSXFree(all_modes
[i
]->private);
2016 WARN(ddraw
, "Fullscreen mode not available!\n");
2019 TSXF86VidModeSwitchToMode(display
, DefaultScreen(display
), vidmode
);
2023 /* FIXME: this function OVERWRITES several signal handlers.
2024 * can we save them? and restore them later? In a way that
2025 * it works for the library too?
2027 TSXF86DGADirectVideo(display
,DefaultScreen(display
),XF86DGADirectGraphics
);
2029 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,this->e
.dga
.fb_height
);
2032 #ifdef RESTORE_SIGNALS
2033 SIGNAL_InitEmulator();
2036 #else /* defined(HAVE_LIBXXF86DGA) */
2037 return E_UNEXPECTED
;
2038 #endif /* defined(HAVE_LIBXXF86DGA) */
2041 static HRESULT WINAPI
Xlib_IDirectDraw_SetDisplayMode(
2042 LPDIRECTDRAW
this,DWORD width
,DWORD height
,DWORD depth
2044 int i
,*depths
,depcount
;
2047 TRACE(ddraw
, "(%p)->SetDisplayMode(%ld,%ld,%ld)\n",
2048 this, width
, height
, depth
);
2050 depths
= TSXListDepths(display
,DefaultScreen(display
),&depcount
);
2051 for (i
=0;i
<depcount
;i
++)
2052 if (depths
[i
]==depth
)
2055 if (i
==depcount
) {/* not found */
2056 sprintf(buf
,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width
,height
,depth
);
2057 MessageBox32A(0,buf
,"WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
2058 return DDERR_UNSUPPORTEDMODE
;
2060 this->d
.width
= width
;
2061 this->d
.height
= height
;
2062 this->d
.depth
= depth
;
2064 _common_IDirectDraw_SetDisplayMode(this);
2066 this->e
.xlib
.paintable
= 1;
2067 this->e
.xlib
.drawable
= WIN_FindWndPtr(this->d
.window
)->window
;
2068 /* We don't have a context for this window. Host off the desktop */
2069 if( !this->e
.xlib
.drawable
)
2070 this->e
.xlib
.drawable
= WIN_GetDesktop()->window
;
2074 static HRESULT WINAPI
DGA_IDirectDraw2_GetCaps(
2075 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2077 #ifdef HAVE_LIBXXF86DGA
2078 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2079 caps1
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2080 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2081 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2083 caps2
->dwVidMemTotal
= this->e
.dga
.fb_memsize
;
2084 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
); /* we can do anything */
2085 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2088 #else /* defined(HAVE_LIBXXF86DGA) */
2089 return E_UNEXPECTED
;
2090 #endif /* defined(HAVE_LIBXXF86DGA) */
2093 static HRESULT WINAPI
Xlib_IDirectDraw2_GetCaps(
2094 LPDIRECTDRAW2
this,LPDDCAPS caps1
,LPDDCAPS caps2
2096 TRACE(ddraw
,"(%p)->GetCaps(%p,%p)\n",this,caps1
,caps2
);
2098 caps1
->dwVidMemTotal
= 2048*1024;
2099 caps1
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
|DDCAPS_GDI
);
2100 caps1
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2102 caps2
->dwVidMemTotal
= 2048*1024;
2103 caps2
->dwCaps
= 0xffffffff&~(DDCAPS_BANKSWITCHED
|DDCAPS_GDI
);
2104 caps2
->ddsCaps
.dwCaps
= 0xffffffff; /* we can do anything */
2106 /* END FIXME: Xlib */
2110 static HRESULT WINAPI
IDirectDraw2_CreateClipper(
2111 LPDIRECTDRAW2
this,DWORD x
,LPDIRECTDRAWCLIPPER
*lpddclip
,LPUNKNOWN lpunk
2113 FIXME(ddraw
,"(%p)->(%08lx,%p,%p),stub!\n",
2114 this,x
,lpddclip
,lpunk
2116 *lpddclip
= (LPDIRECTDRAWCLIPPER
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawClipper
));
2117 (*lpddclip
)->ref
= 1;
2118 (*lpddclip
)->lpvtbl
= &ddclipvt
;
2122 static HRESULT WINAPI
common_IDirectDraw2_CreatePalette(
2123 LPDIRECTDRAW2
this,DWORD x
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2125 *lpddpal
= (LPDIRECTDRAWPALETTE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPalette
));
2126 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
2127 (*lpddpal
)->ref
= 1;
2128 (*lpddpal
)->ddraw
= (LPDIRECTDRAW
)this;
2129 (*lpddpal
)->installed
= 0;
2130 if (this->d
.depth
<=8) {
2131 (*lpddpal
)->cm
= TSXCreateColormap(display
,DefaultRootWindow(display
),DefaultVisualOfScreen(screen
),AllocAll
);
2133 /* we don't want palettes in hicolor or truecolor */
2139 static HRESULT WINAPI
DGA_IDirectDraw2_CreatePalette(
2140 LPDIRECTDRAW2
this,DWORD x
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2143 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,x
,palent
,lpddpal
,lpunk
);
2144 res
= common_IDirectDraw2_CreatePalette(this,x
,palent
,lpddpal
,lpunk
);
2145 if (res
!= 0) return res
;
2146 (*lpddpal
)->lpvtbl
= &dga_ddpalvt
;
2150 static HRESULT WINAPI
Xlib_IDirectDraw2_CreatePalette(
2151 LPDIRECTDRAW2
this,DWORD x
,LPPALETTEENTRY palent
,LPDIRECTDRAWPALETTE
*lpddpal
,LPUNKNOWN lpunk
2153 TRACE(ddraw
,"(%p)->(%08lx,%p,%p,%p)\n",this,x
,palent
,lpddpal
,lpunk
);
2154 *lpddpal
= (LPDIRECTDRAWPALETTE
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDrawPalette
));
2155 if (*lpddpal
== NULL
) return E_OUTOFMEMORY
;
2156 (*lpddpal
)->ref
= 1;
2157 (*lpddpal
)->installed
= 0;
2159 FIXME(ddraw
,"needs to handle palent (%p)\n",palent
);
2161 (*lpddpal
)->ddraw
= (LPDIRECTDRAW
)this;
2162 this->lpvtbl
->fnAddRef(this);
2165 (*lpddpal
)->lpvtbl
= &xlib_ddpalvt
;
2169 static HRESULT WINAPI
DGA_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
2170 #ifdef HAVE_LIBXXF86DGA
2171 TRACE(ddraw
, "(%p)->()\n",this);
2173 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
2174 #ifdef RESTORE_SIGNALS
2175 SIGNAL_InitEmulator();
2178 #else /* defined(HAVE_LIBXXF86DGA) */
2179 return E_UNEXPECTED
;
2183 static HRESULT WINAPI
Xlib_IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2
this) {
2184 TRACE(ddraw
, "(%p)->RestoreDisplayMode()\n", this);
2189 static HRESULT WINAPI
IDirectDraw2_WaitForVerticalBlank(
2190 LPDIRECTDRAW2
this,DWORD x
,HANDLE32 h
2192 TRACE(ddraw
,"(%p)->(0x%08lx,0x%08x)\n",this,x
,h
);
2196 static ULONG WINAPI
IDirectDraw2_AddRef(LPDIRECTDRAW2
this) {
2197 TRACE( ddraw
, "(%p)->() incrementing from %lu.\n", this, this->ref
);
2199 return ++(this->ref
);
2202 static ULONG WINAPI
DGA_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
2203 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
2205 #ifdef HAVE_LIBXXF86DGA
2206 if (!--(this->ref
)) {
2207 TSXF86DGADirectVideo(display
,DefaultScreen(display
),0);
2208 #ifdef RESTORE_SIGNALS
2209 SIGNAL_InitEmulator();
2211 HeapFree(GetProcessHeap(),0,this);
2214 #endif /* defined(HAVE_LIBXXF86DGA) */
2218 static ULONG WINAPI
Xlib_IDirectDraw2_Release(LPDIRECTDRAW2
this) {
2219 TRACE( ddraw
, "(%p)->() decrementing from %lu.\n", this, this->ref
);
2221 if (!--(this->ref
)) {
2222 HeapFree(GetProcessHeap(),0,this);
2225 /* FIXME: destroy window ... */
2229 static HRESULT WINAPI
DGA_IDirectDraw2_QueryInterface(
2230 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
2234 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2235 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
2236 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
2238 this->lpvtbl
->fnAddRef(this);
2241 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
2242 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_ddvt
;
2243 this->lpvtbl
->fnAddRef(this);
2247 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
2248 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&dga_dd2vt
;
2249 this->lpvtbl
->fnAddRef(this);
2253 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
2256 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2258 d3d
->ddraw
= (LPDIRECTDRAW
)this;
2259 this->lpvtbl
->fnAddRef(this);
2260 d3d
->lpvtbl
= &d3dvt
;
2264 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
2267 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2269 d3d
->ddraw
= (LPDIRECTDRAW
)this;
2270 this->lpvtbl
->fnAddRef(this);
2271 d3d
->lpvtbl
= &d3d2vt
;
2275 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
2276 return OLE_E_ENUM_NOMORE
;
2279 static HRESULT WINAPI
Xlib_IDirectDraw2_QueryInterface(
2280 LPDIRECTDRAW2
this,REFIID refiid
,LPVOID
*obj
2284 WINE_StringFromCLSID((LPCLSID
)refiid
,xrefiid
);
2285 TRACE(ddraw
,"(%p)->(%s,%p)\n",this,xrefiid
,obj
);
2286 if (!memcmp(&IID_IUnknown
,refiid
,sizeof(IID_IUnknown
))) {
2288 this->lpvtbl
->fnAddRef(this);
2291 if (!memcmp(&IID_IDirectDraw
,refiid
,sizeof(IID_IDirectDraw
))) {
2292 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_ddvt
;
2293 this->lpvtbl
->fnAddRef(this);
2297 if (!memcmp(&IID_IDirectDraw2
,refiid
,sizeof(IID_IDirectDraw2
))) {
2298 this->lpvtbl
= (LPDIRECTDRAW2_VTABLE
)&xlib_dd2vt
;
2299 this->lpvtbl
->fnAddRef(this);
2303 if (!memcmp(&IID_IDirect3D
,refiid
,sizeof(IID_IDirect3D
))) {
2306 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2308 d3d
->ddraw
= (LPDIRECTDRAW
)this;
2309 this->lpvtbl
->fnAddRef(this);
2310 d3d
->lpvtbl
= &d3dvt
;
2314 if (!memcmp(&IID_IDirect3D2
,refiid
,sizeof(IID_IDirect3D
))) {
2317 d3d
= HeapAlloc(GetProcessHeap(),0,sizeof(*d3d
));
2319 d3d
->ddraw
= (LPDIRECTDRAW
)this;
2320 this->lpvtbl
->fnAddRef(this);
2321 d3d
->lpvtbl
= &d3d2vt
;
2325 WARN(ddraw
,"(%p):interface for IID %s _NOT_ found!\n",this,xrefiid
);
2326 return OLE_E_ENUM_NOMORE
;
2329 static HRESULT WINAPI
IDirectDraw2_GetVerticalBlankStatus(
2330 LPDIRECTDRAW2
this,BOOL32
*status
2332 TRACE(ddraw
,"(%p)->(%p)\n",this,status
);
2337 static HRESULT WINAPI
IDirectDraw2_EnumDisplayModes(
2338 LPDIRECTDRAW2
this,DWORD dwFlags
,LPDDSURFACEDESC lpddsfd
,LPVOID context
,LPDDENUMMODESCALLBACK modescb
2340 DDSURFACEDESC ddsfd
;
2343 } modes
[5] = { /* some of the usual modes */
2350 static int depths
[4] = {8,16,24,32};
2353 TRACE(ddraw
,"(%p)->(0x%08lx,%p,%p,%p)\n",this,dwFlags
,lpddsfd
,context
,modescb
);
2354 ddsfd
.dwSize
= sizeof(ddsfd
);
2355 ddsfd
.dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
2356 if (dwFlags
& DDEDM_REFRESHRATES
) {
2357 ddsfd
.dwFlags
|= DDSD_REFRESHRATE
;
2358 ddsfd
.x
.dwRefreshRate
= 60;
2361 for (i
=0;i
<sizeof(depths
)/sizeof(depths
[0]);i
++) {
2362 ddsfd
.dwBackBufferCount
= 1;
2363 ddsfd
.ddpfPixelFormat
.dwFourCC
= 0;
2364 ddsfd
.ddpfPixelFormat
.dwFlags
= DDPF_RGB
;
2365 ddsfd
.ddpfPixelFormat
.x
.dwRGBBitCount
= depths
[i
];
2366 /* FIXME: those masks would have to be set in depth > 8 */
2368 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0;
2369 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0;
2370 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0;
2371 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
2372 ddsfd
.ddsCaps
.dwCaps
=DDSCAPS_PALETTE
;
2373 ddsfd
.ddpfPixelFormat
.dwFlags
|=DDPF_PALETTEINDEXED8
;
2375 ddsfd
.ddpfPixelFormat
.xy
.dwRGBAlphaBitMask
= 0;
2377 /* FIXME: We should query those from X itself */
2378 switch (depths
[i
]) {
2380 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x000f;
2381 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x00f0;
2382 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x0f00;
2385 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x000000ff;
2386 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000ff00;
2387 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x00ff0000;
2390 ddsfd
.ddpfPixelFormat
.y
.dwRBitMask
= 0x000000ff;
2391 ddsfd
.ddpfPixelFormat
.z
.dwGBitMask
= 0x0000ff00;
2392 ddsfd
.ddpfPixelFormat
.xx
.dwBBitMask
= 0x00ff0000;
2397 ddsfd
.dwWidth
= screenWidth
;
2398 ddsfd
.dwHeight
= screenHeight
;
2399 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
2400 if (!modescb(&ddsfd
,context
)) return 0;
2402 for (j
=0;j
<sizeof(modes
)/sizeof(modes
[0]);j
++) {
2403 ddsfd
.dwWidth
= modes
[j
].w
;
2404 ddsfd
.dwHeight
= modes
[j
].h
;
2405 TRACE(ddraw
," enumerating (%ldx%ldx%d)\n",ddsfd
.dwWidth
,ddsfd
.dwHeight
,depths
[i
]);
2406 if (!modescb(&ddsfd
,context
)) return 0;
2409 if (!(dwFlags
& DDEDM_STANDARDVGAMODES
)) {
2410 /* modeX is not standard VGA */
2412 ddsfd
.dwHeight
= 200;
2413 ddsfd
.dwWidth
= 320;
2414 TRACE(ddraw
," enumerating (320x200x%d)\n",depths
[i
]);
2415 if (!modescb(&ddsfd
,context
)) return 0;
2421 static HRESULT WINAPI
DGA_IDirectDraw2_GetDisplayMode(
2422 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
2424 #ifdef HAVE_LIBXXF86DGA
2425 TRACE(ddraw
,"(%p)->(%p)\n",this,lpddsfd
);
2426 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
2427 lpddsfd
->dwHeight
= screenHeight
;
2428 lpddsfd
->dwWidth
= screenWidth
;
2429 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
2430 lpddsfd
->dwBackBufferCount
= 1;
2431 lpddsfd
->x
.dwRefreshRate
= 60;
2432 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
2433 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
2435 #else /* defined(HAVE_LIBXXF86DGA) */
2436 return E_UNEXPECTED
;
2437 #endif /* defined(HAVE_LIBXXF86DGA) */
2440 static HRESULT WINAPI
Xlib_IDirectDraw2_GetDisplayMode(
2441 LPDIRECTDRAW2
this,LPDDSURFACEDESC lpddsfd
2443 TRACE(ddraw
,"(%p)->GetDisplayMode(%p)\n",this,lpddsfd
);
2444 lpddsfd
->dwFlags
= DDSD_HEIGHT
|DDSD_WIDTH
|DDSD_PITCH
|DDSD_BACKBUFFERCOUNT
|DDSD_PIXELFORMAT
|DDSD_CAPS
;
2445 lpddsfd
->dwHeight
= screenHeight
;
2446 lpddsfd
->dwWidth
= screenWidth
;
2447 /* POOLE FIXME: Xlib */
2448 lpddsfd
->lPitch
= this->e
.dga
.fb_width
*this->d
.depth
/8;
2449 /* END FIXME: Xlib */
2450 lpddsfd
->dwBackBufferCount
= 1;
2451 lpddsfd
->x
.dwRefreshRate
= 60;
2452 lpddsfd
->ddsCaps
.dwCaps
= DDSCAPS_PALETTE
;
2453 _getpixelformat(this,&(lpddsfd
->ddpfPixelFormat
));
2457 static HRESULT WINAPI
IDirectDraw2_FlipToGDISurface(LPDIRECTDRAW2
this) {
2458 TRACE(ddraw
,"(%p)->()\n",this);
2462 static HRESULT WINAPI
IDirectDraw2_GetMonitorFrequency(
2463 LPDIRECTDRAW2
this,LPDWORD freq
2465 FIXME(ddraw
,"(%p)->(%p) returns 60 Hz always\n",this,freq
);
2466 *freq
= 60*100; /* 60 Hz */
2470 /* what can we directly decompress? */
2471 static HRESULT WINAPI
IDirectDraw2_GetFourCCCodes(
2472 LPDIRECTDRAW2
this,LPDWORD x
,LPDWORD y
2474 FIXME(ddraw
,"(%p,%p,%p), stub\n",this,x
,y
);
2478 static HRESULT WINAPI
IDirectDraw2_EnumSurfaces(
2479 LPDIRECTDRAW2
this,DWORD x
,LPDDSURFACEDESC ddsfd
,LPVOID context
,LPDDENUMSURFACESCALLBACK ddsfcb
2481 FIXME(ddraw
,"(%p)->(0x%08lx,%p,%p,%p),stub!\n",this,x
,ddsfd
,context
,ddsfcb
);
2485 static HRESULT WINAPI
IDirectDraw2_Compact(
2486 LPDIRECTDRAW2
this )
2488 FIXME(ddraw
,"(%p)->()\n", this );
2494 /* Note: Hack so we can reuse the old functions without compiler warnings */
2496 # define XCAST(fun) (typeof(dga_ddvt.fn##fun))
2498 # define XCAST(fun) (void*)
2501 static struct IDirectDraw_VTable dga_ddvt
= {
2502 XCAST(QueryInterface
)DGA_IDirectDraw2_QueryInterface
,
2503 XCAST(AddRef
)IDirectDraw2_AddRef
,
2504 XCAST(Release
)DGA_IDirectDraw2_Release
,
2505 XCAST(Compact
)IDirectDraw2_Compact
,
2506 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
2507 XCAST(CreatePalette
)DGA_IDirectDraw2_CreatePalette
,
2508 XCAST(CreateSurface
)DGA_IDirectDraw2_CreateSurface
,
2509 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
2510 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
2511 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
2512 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
2513 XCAST(GetCaps
)DGA_IDirectDraw2_GetCaps
,
2514 XCAST(GetDisplayMode
)DGA_IDirectDraw2_GetDisplayMode
,
2515 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
2516 XCAST(GetGDISurface
)15,
2517 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
2518 XCAST(GetScanLine
)17,
2519 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
2520 XCAST(Initialize
)19,
2521 XCAST(RestoreDisplayMode
)DGA_IDirectDraw2_RestoreDisplayMode
,
2522 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
2523 DGA_IDirectDraw_SetDisplayMode
,
2524 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
2527 static struct IDirectDraw_VTable xlib_ddvt
= {
2528 XCAST(QueryInterface
)Xlib_IDirectDraw2_QueryInterface
,
2529 XCAST(AddRef
)IDirectDraw2_AddRef
,
2530 XCAST(Release
)Xlib_IDirectDraw2_Release
,
2531 XCAST(Compact
)IDirectDraw2_Compact
,
2532 XCAST(CreateClipper
)IDirectDraw2_CreateClipper
,
2533 XCAST(CreatePalette
)Xlib_IDirectDraw2_CreatePalette
,
2534 XCAST(CreateSurface
)Xlib_IDirectDraw2_CreateSurface
,
2535 XCAST(DuplicateSurface
)IDirectDraw2_DuplicateSurface
,
2536 XCAST(EnumDisplayModes
)IDirectDraw2_EnumDisplayModes
,
2537 XCAST(EnumSurfaces
)IDirectDraw2_EnumSurfaces
,
2538 XCAST(FlipToGDISurface
)IDirectDraw2_FlipToGDISurface
,
2539 XCAST(GetCaps
)Xlib_IDirectDraw2_GetCaps
,
2540 XCAST(GetDisplayMode
)Xlib_IDirectDraw2_GetDisplayMode
,
2541 XCAST(GetFourCCCodes
)IDirectDraw2_GetFourCCCodes
,
2542 XCAST(GetGDISurface
)15,
2543 XCAST(GetMonitorFrequency
)IDirectDraw2_GetMonitorFrequency
,
2544 XCAST(GetScanLine
)17,
2545 XCAST(GetVerticalBlankStatus
)IDirectDraw2_GetVerticalBlankStatus
,
2546 XCAST(Initialize
)19,
2547 XCAST(RestoreDisplayMode
)Xlib_IDirectDraw2_RestoreDisplayMode
,
2548 XCAST(SetCooperativeLevel
)IDirectDraw2_SetCooperativeLevel
,
2549 Xlib_IDirectDraw_SetDisplayMode
,
2550 XCAST(WaitForVerticalBlank
)IDirectDraw2_WaitForVerticalBlank
,
2553 /*****************************************************************************
2559 static HRESULT WINAPI
DGA_IDirectDraw2_SetDisplayMode(
2560 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
2562 return DGA_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
2565 static HRESULT WINAPI
Xlib_IDirectDraw2_SetDisplayMode(
2566 LPDIRECTDRAW2
this,DWORD width
,DWORD height
,DWORD depth
,DWORD xx
,DWORD yy
2568 return Xlib_IDirectDraw_SetDisplayMode((LPDIRECTDRAW
)this,width
,height
,depth
);
2571 static HRESULT WINAPI
DGA_IDirectDraw2_GetAvailableVidMem(
2572 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
2574 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
2575 this,ddscaps
,total
,free
2577 if (total
) *total
= this->e
.dga
.fb_memsize
* 1024;
2578 if (free
) *free
= this->e
.dga
.fb_memsize
* 1024;
2582 static HRESULT WINAPI
Xlib_IDirectDraw2_GetAvailableVidMem(
2583 LPDIRECTDRAW2
this,LPDDSCAPS ddscaps
,LPDWORD total
,LPDWORD free
2585 TRACE(ddraw
,"(%p)->(%p,%p,%p)\n",
2586 this,ddscaps
,total
,free
2588 if (total
) *total
= 2048 * 1024;
2589 if (free
) *free
= 2048 * 1024;
2593 static IDirectDraw2_VTable dga_dd2vt
= {
2594 DGA_IDirectDraw2_QueryInterface
,
2595 IDirectDraw2_AddRef
,
2596 DGA_IDirectDraw2_Release
,
2597 IDirectDraw2_Compact
,
2598 IDirectDraw2_CreateClipper
,
2599 DGA_IDirectDraw2_CreatePalette
,
2600 DGA_IDirectDraw2_CreateSurface
,
2602 IDirectDraw2_EnumDisplayModes
,
2603 IDirectDraw2_EnumSurfaces
,
2604 IDirectDraw2_FlipToGDISurface
,
2605 DGA_IDirectDraw2_GetCaps
,
2606 DGA_IDirectDraw2_GetDisplayMode
,
2607 IDirectDraw2_GetFourCCCodes
,
2609 IDirectDraw2_GetMonitorFrequency
,
2611 IDirectDraw2_GetVerticalBlankStatus
,
2613 DGA_IDirectDraw2_RestoreDisplayMode
,
2614 IDirectDraw2_SetCooperativeLevel
,
2615 DGA_IDirectDraw2_SetDisplayMode
,
2616 IDirectDraw2_WaitForVerticalBlank
,
2617 DGA_IDirectDraw2_GetAvailableVidMem
2620 static struct IDirectDraw2_VTable xlib_dd2vt
= {
2621 Xlib_IDirectDraw2_QueryInterface
,
2622 IDirectDraw2_AddRef
,
2623 Xlib_IDirectDraw2_Release
,
2624 IDirectDraw2_Compact
,
2625 IDirectDraw2_CreateClipper
,
2626 Xlib_IDirectDraw2_CreatePalette
,
2627 Xlib_IDirectDraw2_CreateSurface
,
2629 IDirectDraw2_EnumDisplayModes
,
2630 IDirectDraw2_EnumSurfaces
,
2631 IDirectDraw2_FlipToGDISurface
,
2632 Xlib_IDirectDraw2_GetCaps
,
2633 Xlib_IDirectDraw2_GetDisplayMode
,
2634 IDirectDraw2_GetFourCCCodes
,
2636 IDirectDraw2_GetMonitorFrequency
,
2638 IDirectDraw2_GetVerticalBlankStatus
,
2640 Xlib_IDirectDraw2_RestoreDisplayMode
,
2641 IDirectDraw2_SetCooperativeLevel
,
2642 Xlib_IDirectDraw2_SetDisplayMode
,
2643 IDirectDraw2_WaitForVerticalBlank
,
2644 Xlib_IDirectDraw2_GetAvailableVidMem
2647 /******************************************************************************
2651 LRESULT WINAPI
Xlib_DDWndProc(HWND32 hwnd
,UINT32 msg
,WPARAM32 wParam
,LPARAM lParam
)
2654 LPDIRECTDRAW ddraw
= NULL
;
2657 /* FIXME(ddraw,"(0x%04x,%s,0x%08lx,0x%08lx),stub!\n",(int)hwnd,SPY_GetMsgName(msg),(long)wParam,(long)lParam); */
2659 SetLastError( ERROR_SUCCESS
);
2660 ddraw
= (LPDIRECTDRAW
)GetWindowLong32A( hwnd
, ddrawXlibThisOffset
);
2662 ( ( lastError
= GetLastError() ) != ERROR_SUCCESS
)
2665 ERR( ddraw
, "Unable to retrieve this ptr from window. Error %08lx\n", lastError
);
2670 /* Perform any special direct draw functions */
2672 ddraw
->e
.xlib
.paintable
= 1;
2674 /* Now let the application deal with the rest of this */
2675 if( ddraw
->d
.mainWindow
)
2678 /* Don't think that we actually need to call this but...
2679 might as well be on the safe side of things... */
2681 /* I changed hwnd to ddraw->d.mainWindow as I did not see why
2682 it should be the procedures of our fake window that gets called
2683 instead of those of the window provided by the application.
2684 And with this patch, mouse clicks work with Monkey Island III
2686 ret
= DefWindowProc32A( ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
2690 /* We didn't handle the message - give it to the application */
2691 if (ddraw
&& ddraw
->d
.mainWindow
&& WIN_FindWndPtr(ddraw
->d
.mainWindow
)) {
2692 ret
= CallWindowProc32A( WIN_FindWndPtr( ddraw
->d
.mainWindow
)->winproc
,
2693 ddraw
->d
.mainWindow
, msg
, wParam
, lParam
);
2698 ret
= DefWindowProc32A(hwnd
, msg
, wParam
, lParam
);
2704 ret
= DefWindowProc32A(hwnd
,msg
,wParam
,lParam
);
2710 HRESULT WINAPI
DGA_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
2711 #ifdef HAVE_LIBXXF86DGA
2712 int memsize
,banksize
,width
,major
,minor
,flags
,height
;
2716 /* Must be able to access /dev/mem for DGA extensions to work, root is not neccessary. --stephenc */
2717 if ((fd
= open("/dev/mem", O_RDWR
)) != -1)
2721 MSG("Must be able to access /dev/mem to use XF86DGA!\n");
2722 MessageBox32A(0,"Using the XF86DGA extension requires access to /dev/mem.","WINE DirectDraw",MB_OK
|MB_ICONSTOP
);
2723 return E_UNEXPECTED
;
2725 if (!DDRAW_DGA_Available()) {
2726 TRACE(ddraw
,"No XF86DGA detected.\n");
2727 return DDERR_GENERIC
;
2729 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
2730 (*lplpDD
)->lpvtbl
= &dga_ddvt
;
2732 TSXF86DGAQueryVersion(display
,&major
,&minor
);
2733 TRACE(ddraw
,"XF86DGA is version %d.%d\n",major
,minor
);
2734 TSXF86DGAQueryDirectVideo(display
,DefaultScreen(display
),&flags
);
2735 if (!(flags
& XF86DGADirectPresent
))
2736 MSG("direct video is NOT PRESENT.\n");
2737 TSXF86DGAGetVideo(display
,DefaultScreen(display
),&addr
,&width
,&banksize
,&memsize
);
2738 TRACE(ddraw
,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
2739 addr
,width
,banksize
,memsize
2741 (*lplpDD
)->e
.dga
.fb_width
= width
;
2742 (*lplpDD
)->d
.width
= width
;
2743 (*lplpDD
)->e
.dga
.fb_addr
= addr
;
2744 (*lplpDD
)->e
.dga
.fb_memsize
= memsize
;
2745 (*lplpDD
)->e
.dga
.fb_banksize
= banksize
;
2747 TSXF86DGAGetViewPortSize(display
,DefaultScreen(display
),&width
,&height
);
2748 TSXF86DGASetViewPort(display
,DefaultScreen(display
),0,0);
2749 (*lplpDD
)->e
.dga
.fb_height
= screenHeight
;
2751 (*lplpDD
)->e
.dga
.vpmask
= 1;
2753 (*lplpDD
)->e
.dga
.vpmask
= 0;
2756 /* just assume the default depth is the DGA depth too */
2757 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(screen
);
2758 #ifdef RESTORE_SIGNALS
2759 SIGNAL_InitEmulator();
2763 #else /* defined(HAVE_LIBXXF86DGA) */
2764 return DDERR_INVALIDDIRECTDRAWGUID
;
2765 #endif /* defined(HAVE_LIBXXF86DGA) */
2769 DDRAW_XSHM_Available()
2771 #ifdef HAVE_LIBXXSHM
2772 if (TSXShmQueryExtension(display
))
2777 if (TSXShmQueryVersion(display
, &major
, &minor
, &shpix
))
2789 HRESULT WINAPI
Xlib_DirectDrawCreate( LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
2791 *lplpDD
= (LPDIRECTDRAW
)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,sizeof(IDirectDraw
));
2792 (*lplpDD
)->lpvtbl
= &xlib_ddvt
;
2794 (*lplpDD
)->e
.xlib
.drawable
= 0; /* in SetDisplayMode */
2796 (*lplpDD
)->d
.depth
= DefaultDepthOfScreen(screen
);
2797 (*lplpDD
)->d
.height
= screenHeight
;
2798 (*lplpDD
)->d
.width
= screenWidth
;
2800 #ifdef HAVE_LIBXXSHM
2801 /* Test if XShm is available.
2802 As XShm is not ready yet for 'prime-time', it is disabled for now */
2803 if (((*lplpDD
)->e
.xlib
.xshm_active
= 0 /* DDRAW_XSHM_Available() */))
2804 TRACE(ddraw
, "Using XShm extesion.\n");
2810 HRESULT WINAPI
DirectDrawCreate( LPGUID lpGUID
, LPDIRECTDRAW
*lplpDD
, LPUNKNOWN pUnkOuter
) {
2817 WINE_StringFromCLSID(lpGUID
,xclsid
);
2819 sprintf(xclsid
,"<guid-%0x08x>",(int)lpGUID
);
2823 TRACE(ddraw
,"(%s,%p,%p)\n",xclsid
,lplpDD
,pUnkOuter
);
2826 /* if they didn't request a particular interface, use the best
2828 if (DDRAW_DGA_Available())
2829 lpGUID
= &DGA_DirectDraw_GUID
;
2831 lpGUID
= &XLIB_DirectDraw_GUID
;
2834 wc
.style
= CS_GLOBALCLASS
;
2835 wc
.lpfnWndProc
= Xlib_DDWndProc
;
2837 wc
.cbWndExtra
= /* Defines extra mem for window. This is used for storing this */
2838 sizeof( LPDIRECTDRAW
); /* ddrawXlibThisOffset */
2840 /* We can be a child of the desktop since we're really important */
2841 pParentWindow
= WIN_GetDesktop();
2842 wc
.hInstance
= pParentWindow
? pParentWindow
->hwndSelf
: 0;
2846 wc
.hCursor
= (HCURSOR32
)IDC_ARROW32A
;
2847 wc
.hbrBackground
= NULL_BRUSH
;
2848 wc
.lpszMenuName
= 0;
2849 wc
.lpszClassName
= "WINE_DirectDraw";
2850 RegisterClass32A(&wc
);
2852 if (!memcmp(lpGUID
, &DGA_DirectDraw_GUID
, sizeof(GUID
)))
2853 ret
= DGA_DirectDrawCreate(lplpDD
, pUnkOuter
);
2854 else if (!memcmp(lpGUID
, &XLIB_DirectDraw_GUID
, sizeof(GUID
)))
2855 ret
= Xlib_DirectDrawCreate(lplpDD
, pUnkOuter
);
2859 (*lplpDD
)->d
.winclass
= RegisterClass32A(&wc
);
2863 fprintf(stderr
,"DirectDrawCreate(%s,%p,%p): did not recognize requested GUID\n",xclsid
,lplpDD
,pUnkOuter
);
2864 return DDERR_INVALIDDIRECTDRAWGUID
;